QGIS API Documentation 4.3.0-Master (16649ce5cc6)
Loading...
Searching...
No Matches
qgsprocessingdefaultstyledialog.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsprocessingdefaultstyledialog.cpp
3 ------------------------------------
4 Date : September 2026
5 Copyright : (C) 2026 Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "qgsapplication.h"
19#include "qgsfilewidget.h"
20#include "qgsgui.h"
24
25#include <QString>
26
27#include "moc_qgsprocessingdefaultstyledialog.cpp"
28
29using namespace Qt::StringLiterals;
31
32//
33// QgsProcessingDefaultStyleDelegate
34//
35
36QgsProcessingDefaultStyleDelegate::QgsProcessingDefaultStyleDelegate( QObject *parent )
37 : QStyledItemDelegate( parent )
38{}
39
40QWidget *QgsProcessingDefaultStyleDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
41{
42 if ( index.column() == 1 )
43 {
44 auto *editor = new QgsFileWidget( parent );
45 editor->setStorageMode( QgsFileWidget::StorageMode::GetFile );
46 editor->setFilter( u"%1 (*.qml *.QML)"_s.arg( tr( "QGIS Layer Style File" ) ) );
47
48 return editor;
49 }
50 return QStyledItemDelegate::createEditor( parent, option, index );
51}
52
53void QgsProcessingDefaultStyleDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
54{
55 if ( auto *fileWidget = qobject_cast<QgsFileWidget *>( editor ) )
56 {
57 fileWidget->setFilePath( index.model()->data( index, Qt::EditRole ).toString() );
58 }
59 else
60 {
61 QStyledItemDelegate::setEditorData( editor, index );
62 }
63}
64
65void QgsProcessingDefaultStyleDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
66{
67 if ( auto *fileWidget = qobject_cast<QgsFileWidget *>( editor ) )
68 {
69 model->setData( index, fileWidget->filePath(), Qt::EditRole );
70 }
71 else
72 {
73 QStyledItemDelegate::setModelData( editor, model, index );
74 }
75}
76
77void QgsProcessingDefaultStyleDelegate::updateEditorGeometry( QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex & ) const
78{
79 editor->setGeometry( option.rect );
80}
81
82//
83// QgsProcessingDefaultStylesModel
84//
85
86QgsProcessingDefaultStylesModel::QgsProcessingDefaultStylesModel( const QgsProcessingAlgorithm *algorithm, QObject *parent )
87 : QAbstractTableModel( parent )
88{
89 mAlgorithmId = algorithm->id();
91
92 const QgsProcessingOutputDefinitions outputDefs = algorithm->outputDefinitions();
93 for ( const QgsProcessingOutputDefinition *output : outputDefs )
94 {
95 if ( dynamic_cast<const QgsProcessingOutputVectorLayer *>( output )
96 || dynamic_cast<const QgsProcessingOutputRasterLayer *>( output )
97 || dynamic_cast<const QgsProcessingOutputVectorTileLayer *>( output )
98 || dynamic_cast<const QgsProcessingOutputPointCloudLayer *>( output ) )
99 {
100 OutputItem item;
101 item.name = output->name();
102 item.description = output->description();
103 item.stylePath = defaultStyleRegistry->defaultStyleForOutput( mAlgorithmId, output->name() );
104 mItems.append( item );
105 }
106 }
107}
108
109int QgsProcessingDefaultStylesModel::rowCount( const QModelIndex &parent ) const
110{
111 if ( parent.isValid() )
112 return 0;
113
114 return mItems.size();
115}
116
117int QgsProcessingDefaultStylesModel::columnCount( const QModelIndex &parent ) const
118{
119 if ( parent.isValid() )
120 return 0;
121 return 2;
122}
123
124QVariant QgsProcessingDefaultStylesModel::data( const QModelIndex &index, int role ) const
125{
126 if ( !index.isValid() || index.row() >= mItems.size() )
127 return QVariant();
128
129 const OutputItem &item = mItems.at( index.row() );
130
131 switch ( role )
132 {
133 case Qt::DisplayRole:
134 case Qt::EditRole:
135 case Qt::ToolTipRole:
136 switch ( index.column() )
137 {
138 case Column::OutputName:
139 {
140 return item.description.isEmpty() ? item.name : item.description;
141 }
142
143 case Column::StylePath:
144 return item.stylePath;
145
146 default:
147 break;
148 }
149 break;
150
151 default:
152 break;
153 }
154
155 return QVariant();
156}
157
158bool QgsProcessingDefaultStylesModel::setData( const QModelIndex &index, const QVariant &value, int role )
159{
160 if ( index.isValid() && index.column() == Column::StylePath && role == Qt::EditRole )
161 {
162 mItems[index.row()].stylePath = value.toString();
163 emit dataChanged( index, index, { role, Qt::DisplayRole } );
164 return true;
165 }
166 return false;
167}
168
169Qt::ItemFlags QgsProcessingDefaultStylesModel::flags( const QModelIndex &index ) const
170{
171 if ( !index.isValid() )
172 return Qt::NoItemFlags;
173
174 Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
175 if ( index.column() == Column::StylePath )
176 {
177 flags |= Qt::ItemIsEditable;
178 }
179 return flags;
180}
181
182QVariant QgsProcessingDefaultStylesModel::headerData( int section, Qt::Orientation orientation, int role ) const
183{
184 switch ( orientation )
185 {
186 case Qt::Horizontal:
187 {
188 switch ( role )
189 {
190 case Qt::DisplayRole:
191 {
192 switch ( section )
193 {
194 case Column::OutputName:
195 return tr( "Output" );
196 case Column::StylePath:
197 return tr( "Style File" );
198 default:
199 break;
200 }
201 break;
202 }
203
204 default:
205 break;
206 }
207
208 break;
209 }
210 case Qt::Vertical:
211 break;
212 }
213
214 return QAbstractTableModel::headerData( section, orientation, role );
215}
216
217void QgsProcessingDefaultStylesModel::saveStyles()
218{
220 for ( const OutputItem &item : std::as_const( mItems ) )
221 {
222 registry->setDefaultStyleForOutput( mAlgorithmId, item.name, item.stylePath );
223 }
224 registry->saveStyles();
225}
227
228//
229// QgsProcessingDefaultStyleDialog
230//
231
233 : QDialog( parent )
234 , mAlgorithm( algorithm )
235{
236 setupUi( this );
237
238 setObjectName( "QgsProcessingDefaultStyleDialog" );
240
241 setWindowTitle( algorithm->displayName() );
242
243 mModel = new QgsProcessingDefaultStylesModel( mAlgorithm, this );
244 mDelegate = new QgsProcessingDefaultStyleDelegate( this );
245 mTableStyles->setModel( mModel );
246 mTableStyles->setEditTriggers( QAbstractItemView::AllEditTriggers );
247 mTableStyles->horizontalHeader()->setSectionResizeMode( QHeaderView::Interactive );
248 mTableStyles->setSelectionBehavior( QAbstractItemView::SelectRows );
249
250 mTableStyles->setItemDelegateForColumn( 1, mDelegate );
251
252 connect( mButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept );
253 connect( mButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject );
254}
255
257{
258 mModel->saveStyles();
259 QDialog::accept();
260}
261
263{
264 QDialog::showEvent( event );
265
266 if ( !mInitialWidthsSet )
267 {
268 mInitialWidthsSet = true;
269
270 int halfWidth = mTableStyles->viewport()->width() / 2;
271 mTableStyles->setColumnWidth( 0, halfWidth );
272 mTableStyles->setColumnWidth( 1, halfWidth );
273 }
274}
static QgsProcessingRegistry * processingRegistry()
Returns the application's processing registry, used for managing processing providers,...
A widget for selecting a file or a folder.
@ GetFile
Select a single file.
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition qgsgui.cpp:225
Abstract base class for processing algorithms.
QgsProcessingDefaultStyleDialog(const QgsProcessingAlgorithm *algorithm, QWidget *parent=nullptr)
Constructor for QgsProcessingDefaultStyleDialog.
A registry for default styles to apply to layers generated by Processing.
QString defaultStyleForOutput(const QString &algorithmId, const QString &outputName) const
Returns the QML path to the default style to use for the specified output from an algorithm,...
void saveStyles()
Saves registered styles to the configuration file.
void setDefaultStyleForOutput(const QString &algorithmId, const QString &outputName, const QString &qmlPath)
Sets the default style for an output from an algorithm.
Base class for the definition of processing outputs.
A pointcloud layer output for processing algorithms.
A raster layer output for processing algorithms.
A vector layer output for processing algorithms.
A vector tile layer output for processing algorithms.
QgsProcessingDefaultStyleRegistry * defaultStyleRegistry() const
Returns the default style registry, responsible for styling layers generated by Processing tools.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
QList< const QgsProcessingOutputDefinition * > QgsProcessingOutputDefinitions
List of processing parameters.