mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-10 00:04:23 -04:00
Port model help editor dialog to c++
This commit is contained in:
parent
fffc3a768b
commit
d62d0b82e3
@ -93,7 +93,6 @@ Raise, unminimize and activate this window.
|
|||||||
QToolBar *toolbar();
|
QToolBar *toolbar();
|
||||||
QAction *actionOpen();
|
QAction *actionOpen();
|
||||||
QAction *actionSaveInProject();
|
QAction *actionSaveInProject();
|
||||||
QAction *actionEditHelp();
|
|
||||||
QAction *actionRun();
|
QAction *actionRun();
|
||||||
QgsMessageBar *messageBar();
|
QgsMessageBar *messageBar();
|
||||||
QGraphicsView *view();
|
QGraphicsView *view();
|
||||||
|
@ -1,178 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
***************************************************************************
|
|
||||||
HelpEditionDialog.py
|
|
||||||
---------------------
|
|
||||||
Date : August 2012
|
|
||||||
Copyright : (C) 2012 by Victor Olaya
|
|
||||||
Email : volayaf at gmail dot com
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
"""
|
|
||||||
|
|
||||||
__author__ = 'Victor Olaya'
|
|
||||||
__date__ = 'August 2012'
|
|
||||||
__copyright__ = '(C) 2012, Victor Olaya'
|
|
||||||
|
|
||||||
import os
|
|
||||||
import json
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
from qgis.PyQt import uic
|
|
||||||
from qgis.PyQt.QtWidgets import QDialog, QTreeWidgetItem
|
|
||||||
|
|
||||||
from qgis.core import (Qgis,
|
|
||||||
QgsMessageLog,
|
|
||||||
QgsProcessingUtils,
|
|
||||||
QgsProcessingParameterDefinition,
|
|
||||||
QgsProcessingModelAlgorithm)
|
|
||||||
|
|
||||||
pluginPath = os.path.split(os.path.dirname(__file__))[0]
|
|
||||||
|
|
||||||
with warnings.catch_warnings():
|
|
||||||
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
|
||||||
WIDGET, BASE = uic.loadUiType(
|
|
||||||
os.path.join(pluginPath, 'ui', 'DlgHelpEdition.ui'))
|
|
||||||
|
|
||||||
|
|
||||||
class HelpEditionDialog(BASE, WIDGET):
|
|
||||||
ALG_DESC = 'ALG_DESC'
|
|
||||||
ALG_CREATOR = 'ALG_CREATOR'
|
|
||||||
ALG_HELP_CREATOR = 'ALG_HELP_CREATOR'
|
|
||||||
ALG_VERSION = 'ALG_VERSION'
|
|
||||||
SHORT_DESCRIPTION = 'SHORT_DESCRIPTION'
|
|
||||||
HELP_URL = 'HELP_URL'
|
|
||||||
|
|
||||||
def __init__(self, alg):
|
|
||||||
super(HelpEditionDialog, self).__init__(None)
|
|
||||||
self.setupUi(self)
|
|
||||||
|
|
||||||
self.alg = alg
|
|
||||||
self.descriptions = {}
|
|
||||||
if isinstance(self.alg, QgsProcessingModelAlgorithm):
|
|
||||||
self.descriptions = self.alg.helpContent()
|
|
||||||
else:
|
|
||||||
if self.alg.descriptionFile is not None:
|
|
||||||
helpfile = alg.descriptionFile + '.help'
|
|
||||||
if os.path.exists(helpfile):
|
|
||||||
try:
|
|
||||||
with open(helpfile) as f:
|
|
||||||
self.descriptions = json.load(f)
|
|
||||||
except Exception:
|
|
||||||
QgsMessageLog.logMessage(self.tr('Cannot open help file: {0}').format(helpfile), self.tr('Processing'), Qgis.Warning)
|
|
||||||
|
|
||||||
self.currentName = self.ALG_DESC
|
|
||||||
if self.ALG_DESC in self.descriptions:
|
|
||||||
self.text.setText(self.descriptions[self.ALG_DESC])
|
|
||||||
self.tree.itemClicked.connect(self.changeItem)
|
|
||||||
|
|
||||||
self.fillTree()
|
|
||||||
self.updateHtmlView()
|
|
||||||
|
|
||||||
def reject(self):
|
|
||||||
self.descriptions = None
|
|
||||||
QDialog.reject(self)
|
|
||||||
|
|
||||||
def accept(self):
|
|
||||||
self.descriptions[self.currentName] = str(self.text.toPlainText())
|
|
||||||
QDialog.accept(self)
|
|
||||||
|
|
||||||
def getHtml(self):
|
|
||||||
s = '<p>' + self.getDescription(self.ALG_DESC) + '</p>\n'
|
|
||||||
inputs = ""
|
|
||||||
for param in self.alg.parameterDefinitions():
|
|
||||||
if param.flags() & QgsProcessingParameterDefinition.FlagHidden or param.isDestination():
|
|
||||||
continue
|
|
||||||
|
|
||||||
if self.getDescription(param.name()):
|
|
||||||
inputs += '<h3>' + param.description() + '</h3>\n'
|
|
||||||
inputs += '<p>' + self.getDescription(param.name()) + '</p>\n'
|
|
||||||
if inputs:
|
|
||||||
s += '<h2>' + self.tr('Input parameters') + '</h2>\n' + inputs
|
|
||||||
outputs = ""
|
|
||||||
for out in self.alg.outputDefinitions():
|
|
||||||
if self.getDescription(param.name()):
|
|
||||||
outputs += '<h3>' + out.description() + '</h3>\n'
|
|
||||||
outputs += '<p>' + self.getDescription(out.name()) + '</p>\n'
|
|
||||||
if outputs:
|
|
||||||
s += '<h2>' + self.tr('Outputs') + '</h2>\n' + outputs
|
|
||||||
s += '<br>'
|
|
||||||
if self.getDescription(self.ALG_CREATOR):
|
|
||||||
s += '<p align=\"right\">' + self.tr('Algorithm author:') + ' ' + self.getDescription(self.ALG_CREATOR) + '</p>'
|
|
||||||
if self.getDescription(self.ALG_HELP_CREATOR):
|
|
||||||
s += '<p align=\"right\">' + self.tr('Help author:') + ' ' + self.getDescription(self.ALG_HELP_CREATOR) + '</p>'
|
|
||||||
if self.getDescription(self.ALG_VERSION):
|
|
||||||
s += '<p align=\"right\">' + self.tr('Algorithm version:') + ' ' + self.getDescription(self.ALG_VERSION) + '</p>'
|
|
||||||
return s
|
|
||||||
|
|
||||||
def fillTree(self):
|
|
||||||
item = TreeDescriptionItem(self.tr('Algorithm description'), self.ALG_DESC)
|
|
||||||
self.tree.addTopLevelItem(item)
|
|
||||||
item = TreeDescriptionItem(self.tr('Short description'), self.SHORT_DESCRIPTION)
|
|
||||||
self.tree.addTopLevelItem(item)
|
|
||||||
parametersItem = TreeDescriptionItem(self.tr('Input parameters'), None)
|
|
||||||
self.tree.addTopLevelItem(parametersItem)
|
|
||||||
for param in self.alg.parameterDefinitions():
|
|
||||||
if param.flags() & QgsProcessingParameterDefinition.FlagHidden or param.isDestination():
|
|
||||||
continue
|
|
||||||
|
|
||||||
item = TreeDescriptionItem(param.description(), param.name())
|
|
||||||
parametersItem.addChild(item)
|
|
||||||
outputsItem = TreeDescriptionItem(self.tr('Outputs'), None)
|
|
||||||
self.tree.addTopLevelItem(outputsItem)
|
|
||||||
for out in self.alg.outputDefinitions():
|
|
||||||
item = TreeDescriptionItem(out.description(), out.name())
|
|
||||||
outputsItem.addChild(item)
|
|
||||||
item = TreeDescriptionItem(self.tr('Algorithm author'), self.ALG_CREATOR)
|
|
||||||
self.tree.addTopLevelItem(item)
|
|
||||||
item = TreeDescriptionItem(self.tr('Help author'), self.ALG_HELP_CREATOR)
|
|
||||||
self.tree.addTopLevelItem(item)
|
|
||||||
item = TreeDescriptionItem(self.tr('Algorithm version'), self.ALG_VERSION)
|
|
||||||
self.tree.addTopLevelItem(item)
|
|
||||||
item = TreeDescriptionItem(self.tr('Documentation help URL (for help button)'), self.HELP_URL)
|
|
||||||
self.tree.addTopLevelItem(item)
|
|
||||||
|
|
||||||
def changeItem(self):
|
|
||||||
item = self.tree.currentItem()
|
|
||||||
if isinstance(item, TreeDescriptionItem):
|
|
||||||
if self.currentName:
|
|
||||||
self.descriptions[self.currentName] = str(self.text.toPlainText())
|
|
||||||
name = item.name
|
|
||||||
if name:
|
|
||||||
self.text.setEnabled(True)
|
|
||||||
self.updateHtmlView()
|
|
||||||
self.currentName = name
|
|
||||||
if name in self.descriptions:
|
|
||||||
self.text.setText(self.descriptions[name])
|
|
||||||
else:
|
|
||||||
self.text.clear()
|
|
||||||
else:
|
|
||||||
self.currentName = None
|
|
||||||
self.text.clear()
|
|
||||||
self.text.setEnabled(False)
|
|
||||||
self.updateHtmlView()
|
|
||||||
|
|
||||||
def updateHtmlView(self):
|
|
||||||
self.txtPreview.setHtml(self.getHtml())
|
|
||||||
|
|
||||||
def getDescription(self, name):
|
|
||||||
if name in self.descriptions:
|
|
||||||
return self.descriptions[name].replace('\n', '<br>')
|
|
||||||
else:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
|
|
||||||
class TreeDescriptionItem(QTreeWidgetItem):
|
|
||||||
|
|
||||||
def __init__(self, description, name):
|
|
||||||
QTreeWidgetItem.__init__(self)
|
|
||||||
self.name = name
|
|
||||||
self.description = description
|
|
||||||
self.setText(0, description)
|
|
@ -55,7 +55,6 @@ from qgis.gui import (QgsProcessingParameterDefinitionDialog,
|
|||||||
from qgis.utils import iface
|
from qgis.utils import iface
|
||||||
|
|
||||||
from processing.gui.AlgorithmDialog import AlgorithmDialog
|
from processing.gui.AlgorithmDialog import AlgorithmDialog
|
||||||
from processing.gui.HelpEditionDialog import HelpEditionDialog
|
|
||||||
from processing.modeler.ModelerParameterDefinitionDialog import ModelerParameterDefinitionDialog
|
from processing.modeler.ModelerParameterDefinitionDialog import ModelerParameterDefinitionDialog
|
||||||
from processing.modeler.ModelerParametersDialog import ModelerParametersDialog
|
from processing.modeler.ModelerParametersDialog import ModelerParametersDialog
|
||||||
from processing.modeler.ModelerScene import ModelerScene
|
from processing.modeler.ModelerScene import ModelerScene
|
||||||
@ -102,7 +101,6 @@ class ModelerDialog(QgsModelDesignerDialog):
|
|||||||
|
|
||||||
self.actionOpen().triggered.connect(self.openModel)
|
self.actionOpen().triggered.connect(self.openModel)
|
||||||
self.actionSaveInProject().triggered.connect(self.saveInProject)
|
self.actionSaveInProject().triggered.connect(self.saveInProject)
|
||||||
self.actionEditHelp().triggered.connect(self.editHelp)
|
|
||||||
self.actionRun().triggered.connect(self.runModel)
|
self.actionRun().triggered.connect(self.runModel)
|
||||||
|
|
||||||
if model is not None:
|
if model is not None:
|
||||||
@ -125,15 +123,6 @@ class ModelerDialog(QgsModelDesignerDialog):
|
|||||||
|
|
||||||
self.context_generator = ContextGenerator(self.processing_context)
|
self.context_generator = ContextGenerator(self.processing_context)
|
||||||
|
|
||||||
def editHelp(self):
|
|
||||||
alg = self.model()
|
|
||||||
dlg = HelpEditionDialog(alg)
|
|
||||||
dlg.exec_()
|
|
||||||
if dlg.descriptions:
|
|
||||||
self.beginUndoCommand(self.tr('Edit Model Help'))
|
|
||||||
self.model().setHelpContent(dlg.descriptions)
|
|
||||||
self.endUndoCommand()
|
|
||||||
|
|
||||||
def runModel(self):
|
def runModel(self):
|
||||||
valid, errors = self.model().validate()
|
valid, errors = self.model().validate()
|
||||||
if not valid:
|
if not valid:
|
||||||
|
@ -329,6 +329,7 @@ set(QGIS_GUI_SRCS
|
|||||||
processing/qgsprocessingfeaturesourceoptionswidget.cpp
|
processing/qgsprocessingfeaturesourceoptionswidget.cpp
|
||||||
processing/qgsprocessingfieldmapwidgetwrapper.cpp
|
processing/qgsprocessingfieldmapwidgetwrapper.cpp
|
||||||
processing/qgsprocessingguiregistry.cpp
|
processing/qgsprocessingguiregistry.cpp
|
||||||
|
processing/qgsprocessinghelpeditorwidget.cpp
|
||||||
processing/qgsprocessinghistoryprovider.cpp
|
processing/qgsprocessinghistoryprovider.cpp
|
||||||
processing/qgsprocessingmaplayercombobox.cpp
|
processing/qgsprocessingmaplayercombobox.cpp
|
||||||
processing/qgsprocessingmatrixmodelerwidget.cpp
|
processing/qgsprocessingmatrixmodelerwidget.cpp
|
||||||
@ -1165,6 +1166,7 @@ set(QGIS_GUI_HDRS
|
|||||||
processing/qgsprocessingfieldmapwidgetwrapper.h
|
processing/qgsprocessingfieldmapwidgetwrapper.h
|
||||||
processing/qgsprocessinggui.h
|
processing/qgsprocessinggui.h
|
||||||
processing/qgsprocessingguiregistry.h
|
processing/qgsprocessingguiregistry.h
|
||||||
|
processing/qgsprocessinghelpeditorwidget.h
|
||||||
processing/qgsprocessinghistoryprovider.h
|
processing/qgsprocessinghistoryprovider.h
|
||||||
processing/qgsprocessingmaplayercombobox.h
|
processing/qgsprocessingmaplayercombobox.h
|
||||||
processing/qgsprocessingmatrixmodelerwidget.h
|
processing/qgsprocessingmatrixmodelerwidget.h
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "qgsmessagebaritem.h"
|
#include "qgsmessagebaritem.h"
|
||||||
#include "qgspanelwidget.h"
|
#include "qgspanelwidget.h"
|
||||||
#include "qgsprocessingmultipleselectiondialog.h"
|
#include "qgsprocessingmultipleselectiondialog.h"
|
||||||
|
#include "qgsprocessinghelpeditorwidget.h"
|
||||||
|
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
@ -149,6 +150,7 @@ QgsModelDesignerDialog::QgsModelDesignerDialog( QWidget *parent, Qt::WindowFlags
|
|||||||
connect( mActionSnapSelected, &QAction::triggered, mView, &QgsModelGraphicsView::snapSelected );
|
connect( mActionSnapSelected, &QAction::triggered, mView, &QgsModelGraphicsView::snapSelected );
|
||||||
connect( mActionValidate, &QAction::triggered, this, &QgsModelDesignerDialog::validate );
|
connect( mActionValidate, &QAction::triggered, this, &QgsModelDesignerDialog::validate );
|
||||||
connect( mActionReorderInputs, &QAction::triggered, this, &QgsModelDesignerDialog::reorderInputs );
|
connect( mActionReorderInputs, &QAction::triggered, this, &QgsModelDesignerDialog::reorderInputs );
|
||||||
|
connect( mActionEditHelp, &QAction::triggered, this, &QgsModelDesignerDialog::editHelp );
|
||||||
connect( mReorderInputsButton, &QPushButton::clicked, this, &QgsModelDesignerDialog::reorderInputs );
|
connect( mReorderInputsButton, &QPushButton::clicked, this, &QgsModelDesignerDialog::reorderInputs );
|
||||||
|
|
||||||
mActionSnappingEnabled->setChecked( settings.value( QStringLiteral( "/Processing/Modeler/enableSnapToGrid" ), false ).toBool() );
|
mActionSnappingEnabled->setChecked( settings.value( QStringLiteral( "/Processing/Modeler/enableSnapToGrid" ), false ).toBool() );
|
||||||
@ -926,6 +928,19 @@ void QgsModelDesignerDialog::setPanelVisibility( bool hidden )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsModelDesignerDialog::editHelp()
|
||||||
|
{
|
||||||
|
QgsProcessingHelpEditorDialog dialog( this );
|
||||||
|
dialog.setWindowTitle( tr( "Edit Model Help" ) );
|
||||||
|
dialog.setAlgorithm( mModel.get() );
|
||||||
|
if ( dialog.exec() )
|
||||||
|
{
|
||||||
|
beginUndoCommand( tr( "Edit Model Help" ) );
|
||||||
|
mModel->setHelpContent( dialog.helpContent() );
|
||||||
|
endUndoCommand();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QgsModelDesignerDialog::validate()
|
void QgsModelDesignerDialog::validate()
|
||||||
{
|
{
|
||||||
QStringList issues;
|
QStringList issues;
|
||||||
|
@ -127,7 +127,6 @@ class GUI_EXPORT QgsModelDesignerDialog : public QMainWindow, public Ui::QgsMode
|
|||||||
QToolBar *toolbar() { return mToolbar; }
|
QToolBar *toolbar() { return mToolbar; }
|
||||||
QAction *actionOpen() { return mActionOpen; }
|
QAction *actionOpen() { return mActionOpen; }
|
||||||
QAction *actionSaveInProject() { return mActionSaveInProject; }
|
QAction *actionSaveInProject() { return mActionSaveInProject; }
|
||||||
QAction *actionEditHelp() { return mActionEditHelp; }
|
|
||||||
QAction *actionRun() { return mActionRun; }
|
QAction *actionRun() { return mActionRun; }
|
||||||
QgsMessageBar *messageBar() { return mMessageBar; }
|
QgsMessageBar *messageBar() { return mMessageBar; }
|
||||||
QGraphicsView *view() { return mView; }
|
QGraphicsView *view() { return mView; }
|
||||||
@ -182,6 +181,7 @@ class GUI_EXPORT QgsModelDesignerDialog : public QMainWindow, public Ui::QgsMode
|
|||||||
void validate();
|
void validate();
|
||||||
void reorderInputs();
|
void reorderInputs();
|
||||||
void setPanelVisibility( bool hidden );
|
void setPanelVisibility( bool hidden );
|
||||||
|
void editHelp();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
213
src/gui/processing/qgsprocessinghelpeditorwidget.cpp
Normal file
213
src/gui/processing/qgsprocessinghelpeditorwidget.cpp
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsprocessinghelpeditorwidget.h
|
||||||
|
------------------------
|
||||||
|
Date : February 2022
|
||||||
|
Copyright : (C) 2022 Nyall Dawson
|
||||||
|
Email : nyall dot dawson at gmail dot com
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "qgsprocessinghelpeditorwidget.h"
|
||||||
|
#include "qgsprocessingmodelalgorithm.h"
|
||||||
|
#include "qgsgui.h"
|
||||||
|
#include <QTreeWidgetItem>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
///@cond NOT_STABLE
|
||||||
|
|
||||||
|
const QString QgsProcessingHelpEditorWidget::ALGORITHM_DESCRIPTION = QStringLiteral( "ALG_DESC" );
|
||||||
|
const QString QgsProcessingHelpEditorWidget::ALGORITHM_CREATOR = QStringLiteral( "ALG_CREATOR" );
|
||||||
|
const QString QgsProcessingHelpEditorWidget::ALGORITHM_HELP_CREATOR = QStringLiteral( "ALG_HELP_CREATOR" );
|
||||||
|
const QString QgsProcessingHelpEditorWidget::ALGORITHM_VERSION = QStringLiteral( "ALG_VERSION" );
|
||||||
|
const QString QgsProcessingHelpEditorWidget::ALGORITHM_SHORT_DESCRIPTION = QStringLiteral( "SHORT_DESCRIPTION" );
|
||||||
|
const QString QgsProcessingHelpEditorWidget::ALGORITHM_HELP_URL = QStringLiteral( "HELP_URL" );
|
||||||
|
|
||||||
|
|
||||||
|
class QgsProcessingHelpEditorTreeItem : public QTreeWidgetItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
QgsProcessingHelpEditorTreeItem( const QString &name, const QString &description )
|
||||||
|
: QTreeWidgetItem()
|
||||||
|
, name( name )
|
||||||
|
, description( description )
|
||||||
|
{
|
||||||
|
setText( 0, description );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString name;
|
||||||
|
QString description;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
QgsProcessingHelpEditorWidget::QgsProcessingHelpEditorWidget( QWidget *parent )
|
||||||
|
: QWidget( parent )
|
||||||
|
, mCurrentName( ALGORITHM_DESCRIPTION )
|
||||||
|
{
|
||||||
|
setupUi( this );
|
||||||
|
|
||||||
|
connect( mElementTree, &QTreeWidget::currentItemChanged, this, &QgsProcessingHelpEditorWidget::changeItem );
|
||||||
|
connect( mTextEdit, &QTextEdit::textChanged, this, [ = ]
|
||||||
|
{
|
||||||
|
if ( !mCurrentName.isEmpty() )
|
||||||
|
{
|
||||||
|
mHelpContent[ mCurrentName] = mTextEdit->toPlainText();
|
||||||
|
updateHtmlView();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsProcessingHelpEditorWidget::~QgsProcessingHelpEditorWidget() = default;
|
||||||
|
|
||||||
|
void QgsProcessingHelpEditorWidget::setAlgorithm( const QgsProcessingAlgorithm *algorithm )
|
||||||
|
{
|
||||||
|
if ( !algorithm )
|
||||||
|
return;
|
||||||
|
|
||||||
|
mAlgorithm.reset( algorithm->create() );
|
||||||
|
|
||||||
|
if ( const QgsProcessingModelAlgorithm *model = dynamic_cast< const QgsProcessingModelAlgorithm *>( mAlgorithm.get() ) )
|
||||||
|
{
|
||||||
|
mHelpContent = model->helpContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( mHelpContent.contains( ALGORITHM_DESCRIPTION ) )
|
||||||
|
{
|
||||||
|
mTextEdit->setText( mHelpContent.value( ALGORITHM_CREATOR ).toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
mElementTree->addTopLevelItem( new QgsProcessingHelpEditorTreeItem( ALGORITHM_DESCRIPTION, tr( "Algorithm description" ) ) );
|
||||||
|
mElementTree->addTopLevelItem( new QgsProcessingHelpEditorTreeItem( ALGORITHM_SHORT_DESCRIPTION, tr( "Short description" ) ) );
|
||||||
|
|
||||||
|
QgsProcessingHelpEditorTreeItem *parametersItem = new QgsProcessingHelpEditorTreeItem( QString(), tr( "Input parameters" ) );
|
||||||
|
mElementTree->addTopLevelItem( parametersItem );
|
||||||
|
|
||||||
|
const QList< const QgsProcessingParameterDefinition * > definitions = mAlgorithm->parameterDefinitions();
|
||||||
|
for ( const QgsProcessingParameterDefinition *definition : definitions )
|
||||||
|
{
|
||||||
|
if ( definition->flags() & QgsProcessingParameterDefinition::FlagHidden || definition->isDestination() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
parametersItem->addChild( new QgsProcessingHelpEditorTreeItem( definition->name(), definition->description() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsProcessingHelpEditorTreeItem *outputsItem = new QgsProcessingHelpEditorTreeItem( QString(), tr( "Outputs" ) );
|
||||||
|
mElementTree->addTopLevelItem( outputsItem );
|
||||||
|
const QList< const QgsProcessingOutputDefinition * > outputs = mAlgorithm->outputDefinitions();
|
||||||
|
for ( const QgsProcessingOutputDefinition *output : outputs )
|
||||||
|
{
|
||||||
|
outputsItem->addChild( new QgsProcessingHelpEditorTreeItem( output->name(), output->description() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
mElementTree->addTopLevelItem( new QgsProcessingHelpEditorTreeItem( ALGORITHM_CREATOR, tr( "Algorithm author" ) ) );
|
||||||
|
mElementTree->addTopLevelItem( new QgsProcessingHelpEditorTreeItem( ALGORITHM_HELP_CREATOR, tr( "Help author" ) ) );
|
||||||
|
mElementTree->addTopLevelItem( new QgsProcessingHelpEditorTreeItem( ALGORITHM_VERSION, tr( "Algorithm version" ) ) );
|
||||||
|
mElementTree->addTopLevelItem( new QgsProcessingHelpEditorTreeItem( ALGORITHM_HELP_URL, tr( "Documentation help URL (for help button)" ) ) );
|
||||||
|
|
||||||
|
updateHtmlView();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantMap QgsProcessingHelpEditorWidget::helpContent()
|
||||||
|
{
|
||||||
|
if ( !mCurrentName.isEmpty() )
|
||||||
|
mHelpContent[ mCurrentName] = mTextEdit->toPlainText();
|
||||||
|
|
||||||
|
return mHelpContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingHelpEditorWidget::updateHtmlView()
|
||||||
|
{
|
||||||
|
mTextPreview->setHtml( formattedHelp() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingHelpEditorWidget::changeItem( QTreeWidgetItem *, QTreeWidgetItem * )
|
||||||
|
{
|
||||||
|
if ( QgsProcessingHelpEditorTreeItem *item = dynamic_cast< QgsProcessingHelpEditorTreeItem *>( mElementTree->currentItem() ) )
|
||||||
|
{
|
||||||
|
if ( !mCurrentName.isEmpty() )
|
||||||
|
{
|
||||||
|
mHelpContent[ mCurrentName] = mTextEdit->toPlainText();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString name = item->name;
|
||||||
|
if ( !name.isEmpty() )
|
||||||
|
{
|
||||||
|
mTextEdit->setEnabled( true );
|
||||||
|
updateHtmlView();
|
||||||
|
mCurrentName = name;
|
||||||
|
if ( mHelpContent.contains( name ) )
|
||||||
|
mTextEdit->setText( mHelpContent[name].toString() );
|
||||||
|
else
|
||||||
|
mTextEdit->clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mCurrentName.clear();
|
||||||
|
mTextEdit->clear();
|
||||||
|
mTextEdit->setEnabled( false );
|
||||||
|
updateHtmlView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsProcessingHelpEditorWidget::formattedHelp() const
|
||||||
|
{
|
||||||
|
if ( !mAlgorithm )
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
return QgsProcessingUtils::formatHelpMapAsHtml( mHelpContent, mAlgorithm.get() );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsProcessingHelpEditorWidget::helpComponent( const QString &name ) const
|
||||||
|
{
|
||||||
|
if ( mHelpContent.contains( name ) )
|
||||||
|
{
|
||||||
|
QString component = mHelpContent.value( name ).toString();
|
||||||
|
component.replace( '\n', QStringLiteral( "<br>" ) );
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsProcessingHelpEditorDialog::QgsProcessingHelpEditorDialog( QWidget *parent, Qt::WindowFlags flags )
|
||||||
|
: QDialog( parent, flags )
|
||||||
|
{
|
||||||
|
setObjectName( QStringLiteral( "QgsProcessingHelpEditorDialog" ) );
|
||||||
|
|
||||||
|
QVBoxLayout *vLayout = new QVBoxLayout();
|
||||||
|
mWidget = new QgsProcessingHelpEditorWidget();
|
||||||
|
vLayout->addWidget( mWidget, 1 );
|
||||||
|
|
||||||
|
QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
|
||||||
|
connect( buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept );
|
||||||
|
connect( buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject );
|
||||||
|
vLayout->addWidget( buttonBox );
|
||||||
|
setLayout( vLayout );
|
||||||
|
|
||||||
|
QgsGui::enableAutoGeometryRestore( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsProcessingHelpEditorDialog::setAlgorithm( const QgsProcessingAlgorithm *algorithm )
|
||||||
|
{
|
||||||
|
mWidget->setAlgorithm( algorithm );
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantMap QgsProcessingHelpEditorDialog::helpContent()
|
||||||
|
{
|
||||||
|
return mWidget->helpContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///@endcond
|
||||||
|
|
122
src/gui/processing/qgsprocessinghelpeditorwidget.h
Normal file
122
src/gui/processing/qgsprocessinghelpeditorwidget.h
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsprocessinghelpeditorwidget.h
|
||||||
|
------------------------
|
||||||
|
Date : February 2022
|
||||||
|
Copyright : (C) 2022 Nyall Dawson
|
||||||
|
Email : nyall dot dawson at gmail dot com
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QGSPROCESSINGHELPEDITORWIDGET_H
|
||||||
|
#define QGSPROCESSINGHELPEDITORWIDGET_H
|
||||||
|
|
||||||
|
#include "qgis.h"
|
||||||
|
#include "qgis_gui.h"
|
||||||
|
#include "ui_qgsprocessinghelpeditorwidgetbase.h"
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
class QgsProcessingAlgorithm;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///@cond NOT_STABLE
|
||||||
|
|
||||||
|
#define SIP_NO_FILE
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup gui
|
||||||
|
* \brief A widget for editing help for a Processing algorithm.
|
||||||
|
* \warning Not stable API
|
||||||
|
* \since QGIS 3.26
|
||||||
|
*/
|
||||||
|
class GUI_EXPORT QgsProcessingHelpEditorWidget : public QWidget, public Ui::QgsProcessingHelpEditorWidgetBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for QgsProcessingHelpEditorWidget, with the specified \a parent widget.
|
||||||
|
*/
|
||||||
|
QgsProcessingHelpEditorWidget( QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||||
|
~QgsProcessingHelpEditorWidget() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the \a algorithm associated with the widget.
|
||||||
|
*/
|
||||||
|
void setAlgorithm( const QgsProcessingAlgorithm *algorithm );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current help content defined by the widget.
|
||||||
|
*/
|
||||||
|
QVariantMap helpContent();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void updateHtmlView();
|
||||||
|
|
||||||
|
void changeItem( QTreeWidgetItem *current, QTreeWidgetItem *previous );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QString formattedHelp() const;
|
||||||
|
QString helpComponent( const QString &name ) const;
|
||||||
|
|
||||||
|
QVariantMap mHelpContent;
|
||||||
|
|
||||||
|
QString mCurrentName;
|
||||||
|
|
||||||
|
std::unique_ptr< QgsProcessingAlgorithm > mAlgorithm;
|
||||||
|
|
||||||
|
static const QString ALGORITHM_DESCRIPTION;
|
||||||
|
static const QString ALGORITHM_CREATOR;
|
||||||
|
static const QString ALGORITHM_HELP_CREATOR;
|
||||||
|
static const QString ALGORITHM_VERSION;
|
||||||
|
static const QString ALGORITHM_SHORT_DESCRIPTION;
|
||||||
|
static const QString ALGORITHM_HELP_URL;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup gui
|
||||||
|
* \brief A dialog for editing help for a Processing algorithm.
|
||||||
|
* \warning Not stable API
|
||||||
|
* \since QGIS 3.26
|
||||||
|
*/
|
||||||
|
class GUI_EXPORT QgsProcessingHelpEditorDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for QgsProcessingHelpEditorDialog, with the specified \a parent and \a flags.
|
||||||
|
*/
|
||||||
|
QgsProcessingHelpEditorDialog( QWidget *parent SIP_TRANSFERTHIS = nullptr, Qt::WindowFlags flags = Qt::WindowFlags() );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the \a algorithm associated with the dialog.
|
||||||
|
*/
|
||||||
|
void setAlgorithm( const QgsProcessingAlgorithm *algorithm );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current help content defined by the dialog.
|
||||||
|
*/
|
||||||
|
QVariantMap helpContent();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QgsProcessingHelpEditorWidget *mWidget = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///@endcond
|
||||||
|
|
||||||
|
#endif // QGSPROCESSINGHELPEDITORWIDGET_H
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>DlgHelpEdition</class>
|
<class>QgsProcessingHelpEditorWidgetBase</class>
|
||||||
<widget class="QDialog" name="DlgHelpEdition">
|
<widget class="QWidget" name="QgsProcessingHelpEditorWidgetBase">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
@ -17,11 +17,20 @@
|
|||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>6</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin">
|
<property name="leftMargin">
|
||||||
<number>9</number>
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTextEdit" name="txtPreview"/>
|
<widget class="QTextBrowser" name="mTextPreview"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QSplitter" name="splitter_2">
|
<widget class="QSplitter" name="splitter_2">
|
||||||
@ -32,7 +41,7 @@
|
|||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="layoutWidget">
|
<widget class="QWidget" name="layoutWidget1">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>2</number>
|
<number>2</number>
|
||||||
@ -45,7 +54,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTreeWidget" name="tree">
|
<widget class="QTreeWidget" name="mElementTree">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>0</width>
|
<width>0</width>
|
||||||
@ -73,14 +82,14 @@
|
|||||||
<number>2</number>
|
<number>2</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="lblDescription">
|
<widget class="QLabel" name="mLabelDescription">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Element description</string>
|
<string>Element description</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTextEdit" name="text">
|
<widget class="QTextEdit" name="mTextEdit">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>0</width>
|
<width>0</width>
|
||||||
@ -94,51 +103,8 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections>
|
<connections/>
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>accepted()</signal>
|
|
||||||
<receiver>DlgHelpEdition</receiver>
|
|
||||||
<slot>accept()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>248</x>
|
|
||||||
<y>254</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>157</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>rejected()</signal>
|
|
||||||
<receiver>DlgHelpEdition</receiver>
|
|
||||||
<slot>reject()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>316</x>
|
|
||||||
<y>260</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>286</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
</ui>
|
Loading…
x
Reference in New Issue
Block a user