@@ -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);
@@ -61,6 +61,8 @@ private:
QPushButton _outputBrowseButton;
+ QString _lastFilePath;
+
QStringList _getPlugins();
void _importSettings();
@@ -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()
@@ -151,7 +151,9 @@ private:
QAction _contentsAction;
- QShortcut _deselectShortcut;
+ QShortcut _deselectShortcut;
+
+ QString _lastDataFilePath, _lastConfFilePath, _lastPluginFilePath;
void _open();
@@ -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. */
@@ -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. */
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> 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(-)