17#include "moc_qgslabelingengineruleswidget.cpp"
26#include <QDialogButtonBox>
34 : QAbstractItemModel( parent )
43 return Qt::ItemFlags();
45 Qt::ItemFlags res = Qt::ItemIsSelectable;
48 res |= Qt::ItemIsEnabled | Qt::ItemIsEditable;
51 if (
index.column() == 0 )
53 res |= Qt::ItemIsUserCheckable;
71 return static_cast< int >( mRules.size() );
97 return tr(
"This rule is not available for use on this system." );
102 case Qt::CheckStateRole:
104 if (
index.column() != 0 )
106 return rule->
active() ? Qt::Checked : Qt::Unchecked;
118 if ( hasIndex( row, column,
parent ) )
120 return createIndex( row, column, row );
123 return QModelIndex();
128 if ( row < 0 || row >=
static_cast< int >( mRules.size() ) )
131 beginRemoveRows(
parent, row, row + count - 1 );
132 for (
int i = 0; i < count; i++ )
134 if ( row <
static_cast< int >( mRules.size() ) )
136 mRules.erase( mRules.begin() + row );
145 if ( !
index.isValid() )
154 case Qt::CheckStateRole:
156 rule->
setActive( value.toInt() == Qt::Checked );
163 if (
index.column() == 0 )
165 rule->
setName( value.toString() );
185 mRules.emplace_back( rule->clone() );
192 beginInsertRows( QModelIndex(),
static_cast< int >( mRules.size() ),
static_cast< int >( mRules.size() ) );
193 mRules.emplace_back( std::move( rule ) );
199 if ( !
index.isValid() )
202 if (
index.row() < 0 ||
index.row() >=
static_cast< int >( mRules.size() ) )
205 return mRules[
index.row() ].get();
210 if ( !
index.isValid() )
213 if (
index.row() < 0 ||
index.row() >=
static_cast< int >( mRules.size() ) )
216 mRules[
index.row() ] = std::move( rule );
222 QList<QgsAbstractLabelingEngineRule *> res;
223 res.reserve(
static_cast< int >( mRules.size() ) );
224 for (
auto &it : mRules )
226 res.append( it->clone() );
244 viewRules->setModel( mModel );
245 viewRules->setHeaderHidden(
true );
247 mAddRuleMenu =
new QMenu(
this );
248 connect( mAddRuleMenu, &QMenu::aboutToShow,
this, &QgsLabelingEngineRulesWidget::createTypesMenu );
250 btnAddRule->setMenu( mAddRuleMenu );
251 btnAddRule->setPopupMode( QToolButton::InstantPopup );
253 connect( btnEditRule, &QToolButton::clicked,
this, &QgsLabelingEngineRulesWidget::editSelectedRule );
254 connect( btnRemoveRule, &QToolButton::clicked,
this, &QgsLabelingEngineRulesWidget::removeRules );
256 connect( viewRules, &QAbstractItemView::doubleClicked,
this, &QgsLabelingEngineRulesWidget::editRule );
266 return mModel->
rules();
269void QgsLabelingEngineRulesWidget::createTypesMenu()
271 mAddRuleMenu->clear();
274 QList< QAction * > actions;
275 for (
const QString &
id : ruleIds )
281 connect( action, &QAction::triggered,
this, [
this,
id ]
287 std::sort( actions.begin(), actions.end(), [](
const QAction * a,
const QAction * b ) ->
bool
289 return QString::localeAwareCompare( a->text(), b->text() ) < 0;
291 mAddRuleMenu->addActions( actions );
294void QgsLabelingEngineRulesWidget::createRule(
const QString &
id )
299 rule->setName( rule->displayType() );
301 const QModelIndex newRuleIndex = mModel->
index( mModel->
rowCount() - 1, 0, QModelIndex() );
302 viewRules->selectionModel()->setCurrentIndex( newRuleIndex, QItemSelectionModel::SelectionFlag::ClearAndSelect );
303 editRule( newRuleIndex );
307void QgsLabelingEngineRulesWidget::editSelectedRule()
309 const QItemSelection selection = viewRules->selectionModel()->selection();
310 for (
const QItemSelectionRange &range : selection )
312 if ( range.isValid() )
314 const QModelIndex index = range.indexes().value( 0 );
321void QgsLabelingEngineRulesWidget::editRule(
const QModelIndex &index )
329 if ( rule->
id() ==
"minimumDistanceLabelToFeature" )
331 widget =
new QgsLabelingEngineRuleMinimumDistanceLabelToFeatureWidget();
333 else if ( rule->
id() ==
"minimumDistanceLabelToLabel" )
335 widget =
new QgsLabelingEngineRuleMinimumDistanceLabelToLabelWidget();
337 else if ( rule->
id() ==
"maximumDistanceLabelToFeature" )
339 widget =
new QgsLabelingEngineRuleMaximumDistanceLabelToFeatureWidget();
341 else if ( rule->
id() ==
"avoidLabelOverlapWithFeature" )
343 widget =
new QgsLabelingEngineRuleAvoidLabelOverlapWithFeatureWidget();
352 widget->
setPanelTitle( rule->
name().isEmpty() ? tr(
"Configure Rule" ) : rule->name() );
356 std::unique_ptr< QgsAbstractLabelingEngineRule > updatedRule( widget->
rule() );
365 dialog.setRule( rule );
368 std::unique_ptr< QgsAbstractLabelingEngineRule > updatedRule( dialog.rule() );
375void QgsLabelingEngineRulesWidget::removeRules()
377 const QItemSelection selection = viewRules->selectionModel()->selection();
379 for (
const QItemSelectionRange &range : selection )
381 if ( range.isValid() )
383 for (
int row = range.top(); row <= range.bottom(); ++row )
385 if ( !rows.contains( row ) )
391 std::sort( rows.begin(), rows.end() );
392 std::reverse( rows.begin(), rows.end() );
393 for (
int row : std::as_const( rows ) )
395 mModel->removeRow( row );
405 : QDialog( parent, flags )
407 setWindowTitle( tr(
"Configure Rules" ) );
408 setObjectName( QStringLiteral(
"QgsLabelingEngineRulesDialog" ) );
412 QVBoxLayout *layout =
new QVBoxLayout(
this );
413 layout->addWidget( mWidget );
415 mButtonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal,
this );
416 layout->addWidget( mButtonBox );
421 connect( mButtonBox->button( QDialogButtonBox::Ok ), &QAbstractButton::clicked,
this, &QDialog::accept );
422 connect( mButtonBox->button( QDialogButtonBox::Cancel ), &QAbstractButton::clicked,
this, &QDialog::reject );
432 return mWidget->
rules();
Abstract base class for labeling engine rules.
void setActive(bool active)
Sets whether the rule is active.
virtual bool isAvailable() const
Returns true if the rule is available for use within the current QGIS environment.
bool active() const
Returns true if the rule is active.
QString name() const
Returns the name for this instance of the rule.
virtual QString displayType() const =0
Returns a user-friendly, translated string representing the rule type.
virtual QString description() const
Returns a user-friendly description of the rule.
void setName(const QString &name)
Sets the name for this instance of the rule.
virtual QString id() const =0
Returns a string uniquely identifying the rule subclass.
static QgsLabelingEngineRuleRegistry * labelingEngineRuleRegistry()
Gets the registry of available labeling engine rules.
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...
A simple dialog for customizing a labeling engine rule.
QStringList ruleIds() const
Returns a list of the rule IDs for rules present in the registry.
QList< QgsAbstractLabelingEngineRule * > rules() const
Returns the rules shown in the dialog.
void setRules(const QList< QgsAbstractLabelingEngineRule * > &rules)
Sets the rules to show in the dialog.
QgsLabelingEngineRulesDialog(QWidget *parent=nullptr, Qt::WindowFlags flags=QgsGuiUtils::ModalDialogFlags)
Constructor for QgsLabelingEngineRulesDialog.
A model for configuration of a list of labeling engine rules.
QModelIndex index(int row, int column, const QModelIndex &parent) const override
int columnCount(const QModelIndex &parent=QModelIndex()) const override
void setRules(const QList< QgsAbstractLabelingEngineRule * > &rules)
Sets the rules to include in the model.
QModelIndex parent(const QModelIndex &child) const override
QgsLabelingEngineRulesModel(QObject *parent=nullptr)
Constructor for QgsLabelingEngineRulesModel.
QList< QgsAbstractLabelingEngineRule * > rules() const
Returns the rules shown in the widget.
QgsAbstractLabelingEngineRule * ruleAtIndex(const QModelIndex &index) const
Returns the rule at the specified model index.
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
void addRule(std::unique_ptr< QgsAbstractLabelingEngineRule > &rule)
Adds a rule to the model.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Qt::ItemFlags flags(const QModelIndex &index) const override
~QgsLabelingEngineRulesModel() override
void changeRule(const QModelIndex &index, std::unique_ptr< QgsAbstractLabelingEngineRule > &rule)
Swaps the rule at the specified index for a new rule.