Skip to content

Commit

Permalink
Add icon support to actions
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn authored and 3nids committed Sep 16, 2014
1 parent ba7f0a3 commit 089652e
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 22 deletions.
49 changes: 38 additions & 11 deletions src/app/qgsattributeactiondialog.cpp
Expand Up @@ -31,6 +31,7 @@ back to QgsVectorLayer.
#include <QHeaderView>
#include <QMessageBox>
#include <QSettings>
#include <QImageWriter>

QgsAttributeActionDialog::QgsAttributeActionDialog( QgsAttributeAction* actions,
const QgsFields& fields,
Expand Down Expand Up @@ -61,6 +62,8 @@ QgsAttributeActionDialog::QgsAttributeActionDialog( QgsAttributeAction* actions,
connect( insertFieldButton, SIGNAL( clicked() ), this, SLOT( insertField() ) );
connect( insertExpressionButton, SIGNAL( clicked() ), this, SLOT( insertExpression() ) );

connect( chooseIconButton, SIGNAL(clicked()), this, SLOT( chooseIcon() ) );

init();
// Populate the combo box with the field names. Will the field names
// change? If so, they need to be passed into the init() call, or
Expand All @@ -78,13 +81,13 @@ void QgsAttributeActionDialog::init()
for ( int i = 0; i < mActions->size(); i++ )
{
const QgsAction action = ( *mActions )[i];
insertRow( i, action.type(), action.name(), action.action(), action.capture() );
insertRow( i, action.type(), action.name(), action.action(), action.iconPath(), action.capture() );
}

updateButtons();
}

void QgsAttributeActionDialog::insertRow( int row, QgsAction::ActionType type, const QString &name, const QString &action, bool capture )
void QgsAttributeActionDialog::insertRow( int row, QgsAction::ActionType type, const QString &name, const QString &action, const QString& iconPath, bool capture )
{
QTableWidgetItem* item;
attributeActionTable->insertRow( row );
Expand All @@ -97,6 +100,10 @@ void QgsAttributeActionDialog::insertRow( int row, QgsAction::ActionType type, c
item->setFlags( item->flags() & ~( Qt::ItemIsEditable | Qt::ItemIsUserCheckable ) );
item->setCheckState( capture ? Qt::Checked : Qt::Unchecked );
attributeActionTable->setItem( row, 3, item );
QIcon icon = QIcon( iconPath );
QTableWidgetItem* headerItem = new QTableWidgetItem( icon, "" );
headerItem->setData( Qt::UserRole, iconPath );
attributeActionTable->setVerticalHeaderItem( row, headerItem );

updateButtons();
}
Expand Down Expand Up @@ -250,7 +257,7 @@ void QgsAttributeActionDialog::insert( int pos )
if ( pos >= numRows )
{
// Expand the table to have a row with index pos
insertRow( pos, ( QgsAction::ActionType ) actionType->currentIndex(), name, actionAction->toPlainText(), captureCB->isChecked() );
insertRow( pos, ( QgsAction::ActionType ) actionType->currentIndex(), name, actionAction->toPlainText(), actionIcon->text(), captureCB->isChecked() );
}
else
{
Expand All @@ -259,6 +266,8 @@ void QgsAttributeActionDialog::insert( int pos )
attributeActionTable->item( pos, 1 )->setText( name );
attributeActionTable->item( pos, 2 )->setText( actionAction->toPlainText() );
attributeActionTable->item( pos, 3 )->setCheckState( captureCB->isChecked() ? Qt::Checked : Qt::Unchecked );
attributeActionTable->verticalHeaderItem( pos )->setIcon( QIcon( actionIcon->text() ) );
attributeActionTable->verticalHeaderItem( pos )->setData( Qt::UserRole, actionIcon->text() );
}
}
}
Expand Down Expand Up @@ -299,6 +308,23 @@ void QgsAttributeActionDialog::updateButtons()
updateButton->setEnabled( hasSelection && validNewAction );
}

void QgsAttributeActionDialog::chooseIcon()
{
QList<QByteArray> list = QImageWriter::supportedImageFormats();
QStringList formatList;
Q_FOREACH( const QByteArray& format, list )
formatList << QString( "*.%1" ).arg( QString( format ) );

QString filter = QString( "Images( %1 ); All( *.* )" ).arg( formatList.join( " " ) );
QString icon = QFileDialog::getOpenFileName( this, tr( "Choose Icon..." ), actionIcon->text(), filter );

if ( !icon.isNull() )
{
actionIcon->setText( icon );
iconPreview->setPixmap( QPixmap( icon ) );
}
}

