diff --git a/src/lineprofilergui/gui.py b/src/lineprofilergui/gui.py index 008c230..c90bcf6 100644 --- a/src/lineprofilergui/gui.py +++ b/src/lineprofilergui/gui.py @@ -65,6 +65,8 @@ def setup_ui(self): # noqa: PLR0915 self.actionShowOutput.setIcon(ICONS["INFO"]) self.actionLoadLprof = QtGui.QAction(self) self.actionLoadLprof.setIcon(ICONS["READFILE"]) + self.actionExport = QtGui.QAction(self) + self.actionExport.setIcon(ICONS["EXPORT2HTML"]) self.actionQuit = QtGui.QAction(self) self.actionQuit.setIcon(ICONS["ABORT"]) self.actionConfigure = QtGui.QAction(self) @@ -93,6 +95,7 @@ def setup_ui(self): # noqa: PLR0915 self.menuProfiling.addAction(self.actionShowOutput) self.menuProfiling.addSeparator() self.menuProfiling.addAction(self.actionLoadLprof) + self.menuProfiling.addAction(self.actionExport) self.menuProfiling.addSeparator() self.menuProfiling.addAction(self.actionQuit) self.menubar.addAction(self.menuProfiling.menuAction()) @@ -164,6 +167,7 @@ def connect_signals(self): self.actionAbort.triggered.connect(self.kernprof_run.kill) self.actionShowOutput.toggled.connect(self.dockOutputWidget.setVisible) self.actionLoadLprof.triggered.connect(self.selectLprof) + self.actionExport.triggered.connect(self.exportLProfile) self.actionQuit.triggered.connect(QtWidgets.QApplication.instance().quit) self.actionLine_profiler_documentation.triggered.connect( lambda: QtGui.QDesktopServices.openUrl(QtCore.QUrl(LINE_PROFILER_DOC_URL)) @@ -197,6 +201,8 @@ def retranslate_ui(self): self.actionShowOutput.setShortcut(_("F7")) self.actionLoadLprof.setText(_("&Load data...")) self.actionLoadLprof.setShortcut(_("Ctrl+O")) + self.actionExport.setText(_("&Export as HTML...")) + self.actionExport.setShortcut(_("Ctrl+E")) self.actionQuit.setText(_("&Quit")) self.actionQuit.setShortcut(_("Ctrl+Q")) self.actionConfigure.setText(_("&Configuration...")) @@ -249,6 +255,18 @@ def selectLprof(self): if filename: self.load_lprof(filename) + def exportLProfile(self): + filename, _selfilter = QtWidgets.QFileDialog.getSaveFileName( + self, + _("Export line profiler data as HTML"), + "", + _("HTML") + " (*.html);; " + _("All files") + " (*.*)", + ) + if filename: + html = self.resultsTreeWidget.generate_html() + with open(filename, "w") as f: + f.write(html) + @QtCore.Slot() def configure(self): UiConfigDialog(self, self.config).exec() diff --git a/src/lineprofilergui/tree.py b/src/lineprofilergui/tree.py index ac52526..f2a909b 100644 --- a/src/lineprofilergui/tree.py +++ b/src/lineprofilergui/tree.py @@ -312,6 +312,56 @@ def updateColonsVisible(self): col, not settings.value(f"column{col+1}Visible", True, bool) ) + def generate_html(self): + def get_text_color(item: QtWidgets.QTreeWidgetItem): + color = item.foreground(0).color() + return color.name() + + def get_background_color(item: QtWidgets.QTreeWidgetItem): + color = item.background(0).color().name(QtGui.QColor.HexArgb) + return color[0] + color[3:] + color[1:3] # Swap alpha and color + + html = "
" + + for i in range(self.topLevelItemCount()): + top_item = self.topLevelItem(i) + html += '| {self.headerItem().text(col)} | " + html += "
|---|
| {child.text(col)} | ' + html += "