diff --git a/gui/resultstree.cpp b/gui/resultstree.cpp index 8031fa526..b8b3fafa0 100644 --- a/gui/resultstree.cpp +++ b/gui/resultstree.cpp @@ -18,12 +18,15 @@ #include "resultstree.h" +#include #include #include #include #include #include #include +#include +#include ResultsTree::ResultsTree(QSettings &settings, ApplicationList &list) : mSettings(settings), @@ -86,7 +89,7 @@ void ResultsTree::AddErrorItem(const QString &file, //Create the base item for the error and ensure it has a proper //file item as a parent - QStandardItem *item = AddBacktraceFiles(EnsureFileItem(realfile, hide), + QStandardItem *item = AddBacktraceFiles(EnsureFileItem(files[0], hide), realfile, lines[0].toInt(), severity, @@ -290,9 +293,9 @@ void ResultsTree::RefreshTree() } } - -QStandardItem *ResultsTree::EnsureFileItem(const QString &name, bool hide) +QStandardItem *ResultsTree::EnsureFileItem(const QString &fullpath, bool hide) { + QString name = StripPath(fullpath, false); QStandardItem *item = FindFileItem(name); if (item) @@ -303,6 +306,10 @@ QStandardItem *ResultsTree::EnsureFileItem(const QString &name, bool hide) item = CreateItem(name); item->setIcon(QIcon(":images/text-x-generic.png")); + //Add user data to that item + QMap data; + data["files"] = fullpath; + item->setData(QVariant(data)); mModel.appendRow(item); setRowHidden(mModel.rowCount() - 1, QModelIndex(), hide); @@ -325,18 +332,19 @@ void ResultsTree::contextMenuEvent(QContextMenuEvent * e) if (index.isValid()) { mContextItem = mModel.itemFromIndex(index); + + //Create a new context menu + QMenu menu(this); + + //Store all applications in a list + QList actions; + + //Create a signal mapper so we don't have to store data to class + //member variables + QSignalMapper *signalMapper = new QSignalMapper(this); + if (mContextItem && mApplications.GetApplicationCount() > 0 && mContextItem->parent()) { - - //Create a new context menu - QMenu menu(this); - //Store all applications in a list - QList actions; - - //Create a signal mapper so we don't have to store data to class - //member variables - QSignalMapper *signalMapper = new QSignalMapper(this); - //Go through all applications and add them to the context menu for (int i = 0;i < mApplications.GetApplicationCount();i++) { @@ -358,10 +366,32 @@ void ResultsTree::contextMenuEvent(QContextMenuEvent * e) connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(Context(int))); + } - //Start the menu - menu.exec(e->globalPos()); + // Add menuitems to copy full path/filename to clipboard + if (mContextItem) + { + if (mApplications.GetApplicationCount() > 0) + { + menu.addSeparator(); + } + //Create an action for the application + QAction *copyfilename = new QAction(tr("Copy filename"), &menu); + QAction *copypath = new QAction(tr("Copy full path"), &menu); + + menu.addAction(copyfilename); + menu.addAction(copypath); + + connect(copyfilename, SIGNAL(triggered()), this, SLOT(CopyFilename())); + connect(copypath, SIGNAL(triggered()), this, SLOT(CopyFullPath())); + } + + //Start the menu + menu.exec(e->globalPos()); + + if (mContextItem && mApplications.GetApplicationCount() > 0 && mContextItem->parent()) + { //Disconnect all signals for (int i = 0;i < actions.size();i++) { @@ -369,7 +399,6 @@ void ResultsTree::contextMenuEvent(QContextMenuEvent * e) disconnect(actions[i], SIGNAL(triggered()), signalMapper, SLOT(map())); } - disconnect(signalMapper, SIGNAL(mapped(int)), this, SLOT(Context(int))); //And remove the signal mapper @@ -444,6 +473,15 @@ void ResultsTree::StartApplication(QStandardItem *target, int application) } } +void ResultsTree::CopyFilename() +{ + CopyPath(mContextItem, false); +} + +void ResultsTree::CopyFullPath() +{ + CopyPath(mContextItem, true); +} void ResultsTree::Context(int application) { @@ -455,6 +493,34 @@ void ResultsTree::QuickStartApplication(const QModelIndex &index) StartApplication(mModel.itemFromIndex(index), 0); } +void ResultsTree::CopyPath(QStandardItem *target, bool fullPath) +{ + if (target) + { + QVariantMap data = target->data().toMap(); + QString pathStr; + + //Replace (file) with filename + QStringList files = data["files"].toStringList(); + if (files.size() > 0) + { + pathStr = files[0]; + if (!fullPath) + { + QFileInfo fi(pathStr); + pathStr = fi.fileName(); + } + } + else + { + qDebug("Failed to get filename!"); + } + + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(pathStr); + } +} + QString ResultsTree::SeverityToIcon(const QString &severity) { if (severity == "all") diff --git a/gui/resultstree.h b/gui/resultstree.h index 9e1da3c18..c2288e7df 100644 --- a/gui/resultstree.h +++ b/gui/resultstree.h @@ -115,6 +115,18 @@ protected slots: */ void Context(int application); + /** + * @brief Slot for context menu item to copy filename to clipboard + * + */ + void CopyFilename(); + + /** + * @brief Slot for context menu item to copy full path to clipboard + * + */ + void CopyFullPath(); + protected: /** @@ -157,14 +169,21 @@ protected: QString SeverityToIcon(const QString &severity); /** - * @brief Helper function to open an error within target with application - * + * @brief Helper function to open an error within target with application* * * @param target Error tree item to open * @param application Index of the application to open with */ void StartApplication(QStandardItem *target, int application); + /** + * @brief Helper function to copy filename/full path to the clipboard + * + * @param target Error tree item to open + * @param fullpath Are we copying full path or only filename? + */ + void CopyPath(QStandardItem *target, bool fullPath); + /** * @brief Context menu event (user right clicked on the tree) * @@ -254,11 +273,11 @@ protected: /** * @brief Ensures there's a item in the model for the specified file * - * @param name Filename + * @param fullpath Full path to the file item. * @param hide is the error (we want this file item for) hidden? * @return QStandardItem to be used as a parent for all errors for specified file */ - QStandardItem *EnsureFileItem(const QString &name, bool hide); + QStandardItem *EnsureFileItem(const QString &fullpath, bool hide); /** * @brief Show a file item