From: Yordan Karadzhov <ykaradzhov@vmware.com>
To: rostedt@goodmis.org
Cc: linux-trace-devel@vger.kernel.org, y.karadz@gmail.com,
troyengel@gmail.com, Yordan Karadzhov <ykaradzhov@vmware.com>,
Slavomir Kaslev <kaslevs@vmware.com>
Subject: [PATCH v2 2/8] kernel-shark: Add logic for the initial path of Open-File dialogs
Date: Thu, 2 May 2019 15:40:03 +0300 [thread overview]
Message-ID: <20190502124009.32208-3-ykaradzhov@vmware.com> (raw)
In-Reply-To: <20190502124009.32208-1-ykaradzhov@vmware.com>
If the application has been started from its installation location,
all Open File dialogs will start at ${HOME}. Otherwise the dialogs will
start at ${PWD}. If a given dialog has been used already to select a file,
next time the dialog will start in the directory of this file.
Suggested-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Reviewed-by: Slavomir Kaslev <kaslevs@vmware.com>
Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
kernel-shark/src/KsCaptureDialog.cpp | 34 +++-----
kernel-shark/src/KsCaptureDialog.hpp | 2 +
kernel-shark/src/KsMainWindow.cpp | 70 ++++++----------
kernel-shark/src/KsMainWindow.hpp | 4 +-
kernel-shark/src/KsUtils.cpp | 121 +++++++++++++++++++++++++++
kernel-shark/src/KsUtils.hpp | 17 ++++
6 files changed, 183 insertions(+), 65 deletions(-)
diff --git a/kernel-shark/src/KsCaptureDialog.cpp b/kernel-shark/src/KsCaptureDialog.cpp
index 1272c2e..2976a3b 100644
--- a/kernel-shark/src/KsCaptureDialog.cpp
+++ b/kernel-shark/src/KsCaptureDialog.cpp
@@ -206,10 +206,9 @@ void KsCaptureControl::_importSettings()
events = tep_list_events(_localTEP, TEP_EVENT_SORT_SYSTEM);
/* Get the configuration document. */
- fileName = QFileDialog::getOpenFileName(this,
- "Import from Filter",
- KS_DIR,
- "Kernel Shark Config files (*.json);;");
+ fileName = KsUtils::getFile(this, "Import from Filter",
+ "Kernel Shark Config files (*.json);;",
+ _lastFilePath);
if (fileName.isEmpty())
return;
@@ -256,23 +255,16 @@ void KsCaptureControl::_exportSettings()
json_object *jplugin;
QString plugin, out, comm;
QVector<int> ids;
- QString fileName =
- QFileDialog::getSaveFileName(this,
- "Export to File",
- KS_DIR,
- "Kernel Shark Config files (*.json);;");
+ QString fileName;
+
+ fileName = KsUtils::getSaveFile(this, "Export to File",
+ "Kernel Shark Config files (*.json);;",
+ ".json",
+ _lastFilePath);
if (fileName.isEmpty())
return;
- if (!fileName.endsWith(".json")) {
- fileName += ".json";
- if (QFileInfo(fileName).exists()) {
- if (!KsWidgetsLib::fileExistsDialog(fileName))
- return;
- }
- }
-
/* Create a configuration document. */
conf = kshark_record_config_new(KS_CONFIG_JSON);
events = kshark_filter_config_new(KS_CONFIG_JSON);
@@ -312,10 +304,10 @@ void KsCaptureControl::_exportSettings()
void KsCaptureControl::_browse()
{
QString fileName =
- QFileDialog::getSaveFileName(this,
- "Save File",
- KS_DIR,
- "trace-cmd files (*.dat);;All files (*)");
+ KsUtils::getSaveFile(this, "Save File",
+ "trace-cmd files (*.dat);;All files (*)",
+ ".dat",
+ _lastFilePath);
if (!fileName.isEmpty())
_outputLineEdit.setText(fileName);
diff --git a/kernel-shark/src/KsCaptureDialog.hpp b/kernel-shark/src/KsCaptureDialog.hpp
index d65f475..2265704 100644
--- a/kernel-shark/src/KsCaptureDialog.hpp
+++ b/kernel-shark/src/KsCaptureDialog.hpp
@@ -61,6 +61,8 @@ private:
QPushButton _outputBrowseButton;
+ QString _lastFilePath;
+
QStringList _getPlugins();
void _importSettings();
diff --git a/kernel-shark/src/KsMainWindow.cpp b/kernel-shark/src/KsMainWindow.cpp
index c839aca..748bacd 100644
--- a/kernel-shark/src/KsMainWindow.cpp
+++ b/kernel-shark/src/KsMainWindow.cpp
@@ -360,11 +360,11 @@ void KsMainWindow::_createMenus()
void KsMainWindow::_open()
{
- QString fileName =
- QFileDialog::getOpenFileName(this,
- "Open File",
- KS_DIR,
- "trace-cmd files (*.dat);;All files (*)");
+ QString fileName;
+
+ fileName = KsUtils::getFile(this, "Open File",
+ "trace-cmd files (*.dat);;All files (*)",
+ _lastDataFilePath);
if (!fileName.isEmpty())
loadDataFile(fileName);
@@ -429,11 +429,11 @@ void KsMainWindow::_restoreSession()
void KsMainWindow::_importSession()
{
- QString fileName =
- QFileDialog::getOpenFileName(this,
- "Import Session",
- KS_DIR,
- "Kernel Shark Config files (*.json);;");
+ QString fileName;
+
+ fileName = KsUtils::getFile(this, "Import Session",
+ "Kernel Shark Config files (*.json);;",
+ _lastConfFilePath);
if (fileName.isEmpty())
return;
@@ -460,23 +460,15 @@ void KsMainWindow::_updateSession()
void KsMainWindow::_exportSession()
{
- QString fileName =
- QFileDialog::getSaveFileName(this,
- "Export Filter",
- KS_DIR,
- "Kernel Shark Config files (*.json);;");
+ QString fileName;
+ fileName = KsUtils::getSaveFile(this, "Export Filter",
+ "Kernel Shark Config files (*.json);;",
+ ".json",
+ _lastConfFilePath);
if (fileName.isEmpty())
return;
- if (!fileName.endsWith(".json")) {
- fileName += ".json";
- if (QFileInfo(fileName).exists()) {
- if (!KsWidgetsLib::fileExistsDialog(fileName))
- return;
- }
- }
-
_updateSession();
_session.exportToFile(fileName);
}
@@ -512,8 +504,9 @@ void KsMainWindow::_importFilter()
if (!kshark_instance(&kshark_ctx))
return;
- fileName = QFileDialog::getOpenFileName(this, "Import Filter", KS_DIR,
- "Kernel Shark Config files (*.json);;");
+ fileName = KsUtils::getFile(this, "Import Filter",
+ "Kernel Shark Config files (*.json);;",
+ _lastConfFilePath);
if (fileName.isEmpty())
return;
@@ -540,20 +533,14 @@ void KsMainWindow::_exportFilter()
if (!kshark_instance(&kshark_ctx))
return;
- fileName = QFileDialog::getSaveFileName(this, "Export Filter", KS_DIR,
- "Kernel Shark Config files (*.json);;");
+ fileName = KsUtils::getSaveFile(this, "Export Filter",
+ "Kernel Shark Config files (*.json);;",
+ ".json",
+ _lastConfFilePath);
if (fileName.isEmpty())
return;
- if (!fileName.endsWith(".json")) {
- fileName += ".json";
- if (QFileInfo(fileName).exists()) {
- if (!KsWidgetsLib::fileExistsDialog(fileName))
- return;
- }
- }
-
kshark_export_all_event_filters(kshark_ctx, &conf);
kshark_save_config_file(fileName.toStdString().c_str(), conf);
kshark_free_config_doc(conf);
@@ -859,15 +846,12 @@ void KsMainWindow::_pluginAdd()
{
QStringList fileNames;
- fileNames =
- QFileDialog::getOpenFileNames(this, "Add KernelShark plugins",
- KS_DIR,
- "KernelShark Plugins (*.so);;");
-
- if (fileNames.isEmpty())
- return;
+ fileNames = KsUtils::getFiles(this, "Add KernelShark plugins",
+ "KernelShark Plugins (*.so);;",
+ _lastPluginFilePath);
- _plugins.addPlugins(fileNames);
+ if (!fileNames.isEmpty())
+ _plugins.addPlugins(fileNames);
}
void KsMainWindow::_record()
diff --git a/kernel-shark/src/KsMainWindow.hpp b/kernel-shark/src/KsMainWindow.hpp
index ec6506e..2bf3285 100644
--- a/kernel-shark/src/KsMainWindow.hpp
+++ b/kernel-shark/src/KsMainWindow.hpp
@@ -151,7 +151,9 @@ private:
QAction _contentsAction;
- QShortcut _deselectShortcut;
+ QShortcut _deselectShortcut;
+
+ QString _lastDataFilePath, _lastConfFilePath, _lastPluginFilePath;
void _open();
diff --git a/kernel-shark/src/KsUtils.cpp b/kernel-shark/src/KsUtils.cpp
index 6af0c66..8c42206 100644
--- a/kernel-shark/src/KsUtils.cpp
+++ b/kernel-shark/src/KsUtils.cpp
@@ -11,6 +11,7 @@
// KernelShark
#include "KsUtils.hpp"
+#include "KsWidgetsLib.hpp"
namespace KsUtils {
@@ -136,6 +137,126 @@ bool matchCPUVisible(struct kshark_context *kshark_ctx,
return (e->cpu == cpu && (e->visible & KS_GRAPH_VIEW_FILTER_MASK));
}
+/**
+ * @brief Check if the application runs from its installation location.
+ */
+bool isInstalled()
+{
+ QString appPath = QCoreApplication::applicationFilePath();
+ QString installPath(_INSTALL_PREFIX);
+
+ installPath += "/bin/kernelshark";
+ installPath = QDir::cleanPath(installPath);
+
+ return appPath == installPath;
+}
+
+static QString getFileDialog(QWidget *parent,
+ const QString &windowName,
+ const QString &filter,
+ QString &lastFilePath,
+ bool forSave)
+{
+ QString fileName;
+
+ if (lastFilePath.isEmpty()) {
+ lastFilePath = isInstalled() ? QDir::homePath() :
+ QDir::currentPath();
+ }
+
+ if (forSave) {
+ fileName = QFileDialog::getSaveFileName(parent,
+ windowName,
+ lastFilePath,
+ filter);
+ } else {
+ fileName = QFileDialog::getOpenFileName(parent,
+ windowName,
+ lastFilePath,
+ filter);
+ }
+
+ if (!fileName.isEmpty())
+ lastFilePath = QFileInfo(fileName).path();
+
+ return fileName;
+}
+
+static QStringList getFilesDialog(QWidget *parent,
+ const QString &windowName,
+ const QString &filter,
+ QString &lastFilePath)
+{
+ QStringList fileNames;
+
+ if (lastFilePath.isEmpty()) {
+ lastFilePath = isInstalled() ? QDir::homePath() :
+ QDir::currentPath();
+ }
+
+ fileNames = QFileDialog::getOpenFileNames(parent,
+ windowName,
+ lastFilePath,
+ filter);
+
+ if (!fileNames.isEmpty())
+ lastFilePath = QFileInfo(fileNames[0]).path();
+
+ return fileNames;
+}
+
+/**
+ * @brief Open a standard Qt getFileName dialog and return the name of the
+ * selected file. Only one file can be selected.
+ */
+QString getFile(QWidget *parent,
+ const QString &windowName,
+ const QString &filter,
+ QString &lastFilePath)
+{
+ return getFileDialog(parent, windowName, filter, lastFilePath, false);
+}
+
+/**
+ * @brief Open a standard Qt getFileName dialog and return the names of the
+ * selected files. Multiple files can be selected.
+ */
+QStringList getFiles(QWidget *parent,
+ const QString &windowName,
+ const QString &filter,
+ QString &lastFilePath)
+{
+ return getFilesDialog(parent, windowName, filter, lastFilePath);
+}
+
+/**
+ * @brief Open a standard Qt getFileName dialog and return the name of the
+ * selected file. Only one file can be selected.
+ */
+QString getSaveFile(QWidget *parent,
+ const QString &windowName,
+ const QString &filter,
+ const QString &extension,
+ QString &lastFilePath)
+{
+ QString fileName = getFileDialog(parent,
+ windowName,
+ filter,
+ lastFilePath,
+ true);
+
+ if (!fileName.isEmpty() && !fileName.endsWith(extension)) {
+ fileName += extension;
+
+ if (QFileInfo(fileName).exists()) {
+ if (!KsWidgetsLib::fileExistsDialog(fileName))
+ fileName.clear();
+ }
+ }
+
+ return fileName;
+}
+
}; // KsUtils
/** A stream operator for converting QColor into KsPlot::Color. */
diff --git a/kernel-shark/src/KsUtils.hpp b/kernel-shark/src/KsUtils.hpp
index c8b5e88..7b80b21 100644
--- a/kernel-shark/src/KsUtils.hpp
+++ b/kernel-shark/src/KsUtils.hpp
@@ -111,6 +111,23 @@ inline QString Ts2String(int64_t ts, int prec)
bool matchCPUVisible(struct kshark_context *kshark_ctx,
struct kshark_entry *e, int cpu);
+
+QString getFile(QWidget *parent,
+ const QString &windowName,
+ const QString &filter,
+ QString &lastFilePath);
+
+QStringList getFiles(QWidget *parent,
+ const QString &windowName,
+ const QString &filter,
+ QString &lastFilePath);
+
+QString getSaveFile(QWidget *parent,
+ const QString &windowName,
+ const QString &filter,
+ const QString &extension,
+ QString &lastFilePath);
+
}; // KsUtils
/** Identifier of the Dual Marker active state. */
--
2.20.1
next prev parent reply other threads:[~2019-05-02 12:40 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-02 12:40 [PATCH v2 0/8] Modifications needed for KS 1.0 Yordan Karadzhov
2019-05-02 12:40 ` [PATCH v2 1/8] kernel-shark: Add INSTALL PREFIX to the Cmake-generated header file Yordan Karadzhov
2019-05-02 12:40 ` Yordan Karadzhov [this message]
2019-05-02 12:40 ` [PATCH v2 3/8] kernel-shark: Add logic for the plugins search path Yordan Karadzhov
2019-05-03 23:05 ` Steven Rostedt
2019-05-04 8:27 ` Yordan Karadzhov (VMware)
2019-05-04 11:31 ` Steven Rostedt
2019-05-04 8:28 ` Yordan Karadzhov (VMware)
2019-05-02 12:40 ` [PATCH v2 4/8] kernel-shark: Remove the definition of KS_DIR Yordan Karadzhov
2019-05-02 12:40 ` [PATCH v2 5/8] kernel-shark: Remember the paths used by the Open-File dialogs Yordan Karadzhov
2019-05-02 12:40 ` [PATCH v2 6/8] kernel-shark: Add logic for selecting the trace-cmd executable used Yordan Karadzhov
2019-05-02 12:40 ` [PATCH v2 7/8] kernel-shark: Remove hard-coded install paths for libraries and plugins Yordan Karadzhov
2019-05-02 12:40 ` [PATCH v2 8/8] kernel-shark: Use XDG compliant path when saving cached data Yordan Karadzhov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190502124009.32208-3-ykaradzhov@vmware.com \
--to=ykaradzhov@vmware.com \
--cc=kaslevs@vmware.com \
--cc=linux-trace-devel@vger.kernel.org \
--cc=rostedt@goodmis.org \
--cc=troyengel@gmail.com \
--cc=y.karadz@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).