20 #include <QVBoxLayout>
21 #include <QTreeWidget>
24 #include <QMouseEvent>
26 #include <QPushButton>
27 #include <QHeaderView>
28 #include <QMessageBox>
37 VariableEditorDelegate(
QObject *parent = 0, QgsVariableEditorTree *tree = 0 )
52 QgsVariableEditorTree *mParentTree;
55 QIcon QgsVariableEditorTree::mExpandIcon;
64 , mEditableScopeIndex( -1 )
70 mTreeWidget =
new QgsVariableEditorTree(
this );
71 mTreeWidget->setSelectionMode( QAbstractItemView::SingleSelection );
76 horizontalLayout->
addItem( horizontalSpacer );
79 mAddButton->setEnabled(
false );
80 horizontalLayout->
addWidget( mAddButton );
83 mRemoveButton->setEnabled(
false );
84 horizontalLayout->
addWidget( mRemoveButton );
85 verticalLayout->
addLayout( horizontalLayout );
86 connect( mRemoveButton, SIGNAL( clicked() ),
this, SLOT( on_mRemoveButton_clicked() ) );
87 connect( mAddButton, SIGNAL( clicked() ),
this, SLOT( on_mAddButton_clicked() ) );
88 connect( mTreeWidget, SIGNAL( itemSelectionChanged() ),
this, SLOT( selectionChanged() ) );
89 connect( mTreeWidget, SIGNAL( scopeChanged() ),
this, SIGNAL( scopeChanged() ) );
93 setContext( context );
100 settings.
setValue( saveKey() +
"column0width", mTreeWidget->header()->sectionSize( 0 ) );
115 val = settings.
value( saveKey() +
"column0width" );
117 int sectionSize = val.
toInt( &ok );
120 mTreeWidget->header()->resizeSection( 0, sectionSize );
135 mTreeWidget->resetTree();
136 mTreeWidget->setContext( mContext.
data() );
137 mTreeWidget->refreshTree();
142 mEditableScopeIndex = scopeIndex;
143 if ( mEditableScopeIndex >= 0 )
147 mTreeWidget->setEditableScopeIndex( scopeIndex );
148 mTreeWidget->refreshTree();
153 if ( !mContext || mEditableScopeIndex < 0 || mEditableScopeIndex >= mContext->scopeCount() )
157 return mContext->scope( mEditableScopeIndex );
163 if ( !mContext || mEditableScopeIndex < 0 || mEditableScopeIndex >= mContext->scopeCount() )
180 QString QgsVariableEditorWidget::saveKey()
const
185 QString saveKey =
"/QgsVariableEditorTree/" + setGroup +
"/";
189 void QgsVariableEditorWidget::on_mAddButton_clicked()
191 if ( mEditableScopeIndex < 0 || mEditableScopeIndex >= mContext->scopeCount() )
196 mTreeWidget->refreshTree();
197 QTreeWidgetItem* item = mTreeWidget->itemFromVariable( scope,
"new_variable" );
199 mTreeWidget->selectionModel()->select( index, QItemSelectionModel::ClearAndSelect );
200 mTreeWidget->editItem( item, 0 );
205 void QgsVariableEditorWidget::on_mRemoveButton_clicked()
207 if ( mEditableScopeIndex < 0 || mEditableScopeIndex >= mContext->scopeCount() )
215 if ( !( item->
flags() & Qt::ItemIsEditable ) )
220 if ( itemScope != editableScope )
227 mTreeWidget->removeItem( item );
229 mTreeWidget->refreshTree();
232 void QgsVariableEditorWidget::selectionChanged()
234 if ( mEditableScopeIndex < 0 || mEditableScopeIndex >= mContext->scopeCount() )
243 bool removeEnabled =
true;
246 if ( !( item->
flags() & Qt::ItemIsEditable ) )
248 removeEnabled =
false;
254 if ( itemScope != editableScope )
256 removeEnabled =
false;
262 removeEnabled =
false;
274 QgsVariableEditorTree::QgsVariableEditorTree(
QWidget *parent )
276 , mEditorDelegate( 0 )
277 , mEditableScopeIndex( -1 )
281 if ( mExpandIcon.isNull() )
284 pix.fill( Qt::transparent );
291 setIconSize(
QSize( 18, 18 ) );
294 setAlternatingRowColors(
true );
295 setEditTriggers( QAbstractItemView::AllEditTriggers );
296 setRootIsDecorated(
false );
297 header()->setMovable(
false );
298 header()->setResizeMode( QHeaderView::Interactive );
300 mEditorDelegate =
new VariableEditorDelegate(
this,
this );
301 setItemDelegate( mEditorDelegate );
310 int contextIndex = item->
data( 0, ContextIndex ).
toInt( &ok );
318 else if ( mContext->scopeCount() > contextIndex )
320 return mContext->scope( contextIndex );
330 int contextIndex = mContext ? mContext->indexOfScope( scope ) : 0;
331 if ( contextIndex < 0 )
333 return mVariableToItem.value( qMakePair( contextIndex, name ) );
338 if ( !mContext || mEditableScopeIndex < 0 || mEditableScopeIndex >= mContext->scopeCount() )
343 return mContext->scope( mEditableScopeIndex );
346 void QgsVariableEditorTree::refreshTree()
348 if ( !mContext || mEditableScopeIndex < 0 )
358 refreshScopeItems( scope, scopeIndex );
365 QColor baseColor = rowColor( scopeIndex );
366 bool isCurrent = scopeIndex == mEditableScopeIndex;
372 if ( mVariableToItem.contains( qMakePair( scopeIndex, name ) ) )
374 item = mVariableToItem.value( qMakePair( scopeIndex, name ) );
379 mVariableToItem.insert( qMakePair( scopeIndex, name ), item );
383 bool isActive =
true;
387 activeScope = mContext->activeScopeForVariable( name );
388 isActive = activeScope == scope;
396 if ( readOnly || !isCurrent )
410 QString toolTip =
tr(
"Overridden by value from %1" ).arg( activeScope->
name() );
422 item->
setData( 0, RowBaseColor, baseColor );
423 item->
setData( 0, ContextIndex, scopeIndex );
433 bool isCurrent = scopeIndex == mEditableScopeIndex;
436 if ( mScopeToItem.contains( scopeIndex ) )
439 scopeItem = mScopeToItem.value( scopeIndex );
445 mScopeToItem.insert( scopeIndex, scopeItem );
446 scopeItem->
setFlags( scopeItem->
flags() | Qt::ItemIsEnabled );
448 scopeItem->
setFlags( scopeItem->
flags() ^ Qt::ItemIsEditable );
452 scopeItem->
setFont( 0, scopeFont );
455 addTopLevelItem( scopeItem );
458 if ( isCurrent || settings.
value(
"QgsVariableEditor/" + scopeItem->
text( 0 ) +
"/expanded" ).toBool() )
461 scopeItem->
setIcon( 0, mExpandIcon );
464 refreshScopeVariables( scope, scopeIndex );
472 mVariableToItem.remove( mVariableToItem.key( item ) );
483 int contextIndex = mVariableToItem.key( item ).first;
484 mVariableToItem.remove( mVariableToItem.key( item ) );
485 mVariableToItem.insert( qMakePair( contextIndex, name ), item );
491 void QgsVariableEditorTree::resetTree()
493 mVariableToItem.clear();
494 mScopeToItem.clear();
498 void QgsVariableEditorTree::emitChanged()
512 painter->
fillRect( option.rect, baseColor );
513 opt.palette.setColor( QPalette::AlternateBase, baseColor.
lighter( 110 ) );
519 painter->
drawLine( opt.rect.x(), opt.rect.bottom(), opt.rect.right(), opt.rect.bottom() );
523 QColor QgsVariableEditorTree::rowColor(
int index )
const
526 int colorIdx = index % 6;
530 return QColor( 255, 220, 167 );
532 return QColor( 255, 255, 191 );
534 return QColor( 191, 255, 191 );
536 return QColor( 199, 255, 255 );
538 return QColor( 234, 191, 255 );
541 return QColor( 255, 191, 239 );
545 void QgsVariableEditorTree::toggleContextExpanded(
QTreeWidgetItem* item )
557 void QgsVariableEditorTree::editNext(
const QModelIndex& index )
562 if ( index.
column() == 0 )
568 setCurrentIndex( nextIndex );
578 setCurrentIndex( nextIndex );
590 if ( cursorAction == QAbstractItemView::MoveNext )
595 if ( index.
column() + 1 < model()->columnCount() )
597 else if ( index.
row() + 1 < model()->rowCount( index.
parent() ) )
603 else if ( cursorAction == QAbstractItemView::MovePrevious )
608 if ( index.
column() >= 1 )
610 else if ( index.
row() >= 1 )
611 return index.
sibling( index.
row() - 1, model()->columnCount() - 1 );
620 void QgsVariableEditorTree::keyPressEvent(
QKeyEvent *event )
622 switch ( event->
key() )
629 if ( item && !item->
parent() )
632 toggleContextExpanded( item );
635 else if ( item && ( item->
flags() & Qt::ItemIsEditable ) )
638 editNext( currentIndex() );
649 void QgsVariableEditorTree::mousePressEvent(
QMouseEvent *event )
662 if ( event->
pos().
x() + header()->offset() > 20 )
668 if ( event->
modifiers() & Qt::ShiftModifier )
682 toggleContextExpanded( item );
704 if ( !item || !scope )
707 QString variableName = mParentTree->variableNameFromIndex( index );
710 if ( scope != mParentTree->editableScope() || scope->
isReadOnly( variableName ) )
714 lineEdit->
setText( index.
column() == 0 ? variableName : mParentTree->editableScope()->variable( variableName ).toString() );
719 void VariableEditorDelegate::updateEditorGeometry(
QWidget *editor,
723 editor->
setGeometry( option.rect.adjusted( 0, 0, 0, -1 ) );
742 if ( !item || !scope )
749 QString variableName = mParentTree->variableNameFromIndex( index );
750 if ( index.
column() == 0 )
756 if ( newName == variableName )
763 QMessageBox::warning( mParentTree,
tr(
"Rename variable" ),
tr(
"A variable with the name \"%1\" already exists in this context." ).arg( newName ) );
768 mParentTree->renameItem( item, newName );
771 mParentTree->emitChanged();
773 else if ( index.
column() == 1 )
782 mParentTree->emitChanged();
784 mParentTree->refreshTree();
QString & append(QChar ch)
void setContentsMargins(int left, int top, int right, int bottom)
void fillRect(const QRectF &rectangle, const QBrush &brush)
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.
bool hasVariable(const QString &name) const
Tests whether a variable with the specified name exists in the scope.
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. ...
QString name() const
Returns the friendly display name of the context scope.
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.
virtual void setEditorData(QWidget *editor, const QModelIndex &index) const
QStringList filteredVariableNames() const
Returns a fitlered and sorted list of variable names contained within the scope.
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
virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
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
QVariant variable(const QString &name) const
Retrieves a variable's value from the scope.
QColor lighter(int factor) const
void setItalic(bool enable)
virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
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
virtual void keyPressEvent(QKeyEvent *event)
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
bool isReadOnly(const QString &name) const
Tests whether the specified variable is read only and should not be editable by users.
QString text(int column) const
void setSpacing(int spacing)
virtual void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
QStringList variableNames() const
Returns a list of variable names contained within the scope.
void addLayout(QLayout *layout, int stretch)
typedef KeyboardModifiers