void QgsAttributeActionDialog::insertField()
{
// Convert the selected field to an expression and
Expand All @@ -323,24 +349,25 @@ void QgsAttributeActionDialog::apply()
const QgsAction::ActionType type = ( QgsAction::ActionType ) actionType->findText( attributeActionTable->item( i, 0 )->text() );
const QString &name = attributeActionTable->item( i, 1 )->text();
const QString &action = attributeActionTable->item( i, 2 )->text();
const QString icon = attributeActionTable->verticalHeaderItem( i )->data( Qt::UserRole ).toString();
if ( !name.isEmpty() && !action.isEmpty() )
{
QTableWidgetItem *item = attributeActionTable->item( i, 3 );
mActions->addAction( type, name, action, item->checkState() == Qt::Checked );
mActions->addAction( type, name, action, icon, item->checkState() == Qt::Checked );
}
}
}

void QgsAttributeActionDialog::addDefaultActions()
{
int pos = 0;
insertRow( pos++, QgsAction::Generic, tr( "Echo attribute's value" ), "echo \"[% \"MY_FIELD\" %]\"", true );
insertRow( pos++, QgsAction::Generic, tr( "Run an application" ), "ogr2ogr -f \"ESRI Shapefile\" \"[% \"OUTPUT_PATH\" %]\" \"[% \"INPUT_FILE\" %]\"", true );
insertRow( pos++, QgsAction::GenericPython, tr( "Get feature id" ), "QtGui.QMessageBox.information(None, \"Feature id\", \"feature id is [% $id %]\")", false );
insertRow( pos++, QgsAction::GenericPython, tr( "Selected field's value (Identify features tool)" ), "QtGui.QMessageBox.information(None, \"Current field's value\", \"[% $currentfield %]\")", false );
insertRow( pos++, QgsAction::GenericPython, tr( "Clicked coordinates (Run feature actions tool)" ), "QtGui.QMessageBox.information(None, \"Clicked coords\", \"layer: [% $layerid %]\\ncoords: ([% $clickx %],[% $clicky %])\")", false );
insertRow( pos++, QgsAction::OpenUrl, tr( "Open file" ), "[% \"PATH\" %]", false );
insertRow( pos++, QgsAction::OpenUrl, tr( "Search on web based on attribute's value" ), "http://www.google.com/search?q=[% \"ATTRIBUTE\" %]", false );
insertRow( pos++, QgsAction::Generic, tr( "Echo attribute's value" ), "echo \"[% \"MY_FIELD\" %]\"", "", true );
insertRow( pos++, QgsAction::Generic, tr( "Run an application" ), "ogr2ogr -f \"ESRI Shapefile\" \"[% \"OUTPUT_PATH\" %]\" \"[% \"INPUT_FILE\" %]\"", "", true );
insertRow( pos++, QgsAction::GenericPython, tr( "Get feature id" ), "QtGui.QMessageBox.information(None, \"Feature id\", \"feature id is [% $id %]\")", "", false );
insertRow( pos++, QgsAction::GenericPython, tr( "Selected field's value (Identify features tool)" ), "QtGui.QMessageBox.information(None, \"Current field's value\", \"[% $currentfield %]\")", "", false );
insertRow( pos++, QgsAction::GenericPython, tr( "Clicked coordinates (Run feature actions tool)" ), "QtGui.QMessageBox.information(None, \"Clicked coords\", \"layer: [% $layerid %]\\ncoords: ([% $clickx %],[% $clicky %])\")", "", false );
insertRow( pos++, QgsAction::OpenUrl, tr( "Open file" ), "[% \"PATH\" %]", "", false );
insertRow( pos++, QgsAction::OpenUrl, tr( "Search on web based on attribute's value" ), "http://www.google.com/search?q=[% \"ATTRIBUTE\" %]", "", false );
}

void QgsAttributeActionDialog::itemSelectionChanged()
Expand Down
3 changes: 2 additions & 1 deletion src/app/qgsattributeactiondialog.h
Expand Up @@ -58,10 +58,11 @@ class APP_EXPORT QgsAttributeActionDialog: public QWidget, private Ui::QgsAttrib

private slots:
void updateButtons();
void chooseIcon();

private:

void insertRow( int row, QgsAction::ActionType type, const QString &name, const QString &action, bool capture );
void insertRow(int row, QgsAction::ActionType type, const QString &name, const QString &action, const QString& iconPath, bool capture );
void swapRows( int row1, int row2 );

void insert( int pos );
Expand Down
7 changes: 7 additions & 0 deletions src/core/qgsattributeaction.cpp
Expand Up @@ -45,6 +45,11 @@ void QgsAttributeAction::addAction( QgsAction::ActionType type, QString name, QS
mActions << QgsAction( type, name, action, capture );
}

void QgsAttributeAction::addAction(QgsAction::ActionType type, QString name, QString action, const QString& icon, bool capture)
{
mActions << QgsAction( type, name, action, icon, capture );
}

