diff --git a/src/qgsattributeaction.cpp b/src/qgsattributeaction.cpp index 3e0f5faa4f3..88ef91e83c6 100644 --- a/src/qgsattributeaction.cpp +++ b/src/qgsattributeaction.cpp @@ -39,7 +39,8 @@ void QgsAttributeAction::addAction(QString name, QString action, mActions.push_back(QgsAction(name, action, capture)); } -void QgsAttributeAction::doAction(unsigned int index, QString value) +void QgsAttributeAction::doAction(unsigned int index, const std::vector >& values, + int defaultValueIndex) { aIter action = retrieveAction(index); @@ -55,7 +56,7 @@ void QgsAttributeAction::doAction(unsigned int index, QString value) if (action != end()) { - QString expanded_action = expandAction(action->action(), value); + QString expanded_action = expandAction(action->action(), values, defaultValueIndex); std::cout << "Running command '" << expanded_action << "'.\n"; QStringList args = QStringList::split(" ", expanded_action); @@ -89,15 +90,35 @@ QgsAttributeAction::aIter QgsAttributeAction::retrieveAction(unsigned int index) return a_iter; } -QString QgsAttributeAction::expandAction(QString action, QString value) +QString QgsAttributeAction::expandAction(QString action, const std::vector >& values, + int clickedOnValue) { - // This functions currently replaces all % characters in the action - // with the given value. Additional substitutions could include: - // - symbols for $CWD, $HOME, etc (and their OSX and Windows - // equivalents) - // - other values in the same row as the given value + // This function currently replaces all %% characters in the action + // with the value from values[clickedOnValue].second, and then + // searches for all strings that go %attribite_name, where + // attribute_name is found in values[x].first, and replaces any that + // it finds by values[s].second. - QString expanded_action = action.replace("%", value); + // Additional substitutions could include symbols for $CWD, $HOME, + // etc (and their OSX and Windows equivalents) + + // This function will potentially fall apart if any of the + // substitutions produce text that could match another + // substition. May be better to adopt a two pass approach - identify + // all matches and their substitutions and then do a second pass + // for the actual substitutions. + + QString expanded_action; + if (clickedOnValue >= 0 && clickedOnValue < values.size()) + expanded_action = action.replace("%%", values[clickedOnValue].second); + else + expanded_action = action; + + for (int i = 0; i < values.size(); ++i) + { + QString to_replace = "%" + values[i].first; + expanded_action = expanded_action.replace(to_replace, values[i].second); + } return expanded_action; } diff --git a/src/qgsattributeaction.h b/src/qgsattributeaction.h index 858bba1b099..4d7eaa8cdd4 100644 --- a/src/qgsattributeaction.h +++ b/src/qgsattributeaction.h @@ -30,7 +30,8 @@ #include #include - +#include +#include class QDomNode; class QDomDocument; @@ -85,8 +86,11 @@ class QgsAttributeAction // dialog box. void addAction(QString name, QString action, bool capture = false); - //! Does the action for the given attribute. - void doAction(unsigned int index, QString value); + //! Does the action using the given values. defaultValueIndex is an + // index into values which indicates which value in the values vector + // is to be used if the action has a default placeholder. + void doAction(unsigned int index, const std::vector >& values, + int defaultValueIndex = 0); //! Returns a const_iterator that points to the QgsAction at the // given position in the data collection. The insertion order is @@ -111,7 +115,8 @@ class QgsAttributeAction //! Expands the given action, replacing all %'s with the value as // given. - static QString expandAction(QString action, QString value); + static QString expandAction(QString action, const std::vector >& values, + int defaultValueIndex); //! Writes the actions out in XML format bool writeXML(QDomNode& layer_node, QDomDocument& doc) const; diff --git a/src/qgsattributeactiondialogbase.ui b/src/qgsattributeactiondialogbase.ui index bab9a574cca..1581919b023 100644 --- a/src/qgsattributeactiondialogbase.ui +++ b/src/qgsattributeactiondialogbase.ui @@ -1,4 +1,4 @@ - + QgsAttributeActionDialogBase @@ -93,7 +93,11 @@ Enter actions here - Use this table to create actions that can be selected from the Identify Results dialog box. Each action has a name, which appears in the Identify Results popup menu. The action is executed in a shell, and the symbol % is replaced with the value of the parameter that was right-clicked on in the Identify Results dialog box + Use this table to create actions that can be selected from the Identify Results dialog box. Each action has a name, which appears in the Identify Results popup menu. The action is executed as a separate process. + +Any %% symbol in the action is replaced by the value of the attribute that was right-clicked on in the Identify Results dialog box. + +Any symbols that start with a % and are then followed by the name of an attribute are replaced by the value of that attribute. For example, if there is an attribute called 'filename' with a value of 'text.txt' and there is an action that includes the text '%filename' it will be replaced by text.txt when the action is run. diff --git a/src/qgsidentifyresults.cpp b/src/qgsidentifyresults.cpp index 9ad993052c7..fda26fb64e2 100644 --- a/src/qgsidentifyresults.cpp +++ b/src/qgsidentifyresults.cpp @@ -27,7 +27,7 @@ #include "qgsidentifyresults.h" -QgsIdentifyResults::QgsIdentifyResults(const QgsAttributeAction& aa) : mActions(aa), mActionPopup(0) +QgsIdentifyResults::QgsIdentifyResults(const QgsAttributeAction& aa) : mActions(aa), mClickedOnValue(0), mActionPopup(0) { } @@ -77,9 +77,36 @@ void QgsIdentifyResults::popupContextMenu(QListViewItem* item, mActionPopup->setItemParameter(id, j); } } - // Save the attribute value as this is needed for substituting into + // Save the attribute values as these are needed for substituting into // the action. - mValue = item->text(1); + // A little bit complicated because the user could of right-clicked + // on a parent or a child in the dialog box. We also want to keep + // track of which row in the identify results table was actually + // clicked on. This is stored as an index into the mValues vector. + + QListViewItem* parent = item->parent(); + QListViewItem* child; + + if (item->parent() == 0) + child = item->firstChild(); + else + child = parent->firstChild(); + + mValues.clear(); + int j = 0; + while (child != 0) + { + mValues.push_back(std::make_pair(child->text(0), child->text(1))); + // Need to do the comparison on the text strings rather than the + // pointers because if the user clicked on the parent, we need + // to pick up which child that actually is (the parent in the + // identify results dialog box is just one of the children + // that has been chosen by some method). + if (child->text(0) == item->text(0)) + mClickedOnValue = j; + ++j; + child = child->nextSibling(); + } mActionPopup->popup(p); } @@ -129,5 +156,5 @@ void QgsIdentifyResults::setTitle(QString title) // Run the action that was selected in the popup menu void QgsIdentifyResults::popupItemSelected(int id) { - mActions.doAction(id, mValue); + mActions.doAction(id, mValues, mClickedOnValue); } diff --git a/src/qgsidentifyresults.h b/src/qgsidentifyresults.h index f13cf4544c3..3b91cd66d5f 100644 --- a/src/qgsidentifyresults.h +++ b/src/qgsidentifyresults.h @@ -26,6 +26,7 @@ #include "qgsattributeaction.h" #include +#include class QPopupMenu; @@ -63,8 +64,9 @@ class QgsIdentifyResults:public QgsIdentifyResultsBase private: QgsAttributeAction mActions; + int mClickedOnValue; QPopupMenu* mActionPopup; - QString mValue; + std::vector > mValues; }; #endif