Make it possible to easily diff between files from the heaptrack_gui.
authorMilian Wolff <mail@milianw.de>
Fri, 17 Jun 2016 14:38:45 +0000 (16:38 +0200)
committerMilian Wolff <mail@milianw.de>
Fri, 17 Jun 2016 14:38:45 +0000 (16:38 +0200)
CMakeLists.txt
gui/CMakeLists.txt
gui/mainwindow.cpp
gui/mainwindow.h
gui/mainwindow.ui

index 84d2e29..a733949 100644 (file)
@@ -32,7 +32,7 @@ find_package(Qt5 5.2.0 NO_MODULE OPTIONAL_COMPONENTS Widgets)
 find_package(ECM 1.0.0 NO_MODULE)
 if(Qt5_FOUND AND ECM_FOUND)
     set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
-        find_package(KF5 OPTIONAL_COMPONENTS CoreAddons I18n ItemModels ThreadWeaver ConfigWidgets)
+        find_package(KF5 OPTIONAL_COMPONENTS CoreAddons I18n ItemModels ThreadWeaver ConfigWidgets KIO)
         find_package(KChart "2.6.0")
         set_package_properties(KChart PROPERTIES TYPE RECOMMENDED PURPOSE "Required for the heaptrack_gui executable. Get it from the kdiagram module.")
         if (KF5_FOUND AND KChart_FOUND)
index 47c60b7..230eacf 100644 (file)
@@ -44,6 +44,7 @@ target_link_libraries(heaptrack_gui
     KF5::ThreadWeaver
     KF5::ConfigWidgets
     KF5::I18n
+    KF5::KIOWidgets
     KChart
     sharedprint)
 
index 1e87dd3..0c3a5de 100644 (file)
@@ -24,7 +24,6 @@
 #include <cmath>
 
 #include <KRecursiveFilterProxyModel>
-#include <KStandardAction>
 #include <KLocalizedString>
 
 #include <QFileDialog>
@@ -223,8 +222,7 @@ MainWindow::MainWindow(QWidget* parent)
             this, [this, removeProgress] (const QString& failedFile) {
         removeProgress();
         m_ui->pages->setCurrentWidget(m_ui->openPage);
-        m_ui->messages->setText(i18n("Failed to parse file %1.", failedFile));
-        m_ui->messages->show();
+        showError(i18n("Failed to parse file %1.", failedFile));
     });
     m_ui->messages->hide();
 
@@ -303,8 +301,43 @@ MainWindow::MainWindow(QWidget* parent)
     connect(m_ui->callerCalleeFilterModule, &QLineEdit::textChanged,
             bottomUpProxy, &TreeProxy::setModuleFilter);
 
-    auto openFile = KStandardAction::open(this, SLOT(openFile()), this);
-    m_ui->openFile->setDefaultAction(openFile);
+    auto validateInputFile = [this] (const QString &path, bool allowEmpty) -> bool {
+        if (path.isEmpty()) {
+            return allowEmpty;
+        }
+
+        const auto file = QFileInfo(path);
+        if (!file.exists()) {
+            showError(i18n("Input data %1 does not exist.", path));
+        } else if (!file.isFile()) {
+            showError(i18n("Input data %1 is not a file.", path));
+        } else if (!file.isReadable()) {
+            showError(i18n("Input data %1 is not readable.", path));
+        } else {
+            return true;
+        }
+        return false;
+    };
+
+    auto validateInput = [this, validateInputFile] () {
+        m_ui->messages->hide();
+        m_ui->buttonBox->setEnabled(
+            validateInputFile(m_ui->openFile->url().toLocalFile(), false)
+            && validateInputFile(m_ui->compareTo->url().toLocalFile(), true)
+        );
+    };
+
+    connect(m_ui->openFile, &KUrlRequester::textChanged,
+            this, validateInput);
+    connect(m_ui->compareTo, &KUrlRequester::textChanged,
+            this, validateInput);
+    connect(m_ui->buttonBox, &QDialogButtonBox::accepted,
+            this, [this] () {
+                const auto path = m_ui->openFile->url().toLocalFile();
+                Q_ASSERT(!path.isEmpty());
+                const auto base = m_ui->compareTo->url().toLocalFile();
+                loadFile(path, base);
+            });
 
     setupStacks();
 
@@ -332,7 +365,13 @@ MainWindow::~MainWindow()
 void MainWindow::loadFile(const QString& file, const QString& diffBase)
 {
     m_ui->loadingLabel->setText(i18n("Loading file %1, please wait...", file));
-    setWindowTitle(i18nc("%1: file name that is open", "Heaptrack - %1", file));
+    if (diffBase.isEmpty()) {
+        setWindowTitle(i18nc("%1: file name that is open", "Heaptrack - %1",
+                             QFileInfo(file).fileName()));
+    } else {
+        setWindowTitle(i18nc("%1, %2: file names that are open", "Heaptrack - %1 compared to %2",
+                             QFileInfo(file).fileName(), QFileInfo(diffBase).fileName()));
+    }
     m_ui->pages->setCurrentWidget(m_ui->loadingPage);
     m_parser->parse(file, diffBase);
 }