void QgsAttributeAction::removeAction( int index )
{
if ( index >= 0 && index < mActions.size() )
Expand Down Expand Up @@ -236,6 +241,7 @@ bool QgsAttributeAction::writeXML( QDomNode& layer_node, QDomDocument& doc ) con
QDomElement actionSetting = doc.createElement( "actionsetting" );
actionSetting.setAttribute( "type", mActions[i].type() );
actionSetting.setAttribute( "name", mActions[i].name() );
actionSetting.setAttribute( "icon", mActions[i].iconPath() );
actionSetting.setAttribute( "action", mActions[i].action() );
actionSetting.setAttribute( "capture", mActions[i].capture() );
aActions.appendChild( actionSetting );
Expand All @@ -260,6 +266,7 @@ bool QgsAttributeAction::readXML( const QDomNode& layer_node )
addAction(( QgsAction::ActionType ) setting.attributeNode( "type" ).value().toInt(),
setting.attributeNode( "name" ).value(),
setting.attributeNode( "action" ).value(),
setting.attributeNode( "icon" ).value(),
setting.attributeNode( "capture" ).value().toInt() != 0 );
}
}
Expand Down
31 changes: 25 additions & 6 deletions src/core/qgsattributeaction.h
Expand Up @@ -25,7 +25,7 @@
#define QGSATTRIBUTEACTION_H

#include <QString>
#include <QObject>
#include <QIcon>

#include <qgsfeature.h>

Expand Down Expand Up @@ -53,9 +53,18 @@ class CORE_EXPORT QgsAction
QgsAction( ActionType type, QString name, QString action, bool capture ) :
mType( type ), mName( name ), mAction( action ), mCaptureOutput( capture ) {}

QgsAction( ActionType type, QString name, QString action, const QString& icon, bool capture ) :
mType( type ), mName( name ), mIcon( icon ), mAction( action ), mCaptureOutput( capture ) {}

//! The name of the action
QString name() const { return mName; }

//! The path to the icon
const QString iconPath() const { return mIcon; }

//! The icon
const QIcon icon() const { return QIcon( mIcon ); }

//! The action
QString action() const { return mAction; }

Expand Down Expand Up @@ -84,6 +93,7 @@ class CORE_EXPORT QgsAction
private:
ActionType mType;
QString mName;
QString mIcon;
QString mAction;
bool mCaptureOutput;
};
Expand All @@ -102,13 +112,22 @@ class CORE_EXPORT QgsAttributeAction
//! Destructor
virtual ~QgsAttributeAction() {}

//! Add an action with the given name and action details.
// Will happily have duplicate names and actions. If
// capture is true, when running the action using doAction(),
// any stdout from the process will be captured and displayed in a
// dialog box.
/** Add an action with the given name and action details.
* Will happily have duplicate names and actions. If
* capture is true, when running the action using doAction(),
* any stdout from the process will be captured and displayed in a
* dialog box.
*/
void addAction( QgsAction::ActionType type, QString name, QString action, bool capture = false );

/** Add an action with the given name and action details.
* Will happily have duplicate names and actions. If
* capture is true, when running the action using doAction(),
* any stdout from the process will be captured and displayed in a
* dialog box.
*/
void addAction(QgsAction::ActionType type, QString name, QString action, const QString& icon, bool capture = false );

//! Remove an action at given index
void removeAction( int index );

Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgsactionmenu.cpp
Expand Up @@ -126,7 +126,7 @@ void QgsActionMenu::reloadActions()
{
const QgsAction& qaction( mActions->at( idx ) );

QAction* action = new QAction( qaction.name(), this );
QAction* action = new QAction( qaction.icon(), qaction.name(), this );

// Only enable items on supported platforms
if ( !qaction.runable() )
Expand Down
46 changes: 43 additions & 3 deletions src/ui/qgsattributeactiondialogbase.ui
Expand Up @@ -291,6 +291,13 @@
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Icon</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="textLabel2">
<property name="whatsThis">
<string>Enter the action here. This can be any program, script or command that is available on your system. When the action is invoked any set of characters that start with a % and then have the name of a field will be replaced by the value of that field. The special characters %% will be replaced by the value of the field that was selected. Double quote marks group text into single arguments to the program, script or command. Double quotes will be ignored if prefixed with a backslash</string>
Expand All @@ -303,7 +310,7 @@
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="1">
<widget class="QToolButton" name="browseButton">
Expand Down Expand Up @@ -356,7 +363,7 @@
</item>
</layout>
</item>
<item row="3" column="1">
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="insertExpressionButton">
Expand Down Expand Up @@ -415,7 +422,7 @@
</item>
</layout>
</item>
<item row="4" column="0" colspan="2">
<item row="5" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer">
Expand Down Expand Up @@ -455,6 +462,39 @@
</item>
</layout>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="iconPreview">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>24</horstretch>
<verstretch>24</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="actionIcon"/>
</item>
<item>
<widget class="QToolButton" name="chooseIconButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
<widget class="QLabel" name="label">
<property name="geometry">
Expand Down

0 comments on commit 089652e

Please sign in to comment.