* [PATCH 1/6] perf scripts python: exported-sql-viewer.py: Fix error when shrinking / enlarging font
2019-05-03 12:08 [PATCH 0/6] perf scripts python: exported-sql-viewer.py: Minor improvements Adrian Hunter
@ 2019-05-03 12:08 ` Adrian Hunter
2019-05-13 19:57 ` Arnaldo Carvalho de Melo
2019-05-18 8:55 ` [tip:perf/core] " tip-bot for Adrian Hunter
2019-05-03 12:08 ` [PATCH 2/6] perf scripts python: exported-sql-viewer.py: Move view creation Adrian Hunter
` (4 subsequent siblings)
5 siblings, 2 replies; 17+ messages in thread
From: Adrian Hunter @ 2019-05-03 12:08 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: Jiri Olsa, linux-kernel
Fix the following error if shrink / enlarge font is used with the help
window.
Traceback (most recent call last):
File "tools/perf/scripts/python/exported-sql-viewer.py", line 2791, in ShrinkFont
ShrinkFont(win.view)
AttributeError: 'HelpWindow' object has no attribute 'view'
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
tools/perf/scripts/python/exported-sql-viewer.py | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index c586abfb2b46..289e8dbd1444 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -2770,6 +2770,14 @@ class MainWindow(QMainWindow):
help_menu = menu.addMenu("&Help")
help_menu.addAction(CreateAction("&Exported SQL Viewer Help", "Helpful information", self.Help, self, QKeySequence.HelpContents))
+ def Try(self, fn):
+ win = self.mdi_area.activeSubWindow()
+ if win:
+ try:
+ fn(win.view)
+ except:
+ pass
+
def Find(self):
win = self.mdi_area.activeSubWindow()
if win:
@@ -2787,12 +2795,10 @@ class MainWindow(QMainWindow):
pass
def ShrinkFont(self):
- win = self.mdi_area.activeSubWindow()
- ShrinkFont(win.view)
+ self.Try(ShrinkFont)
def EnlargeFont(self):
- win = self.mdi_area.activeSubWindow()
- EnlargeFont(win.view)
+ self.Try(EnlargeFont)
def EventMenu(self, events, reports_menu):
branches_events = 0
--
2.17.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 1/6] perf scripts python: exported-sql-viewer.py: Fix error when shrinking / enlarging font
2019-05-03 12:08 ` [PATCH 1/6] perf scripts python: exported-sql-viewer.py: Fix error when shrinking / enlarging font Adrian Hunter
@ 2019-05-13 19:57 ` Arnaldo Carvalho de Melo
2019-05-18 8:55 ` [tip:perf/core] " tip-bot for Adrian Hunter
1 sibling, 0 replies; 17+ messages in thread
From: Arnaldo Carvalho de Melo @ 2019-05-13 19:57 UTC (permalink / raw)
To: Adrian Hunter; +Cc: Jiri Olsa, linux-kernel
Em Fri, May 03, 2019 at 03:08:23PM +0300, Adrian Hunter escreveu:
> Fix the following error if shrink / enlarge font is used with the help
> window.
>
> Traceback (most recent call last):
> File "tools/perf/scripts/python/exported-sql-viewer.py", line 2791, in ShrinkFont
> ShrinkFont(win.view)
> AttributeError: 'HelpWindow' object has no attribute 'view'
Humm, this is kinda frustrating, I tried it and expected it to either
enlarge/shrink or tell me that that is not possible, and why :-\
Anyway, if you think this is the best approach, applied.
- Arnaldo
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
> tools/perf/scripts/python/exported-sql-viewer.py | 14 ++++++++++----
> 1 file changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
> index c586abfb2b46..289e8dbd1444 100755
> --- a/tools/perf/scripts/python/exported-sql-viewer.py
> +++ b/tools/perf/scripts/python/exported-sql-viewer.py
> @@ -2770,6 +2770,14 @@ class MainWindow(QMainWindow):
> help_menu = menu.addMenu("&Help")
> help_menu.addAction(CreateAction("&Exported SQL Viewer Help", "Helpful information", self.Help, self, QKeySequence.HelpContents))
>
> + def Try(self, fn):
> + win = self.mdi_area.activeSubWindow()
> + if win:
> + try:
> + fn(win.view)
> + except:
> + pass
> +
> def Find(self):
> win = self.mdi_area.activeSubWindow()
> if win:
> @@ -2787,12 +2795,10 @@ class MainWindow(QMainWindow):
> pass
>
> def ShrinkFont(self):
> - win = self.mdi_area.activeSubWindow()
> - ShrinkFont(win.view)
> + self.Try(ShrinkFont)
>
> def EnlargeFont(self):
> - win = self.mdi_area.activeSubWindow()
> - EnlargeFont(win.view)
> + self.Try(EnlargeFont)
>
> def EventMenu(self, events, reports_menu):
> branches_events = 0
> --
> 2.17.1
--
- Arnaldo
^ permalink raw reply [flat|nested] 17+ messages in thread
* [tip:perf/core] perf scripts python: exported-sql-viewer.py: Fix error when shrinking / enlarging font
2019-05-03 12:08 ` [PATCH 1/6] perf scripts python: exported-sql-viewer.py: Fix error when shrinking / enlarging font Adrian Hunter
2019-05-13 19:57 ` Arnaldo Carvalho de Melo
@ 2019-05-18 8:55 ` tip-bot for Adrian Hunter
1 sibling, 0 replies; 17+ messages in thread
From: tip-bot for Adrian Hunter @ 2019-05-18 8:55 UTC (permalink / raw)
To: linux-tip-commits
Cc: mingo, tglx, adrian.hunter, linux-kernel, acme, hpa, jolsa
Commit-ID: 4b2084537e5f3b58337bce894391fb63bf3b0e28
Gitweb: https://git.kernel.org/tip/4b2084537e5f3b58337bce894391fb63bf3b0e28
Author: Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Fri, 3 May 2019 15:08:23 +0300
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 15 May 2019 16:36:47 -0300
perf scripts python: exported-sql-viewer.py: Fix error when shrinking / enlarging font
Fix the following error if shrink / enlarge font is used with the help
window.
Traceback (most recent call last):
File "tools/perf/scripts/python/exported-sql-viewer.py", line 2791, in ShrinkFont
ShrinkFont(win.view)
AttributeError: 'HelpWindow' object has no attribute 'view'
Committer testing:
Before, matches above output:
$ python ~acme/libexec/perf-core/scripts/python/exported-sql-viewer.py ~/c/adrian.hunter/simple-retpoline.db
Traceback (most recent call last):
File "/home/acme/libexec/perf-core/scripts/python/exported-sql-viewer.py", line 2780, in EnlargeFont
EnlargeFont(win.view)
AttributeError: 'HelpWindow' object has no attribute 'view'
$
After:
No more tracebacks, but the fonts don't get enlarged, which is kinda
frustrating...
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/20190503120828.25326-2-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/scripts/python/exported-sql-viewer.py | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index db4655168ab1..fd073e4af8da 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -2755,6 +2755,14 @@ class MainWindow(QMainWindow):
help_menu = menu.addMenu("&Help")
help_menu.addAction(CreateAction("&Exported SQL Viewer Help", "Helpful information", self.Help, self, QKeySequence.HelpContents))
+ def Try(self, fn):
+ win = self.mdi_area.activeSubWindow()
+ if win:
+ try:
+ fn(win.view)
+ except:
+ pass
+
def Find(self):
win = self.mdi_area.activeSubWindow()
if win:
@@ -2772,12 +2780,10 @@ class MainWindow(QMainWindow):
pass
def ShrinkFont(self):
- win = self.mdi_area.activeSubWindow()
- ShrinkFont(win.view)
+ self.Try(ShrinkFont)
def EnlargeFont(self):
- win = self.mdi_area.activeSubWindow()
- EnlargeFont(win.view)
+ self.Try(EnlargeFont)
def EventMenu(self, events, reports_menu):
branches_events = 0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 2/6] perf scripts python: exported-sql-viewer.py: Move view creation
2019-05-03 12:08 [PATCH 0/6] perf scripts python: exported-sql-viewer.py: Minor improvements Adrian Hunter
2019-05-03 12:08 ` [PATCH 1/6] perf scripts python: exported-sql-viewer.py: Fix error when shrinking / enlarging font Adrian Hunter
@ 2019-05-03 12:08 ` Adrian Hunter
2019-05-18 8:54 ` [tip:perf/core] " tip-bot for Adrian Hunter
2019-05-03 12:08 ` [PATCH 3/6] perf scripts python: exported-sql-viewer.py: Add tree level Adrian Hunter
` (3 subsequent siblings)
5 siblings, 1 reply; 17+ messages in thread
From: Adrian Hunter @ 2019-05-03 12:08 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: Jiri Olsa, linux-kernel
As preparation for adding support for copying to clipboard, create view in
TreeWindowBase instead of derived classes.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
tools/perf/scripts/python/exported-sql-viewer.py | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index 289e8dbd1444..73fc02d6d1e4 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -891,9 +891,10 @@ class TreeWindowBase(QMdiSubWindow):
super(TreeWindowBase, self).__init__(parent)
self.model = None
- self.view = None
self.find_bar = None
+ self.view = QTreeView()
+
def DisplayFound(self, ids):
if not len(ids):
return False
@@ -935,7 +936,6 @@ class CallGraphWindow(TreeWindowBase):
self.model = LookupCreateModel("Context-Sensitive Call Graph", lambda x=glb: CallGraphModel(x))
- self.view = QTreeView()
self.view.setModel(self.model)
for c, w in ((0, 250), (1, 100), (2, 60), (3, 70), (4, 70), (5, 100)):
@@ -958,7 +958,6 @@ class CallTreeWindow(TreeWindowBase):
self.model = LookupCreateModel("Call Tree", lambda x=glb: CallTreeModel(x))
- self.view = QTreeView()
self.view.setModel(self.model)
for c, w in ((0, 230), (1, 100), (2, 100), (3, 70), (4, 70), (5, 100)):
--
2.17.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [tip:perf/core] perf scripts python: exported-sql-viewer.py: Move view creation
2019-05-03 12:08 ` [PATCH 2/6] perf scripts python: exported-sql-viewer.py: Move view creation Adrian Hunter
@ 2019-05-18 8:54 ` tip-bot for Adrian Hunter
0 siblings, 0 replies; 17+ messages in thread
From: tip-bot for Adrian Hunter @ 2019-05-18 8:54 UTC (permalink / raw)
To: linux-tip-commits
Cc: jolsa, hpa, acme, mingo, adrian.hunter, tglx, linux-kernel
Commit-ID: be6e747136a4dc8aad99259e47fd6f7362a43996
Gitweb: https://git.kernel.org/tip/be6e747136a4dc8aad99259e47fd6f7362a43996
Author: Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Fri, 3 May 2019 15:08:24 +0300
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 15 May 2019 16:36:47 -0300
perf scripts python: exported-sql-viewer.py: Move view creation
As preparation for adding support for copying to clipboard, create view
in TreeWindowBase instead of derived classes.
Committer testing:
Tested using an old .db used to test some older patches:
$ python ~acme/libexec/perf-core/scripts/python/exported-sql-viewer.py ~/c/adrian.hunter/simple-retpoline.db
Nothing breaks.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/20190503120828.25326-3-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/scripts/python/exported-sql-viewer.py | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index 74ef92f1d19a..db4655168ab1 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -877,9 +877,10 @@ class TreeWindowBase(QMdiSubWindow):
super(TreeWindowBase, self).__init__(parent)
self.model = None
- self.view = None
self.find_bar = None
+ self.view = QTreeView()
+
def DisplayFound(self, ids):
if not len(ids):
return False
@@ -921,7 +922,6 @@ class CallGraphWindow(TreeWindowBase):
self.model = LookupCreateModel("Context-Sensitive Call Graph", lambda x=glb: CallGraphModel(x))
- self.view = QTreeView()
self.view.setModel(self.model)
for c, w in ((0, 250), (1, 100), (2, 60), (3, 70), (4, 70), (5, 100)):
@@ -944,7 +944,6 @@ class CallTreeWindow(TreeWindowBase):
self.model = LookupCreateModel("Call Tree", lambda x=glb: CallTreeModel(x))
- self.view = QTreeView()
self.view.setModel(self.model)
for c, w in ((0, 230), (1, 100), (2, 100), (3, 70), (4, 70), (5, 100)):
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 3/6] perf scripts python: exported-sql-viewer.py: Add tree level
2019-05-03 12:08 [PATCH 0/6] perf scripts python: exported-sql-viewer.py: Minor improvements Adrian Hunter
2019-05-03 12:08 ` [PATCH 1/6] perf scripts python: exported-sql-viewer.py: Fix error when shrinking / enlarging font Adrian Hunter
2019-05-03 12:08 ` [PATCH 2/6] perf scripts python: exported-sql-viewer.py: Move view creation Adrian Hunter
@ 2019-05-03 12:08 ` Adrian Hunter
2019-05-18 8:55 ` [tip:perf/core] " tip-bot for Adrian Hunter
2019-05-03 12:08 ` [PATCH 4/6] perf scripts python: exported-sql-viewer.py: Add copy to clipboard Adrian Hunter
` (2 subsequent siblings)
5 siblings, 1 reply; 17+ messages in thread
From: Adrian Hunter @ 2019-05-03 12:08 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: Jiri Olsa, linux-kernel
As preparation for adding support for copying to clipboard, keep track of
what level each item is in tree items.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
tools/perf/scripts/python/exported-sql-viewer.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index 73fc02d6d1e4..c0fb88d440ba 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -470,6 +470,10 @@ class CallGraphLevelItemBase(object):
self.query_done = False;
self.child_count = 0
self.child_items = []
+ if parent_item:
+ self.level = parent_item.level + 1
+ else:
+ self.level = 0
def getChildItem(self, row):
return self.child_items[row]
--
2.17.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [tip:perf/core] perf scripts python: exported-sql-viewer.py: Add tree level
2019-05-03 12:08 ` [PATCH 3/6] perf scripts python: exported-sql-viewer.py: Add tree level Adrian Hunter
@ 2019-05-18 8:55 ` tip-bot for Adrian Hunter
0 siblings, 0 replies; 17+ messages in thread
From: tip-bot for Adrian Hunter @ 2019-05-18 8:55 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, mingo, acme, jolsa, tglx, hpa, adrian.hunter
Commit-ID: 3ac641f4acd66c109b74f108f8a61f2905702b10
Gitweb: https://git.kernel.org/tip/3ac641f4acd66c109b74f108f8a61f2905702b10
Author: Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Fri, 3 May 2019 15:08:25 +0300
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 15 May 2019 16:36:47 -0300
perf scripts python: exported-sql-viewer.py: Add tree level
As preparation for adding support for copying to clipboard, keep track of
what level each item is in tree items.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/20190503120828.25326-4-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/scripts/python/exported-sql-viewer.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index fd073e4af8da..48953257a1f0 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -456,6 +456,10 @@ class CallGraphLevelItemBase(object):
self.query_done = False;
self.child_count = 0
self.child_items = []
+ if parent_item:
+ self.level = parent_item.level + 1
+ else:
+ self.level = 0
def getChildItem(self, row):
return self.child_items[row]
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 4/6] perf scripts python: exported-sql-viewer.py: Add copy to clipboard
2019-05-03 12:08 [PATCH 0/6] perf scripts python: exported-sql-viewer.py: Minor improvements Adrian Hunter
` (2 preceding siblings ...)
2019-05-03 12:08 ` [PATCH 3/6] perf scripts python: exported-sql-viewer.py: Add tree level Adrian Hunter
@ 2019-05-03 12:08 ` Adrian Hunter
2019-05-13 20:03 ` Arnaldo Carvalho de Melo
2019-05-18 8:56 ` [tip:perf/core] " tip-bot for Adrian Hunter
2019-05-03 12:08 ` [PATCH 5/6] perf scripts python: exported-sql-viewer.py: Add context menu Adrian Hunter
2019-05-03 12:08 ` [PATCH 6/6] perf scripts python: exported-sql-viewer.py: Add 'About' dialog box Adrian Hunter
5 siblings, 2 replies; 17+ messages in thread
From: Adrian Hunter @ 2019-05-03 12:08 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: Jiri Olsa, linux-kernel
Add support for copying to clipboard. Two menu options are added to copy the
selected rows / columns with normal spacing, or as comma-separated-values.
In the case of trees, only entire rows can be copied.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
.../scripts/python/exported-sql-viewer.py | 217 ++++++++++++++++++
1 file changed, 217 insertions(+)
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index c0fb88d440ba..5804d9705ab7 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -898,6 +898,8 @@ class TreeWindowBase(QMdiSubWindow):
self.find_bar = None
self.view = QTreeView()
+ self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
+ self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard
def DisplayFound(self, ids):
if not len(ids):
@@ -1666,6 +1668,8 @@ class BranchWindow(QMdiSubWindow):
self.view = QTreeView()
self.view.setUniformRowHeights(True)
+ self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
+ self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard
self.view.setModel(self.model)
self.ResizeColumnsToContents()
@@ -2278,6 +2282,207 @@ class ResizeColumnsToContentsBase(QObject):
self.data_model.rowsInserted.disconnect(self.UpdateColumnWidths)
self.ResizeColumnsToContents()
+# Convert value to CSV
+
+def ToCSValue(val):
+ if '"' in val:
+ val = val.replace('"', '""')
+ if "," in val or '"' in val:
+ val = '"' + val + '"'
+ return val
+
+# Key to sort table model indexes by row / column, assuming fewer than 1000 columns
+
+glb_max_cols = 1000
+
+def RowColumnKey(a):
+ return a.row() * glb_max_cols + a.column()
+
+# Copy selected table cells to clipboard
+
+def CopyTableCellsToClipboard(view, as_csv=False, with_hdr=False):
+ indexes = sorted(view.selectedIndexes(), key=RowColumnKey)
+ idx_cnt = len(indexes)
+ if not idx_cnt:
+ return
+ if idx_cnt == 1:
+ with_hdr=False
+ min_row = indexes[0].row()
+ max_row = indexes[0].row()
+ min_col = indexes[0].column()
+ max_col = indexes[0].column()
+ for i in indexes:
+ min_row = min(min_row, i.row())
+ max_row = max(max_row, i.row())
+ min_col = min(min_col, i.column())
+ max_col = max(max_col, i.column())
+ if max_col > glb_max_cols:
+ raise RuntimeError("glb_max_cols is too low")
+ max_width = [0] * (1 + max_col - min_col)
+ for i in indexes:
+ c = i.column() - min_col
+ max_width[c] = max(max_width[c], len(str(i.data())))
+ text = ""
+ pad = ""
+ sep = ""
+ if with_hdr:
+ model = indexes[0].model()
+ for col in range(min_col, max_col + 1):
+ val = model.headerData(col, Qt.Horizontal)
+ if as_csv:
+ text += sep + ToCSValue(val)
+ sep = ","
+ else:
+ c = col - min_col
+ max_width[c] = max(max_width[c], len(val))
+ width = max_width[c]
+ align = model.headerData(col, Qt.Horizontal, Qt.TextAlignmentRole)
+ if align & Qt.AlignRight:
+ val = val.rjust(width)
+ text += pad + sep + val
+ pad = " " * (width - len(val))
+ sep = " "
+ text += "\n"
+ pad = ""
+ sep = ""
+ last_row = min_row
+ for i in indexes:
+ if i.row() > last_row:
+ last_row = i.row()
+ text += "\n"
+ pad = ""
+ sep = ""
+ if as_csv:
+ text += sep + ToCSValue(str(i.data()))
+ sep = ","
+ else:
+ width = max_width[i.column() - min_col]
+ if i.data(Qt.TextAlignmentRole) & Qt.AlignRight:
+ val = str(i.data()).rjust(width)
+ else:
+ val = str(i.data())
+ text += pad + sep + val
+ pad = " " * (width - len(val))
+ sep = " "
+ QApplication.clipboard().setText(text)
+
+def CopyTreeCellsToClipboard(view, as_csv=False, with_hdr=False):
+ indexes = view.selectedIndexes()
+ if not len(indexes):
+ return
+
+ selection = view.selectionModel()
+
+ first = None
+ for i in indexes:
+ above = view.indexAbove(i)
+ if not selection.isSelected(above):
+ first = i
+ break
+
+ if first is None:
+ raise RuntimeError("CopyTreeCellsToClipboard internal error")
+
+ model = first.model()
+ row_cnt = 0
+ col_cnt = model.columnCount(first)
+ max_width = [0] * col_cnt
+
+ indent_sz = 2
+ indent_str = " " * indent_sz
+
+ expanded_mark_sz = 2
+ if sys.version_info[0] == 3:
+ expanded_mark = "\u25BC "
+ not_expanded_mark = "\u25B6 "
+ else:
+ expanded_mark = unicode(chr(0xE2) + chr(0x96) + chr(0xBC) + " ", "utf-8")
+ not_expanded_mark = unicode(chr(0xE2) + chr(0x96) + chr(0xB6) + " ", "utf-8")
+ leaf_mark = " "
+
+ if not as_csv:
+ pos = first
+ while True:
+ row_cnt += 1
+ row = pos.row()
+ for c in range(col_cnt):
+ i = pos.sibling(row, c)
+ if c:
+ n = len(str(i.data()))
+ else:
+ n = len(str(i.data()).strip())
+ n += (i.internalPointer().level - 1) * indent_sz
+ n += expanded_mark_sz
+ max_width[c] = max(max_width[c], n)
+ pos = view.indexBelow(pos)
+ if not selection.isSelected(pos):
+ break
+
+ text = ""
+ pad = ""
+ sep = ""
+ if with_hdr:
+ for c in range(col_cnt):
+ val = model.headerData(c, Qt.Horizontal, Qt.DisplayRole).strip()
+ if as_csv:
+ text += sep + ToCSValue(val)
+ sep = ","
+ else:
+ max_width[c] = max(max_width[c], len(val))
+ width = max_width[c]
+ align = model.headerData(c, Qt.Horizontal, Qt.TextAlignmentRole)
+ if align & Qt.AlignRight:
+ val = val.rjust(width)
+ text += pad + sep + val
+ pad = " " * (width - len(val))
+ sep = " "
+ text += "\n"
+ pad = ""
+ sep = ""
+
+ pos = first
+ while True:
+ row = pos.row()
+ for c in range(col_cnt):
+ i = pos.sibling(row, c)
+ val = str(i.data())
+ if not c:
+ if model.hasChildren(i):
+ if view.isExpanded(i):
+ mark = expanded_mark
+ else:
+ mark = not_expanded_mark
+ else:
+ mark = leaf_mark
+ val = indent_str * (i.internalPointer().level - 1) + mark + val.strip()
+ if as_csv:
+ text += sep + ToCSValue(val)
+ sep = ","
+ else:
+ width = max_width[c]
+ if c and i.data(Qt.TextAlignmentRole) & Qt.AlignRight:
+ val = val.rjust(width)
+ text += pad + sep + val
+ pad = " " * (width - len(val))
+ sep = " "
+ pos = view.indexBelow(pos)
+ if not selection.isSelected(pos):
+ break
+ text = text.rstrip() + "\n"
+ pad = ""
+ sep = ""
+
+ QApplication.clipboard().setText(text)
+
+def CopyCellsToClipboard(view, as_csv=False, with_hdr=False):
+ view.CopyCellsToClipboard(view, as_csv, with_hdr)
+
+def CopyCellsToClipboardHdr(view):
+ CopyCellsToClipboard(view, False, True)
+
+def CopyCellsToClipboardCSV(view):
+ CopyCellsToClipboard(view, True, True)
+
# Table window
class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
@@ -2296,6 +2501,8 @@ class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
self.view.verticalHeader().setVisible(False)
self.view.sortByColumn(-1, Qt.AscendingOrder)
self.view.setSortingEnabled(True)
+ self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
+ self.view.CopyCellsToClipboard = CopyTableCellsToClipboard
self.ResizeColumnsToContents()
@@ -2412,6 +2619,8 @@ class TopCallsWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
self.view.setModel(self.model)
self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.view.verticalHeader().setVisible(False)
+ self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
+ self.view.CopyCellsToClipboard = CopyTableCellsToClipboard
self.ResizeColumnsToContents()
@@ -2749,6 +2958,8 @@ class MainWindow(QMainWindow):
file_menu.addAction(CreateExitAction(glb.app, self))
edit_menu = menu.addMenu("&Edit")
+ edit_menu.addAction(CreateAction("&Copy", "Copy to clipboard", self.CopyToClipboard, self, QKeySequence.Copy))
+ edit_menu.addAction(CreateAction("Copy as CS&V", "Copy to clipboard as CSV", self.CopyToClipboardCSV, self))
edit_menu.addAction(CreateAction("&Find...", "Find items", self.Find, self, QKeySequence.Find))
edit_menu.addAction(CreateAction("Fetch &more records...", "Fetch more records", self.FetchMoreRecords, self, [QKeySequence(Qt.Key_F8)]))
edit_menu.addAction(CreateAction("&Shrink Font", "Make text smaller", self.ShrinkFont, self, [QKeySequence("Ctrl+-")]))
@@ -2781,6 +2992,12 @@ class MainWindow(QMainWindow):
except:
pass
+ def CopyToClipboard(self):
+ self.Try(CopyCellsToClipboardHdr)
+
+ def CopyToClipboardCSV(self):
+ self.Try(CopyCellsToClipboardCSV)
+
def Find(self):
win = self.mdi_area.activeSubWindow()
if win:
--
2.17.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 4/6] perf scripts python: exported-sql-viewer.py: Add copy to clipboard
2019-05-03 12:08 ` [PATCH 4/6] perf scripts python: exported-sql-viewer.py: Add copy to clipboard Adrian Hunter
@ 2019-05-13 20:03 ` Arnaldo Carvalho de Melo
2019-05-18 8:56 ` [tip:perf/core] " tip-bot for Adrian Hunter
1 sibling, 0 replies; 17+ messages in thread
From: Arnaldo Carvalho de Melo @ 2019-05-13 20:03 UTC (permalink / raw)
To: Adrian Hunter; +Cc: Jiri Olsa, linux-kernel, linux-perf-users
Em Fri, May 03, 2019 at 03:08:26PM +0300, Adrian Hunter escreveu:
> Add support for copying to clipboard. Two menu options are added to copy the
> selected rows / columns with normal spacing, or as comma-separated-values.
> In the case of trees, only entire rows can be copied.
Cool, it works:
Comitter testing:
$ python ~acme/libexec/perf-core/scripts/python/exported-sql-viewer.py ~/c/adrian.hunter/simple-retpoline.db
Select the lines, press control+C and on the same terminal,
press control+shift+V and voilà:
Call Path Object Count Time (ns) Time (%) Branch Count Branch Count (%)
▼ 14503:14503
▼ _start ld-2.28.so 1 156267 100.0 10602 100.0
unknown unknown 1 2276 1.5 1 0.0
▼ _dl_start ld-2.28.so 1 137047 87.7 10088 95.2
▶ unknown unknown 4 4127 3.0 4 0.0
_dl_setup_hash ld-2.28.so 1 0 0.0 1 0.0
▶ _dl_sysdep_start ld-2.28.so 1 131342 95.8 9981 98.9
▼ _dl_init ld-2.28.so 1 9142 5.9 326 3.1
▼ call_init.part.0 ld-2.28.so 3 9133 99.9 319 97.9
▶ _init libc-2.28.so 1 6877 75.3 110 34.5
▶ check_stdfiles_vtables libc-2.28.so 1 76 0.8 2 0.6
▶ init_cacheinfo libc-2.28.so 1 1991 21.8 197 61.8
▶ _start simple-retpoline 1 7457 4.8 182 1.7
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
> .../scripts/python/exported-sql-viewer.py | 217 ++++++++++++++++++
> 1 file changed, 217 insertions(+)
>
> diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
> index c0fb88d440ba..5804d9705ab7 100755
> --- a/tools/perf/scripts/python/exported-sql-viewer.py
> +++ b/tools/perf/scripts/python/exported-sql-viewer.py
> @@ -898,6 +898,8 @@ class TreeWindowBase(QMdiSubWindow):
> self.find_bar = None
>
> self.view = QTreeView()
> + self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
> + self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard
>
> def DisplayFound(self, ids):
> if not len(ids):
> @@ -1666,6 +1668,8 @@ class BranchWindow(QMdiSubWindow):
>
> self.view = QTreeView()
> self.view.setUniformRowHeights(True)
> + self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
> + self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard
> self.view.setModel(self.model)
>
> self.ResizeColumnsToContents()
> @@ -2278,6 +2282,207 @@ class ResizeColumnsToContentsBase(QObject):
> self.data_model.rowsInserted.disconnect(self.UpdateColumnWidths)
> self.ResizeColumnsToContents()
>
> +# Convert value to CSV
> +
> +def ToCSValue(val):
> + if '"' in val:
> + val = val.replace('"', '""')
> + if "," in val or '"' in val:
> + val = '"' + val + '"'
> + return val
> +
> +# Key to sort table model indexes by row / column, assuming fewer than 1000 columns
> +
> +glb_max_cols = 1000
> +
> +def RowColumnKey(a):
> + return a.row() * glb_max_cols + a.column()
> +
> +# Copy selected table cells to clipboard
> +
> +def CopyTableCellsToClipboard(view, as_csv=False, with_hdr=False):
> + indexes = sorted(view.selectedIndexes(), key=RowColumnKey)
> + idx_cnt = len(indexes)
> + if not idx_cnt:
> + return
> + if idx_cnt == 1:
> + with_hdr=False
> + min_row = indexes[0].row()
> + max_row = indexes[0].row()
> + min_col = indexes[0].column()
> + max_col = indexes[0].column()
> + for i in indexes:
> + min_row = min(min_row, i.row())
> + max_row = max(max_row, i.row())
> + min_col = min(min_col, i.column())
> + max_col = max(max_col, i.column())
> + if max_col > glb_max_cols:
> + raise RuntimeError("glb_max_cols is too low")
> + max_width = [0] * (1 + max_col - min_col)
> + for i in indexes:
> + c = i.column() - min_col
> + max_width[c] = max(max_width[c], len(str(i.data())))
> + text = ""
> + pad = ""
> + sep = ""
> + if with_hdr:
> + model = indexes[0].model()
> + for col in range(min_col, max_col + 1):
> + val = model.headerData(col, Qt.Horizontal)
> + if as_csv:
> + text += sep + ToCSValue(val)
> + sep = ","
> + else:
> + c = col - min_col
> + max_width[c] = max(max_width[c], len(val))
> + width = max_width[c]
> + align = model.headerData(col, Qt.Horizontal, Qt.TextAlignmentRole)
> + if align & Qt.AlignRight:
> + val = val.rjust(width)
> + text += pad + sep + val
> + pad = " " * (width - len(val))
> + sep = " "
> + text += "\n"
> + pad = ""
> + sep = ""
> + last_row = min_row
> + for i in indexes:
> + if i.row() > last_row:
> + last_row = i.row()
> + text += "\n"
> + pad = ""
> + sep = ""
> + if as_csv:
> + text += sep + ToCSValue(str(i.data()))
> + sep = ","
> + else:
> + width = max_width[i.column() - min_col]
> + if i.data(Qt.TextAlignmentRole) & Qt.AlignRight:
> + val = str(i.data()).rjust(width)
> + else:
> + val = str(i.data())
> + text += pad + sep + val
> + pad = " " * (width - len(val))
> + sep = " "
> + QApplication.clipboard().setText(text)
> +
> +def CopyTreeCellsToClipboard(view, as_csv=False, with_hdr=False):
> + indexes = view.selectedIndexes()
> + if not len(indexes):
> + return
> +
> + selection = view.selectionModel()
> +
> + first = None
> + for i in indexes:
> + above = view.indexAbove(i)
> + if not selection.isSelected(above):
> + first = i
> + break
> +
> + if first is None:
> + raise RuntimeError("CopyTreeCellsToClipboard internal error")
> +
> + model = first.model()
> + row_cnt = 0
> + col_cnt = model.columnCount(first)
> + max_width = [0] * col_cnt
> +
> + indent_sz = 2
> + indent_str = " " * indent_sz
> +
> + expanded_mark_sz = 2
> + if sys.version_info[0] == 3:
> + expanded_mark = "\u25BC "
> + not_expanded_mark = "\u25B6 "
> + else:
> + expanded_mark = unicode(chr(0xE2) + chr(0x96) + chr(0xBC) + " ", "utf-8")
> + not_expanded_mark = unicode(chr(0xE2) + chr(0x96) + chr(0xB6) + " ", "utf-8")
> + leaf_mark = " "
> +
> + if not as_csv:
> + pos = first
> + while True:
> + row_cnt += 1
> + row = pos.row()
> + for c in range(col_cnt):
> + i = pos.sibling(row, c)
> + if c:
> + n = len(str(i.data()))
> + else:
> + n = len(str(i.data()).strip())
> + n += (i.internalPointer().level - 1) * indent_sz
> + n += expanded_mark_sz
> + max_width[c] = max(max_width[c], n)
> + pos = view.indexBelow(pos)
> + if not selection.isSelected(pos):
> + break
> +
> + text = ""
> + pad = ""
> + sep = ""
> + if with_hdr:
> + for c in range(col_cnt):
> + val = model.headerData(c, Qt.Horizontal, Qt.DisplayRole).strip()
> + if as_csv:
> + text += sep + ToCSValue(val)
> + sep = ","
> + else:
> + max_width[c] = max(max_width[c], len(val))
> + width = max_width[c]
> + align = model.headerData(c, Qt.Horizontal, Qt.TextAlignmentRole)
> + if align & Qt.AlignRight:
> + val = val.rjust(width)
> + text += pad + sep + val
> + pad = " " * (width - len(val))
> + sep = " "
> + text += "\n"
> + pad = ""
> + sep = ""
> +
> + pos = first
> + while True:
> + row = pos.row()
> + for c in range(col_cnt):
> + i = pos.sibling(row, c)
> + val = str(i.data())
> + if not c:
> + if model.hasChildren(i):
> + if view.isExpanded(i):
> + mark = expanded_mark
> + else:
> + mark = not_expanded_mark
> + else:
> + mark = leaf_mark
> + val = indent_str * (i.internalPointer().level - 1) + mark + val.strip()
> + if as_csv:
> + text += sep + ToCSValue(val)
> + sep = ","
> + else:
> + width = max_width[c]
> + if c and i.data(Qt.TextAlignmentRole) & Qt.AlignRight:
> + val = val.rjust(width)
> + text += pad + sep + val
> + pad = " " * (width - len(val))
> + sep = " "
> + pos = view.indexBelow(pos)
> + if not selection.isSelected(pos):
> + break
> + text = text.rstrip() + "\n"
> + pad = ""
> + sep = ""
> +
> + QApplication.clipboard().setText(text)
> +
> +def CopyCellsToClipboard(view, as_csv=False, with_hdr=False):
> + view.CopyCellsToClipboard(view, as_csv, with_hdr)
> +
> +def CopyCellsToClipboardHdr(view):
> + CopyCellsToClipboard(view, False, True)
> +
> +def CopyCellsToClipboardCSV(view):
> + CopyCellsToClipboard(view, True, True)
> +
> # Table window
>
> class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
> @@ -2296,6 +2501,8 @@ class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
> self.view.verticalHeader().setVisible(False)
> self.view.sortByColumn(-1, Qt.AscendingOrder)
> self.view.setSortingEnabled(True)
> + self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
> + self.view.CopyCellsToClipboard = CopyTableCellsToClipboard
>
> self.ResizeColumnsToContents()
>
> @@ -2412,6 +2619,8 @@ class TopCallsWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
> self.view.setModel(self.model)
> self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
> self.view.verticalHeader().setVisible(False)
> + self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
> + self.view.CopyCellsToClipboard = CopyTableCellsToClipboard
>
> self.ResizeColumnsToContents()
>
> @@ -2749,6 +2958,8 @@ class MainWindow(QMainWindow):
> file_menu.addAction(CreateExitAction(glb.app, self))
>
> edit_menu = menu.addMenu("&Edit")
> + edit_menu.addAction(CreateAction("&Copy", "Copy to clipboard", self.CopyToClipboard, self, QKeySequence.Copy))
> + edit_menu.addAction(CreateAction("Copy as CS&V", "Copy to clipboard as CSV", self.CopyToClipboardCSV, self))
> edit_menu.addAction(CreateAction("&Find...", "Find items", self.Find, self, QKeySequence.Find))
> edit_menu.addAction(CreateAction("Fetch &more records...", "Fetch more records", self.FetchMoreRecords, self, [QKeySequence(Qt.Key_F8)]))
> edit_menu.addAction(CreateAction("&Shrink Font", "Make text smaller", self.ShrinkFont, self, [QKeySequence("Ctrl+-")]))
> @@ -2781,6 +2992,12 @@ class MainWindow(QMainWindow):
> except:
> pass
>
> + def CopyToClipboard(self):
> + self.Try(CopyCellsToClipboardHdr)
> +
> + def CopyToClipboardCSV(self):
> + self.Try(CopyCellsToClipboardCSV)
> +
> def Find(self):
> win = self.mdi_area.activeSubWindow()
> if win:
> --
> 2.17.1
--
- Arnaldo
^ permalink raw reply [flat|nested] 17+ messages in thread
* [tip:perf/core] perf scripts python: exported-sql-viewer.py: Add copy to clipboard
2019-05-03 12:08 ` [PATCH 4/6] perf scripts python: exported-sql-viewer.py: Add copy to clipboard Adrian Hunter
2019-05-13 20:03 ` Arnaldo Carvalho de Melo
@ 2019-05-18 8:56 ` tip-bot for Adrian Hunter
1 sibling, 0 replies; 17+ messages in thread
From: tip-bot for Adrian Hunter @ 2019-05-18 8:56 UTC (permalink / raw)
To: linux-tip-commits
Cc: jolsa, acme, adrian.hunter, mingo, tglx, hpa, linux-kernel
Commit-ID: 96c43b9a7ab3b70bc35d762f7b76082dfd118a6a
Gitweb: https://git.kernel.org/tip/96c43b9a7ab3b70bc35d762f7b76082dfd118a6a
Author: Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Fri, 3 May 2019 15:08:26 +0300
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 15 May 2019 16:36:47 -0300
perf scripts python: exported-sql-viewer.py: Add copy to clipboard
Add support for copying to clipboard. Two menu options are added to copy the
selected rows / columns with normal spacing, or as comma-separated-values.
In the case of trees, only entire rows can be copied.
Comitter testing:
$ python ~acme/libexec/perf-core/scripts/python/exported-sql-viewer.py ~/c/adrian.hunter/simple-retpoline.db
Select the lines, press control+C and on the same terminal,
press control+shift+V and voilà:
Call Path Object Count Time (ns) Time (%) Branch Count Branch Count (%)
▼ 14503:14503
▼ _start ld-2.28.so 1 156267 100.0 10602 100.0
unknown unknown 1 2276 1.5 1 0.0
▼ _dl_start ld-2.28.so 1 137047 87.7 10088 95.2
▶ unknown unknown 4 4127 3.0 4 0.0
_dl_setup_hash ld-2.28.so 1 0 0.0 1 0.0
▶ _dl_sysdep_start ld-2.28.so 1 131342 95.8 9981 98.9
▼ _dl_init ld-2.28.so 1 9142 5.9 326 3.1
▼ call_init.part.0 ld-2.28.so 3 9133 99.9 319 97.9
▶ _init libc-2.28.so 1 6877 75.3 110 34.5
▶ check_stdfiles_vtables libc-2.28.so 1 76 0.8 2 0.6
▶ init_cacheinfo libc-2.28.so 1 1991 21.8 197 61.8
▶ _start simple-retpoline 1 7457 4.8 182 1.7
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/20190503120828.25326-5-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/scripts/python/exported-sql-viewer.py | 217 +++++++++++++++++++++++
1 file changed, 217 insertions(+)
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index 48953257a1f0..baa2b220238a 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -884,6 +884,8 @@ class TreeWindowBase(QMdiSubWindow):
self.find_bar = None
self.view = QTreeView()
+ self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
+ self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard
def DisplayFound(self, ids):
if not len(ids):
@@ -1652,6 +1654,8 @@ class BranchWindow(QMdiSubWindow):
self.view = QTreeView()
self.view.setUniformRowHeights(True)
+ self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
+ self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard
self.view.setModel(self.model)
self.ResizeColumnsToContents()
@@ -2264,6 +2268,207 @@ class ResizeColumnsToContentsBase(QObject):
self.data_model.rowsInserted.disconnect(self.UpdateColumnWidths)
self.ResizeColumnsToContents()
+# Convert value to CSV
+
+def ToCSValue(val):
+ if '"' in val:
+ val = val.replace('"', '""')
+ if "," in val or '"' in val:
+ val = '"' + val + '"'
+ return val
+
+# Key to sort table model indexes by row / column, assuming fewer than 1000 columns
+
+glb_max_cols = 1000
+
+def RowColumnKey(a):
+ return a.row() * glb_max_cols + a.column()
+
+# Copy selected table cells to clipboard
+
+def CopyTableCellsToClipboard(view, as_csv=False, with_hdr=False):
+ indexes = sorted(view.selectedIndexes(), key=RowColumnKey)
+ idx_cnt = len(indexes)
+ if not idx_cnt:
+ return
+ if idx_cnt == 1:
+ with_hdr=False
+ min_row = indexes[0].row()
+ max_row = indexes[0].row()
+ min_col = indexes[0].column()
+ max_col = indexes[0].column()
+ for i in indexes:
+ min_row = min(min_row, i.row())
+ max_row = max(max_row, i.row())
+ min_col = min(min_col, i.column())
+ max_col = max(max_col, i.column())
+ if max_col > glb_max_cols:
+ raise RuntimeError("glb_max_cols is too low")
+ max_width = [0] * (1 + max_col - min_col)
+ for i in indexes:
+ c = i.column() - min_col
+ max_width[c] = max(max_width[c], len(str(i.data())))
+ text = ""
+ pad = ""
+ sep = ""
+ if with_hdr:
+ model = indexes[0].model()
+ for col in range(min_col, max_col + 1):
+ val = model.headerData(col, Qt.Horizontal)
+ if as_csv:
+ text += sep + ToCSValue(val)
+ sep = ","
+ else:
+ c = col - min_col
+ max_width[c] = max(max_width[c], len(val))
+ width = max_width[c]
+ align = model.headerData(col, Qt.Horizontal, Qt.TextAlignmentRole)
+ if align & Qt.AlignRight:
+ val = val.rjust(width)
+ text += pad + sep + val
+ pad = " " * (width - len(val))
+ sep = " "
+ text += "\n"
+ pad = ""
+ sep = ""
+ last_row = min_row
+ for i in indexes:
+ if i.row() > last_row:
+ last_row = i.row()
+ text += "\n"
+ pad = ""
+ sep = ""
+ if as_csv:
+ text += sep + ToCSValue(str(i.data()))
+ sep = ","
+ else:
+ width = max_width[i.column() - min_col]
+ if i.data(Qt.TextAlignmentRole) & Qt.AlignRight:
+ val = str(i.data()).rjust(width)
+ else:
+ val = str(i.data())
+ text += pad + sep + val
+ pad = " " * (width - len(val))
+ sep = " "
+ QApplication.clipboard().setText(text)
+
+def CopyTreeCellsToClipboard(view, as_csv=False, with_hdr=False):
+ indexes = view.selectedIndexes()
+ if not len(indexes):
+ return
+
+ selection = view.selectionModel()
+
+ first = None
+ for i in indexes:
+ above = view.indexAbove(i)
+ if not selection.isSelected(above):
+ first = i
+ break
+
+ if first is None:
+ raise RuntimeError("CopyTreeCellsToClipboard internal error")
+
+ model = first.model()
+ row_cnt = 0
+ col_cnt = model.columnCount(first)
+ max_width = [0] * col_cnt
+
+ indent_sz = 2
+ indent_str = " " * indent_sz
+
+ expanded_mark_sz = 2
+ if sys.version_info[0] == 3:
+ expanded_mark = "\u25BC "
+ not_expanded_mark = "\u25B6 "
+ else:
+ expanded_mark = unicode(chr(0xE2) + chr(0x96) + chr(0xBC) + " ", "utf-8")
+ not_expanded_mark = unicode(chr(0xE2) + chr(0x96) + chr(0xB6) + " ", "utf-8")
+ leaf_mark = " "
+
+ if not as_csv:
+ pos = first
+ while True:
+ row_cnt += 1
+ row = pos.row()
+ for c in range(col_cnt):
+ i = pos.sibling(row, c)
+ if c:
+ n = len(str(i.data()))
+ else:
+ n = len(str(i.data()).strip())
+ n += (i.internalPointer().level - 1) * indent_sz
+ n += expanded_mark_sz
+ max_width[c] = max(max_width[c], n)
+ pos = view.indexBelow(pos)
+ if not selection.isSelected(pos):
+ break
+
+ text = ""
+ pad = ""
+ sep = ""
+ if with_hdr:
+ for c in range(col_cnt):
+ val = model.headerData(c, Qt.Horizontal, Qt.DisplayRole).strip()
+ if as_csv:
+ text += sep + ToCSValue(val)
+ sep = ","
+ else:
+ max_width[c] = max(max_width[c], len(val))
+ width = max_width[c]
+ align = model.headerData(c, Qt.Horizontal, Qt.TextAlignmentRole)
+ if align & Qt.AlignRight:
+ val = val.rjust(width)
+ text += pad + sep + val
+ pad = " " * (width - len(val))
+ sep = " "
+ text += "\n"
+ pad = ""
+ sep = ""
+
+ pos = first
+ while True:
+ row = pos.row()
+ for c in range(col_cnt):
+ i = pos.sibling(row, c)
+ val = str(i.data())
+ if not c:
+ if model.hasChildren(i):
+ if view.isExpanded(i):
+ mark = expanded_mark
+ else:
+ mark = not_expanded_mark
+ else:
+ mark = leaf_mark
+ val = indent_str * (i.internalPointer().level - 1) + mark + val.strip()
+ if as_csv:
+ text += sep + ToCSValue(val)
+ sep = ","
+ else:
+ width = max_width[c]
+ if c and i.data(Qt.TextAlignmentRole) & Qt.AlignRight:
+ val = val.rjust(width)
+ text += pad + sep + val
+ pad = " " * (width - len(val))
+ sep = " "
+ pos = view.indexBelow(pos)
+ if not selection.isSelected(pos):
+ break
+ text = text.rstrip() + "\n"
+ pad = ""
+ sep = ""
+
+ QApplication.clipboard().setText(text)
+
+def CopyCellsToClipboard(view, as_csv=False, with_hdr=False):
+ view.CopyCellsToClipboard(view, as_csv, with_hdr)
+
+def CopyCellsToClipboardHdr(view):
+ CopyCellsToClipboard(view, False, True)
+
+def CopyCellsToClipboardCSV(view):
+ CopyCellsToClipboard(view, True, True)
+
# Table window
class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
@@ -2282,6 +2487,8 @@ class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
self.view.verticalHeader().setVisible(False)
self.view.sortByColumn(-1, Qt.AscendingOrder)
self.view.setSortingEnabled(True)
+ self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
+ self.view.CopyCellsToClipboard = CopyTableCellsToClipboard
self.ResizeColumnsToContents()
@@ -2398,6 +2605,8 @@ class TopCallsWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
self.view.setModel(self.model)
self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.view.verticalHeader().setVisible(False)
+ self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
+ self.view.CopyCellsToClipboard = CopyTableCellsToClipboard
self.ResizeColumnsToContents()
@@ -2735,6 +2944,8 @@ class MainWindow(QMainWindow):
file_menu.addAction(CreateExitAction(glb.app, self))
edit_menu = menu.addMenu("&Edit")
+ edit_menu.addAction(CreateAction("&Copy", "Copy to clipboard", self.CopyToClipboard, self, QKeySequence.Copy))
+ edit_menu.addAction(CreateAction("Copy as CS&V", "Copy to clipboard as CSV", self.CopyToClipboardCSV, self))
edit_menu.addAction(CreateAction("&Find...", "Find items", self.Find, self, QKeySequence.Find))
edit_menu.addAction(CreateAction("Fetch &more records...", "Fetch more records", self.FetchMoreRecords, self, [QKeySequence(Qt.Key_F8)]))
edit_menu.addAction(CreateAction("&Shrink Font", "Make text smaller", self.ShrinkFont, self, [QKeySequence("Ctrl+-")]))
@@ -2767,6 +2978,12 @@ class MainWindow(QMainWindow):
except:
pass
+ def CopyToClipboard(self):
+ self.Try(CopyCellsToClipboardHdr)
+
+ def CopyToClipboardCSV(self):
+ self.Try(CopyCellsToClipboardCSV)
+
def Find(self):
win = self.mdi_area.activeSubWindow()
if win:
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 5/6] perf scripts python: exported-sql-viewer.py: Add context menu
2019-05-03 12:08 [PATCH 0/6] perf scripts python: exported-sql-viewer.py: Minor improvements Adrian Hunter
` (3 preceding siblings ...)
2019-05-03 12:08 ` [PATCH 4/6] perf scripts python: exported-sql-viewer.py: Add copy to clipboard Adrian Hunter
@ 2019-05-03 12:08 ` Adrian Hunter
2019-05-13 20:09 ` Arnaldo Carvalho de Melo
2019-05-18 8:57 ` [tip:perf/core] " tip-bot for Adrian Hunter
2019-05-03 12:08 ` [PATCH 6/6] perf scripts python: exported-sql-viewer.py: Add 'About' dialog box Adrian Hunter
5 siblings, 2 replies; 17+ messages in thread
From: Adrian Hunter @ 2019-05-03 12:08 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: Jiri Olsa, linux-kernel
Add a context menu (right-click) that provides options for copying to
clipboard, including, for trees, the ability to copy only the cell under
the mouse pointer.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
.../scripts/python/exported-sql-viewer.py | 41 +++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index 5804d9705ab7..421f3828ea43 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -901,6 +901,8 @@ class TreeWindowBase(QMdiSubWindow):
self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard
+ self.context_menu = TreeContextMenu(self.view)
+
def DisplayFound(self, ids):
if not len(ids):
return False
@@ -1674,6 +1676,8 @@ class BranchWindow(QMdiSubWindow):
self.ResizeColumnsToContents()
+ self.context_menu = TreeContextMenu(self.view)
+
self.find_bar = FindBar(self, self, True)
self.finder = ChildDataItemFinder(self.model.root)
@@ -2483,6 +2487,39 @@ def CopyCellsToClipboardHdr(view):
def CopyCellsToClipboardCSV(view):
CopyCellsToClipboard(view, True, True)
+# Context menu
+
+class ContextMenu(object):
+
+ def __init__(self, view):
+ self.view = view
+ self.view.setContextMenuPolicy(Qt.CustomContextMenu)
+ self.view.customContextMenuRequested.connect(self.ShowContextMenu)
+
+ def ShowContextMenu(self, pos):
+ menu = QMenu(self.view)
+ self.AddActions(menu)
+ menu.exec_(self.view.mapToGlobal(pos))
+
+ def AddCopy(self, menu):
+ menu.addAction(CreateAction("&Copy selection", "Copy to clipboard", lambda: CopyCellsToClipboardHdr(self.view), self.view))
+ menu.addAction(CreateAction("Copy selection as CS&V", "Copy to clipboard as CSV", lambda: CopyCellsToClipboardCSV(self.view), self.view))
+
+ def AddActions(self, menu):
+ self.AddCopy(menu)
+
+class TreeContextMenu(ContextMenu):
+
+ def __init__(self, view):
+ super(TreeContextMenu, self).__init__(view)
+
+ def AddActions(self, menu):
+ i = self.view.currentIndex()
+ text = str(i.data()).strip()
+ if len(text):
+ menu.addAction(CreateAction('Copy "' + text + '"', "Copy to clipboard", lambda: QApplication.clipboard().setText(text), self.view))
+ self.AddCopy(menu)
+
# Table window
class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
@@ -2506,6 +2543,8 @@ class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
self.ResizeColumnsToContents()
+ self.context_menu = ContextMenu(self.view)
+
self.find_bar = FindBar(self, self, True)
self.finder = ChildDataItemFinder(self.data_model)
@@ -2622,6 +2661,8 @@ class TopCallsWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
self.view.CopyCellsToClipboard = CopyTableCellsToClipboard
+ self.context_menu = ContextMenu(self.view)
+
self.ResizeColumnsToContents()
self.find_bar = FindBar(self, self, True)
--
2.17.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 5/6] perf scripts python: exported-sql-viewer.py: Add context menu
2019-05-03 12:08 ` [PATCH 5/6] perf scripts python: exported-sql-viewer.py: Add context menu Adrian Hunter
@ 2019-05-13 20:09 ` Arnaldo Carvalho de Melo
2019-05-18 8:57 ` [tip:perf/core] " tip-bot for Adrian Hunter
1 sibling, 0 replies; 17+ messages in thread
From: Arnaldo Carvalho de Melo @ 2019-05-13 20:09 UTC (permalink / raw)
To: Adrian Hunter; +Cc: Jiri Olsa, linux-kernel
Em Fri, May 03, 2019 at 03:08:27PM +0300, Adrian Hunter escreveu:
> Add a context menu (right-click) that provides options for copying to
> clipboard, including, for trees, the ability to copy only the cell under
> the mouse pointer.
Works as well:
Committer testing:
$ python ~acme/libexec/perf-core/scripts/python/exported-sql-viewer.py ~/c/adrian.hunter/simple-retpoline.db
Simply right click and pick "Copy selection", that at this point has
just the first line, not expanded, then see what was copied by pressing
shift+control+v on a terminal:
Call Path,Object,Count,Time (ns),Time (%),Branch Count,Branch Count (%)
▶ simple-retpolin,,,,,,
Ditto after expanding, i.e. the selection continues to be just one
line:
Call Path Object Count Time (ns) Time (%) Branch Count Branch Count (%)
▼ simple-retpolin
Now select all the lines with the mouse and control+shift+v again:
Call Path Object Count Time (ns) Time (%) Branch Count Branch Count (%)
▼ 14503:14503
▼ _start ld-2.28.so 1 156267 100.0 10602 100.0
▶ unknown unknown 1 2276 1.5 1 0.0
▶ _dl_start ld-2.28.so 1 137047 87.7 10088 95.2
▶ _dl_init ld-2.28.so 1 9142 5.9 326 3.1
▼ _start simple-retpoline 1 7457 4.8 182 1.7
▶ unknown unknown 1 805 10.8 1 0.5
▶ __libc_start_main libc-2.28.so 1 6347 85.1 179 98.4
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
> .../scripts/python/exported-sql-viewer.py | 41 +++++++++++++++++++
> 1 file changed, 41 insertions(+)
>
> diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
> index 5804d9705ab7..421f3828ea43 100755
> --- a/tools/perf/scripts/python/exported-sql-viewer.py
> +++ b/tools/perf/scripts/python/exported-sql-viewer.py
> @@ -901,6 +901,8 @@ class TreeWindowBase(QMdiSubWindow):
> self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
> self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard
>
> + self.context_menu = TreeContextMenu(self.view)
> +
> def DisplayFound(self, ids):
> if not len(ids):
> return False
> @@ -1674,6 +1676,8 @@ class BranchWindow(QMdiSubWindow):
>
> self.ResizeColumnsToContents()
>
> + self.context_menu = TreeContextMenu(self.view)
> +
> self.find_bar = FindBar(self, self, True)
>
> self.finder = ChildDataItemFinder(self.model.root)
> @@ -2483,6 +2487,39 @@ def CopyCellsToClipboardHdr(view):
> def CopyCellsToClipboardCSV(view):
> CopyCellsToClipboard(view, True, True)
>
> +# Context menu
> +
> +class ContextMenu(object):
> +
> + def __init__(self, view):
> + self.view = view
> + self.view.setContextMenuPolicy(Qt.CustomContextMenu)
> + self.view.customContextMenuRequested.connect(self.ShowContextMenu)
> +
> + def ShowContextMenu(self, pos):
> + menu = QMenu(self.view)
> + self.AddActions(menu)
> + menu.exec_(self.view.mapToGlobal(pos))
> +
> + def AddCopy(self, menu):
> + menu.addAction(CreateAction("&Copy selection", "Copy to clipboard", lambda: CopyCellsToClipboardHdr(self.view), self.view))
> + menu.addAction(CreateAction("Copy selection as CS&V", "Copy to clipboard as CSV", lambda: CopyCellsToClipboardCSV(self.view), self.view))
> +
> + def AddActions(self, menu):
> + self.AddCopy(menu)
> +
> +class TreeContextMenu(ContextMenu):
> +
> + def __init__(self, view):
> + super(TreeContextMenu, self).__init__(view)
> +
> + def AddActions(self, menu):
> + i = self.view.currentIndex()
> + text = str(i.data()).strip()
> + if len(text):
> + menu.addAction(CreateAction('Copy "' + text + '"', "Copy to clipboard", lambda: QApplication.clipboard().setText(text), self.view))
> + self.AddCopy(menu)
> +
> # Table window
>
> class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
> @@ -2506,6 +2543,8 @@ class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
>
> self.ResizeColumnsToContents()
>
> + self.context_menu = ContextMenu(self.view)
> +
> self.find_bar = FindBar(self, self, True)
>
> self.finder = ChildDataItemFinder(self.data_model)
> @@ -2622,6 +2661,8 @@ class TopCallsWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
> self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
> self.view.CopyCellsToClipboard = CopyTableCellsToClipboard
>
> + self.context_menu = ContextMenu(self.view)
> +
> self.ResizeColumnsToContents()
>
> self.find_bar = FindBar(self, self, True)
> --
> 2.17.1
--
- Arnaldo
^ permalink raw reply [flat|nested] 17+ messages in thread
* [tip:perf/core] perf scripts python: exported-sql-viewer.py: Add context menu
2019-05-03 12:08 ` [PATCH 5/6] perf scripts python: exported-sql-viewer.py: Add context menu Adrian Hunter
2019-05-13 20:09 ` Arnaldo Carvalho de Melo
@ 2019-05-18 8:57 ` tip-bot for Adrian Hunter
1 sibling, 0 replies; 17+ messages in thread
From: tip-bot for Adrian Hunter @ 2019-05-18 8:57 UTC (permalink / raw)
To: linux-tip-commits
Cc: hpa, jolsa, linux-kernel, adrian.hunter, acme, tglx, mingo
Commit-ID: 9bc4e4bfe6169343a8f019cd5d7843a558b78363
Gitweb: https://git.kernel.org/tip/9bc4e4bfe6169343a8f019cd5d7843a558b78363
Author: Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Fri, 3 May 2019 15:08:27 +0300
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 15 May 2019 16:36:47 -0300
perf scripts python: exported-sql-viewer.py: Add context menu
Add a context menu (right-click) that provides options for copying to
clipboard, including, for trees, the ability to copy only the cell under
the mouse pointer.
Committer testing:
$ python ~acme/libexec/perf-core/scripts/python/exported-sql-viewer.py ~/c/adrian.hunter/simple-retpoline.db
Simply right click and pick "Copy selection", that at this point has
just the first line, not expanded, then see what was copied by pressing
shift+control+v on a terminal:
Call Path,Object,Count,Time (ns),Time (%),Branch Count,Branch Count (%)
▶ simple-retpolin,,,,,,
Ditto after expanding, i.e. the selection continues to be just one
line:
Call Path Object Count Time (ns) Time (%) Branch Count Branch Count (%)
▼ simple-retpolin
Now select all the lines with the mouse and control+shift+v again:
Call Path Object Count Time (ns) Time (%) Branch Count Branch Count (%)
▼ 14503:14503
▼ _start ld-2.28.so 1 156267 100.0 10602 100.0
▶ unknown unknown 1 2276 1.5 1 0.0
▶ _dl_start ld-2.28.so 1 137047 87.7 10088 95.2
▶ _dl_init ld-2.28.so 1 9142 5.9 326 3.1
▼ _start simple-retpoline 1 7457 4.8 182 1.7
▶ unknown unknown 1 805 10.8 1 0.5
▶ __libc_start_main libc-2.28.so 1 6347 85.1 179 98.4
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/20190503120828.25326-6-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/scripts/python/exported-sql-viewer.py | 41 ++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index baa2b220238a..affd80ebcae0 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -887,6 +887,8 @@ class TreeWindowBase(QMdiSubWindow):
self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard
+ self.context_menu = TreeContextMenu(self.view)
+
def DisplayFound(self, ids):
if not len(ids):
return False
@@ -1660,6 +1662,8 @@ class BranchWindow(QMdiSubWindow):
self.ResizeColumnsToContents()
+ self.context_menu = TreeContextMenu(self.view)
+
self.find_bar = FindBar(self, self, True)
self.finder = ChildDataItemFinder(self.model.root)
@@ -2469,6 +2473,39 @@ def CopyCellsToClipboardHdr(view):
def CopyCellsToClipboardCSV(view):
CopyCellsToClipboard(view, True, True)
+# Context menu
+
+class ContextMenu(object):
+
+ def __init__(self, view):
+ self.view = view
+ self.view.setContextMenuPolicy(Qt.CustomContextMenu)
+ self.view.customContextMenuRequested.connect(self.ShowContextMenu)
+
+ def ShowContextMenu(self, pos):
+ menu = QMenu(self.view)
+ self.AddActions(menu)
+ menu.exec_(self.view.mapToGlobal(pos))
+
+ def AddCopy(self, menu):
+ menu.addAction(CreateAction("&Copy selection", "Copy to clipboard", lambda: CopyCellsToClipboardHdr(self.view), self.view))
+ menu.addAction(CreateAction("Copy selection as CS&V", "Copy to clipboard as CSV", lambda: CopyCellsToClipboardCSV(self.view), self.view))
+
+ def AddActions(self, menu):
+ self.AddCopy(menu)
+
+class TreeContextMenu(ContextMenu):
+
+ def __init__(self, view):
+ super(TreeContextMenu, self).__init__(view)
+
+ def AddActions(self, menu):
+ i = self.view.currentIndex()
+ text = str(i.data()).strip()
+ if len(text):
+ menu.addAction(CreateAction('Copy "' + text + '"', "Copy to clipboard", lambda: QApplication.clipboard().setText(text), self.view))
+ self.AddCopy(menu)
+
# Table window
class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
@@ -2492,6 +2529,8 @@ class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
self.ResizeColumnsToContents()
+ self.context_menu = ContextMenu(self.view)
+
self.find_bar = FindBar(self, self, True)
self.finder = ChildDataItemFinder(self.data_model)
@@ -2608,6 +2647,8 @@ class TopCallsWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
self.view.CopyCellsToClipboard = CopyTableCellsToClipboard
+ self.context_menu = ContextMenu(self.view)
+
self.ResizeColumnsToContents()
self.find_bar = FindBar(self, self, True)
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 6/6] perf scripts python: exported-sql-viewer.py: Add 'About' dialog box
2019-05-03 12:08 [PATCH 0/6] perf scripts python: exported-sql-viewer.py: Minor improvements Adrian Hunter
` (4 preceding siblings ...)
2019-05-03 12:08 ` [PATCH 5/6] perf scripts python: exported-sql-viewer.py: Add context menu Adrian Hunter
@ 2019-05-03 12:08 ` Adrian Hunter
2019-05-13 20:12 ` Arnaldo Carvalho de Melo
2019-05-18 8:58 ` [tip:perf/core] " tip-bot for Adrian Hunter
5 siblings, 2 replies; 17+ messages in thread
From: Adrian Hunter @ 2019-05-03 12:08 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: Jiri Olsa, linux-kernel
With support for Python 2 or 3 and PySide 1 or 2 (Qt 4 or 5), it is useful
to see what versions are in use. Add an 'About' dialog box that displays
Python, PySide, Qt and database server (SQLite or PostgreSQL) version
numbers.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
.../scripts/python/exported-sql-viewer.py | 59 +++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index 421f3828ea43..6fe553258ce5 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -2927,6 +2927,60 @@ class HelpOnlyWindow(QMainWindow):
self.setCentralWidget(self.text)
+# PostqreSQL server version
+
+def PostqreSQLServerVersion(db):
+ query = QSqlQuery(db)
+ QueryExec(query, "SELECT VERSION()")
+ if query.next():
+ v_str = query.value(0)
+ v_list = v_str.strip().split(" ")
+ if v_list[0] == "PostgreSQL" and v_list[2] == "on":
+ return v_list[1]
+ return v_str
+ return "Unknown"
+
+# SQLite version
+
+def SQLiteVersion(db):
+ query = QSqlQuery(db)
+ QueryExec(query, "SELECT sqlite_version()")
+ if query.next():
+ return query.value(0)
+ return "Unknown"
+
+# About dialog
+
+class AboutDialog(QDialog):
+
+ def __init__(self, glb, parent=None):
+ super(AboutDialog, self).__init__(parent)
+
+ self.setWindowTitle("About Exported SQL Viewer")
+ self.setMinimumWidth(300)
+
+ pyside_version = "1" if pyside_version_1 else "2"
+
+ text = "<pre>"
+ text += "Python version: " + sys.version.split(" ")[0] + "\n"
+ text += "PySide version: " + pyside_version + "\n"
+ text += "Qt version: " + qVersion() + "\n"
+ if glb.dbref.is_sqlite3:
+ text += "SQLite version: " + SQLiteVersion(glb.db) + "\n"
+ else:
+ text += "PostqreSQL version: " + PostqreSQLServerVersion(glb.db) + "\n"
+ text += "</pre>"
+
+ self.text = QTextBrowser()
+ self.text.setHtml(text)
+ self.text.setReadOnly(True)
+ self.text.setOpenExternalLinks(True)
+
+ self.vbox = QVBoxLayout()
+ self.vbox.addWidget(self.text)
+
+ self.setLayout(self.vbox);
+
# Font resize
def ResizeFont(widget, diff):
@@ -3024,6 +3078,7 @@ class MainWindow(QMainWindow):
help_menu = menu.addMenu("&Help")
help_menu.addAction(CreateAction("&Exported SQL Viewer Help", "Helpful information", self.Help, self, QKeySequence.HelpContents))
+ help_menu.addAction(CreateAction("&About Exported SQL Viewer", "About this application", self.About, self))
def Try(self, fn):
win = self.mdi_area.activeSubWindow()
@@ -3109,6 +3164,10 @@ class MainWindow(QMainWindow):
def Help(self):
HelpWindow(self.glb, self)
+ def About(self):
+ dialog = AboutDialog(self.glb, self)
+ dialog.exec_()
+
# XED Disassembler
class xed_state_t(Structure):
--
2.17.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 6/6] perf scripts python: exported-sql-viewer.py: Add 'About' dialog box
2019-05-03 12:08 ` [PATCH 6/6] perf scripts python: exported-sql-viewer.py: Add 'About' dialog box Adrian Hunter
@ 2019-05-13 20:12 ` Arnaldo Carvalho de Melo
2019-05-18 8:58 ` [tip:perf/core] " tip-bot for Adrian Hunter
1 sibling, 0 replies; 17+ messages in thread
From: Arnaldo Carvalho de Melo @ 2019-05-13 20:12 UTC (permalink / raw)
To: Adrian Hunter; +Cc: Jiri Olsa, linux-kernel
Em Fri, May 03, 2019 at 03:08:28PM +0300, Adrian Hunter escreveu:
> With support for Python 2 or 3 and PySide 1 or 2 (Qt 4 or 5), it is useful
> to see what versions are in use. Add an 'About' dialog box that displays
> Python, PySide, Qt and database server (SQLite or PostgreSQL) version
> numbers.
Works as well, here:
Committer testing:
$ python ~acme/libexec/perf-core/scripts/python/exported-sql-viewer.py ~/c/adrian.hunter/simple-retpoline.db
Then go to 'Help', then 'About', select all the lines with the mouse
press 'Control+C', then, on the same terminal press control+shift+V
which shows my current environment:
Python version: 2.7.16
PySide version: 1
Qt version: 4.8.7
SQLite version: 3.26.0
-------------------
Patchkit applied, thanks.
- Arnaldo
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
> .../scripts/python/exported-sql-viewer.py | 59 +++++++++++++++++++
> 1 file changed, 59 insertions(+)
>
> diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
> index 421f3828ea43..6fe553258ce5 100755
> --- a/tools/perf/scripts/python/exported-sql-viewer.py
> +++ b/tools/perf/scripts/python/exported-sql-viewer.py
> @@ -2927,6 +2927,60 @@ class HelpOnlyWindow(QMainWindow):
>
> self.setCentralWidget(self.text)
>
> +# PostqreSQL server version
> +
> +def PostqreSQLServerVersion(db):
> + query = QSqlQuery(db)
> + QueryExec(query, "SELECT VERSION()")
> + if query.next():
> + v_str = query.value(0)
> + v_list = v_str.strip().split(" ")
> + if v_list[0] == "PostgreSQL" and v_list[2] == "on":
> + return v_list[1]
> + return v_str
> + return "Unknown"
> +
> +# SQLite version
> +
> +def SQLiteVersion(db):
> + query = QSqlQuery(db)
> + QueryExec(query, "SELECT sqlite_version()")
> + if query.next():
> + return query.value(0)
> + return "Unknown"
> +
> +# About dialog
> +
> +class AboutDialog(QDialog):
> +
> + def __init__(self, glb, parent=None):
> + super(AboutDialog, self).__init__(parent)
> +
> + self.setWindowTitle("About Exported SQL Viewer")
> + self.setMinimumWidth(300)
> +
> + pyside_version = "1" if pyside_version_1 else "2"
> +
> + text = "<pre>"
> + text += "Python version: " + sys.version.split(" ")[0] + "\n"
> + text += "PySide version: " + pyside_version + "\n"
> + text += "Qt version: " + qVersion() + "\n"
> + if glb.dbref.is_sqlite3:
> + text += "SQLite version: " + SQLiteVersion(glb.db) + "\n"
> + else:
> + text += "PostqreSQL version: " + PostqreSQLServerVersion(glb.db) + "\n"
> + text += "</pre>"
> +
> + self.text = QTextBrowser()
> + self.text.setHtml(text)
> + self.text.setReadOnly(True)
> + self.text.setOpenExternalLinks(True)
> +
> + self.vbox = QVBoxLayout()
> + self.vbox.addWidget(self.text)
> +
> + self.setLayout(self.vbox);
> +
> # Font resize
>
> def ResizeFont(widget, diff):
> @@ -3024,6 +3078,7 @@ class MainWindow(QMainWindow):
>
> help_menu = menu.addMenu("&Help")
> help_menu.addAction(CreateAction("&Exported SQL Viewer Help", "Helpful information", self.Help, self, QKeySequence.HelpContents))
> + help_menu.addAction(CreateAction("&About Exported SQL Viewer", "About this application", self.About, self))
>
> def Try(self, fn):
> win = self.mdi_area.activeSubWindow()
> @@ -3109,6 +3164,10 @@ class MainWindow(QMainWindow):
> def Help(self):
> HelpWindow(self.glb, self)
>
> + def About(self):
> + dialog = AboutDialog(self.glb, self)
> + dialog.exec_()
> +
> # XED Disassembler
>
> class xed_state_t(Structure):
> --
> 2.17.1
--
- Arnaldo
^ permalink raw reply [flat|nested] 17+ messages in thread
* [tip:perf/core] perf scripts python: exported-sql-viewer.py: Add 'About' dialog box
2019-05-03 12:08 ` [PATCH 6/6] perf scripts python: exported-sql-viewer.py: Add 'About' dialog box Adrian Hunter
2019-05-13 20:12 ` Arnaldo Carvalho de Melo
@ 2019-05-18 8:58 ` tip-bot for Adrian Hunter
1 sibling, 0 replies; 17+ messages in thread
From: tip-bot for Adrian Hunter @ 2019-05-18 8:58 UTC (permalink / raw)
To: linux-tip-commits
Cc: tglx, mingo, jolsa, hpa, acme, adrian.hunter, linux-kernel
Commit-ID: b62d18aba1109506c1926ab7b564c4ac3bd48786
Gitweb: https://git.kernel.org/tip/b62d18aba1109506c1926ab7b564c4ac3bd48786
Author: Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Fri, 3 May 2019 15:08:28 +0300
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 15 May 2019 16:36:47 -0300
perf scripts python: exported-sql-viewer.py: Add 'About' dialog box
With support for Python 2 or 3 and PySide 1 or 2 (Qt 4 or 5), it is
useful to see what versions are in use. Add an 'About' dialog box that
displays Python, PySide, Qt and database server (SQLite or PostgreSQL)
version numbers.
Committer testing:
$ python ~acme/libexec/perf-core/scripts/python/exported-sql-viewer.py ~/c/adrian.hunter/simple-retpoline.db
Then go to 'Help', then 'About', select all the lines with the mouse
press 'Control+C', then, on the same terminal press control+shift+V
which shows my current environment:
Python version: 2.7.16
PySide version: 1
Qt version: 4.8.7
SQLite version: 3.26.0
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/20190503120828.25326-7-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/scripts/python/exported-sql-viewer.py | 59 ++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index affd80ebcae0..affed7d149be 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -2913,6 +2913,60 @@ class HelpOnlyWindow(QMainWindow):
self.setCentralWidget(self.text)
+# PostqreSQL server version
+
+def PostqreSQLServerVersion(db):
+ query = QSqlQuery(db)
+ QueryExec(query, "SELECT VERSION()")
+ if query.next():
+ v_str = query.value(0)
+ v_list = v_str.strip().split(" ")
+ if v_list[0] == "PostgreSQL" and v_list[2] == "on":
+ return v_list[1]
+ return v_str
+ return "Unknown"
+
+# SQLite version
+
+def SQLiteVersion(db):
+ query = QSqlQuery(db)
+ QueryExec(query, "SELECT sqlite_version()")
+ if query.next():
+ return query.value(0)
+ return "Unknown"
+
+# About dialog
+
+class AboutDialog(QDialog):
+
+ def __init__(self, glb, parent=None):
+ super(AboutDialog, self).__init__(parent)
+
+ self.setWindowTitle("About Exported SQL Viewer")
+ self.setMinimumWidth(300)
+
+ pyside_version = "1" if pyside_version_1 else "2"
+
+ text = "<pre>"
+ text += "Python version: " + sys.version.split(" ")[0] + "\n"
+ text += "PySide version: " + pyside_version + "\n"
+ text += "Qt version: " + qVersion() + "\n"
+ if glb.dbref.is_sqlite3:
+ text += "SQLite version: " + SQLiteVersion(glb.db) + "\n"
+ else:
+ text += "PostqreSQL version: " + PostqreSQLServerVersion(glb.db) + "\n"
+ text += "</pre>"
+
+ self.text = QTextBrowser()
+ self.text.setHtml(text)
+ self.text.setReadOnly(True)
+ self.text.setOpenExternalLinks(True)
+
+ self.vbox = QVBoxLayout()
+ self.vbox.addWidget(self.text)
+
+ self.setLayout(self.vbox);
+
# Font resize
def ResizeFont(widget, diff):
@@ -3010,6 +3064,7 @@ class MainWindow(QMainWindow):
help_menu = menu.addMenu("&Help")
help_menu.addAction(CreateAction("&Exported SQL Viewer Help", "Helpful information", self.Help, self, QKeySequence.HelpContents))
+ help_menu.addAction(CreateAction("&About Exported SQL Viewer", "About this application", self.About, self))
def Try(self, fn):
win = self.mdi_area.activeSubWindow()
@@ -3095,6 +3150,10 @@ class MainWindow(QMainWindow):
def Help(self):
HelpWindow(self.glb, self)
+ def About(self):
+ dialog = AboutDialog(self.glb, self)
+ dialog.exec_()
+
# XED Disassembler
class xed_state_t(Structure):
^ permalink raw reply related [flat|nested] 17+ messages in thread