20 #include <QVBoxLayout> 21 #include <QTreeWidget> 24 #include <QMouseEvent> 26 #include <QPushButton> 27 #include <QHeaderView> 28 #include <QMessageBox> 39 , mEditableScopeIndex( -1 )
45 mTreeWidget =
new QgsVariableEditorTree(
this );
46 mTreeWidget->setSelectionMode( QAbstractItemView::SingleSelection );
51 horizontalLayout->
addItem( horizontalSpacer );
55 horizontalLayout->
addWidget( mAddButton );
59 horizontalLayout->
addWidget( mRemoveButton );
60 verticalLayout->
addLayout( horizontalLayout );
61 connect( mRemoveButton, SIGNAL( clicked() ),
this, SLOT( on_mRemoveButton_clicked() ) );
62 connect( mAddButton, SIGNAL( clicked() ),
this, SLOT( on_mAddButton_clicked() ) );
63 connect( mTreeWidget, SIGNAL( itemSelectionChanged() ),
this, SLOT( selectionChanged() ) );
75 settings.
setValue( saveKey() +
"column0width", mTreeWidget->header()->sectionSize( 0 ) );
90 val = settings.
value( saveKey() +
"column0width" );
92 int sectionSize = val.
toInt( &ok );
95 mTreeWidget->header()->resizeSection( 0, sectionSize );
110 mTreeWidget->resetTree();
111 mTreeWidget->setContext( mContext.
data() );
112 mTreeWidget->refreshTree();
117 mEditableScopeIndex = scopeIndex;
118 if ( mEditableScopeIndex >= 0 )
122 mTreeWidget->setEditableScopeIndex( scopeIndex );
123 mTreeWidget->refreshTree();
128 if ( !mContext || mEditableScopeIndex < 0 || mEditableScopeIndex >= mContext->scopeCount() )
132 return mContext->scope( mEditableScopeIndex );
138 if ( !mContext || mEditableScopeIndex < 0 || mEditableScopeIndex >= mContext->scopeCount() )
155 QString QgsVariableEditorWidget::saveKey()
const 160 QString saveKey =
"/QgsVariableEditorTree/" + setGroup +
'/';
164 void QgsVariableEditorWidget::on_mAddButton_clicked()
166 if ( mEditableScopeIndex < 0 || mEditableScopeIndex >= mContext->scopeCount() )
171 mTreeWidget->refreshTree();
172 QTreeWidgetItem* item = mTreeWidget->itemFromVariable( scope,
"new_variable" );
174 mTreeWidget->selectionModel()->select( index, QItemSelectionModel::ClearAndSelect );
175 mTreeWidget->editItem( item, 0 );
180 void QgsVariableEditorWidget::on_mRemoveButton_clicked()
182 if ( mEditableScopeIndex < 0 || mEditableScopeIndex >= mContext->scopeCount() )
190 if ( !( item->
flags() & Qt::ItemIsEditable ) )
195 if ( itemScope != editableScope )
202 mTreeWidget->removeItem( item );
204 mTreeWidget->refreshTree();
207 void QgsVariableEditorWidget::selectionChanged()
209 if ( mEditableScopeIndex < 0 || mEditableScopeIndex >= mContext->scopeCount() )
218 bool removeEnabled =
true;
221 if ( !( item->
flags() & Qt::ItemIsEditable ) )
223 removeEnabled =
false;
229 if ( itemScope != editableScope )
231 removeEnabled =
false;
237 removeEnabled =
false;
250 QgsVariableEditorTree::QgsVariableEditorTree(
QWidget *
parent )
252 , mEditorDelegate(
nullptr )
253 , mEditableScopeIndex( -1 )
254 , mContext(
nullptr )
257 if ( mExpandIcon.isNull() )
260 pix.
fill( Qt::transparent );
267 setIconSize(
QSize( 18, 18 ) );
270 setAlternatingRowColors(
true );
271 setEditTriggers( QAbstractItemView::AllEditTriggers );
272 setRootIsDecorated(
false );
273 header()->setMovable(
false );
274 header()->setResizeMode( QHeaderView::Interactive );
276 mEditorDelegate =
new VariableEditorDelegate(
this,
this );
277 setItemDelegate( mEditorDelegate );
286 int contextIndex = item->
data( 0, ContextIndex ).
toInt( &ok );
294 else if ( mContext->scopeCount() > contextIndex )
296 return mContext->scope( contextIndex );
306 int contextIndex = mContext ? mContext->indexOfScope( scope ) : 0;
307 if ( contextIndex < 0 )
309 return mVariableToItem.value( qMakePair( contextIndex, name ) );
314 if ( !mContext || mEditableScopeIndex < 0 || mEditableScopeIndex >= mContext->scopeCount() )
319 return mContext->scope( mEditableScopeIndex );
322 void QgsVariableEditorTree::refreshTree()
324 if ( !mContext || mEditableScopeIndex < 0 )
334 refreshScopeItems( scope, scopeIndex );
341 QColor baseColor = rowColor( scopeIndex );
342 bool isCurrent = scopeIndex == mEditableScopeIndex;
348 if ( mVariableToItem.contains( qMakePair( scopeIndex, name ) ) )
350 item = mVariableToItem.value( qMakePair( scopeIndex, name ) );
355 mVariableToItem.insert( qMakePair( scopeIndex, name ), item );
359 bool isActive =
true;
363 activeScope = mContext->activeScopeForVariable( name );
364 isActive = activeScope == scope;
372 if ( readOnly || !isCurrent )
398 item->
setData( 0, RowBaseColor, baseColor );
399 item->
setData( 0, ContextIndex, scopeIndex );
409 bool isCurrent = scopeIndex == mEditableScopeIndex;
412 if ( mScopeToItem.contains( scopeIndex ) )
415 scopeItem = mScopeToItem.value( scopeIndex );
421 mScopeToItem.insert( scopeIndex, scopeItem );
422 scopeItem->
setFlags( scopeItem->
flags() | Qt::ItemIsEnabled );
424 scopeItem->
setFlags( scopeItem->
flags() ^ Qt::ItemIsEditable );
428 scopeItem->
setFont( 0, scopeFont );
431 addTopLevelItem( scopeItem );
434 if ( isCurrent || settings.
value(
"QgsVariableEditor/" + scopeItem->
text( 0 ) +
"/expanded" ).toBool() )
437 scopeItem->
setIcon( 0, mExpandIcon );
440 refreshScopeVariables( scope, scopeIndex );
448 mVariableToItem.remove( mVariableToItem.key( item ) );
459 int contextIndex = mVariableToItem.key( item ).first;
460 mVariableToItem.remove( mVariableToItem.key( item ) );
461 mVariableToItem.insert( qMakePair( contextIndex, name ), item );
467 void QgsVariableEditorTree::resetTree()
469 mVariableToItem.clear();
470 mScopeToItem.clear();
474 void QgsVariableEditorTree::emitChanged()
488 painter->
fillRect( option.rect, baseColor );
489 opt.palette.setColor( QPalette::AlternateBase, baseColor.
lighter( 110 ) );
495 painter->
drawLine( opt.rect.x(), opt.rect.bottom(), opt.rect.right(), opt.rect.bottom() );
499 QColor QgsVariableEditorTree::rowColor(
int index )
const 502 int colorIdx = index % 6;
506 return QColor( 255, 220, 167 );
508 return QColor( 255, 255, 191 );
510 return QColor( 191, 255, 191 );
512 return QColor( 199, 255, 255 );
514 return QColor( 234, 191, 255 );
517 return QColor( 255, 191, 239 );
521 void QgsVariableEditorTree::toggleContextExpanded(
QTreeWidgetItem* item )
533 void QgsVariableEditorTree::editNext(
const QModelIndex& index )
538 if ( index.
column() == 0 )
544 setCurrentIndex( nextIndex );
554 setCurrentIndex( nextIndex );
566 if ( cursorAction == QAbstractItemView::MoveNext )
571 if ( index.
column() + 1 < model()->columnCount() )
573 else if ( index.
row() + 1 < model()->rowCount( index.
parent() ) )
579 else if ( cursorAction == QAbstractItemView::MovePrevious )
584 if ( index.
column() >= 1 )
586 else if ( index.
row() >= 1 )
587 return index.
sibling( index.
row() - 1, model()->columnCount() - 1 );
598 switch ( event->
key() )
605 if ( item && !item->
parent() )
608 toggleContextExpanded( item );
611 else if ( item && ( item->
flags() & Qt::ItemIsEditable ) )
614 editNext( currentIndex() );
625 void QgsVariableEditorTree::mousePressEvent(
QMouseEvent *event )
638 if ( event->
pos().
x() + header()->offset() > 20 )
644 if ( event->
modifiers() & Qt::ShiftModifier )
658 toggleContextExpanded( item );
679 if ( !item || !scope )
682 QString variableName = mParentTree->variableNameFromIndex( index );
685 if ( scope != mParentTree->editableScope() || scope->
isReadOnly( variableName ) )
689 lineEdit->
setText( index.
column() == 0 ? variableName : mParentTree->editableScope()->variable( variableName ).toString() );
694 void VariableEditorDelegate::updateEditorGeometry(
QWidget *editor,
698 editor->
setGeometry( option.rect.adjusted( 0, 0, 0, -1 ) );
717 if ( !item || !scope )
724 QString variableName = mParentTree->variableNameFromIndex( index );
725 if ( index.
column() == 0 )
731 if ( newName == variableName )
738 QMessageBox::warning( mParentTree,
tr(
"Rename variable" ),
tr(
"A variable with the name \"%1\" already exists in this context." ).arg( newName ) );
743 mParentTree->renameItem( item, newName );
746 mParentTree->emitChanged();
748 else if ( index.
column() == 1 )
757 mParentTree->emitChanged();
759 mParentTree->refreshTree();
bool hasVariable(const QString &name) const
Tests whether a variable with the specified name exists in the scope.
QString & append(QChar ch)
void setContentsMargins(int left, int top, int right, int bottom)
void fillRect(const QRectF &rectangle, const QBrush &brush)
void fill(const QColor &color)
virtual QModelIndex moveCursor(CursorAction cursorAction, QFlags< Qt::KeyboardModifier > modifiers)
void setText(const QString &)
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
QStringList variableNames() const
Returns a list of variable names contained within the scope.
bool isReadOnly(const QString &name) const
Tests whether the specified variable is read only and should not be editable by users.
void drawLine(const QLineF &line)
QString tr(const char *sourceText, const char *disambiguation, int n)
void setVariable(const QString &name, const QVariant &value)
Convenience method for setting a variable in the context scope by name and value. ...
void setBold(bool enable)
void setValue(const QString &key, const QVariant &value)
const char * name() const
bool removeVariable(const QString &name)
Removes a variable from the context scope, if found.
int toInt(bool *ok) const
void setPen(const QColor &color)
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
virtual void addItem(QLayoutItem *item)
QString objectName() const
virtual int styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const=0
QVariant variable(const QString &name) const
Retrieves a variable's value from the scope.
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Single scope for storing variables and functions for use within a QgsExpressionContext.
QModelIndex parent() const
QColor lighter(int factor) const
void setItalic(bool enable)
QVariant value(const QString &key, const QVariant &defaultValue) const
QModelIndex sibling(int row, int column) const
void setText(int column, const QString &text)
void setStrikeOut(bool enable)
StandardButton warning(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
virtual void mousePressEvent(QMouseEvent *event)
iterator insert(const Key &key, const T &value)
const QPoint & pos() const
QString name() const
Returns the friendly display name of the context scope.
virtual void keyPressEvent(QKeyEvent *event)
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QStringList filteredVariableNames() const
Returns a fitlered and sorted list of variable names contained within the scope.
QString text(int column) const
void setSpacing(int spacing)
virtual void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
void addLayout(QLayout *layout, int stretch)
typedef KeyboardModifiers