* [PATCH 2/5] kernel-shark: Add logic for the initial path of Open-File dialogs
2019-04-23 13:27 [PATCH 0/5] Modifications needed for KS 1.0 Yordan Karadzhov
2019-04-23 13:27 ` [PATCH 1/5] kernel-shark: Add INSTALL PREFIX to the Cmake-generated header file Yordan Karadzhov
@ 2019-04-23 13:27 ` Yordan Karadzhov
2019-04-23 13:27 ` [PATCH 3/5] kernel-shark: Add logic for the plugins search path Yordan Karadzhov
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Yordan Karadzhov @ 2019-04-23 13:27 UTC (permalink / raw)
To: rostedt; +Cc: linux-trace-devel, y.karadz, Yordan Karadzhov
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(-)
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
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/5] kernel-shark: Add logic for the plugins search path
2019-04-23 13:27 [PATCH 0/5] Modifications needed for KS 1.0 Yordan Karadzhov
2019-04-23 13:27 ` [PATCH 1/5] kernel-shark: Add INSTALL PREFIX to the Cmake-generated header file Yordan Karadzhov
2019-04-23 13:27 ` [PATCH 2/5] kernel-shark: Add logic for the initial path of Open-File dialogs Yordan Karadzhov
@ 2019-04-23 13:27 ` Yordan Karadzhov
2019-04-23 13:27 ` [PATCH 4/5] kernel-shark: Remove the definition of KS_DIR Yordan Karadzhov
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Yordan Karadzhov @ 2019-04-23 13:27 UTC (permalink / raw)
To: rostedt; +Cc: linux-trace-devel, y.karadz, Yordan Karadzhov
If the application has not been started from its installation location
and the the directory
app_file_path + "../../kernel-shark/lib"
exists, all build-in plugins will be loaded from this directory. In any
other case all build-in plugins will be loaded from
_INSTALL_PREFIX/lib/kshark/plugins/
Suggested-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
kernel-shark/src/KsUtils.cpp | 40 ++++++++++++++++++-------
kernel-shark/src/KsUtils.hpp | 2 ++
kernel-shark/src/plugins/CMakeLists.txt | 2 +-
3 files changed, 32 insertions(+), 12 deletions(-)
diff --git a/kernel-shark/src/KsUtils.cpp b/kernel-shark/src/KsUtils.cpp
index 8c42206..f62e53a 100644
--- a/kernel-shark/src/KsUtils.cpp
+++ b/kernel-shark/src/KsUtils.cpp
@@ -544,13 +544,12 @@ void KsPluginManager::_parsePluginList()
*/
void KsPluginManager::registerFromList(kshark_context *kshark_ctx)
{
- auto lamRegBuiltIn = [&kshark_ctx](const QString &plugin)
+ auto lamRegBuiltIn = [&kshark_ctx, this](const QString &plugin)
{
char *lib;
int n;
- n = asprintf(&lib, "%s/lib/plugin-%s.so",
- KS_DIR, plugin.toStdString().c_str());
+ lib = _pluginLibFromName(plugin, n);
if (n <= 0)
return;
@@ -579,13 +578,12 @@ void KsPluginManager::registerFromList(kshark_context *kshark_ctx)
*/
void KsPluginManager::unregisterFromList(kshark_context *kshark_ctx)
{
- auto lamUregBuiltIn = [&kshark_ctx](const QString &plugin)
+ auto lamUregBuiltIn = [&kshark_ctx, this](const QString &plugin)
{
char *lib;
int n;
- n = asprintf(&lib, "%s/lib/plugin-%s.so",
- KS_DIR, plugin.toStdString().c_str());
+ lib = _pluginLibFromName(plugin, n);
if (n <= 0)
return;
@@ -608,6 +606,28 @@ void KsPluginManager::unregisterFromList(kshark_context *kshark_ctx)
lamUregUser);
}
+char *KsPluginManager::_pluginLibFromName(const QString &plugin, int &n)
+{
+ QString execPath = QCoreApplication::applicationFilePath();
+ QString path = QFileInfo(execPath).path();
+ std::string pluginStr = plugin.toStdString();
+ char *lib;
+ QDir dir;
+
+ dir.setCurrent(path);
+ if (!KsUtils::isInstalled() && dir.cd("../../kernel-shark/lib")) {
+ std::string pathStr = dir.path().toStdString();
+
+ n = asprintf(&lib, "%s/plugin-%s.so",
+ pathStr.c_str(), pluginStr.c_str());
+ } else {
+ n = asprintf(&lib, "%s/lib/kshark/plugins/plugin-%s.so",
+ _INSTALL_PREFIX, pluginStr.c_str());
+ }
+
+ return lib;
+}
+
/**
* @brief Register a Plugin.
*
@@ -629,8 +649,7 @@ void KsPluginManager::registerPlugin(const QString &plugin)
* The argument is the name of the plugin. From the
* name get the library .so file.
*/
- n = asprintf(&lib, "%s/lib/plugin-%s.so",
- KS_DIR, plugin.toStdString().c_str());
+ lib = _pluginLibFromName(plugin, n);
if (n > 0) {
kshark_register_plugin(kshark_ctx, lib);
_registeredKsPlugins[i] = true;
@@ -691,8 +710,7 @@ void KsPluginManager::unregisterPlugin(const QString &plugin)
* The argument is the name of the plugin. From the
* name get the library .so file.
*/
- n = asprintf(&lib, "%s/lib/plugin-%s.so", KS_DIR,
- plugin.toStdString().c_str());
+ lib = _pluginLibFromName(plugin, n);
if (n > 0) {
kshark_unregister_plugin(kshark_ctx, lib);
_registeredKsPlugins[i] = false;
@@ -700,7 +718,7 @@ void KsPluginManager::unregisterPlugin(const QString &plugin)
}
return;
- } else if (plugin.contains("/lib/plugin-" +
+ } else if (plugin.contains("/lib/plugin-" +
_ksPluginList[i], Qt::CaseInsensitive)) {
/*
* The argument is the name of the library .so file.
diff --git a/kernel-shark/src/KsUtils.hpp b/kernel-shark/src/KsUtils.hpp
index 7b80b21..1c87271 100644
--- a/kernel-shark/src/KsUtils.hpp
+++ b/kernel-shark/src/KsUtils.hpp
@@ -241,6 +241,8 @@ signals:
private:
void _parsePluginList();
+ char *_pluginLibFromName(const QString &plugin, int &n);
+
template <class T>
void _forEachInList(const QStringList &pl,
const QVector<bool> ®,
diff --git a/kernel-shark/src/plugins/CMakeLists.txt b/kernel-shark/src/plugins/CMakeLists.txt
index 6098275..64cf98d 100644
--- a/kernel-shark/src/plugins/CMakeLists.txt
+++ b/kernel-shark/src/plugins/CMakeLists.txt
@@ -29,6 +29,6 @@ BUILD_PLUGIN(NAME missed_events
list(APPEND PLUGIN_LIST "missed_events default") # This plugin will be loaded by default
install(TARGETS sched_events missed_events
- LIBRARY DESTINATION ${_INSTALL_PREFIX}/lib/kshark/)
+ LIBRARY DESTINATION ${_INSTALL_PREFIX}/lib/kshark/plugins/)
set(PLUGINS ${PLUGIN_LIST} PARENT_SCOPE)
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread