summaryrefslogtreecommitdiff
path: root/portato/gui
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--portato/gui/gtk/windows.py51
-rw-r--r--portato/gui/qt/windows.py30
-rw-r--r--portato/gui/templates/portato.glade429
-rw-r--r--portato/gui/templates/ui/LogDialog.ui88
-rw-r--r--portato/gui/templates/ui/MainWindow.ui22
5 files changed, 412 insertions, 208 deletions
diff --git a/portato/gui/gtk/windows.py b/portato/gui/gtk/windows.py
index 51179c3..33cd037 100644
--- a/portato/gui/gtk/windows.py
+++ b/portato/gui/gtk/windows.py
@@ -33,7 +33,7 @@ from wrapper import GtkTree, GtkConsole
from usetips import UseTips
# other
-import types
+import types, logging
GLADE_FILE = DATA_DIR+"portato.glade"
@@ -832,6 +832,44 @@ class PackageTable:
return True
+class LogWindow (AbstractDialog, logging.Handler):
+
+ def __init__ (self, parent):
+ AbstractDialog.__init__(self, parent)
+ logging.Handler.__init__(self, logging.INFO)
+
+ self.logView = self.tree.get_widget("logView")
+ logging.getLogger("portatoLogger").addHandler(self)
+
+ self.deleteIsOk = False
+
+ def format (self, record):
+
+ if (record.levelno > logging.INFO):
+ return "%s: %s" % (record.levelname, record.getMessage())
+ else:
+ return record.getMessage()
+
+ def emit (self, record):
+ self.logView.get_buffer().insert_at_cursor(self.format(record)+"\n")
+
+ def show (self):
+ self.window.show()
+
+ def close (self):
+ self.window.hide()
+
+ def destroy (self):
+ self.deleteIsOk = True
+ self.window.destroy()
+
+ def cb_delete (self, *args):
+ if not self.deleteIsOk:
+ self.close()
+ return True
+ else:
+ return False
+
class MainWindow (Window):
"""Application main window."""
@@ -852,13 +890,16 @@ class MainWindow (Window):
mHeight = 800
if gtk.gdk.screen_height() <= 800: mHeight = 600
self.window.set_geometry_hints (self.window, min_width = 600, min_height = mHeight, max_height = gtk.gdk.screen_height(), max_width = gtk.gdk.screen_width())
-
+
# booleans
self.doUpdate = False
# installed pixbuf
self.instPixbuf = self.window.render_icon(gtk.STOCK_YES, gtk.ICON_SIZE_MENU)
+ # get the logging window as soon as possible
+ self.logWindow = LogWindow(self.window)
+
# package db
self.db = Database()
self.db.populate()
@@ -1232,7 +1273,10 @@ class MainWindow (Window):
PluginWindow(self.window, queue)
return True
-
+
+ def cb_show_log_clicked (self, btn):
+ self.logWindow.show()
+
@Window.watch_cursor
def cb_show_updates_clicked (self, button):
UpdateWindow(self.window, system.get_updated_packages(), self.queue, self.jump_to)
@@ -1322,6 +1366,7 @@ class MainWindow (Window):
def cb_destroy (self, widget):
"""Calls main_quit()."""
+ self.logWindow.destroy()
gtk.main_quit()
def main (self):
diff --git a/portato/gui/qt/windows.py b/portato/gui/qt/windows.py
index 5aa0e24..ba4dcc5 100644
--- a/portato/gui/qt/windows.py
+++ b/portato/gui/qt/windows.py
@@ -32,7 +32,7 @@ from highlighter import EbuildHighlighter
from dialogs import *
from helper import qCheck, qIsChecked
-import types
+import types, logging
UI_DIR = DATA_DIR+"ui/"
@@ -252,6 +252,27 @@ class EbuildDialog (Window):
self.doc.setPlainText("".join(lines))
self.ebuildEdit.setDocument(self.doc)
+class LogDialog (Window, logging.Handler):
+
+ __metaclass__ = WindowMeta
+
+ def __init__ (self, parent):
+ Window.__init__(self, parent)
+
+ self.setAttribute(Qt.Qt.WA_DeleteOnClose, False)
+ logging.Handler.__init__(self, logging.INFO)
+ logging.getLogger("portatoLogger").addHandler(self)
+
+ def format (self, record):
+
+ if (record.levelno > logging.INFO):
+ return "%s: %s" % (record.levelname, record.getMessage())
+ else:
+ return record.getMessage()
+
+ def emit (self, record):
+ self.logView.insertPlainText(self.format(record)+"\n")
+
class PreferenceWindow (Window):
"""Window displaying some preferences."""
@@ -707,6 +728,9 @@ class MainWindow (Window):
self.doUpdate = False
self.pkgDetails = PackageDetails(self)
+ # set the logger as early as possible
+ self.logDialog = LogDialog(self)
+
# package db
self.db = Database()
self.db.populate()
@@ -843,6 +867,10 @@ class MainWindow (Window):
self.systray = None
@Qt.pyqtSignature("")
+ def on_logAction_triggered (self):
+ self.logDialog.show()
+
+ @Qt.pyqtSignature("")
def on_aboutAction_triggered (self):
AboutDialog(self).exec_()
diff --git a/portato/gui/templates/portato.glade b/portato/gui/templates/portato.glade
index 9238f51..b28591c 100644
--- a/portato/gui/templates/portato.glade
+++ b/portato/gui/templates/portato.glade
@@ -328,6 +328,15 @@
</child>
</widget>
</child>
+ <child>
+ <widget class="GtkMenuItem" id="logItem">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Show _Log</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="cb_show_log_clicked"/>
+ </widget>
+ </child>
</widget>
</child>
</widget>
@@ -442,53 +451,75 @@
<property name="n_rows">4</property>
<property name="n_columns">2</property>
<child>
- <widget class="GtkHBox" id="checkHB">
+ <widget class="GtkScrolledWindow" id="useListScroll">
<property name="visible">True</property>
- <property name="spacing">1</property>
- <property name="homogeneous">True</property>
- <child>
- <widget class="GtkCheckButton" id="installedCheck">
- <property name="visible">True</property>
- <property name="no_show_all">True</property>
- <property name="label" translatable="yes">Installed</property>
- <property name="response_id">0</property>
- <property name="draw_indicator">True</property>
- <signal name="button_press_event" handler="cb_button_pressed"/>
- </widget>
- <packing>
- <property name="fill">False</property>
- </packing>
- </child>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<child>
- <widget class="GtkCheckButton" id="maskedCheck">
+ <widget class="GtkTreeView" id="useList">
<property name="visible">True</property>
- <property name="no_show_all">True</property>
- <property name="label" translatable="yes">Masked</property>
- <property name="response_id">0</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="cb_masked_toggled"/>
</widget>
- <packing>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
</child>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_padding">5</property>
+ <property name="y_padding">5</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="comboVB">
+ <property name="visible">True</property>
<child>
- <widget class="GtkCheckButton" id="testingCheck">
- <property name="visible">True</property>
- <property name="no_show_all">True</property>
- <property name="label" translatable="yes">Testing</property>
- <property name="response_id">0</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="cb_testing_toggled"/>
- </widget>
- <packing>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
+ <placeholder/>
</child>
</widget>
<packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ <property name="x_padding">5</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="descLabel">
+ <property name="visible">True</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="y_padding">10</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="missingLabel">
+ <property name="visible">True</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes">&lt;span foreground='red'&gt;&lt;b&gt;MISSING KEYWORD&lt;/b&gt;&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="notInSysLabel">
+ <property name="visible">True</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Installed, but not in portage anymore&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
@@ -555,80 +586,58 @@
</packing>
</child>
<child>
- <widget class="GtkLabel" id="notInSysLabel">
- <property name="visible">True</property>
- <property name="no_show_all">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Installed, but not in portage anymore&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="missingLabel">
- <property name="visible">True</property>
- <property name="no_show_all">True</property>
- <property name="label" translatable="yes">&lt;span foreground='red'&gt;&lt;b&gt;MISSING KEYWORD&lt;/b&gt;&lt;/span&gt;</property>
- <property name="use_markup">True</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="descLabel">
- <property name="visible">True</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">True</property>
- </widget>
- <packing>
- <property name="right_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- <property name="y_padding">10</property>
- </packing>
- </child>
- <child>
- <widget class="GtkVBox" id="comboVB">
+ <widget class="GtkHBox" id="checkHB">
<property name="visible">True</property>
+ <property name="spacing">1</property>
+ <property name="homogeneous">True</property>
<child>
- <placeholder/>
+ <widget class="GtkCheckButton" id="installedCheck">
+ <property name="visible">True</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes">Installed</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ <signal name="button_press_event" handler="cb_button_pressed"/>
+ </widget>
+ <packing>
+ <property name="fill">False</property>
+ </packing>
</child>
- </widget>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options">GTK_FILL</property>
- <property name="x_padding">5</property>
- </packing>
- </child>
- <child>
- <widget class="GtkScrolledWindow" id="useListScroll">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<child>
- <widget class="GtkTreeView" id="useList">
+ <widget class="GtkCheckButton" id="maskedCheck">
+ <property name="visible">True</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes">Masked</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="cb_masked_toggled"/>
+ </widget>
+ <packing>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="testingCheck">
<property name="visible">True</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes">Testing</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="cb_testing_toggled"/>
</widget>
+ <packing>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
</child>
</widget>
<packing>
+ <property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_padding">5</property>
- <property name="y_padding">5</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
</packing>
</child>
</widget>
@@ -1003,189 +1012,189 @@
<placeholder/>
</child>
<child>
- <widget class="GtkLabel" id="maskLabel">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="xpad">5</property>
- <property name="label" translatable="yes">&lt;u&gt;&lt;i&gt;Masking Keywords&lt;/i&gt;&lt;/u&gt;</property>
- <property name="use_markup">True</property>
- <property name="single_line_mode">True</property>
- </widget>
- <packing>
- <property name="top_attach">7</property>
- <property name="bottom_attach">8</property>
- <property name="y_padding">5</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="testLabel">
+ <widget class="GtkEntry" id="useFileEdit">
<property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="xpad">5</property>
- <property name="label" translatable="yes">&lt;u&gt;&lt;i&gt;Testing Keywords&lt;/i&gt;&lt;/u&gt;</property>
- <property name="use_markup">True</property>
- <property name="single_line_mode">True</property>
</widget>
<packing>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="y_padding">5</property>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="useLabel">
+ <widget class="GtkLabel" id="useEditLabel">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="xpad">5</property>
- <property name="label" translatable="yes">&lt;u&gt;&lt;i&gt;Use-Flags&lt;/i&gt;&lt;/u&gt;</property>
- <property name="use_markup">True</property>
+ <property name="label" translatable="yes">File name to use, if package.use is a directory: </property>
<property name="single_line_mode">True</property>
</widget>
<packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_padding">6</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
</packing>
</child>
<child>
- <widget class="GtkEventBox" id="hintEB">
+ <widget class="GtkCheckButton" id="usePerVersionCheck">
<property name="visible">True</property>
- <child>
- <widget class="GtkFrame" id="hintFrame">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">GTK_SHADOW_OUT</property>
- <child>
- <widget class="GtkLabel" id="hintLabel">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">&lt;u&gt;You may use the following placeholders:&lt;/u&gt;
-
-&lt;i&gt;$(cat)&lt;/i&gt;: category
-&lt;i&gt;$(pkg)&lt;/i&gt;: package name
-&lt;i&gt;$(cat-1)/$(cat-2)&lt;/i&gt;: first/second part of the category</property>
- <property name="use_markup">True</property>
- </widget>
- </child>
- <child>
- <placeholder/>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- </child>
+ <property name="label" translatable="yes">Add only exact version to package.use</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
</widget>
<packing>
<property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
</packing>
</child>
<child>
- <widget class="GtkCheckButton" id="maskPerVersionCheck">
+ <widget class="GtkCheckButton" id="testPerVersionCheck">
<property name="visible">True</property>
- <property name="label" translatable="yes">Add only exact version to package.mask/package.unmask</property>
+ <property name="label" translatable="yes">Add only exact version to package.keywords</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="right_attach">2</property>
- <property name="top_attach">8</property>
- <property name="bottom_attach">9</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="maskEditLabel">
+ <widget class="GtkLabel" id="testEditLabel">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">File name to use, if package.mask/package.unmask is a directory: </property>
+ <property name="label" translatable="yes">File name to use, if package.keywords is a directory: </property>
<property name="single_line_mode">True</property>
</widget>
<packing>
- <property name="top_attach">9</property>
- <property name="bottom_attach">10</property>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
</packing>
</child>
<child>
- <widget class="GtkEntry" id="maskFileEdit">
+ <widget class="GtkEntry" id="testFileEdit">
<property name="visible">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">9</property>
- <property name="bottom_attach">10</property>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
</packing>
</child>
<child>
- <widget class="GtkEntry" id="testFileEdit">
+ <widget class="GtkEntry" id="maskFileEdit">
<property name="visible">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">6</property>
- <property name="bottom_attach">7</property>
+ <property name="top_attach">9</property>
+ <property name="bottom_attach">10</property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="testEditLabel">
+ <widget class="GtkLabel" id="maskEditLabel">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">File name to use, if package.keywords is a directory: </property>
+ <property name="label" translatable="yes">File name to use, if package.mask/package.unmask is a directory: </property>
<property name="single_line_mode">True</property>
</widget>
<packing>
- <property name="top_attach">6</property>
- <property name="bottom_attach">7</property>
+ <property name="top_attach">9</property>
+ <property name="bottom_attach">10</property>
</packing>
</child>
<child>
- <widget class="GtkCheckButton" id="testPerVersionCheck">
+ <widget class="GtkCheckButton" id="maskPerVersionCheck">
<property name="visible">True</property>
- <property name="label" translatable="yes">Add only exact version to package.keywords</property>
+ <property name="label" translatable="yes">Add only exact version to package.mask/package.unmask</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="right_attach">2</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
+ <property name="top_attach">8</property>
+ <property name="bottom_attach">9</property>
</packing>
</child>
<child>
- <widget class="GtkCheckButton" id="usePerVersionCheck">
+ <widget class="GtkEventBox" id="hintEB">
<property name="visible">True</property>
- <property name="label" translatable="yes">Add only exact version to package.use</property>
- <property name="response_id">0</property>
- <property name="draw_indicator">True</property>
+ <child>
+ <widget class="GtkFrame" id="hintFrame">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">GTK_SHADOW_OUT</property>
+ <child>
+ <widget class="GtkLabel" id="hintLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;u&gt;You may use the following placeholders:&lt;/u&gt;
+
+&lt;i&gt;$(cat)&lt;/i&gt;: category
+&lt;i&gt;$(pkg)&lt;/i&gt;: package name
+&lt;i&gt;$(cat-1)/$(cat-2)&lt;/i&gt;: first/second part of the category</property>
+ <property name="use_markup">True</property>
+ </widget>
+ </child>
+ <child>
+ <placeholder/>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
</widget>
<packing>
<property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="useEditLabel">
+ <widget class="GtkLabel" id="useLabel">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">File name to use, if package.use is a directory: </property>
+ <property name="xpad">5</property>
+ <property name="label" translatable="yes">&lt;u&gt;&lt;i&gt;Use-Flags&lt;/i&gt;&lt;/u&gt;</property>
+ <property name="use_markup">True</property>
<property name="single_line_mode">True</property>
</widget>
<packing>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_padding">6</property>
</packing>
</child>
<child>
- <widget class="GtkEntry" id="useFileEdit">
+ <widget class="GtkLabel" id="testLabel">
<property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="xpad">5</property>
+ <property name="label" translatable="yes">&lt;u&gt;&lt;i&gt;Testing Keywords&lt;/i&gt;&lt;/u&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="single_line_mode">True</property>
</widget>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="y_padding">5</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="maskLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="xpad">5</property>
+ <property name="label" translatable="yes">&lt;u&gt;&lt;i&gt;Masking Keywords&lt;/i&gt;&lt;/u&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="single_line_mode">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">7</property>
+ <property name="bottom_attach">8</property>
+ <property name="y_padding">5</property>
</packing>
</child>
</widget>
@@ -1607,4 +1616,32 @@ uses code from: Daniel J. Popowich</property>
</widget>
</child>
</widget>
+ <widget class="GtkWindow" id="LogWindow">
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="title" translatable="yes">Logging Output</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="default_width">400</property>
+ <property name="default_height">500</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="urgency_hint">True</property>
+ <signal name="delete_event" handler="cb_delete"/>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <child>
+ <widget class="GtkTextView" id="logView">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="editable">False</property>
+ <property name="cursor_visible">False</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
</glade-interface>
diff --git a/portato/gui/templates/ui/LogDialog.ui b/portato/gui/templates/ui/LogDialog.ui
new file mode 100644
index 0000000..3415893
--- /dev/null
+++ b/portato/gui/templates/ui/LogDialog.ui
@@ -0,0 +1,88 @@
+<ui version="4.0" >
+ <class>LogDialog</class>
+ <widget class="QDialog" name="LogDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>481</width>
+ <height>603</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Log Viewer</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QTextEdit" name="logView" >
+ <property name="undoRedoEnabled" >
+ <bool>false</bool>
+ </property>
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ <property name="acceptRichText" >
+ <bool>false</bool>
+ </property>
+ <property name="cursorWidth" >
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Ok</set>
+ </property>
+ <property name="centerButtons" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>LogDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>LogDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/portato/gui/templates/ui/MainWindow.ui b/portato/gui/templates/ui/MainWindow.ui
index 5329f9e..0011ead 100644
--- a/portato/gui/templates/ui/MainWindow.ui
+++ b/portato/gui/templates/ui/MainWindow.ui
@@ -428,13 +428,6 @@ p, li { white-space: pre-wrap; }
<addaction name="separator" />
<addaction name="quitAction" />
</widget>
- <widget class="QMenu" name="helpMenu" >
- <property name="title" >
- <string>&amp;?</string>
- </property>
- <addaction name="aboutAction" />
- <addaction name="pluginAction" />
- </widget>
<widget class="QMenu" name="emergeMenu" >
<property name="title" >
<string>&amp;Emerge</string>
@@ -450,6 +443,14 @@ p, li { white-space: pre-wrap; }
<addaction name="killAction" />
<addaction name="pauseAction" />
</widget>
+ <widget class="QMenu" name="helpMenu" >
+ <property name="title" >
+ <string>&amp;?</string>
+ </property>
+ <addaction name="aboutAction" />
+ <addaction name="pluginAction" />
+ <addaction name="logAction" />
+ </widget>
<addaction name="fileMenu" />
<addaction name="emergeMenu" />
<addaction name="helpMenu" />
@@ -544,7 +545,7 @@ p, li { white-space: pre-wrap; }
</action>
<action name="pluginAction" >
<property name="text" >
- <string>Plugins</string>
+ <string>&amp;Plugins</string>
</property>
</action>
<action name="pauseAction" >
@@ -555,6 +556,11 @@ p, li { white-space: pre-wrap; }
<string>Emerge &amp;paused</string>
</property>
</action>
+ <action name="logAction" >
+ <property name="text" >
+ <string>Show &amp;Logs</string>
+ </property>
+ </action>
</widget>
<customwidgets>
<customwidget>