@@ -349,6 +388,12 @@ void MainWindow::openFile()
     dialog->show();
 }
 
+void MainWindow::showError(const QString &message)
+{
+    m_ui->messages->setText(message);
+    m_ui->messages->show();
+}
+
 void MainWindow::setupStacks()
 {
     auto stacksModel = new StacksModel(this);
index b43109a..97084f2 100644 (file)
@@ -43,6 +43,7 @@ public slots:
     void openFile();
 
 private:
+    void showError(const QString &message);
     void setupStacks();
 
     QScopedPointer<Ui::MainWindow> m_ui;
index 2c8c54a..823047a 100644 (file)
     <item>
      <widget class="QStackedWidget" name="pages">
       <widget class="QWidget" name="openPage">
-       <layout class="QHBoxLayout" name="horizontalLayout_3">
+       <layout class="QVBoxLayout" name="verticalLayout_15">
         <item>
-         <widget class="QToolButton" name="openFile">
-          <property name="text">
-           <string notr="true">...</string>
+         <spacer name="verticalSpacer_4">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>40</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QGroupBox" name="groupBox">
+          <property name="title">
+           <string>Open Heaptrack Data</string>
+          </property>
+          <layout class="QFormLayout" name="formLayout">
+           <item row="1" column="1">
+            <widget class="KUrlRequester" name="openFile">
+             <property name="toolTip">
+              <string>&lt;qt&gt;&lt;p&gt;This field specifies the primary heaptrack data file. These files are called &lt;tt&gt;heaptrack.$APP.$PID.gz&lt;/tt&gt;. You can produce such a file by profiling your application, e.g. via:&lt;/p&gt;
+&lt;pre&gt;&lt;code&gt;heaptrack &amp;lt;yourapplication&amp;gt; ...&lt;/code&gt;&lt;/pre&gt;
+&lt;p&gt;Or, alternatively, you can attach to a running process via&lt;/p&gt;
+&lt;pre&gt;&lt;code&gt;heaptrack --pid $(pidof &amp;lt;yourapplication&amp;gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/qt&gt;</string>
+             </property>
+             <property name="filter">
+              <string>heaptrack.*.*.gz</string>
+             </property>
+             <property name="placeholderText">
+              <string>path/to/heaptrack.$APP.$PID.gz</string>
+             </property>
+             <property name="fileDialogModality">
+              <enum>Qt::WindowModal</enum>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="1">
+            <widget class="KUrlRequester" name="compareTo">
+             <property name="toolTip">
+              <string>&lt;qt&gt;You can optionally specify a second heaptrack data file to compare to. If set, this file will be used as a base and its cost gets subtracted from the primary data costs.&lt;/qt&gt;</string>
+             </property>
+             <property name="filter">
+              <string>heaptrack.*.*.gz</string>
+             </property>
+             <property name="placeholderText">
+              <string>path/to/heaptrack.$APP.$PID.gz</string>
+             </property>
+             <property name="fileDialogModality">
+              <enum>Qt::WindowModal</enum>
+             </property>
+            </widget>
+           </item>
+           <item row="1" column="0">
+            <widget class="QLabel" name="openFileLabel">
+             <property name="text">
+              <string>Profile &amp;Data:</string>
+             </property>
+             <property name="buddy">
+              <cstring>openFile</cstring>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="0">
+            <widget class="QLabel" name="compareToLabel">
+             <property name="text">
+              <string>Compare to:</string>
+             </property>
+             <property name="buddy">
+              <cstring>compareTo</cstring>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </widget>
+        </item>
+        <item>
+         <widget class="QDialogButtonBox" name="buttonBox">
+          <property name="enabled">
+           <bool>false</bool>
           </property>
-          <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonTextUnderIcon</enum>
+          <property name="standardButtons">
+           <set>QDialogButtonBox::Open</set>
           </property>
          </widget>
         </item>
+        <item>
+         <spacer name="verticalSpacer_3">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>40</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
        </layout>
       </widget>
       <widget class="QWidget" name="loadingPage">
    <header>kmessagewidget.h</header>
   </customwidget>
   <customwidget>
+   <class>KUrlRequester</class>
+   <extends>QWidget</extends>
+   <header>kurlrequester.h</header>
+  </customwidget>
+  <customwidget>
    <class>ChartWidget</class>
    <extends>QWidget</extends>
    <header>chartwidget.h</header>