summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etc/portato.cfg14
-rw-r--r--portato/gui/gtk/windows.py45
-rw-r--r--portato/gui/gui_helper.py5
-rw-r--r--portato/gui/qt/windows.py53
-rw-r--r--portato/gui/templates/portato.glade85
-rw-r--r--portato/gui/templates/ui/PreferenceWindow.ui29
6 files changed, 211 insertions, 20 deletions
diff --git a/etc/portato.cfg b/etc/portato.cfg
index 0692e88..0b38488 100644
--- a/etc/portato.cfg
+++ b/etc/portato.cfg
@@ -48,6 +48,18 @@ maskperversion = True
useperversion = True
#
+# Frontend section for options common to more than one GUI.
+# Not all frontends have to support all of the options.
+#
+[Gui]
+
+; show the systray icon?- boolean values
+showsystray = true
+
+; control whether to completely hide on minimization - boolean values
+hideonminimize = true
+
+#
# GTK-Section for options of the GTK-Frontend
#
[Gtk]
@@ -60,7 +72,7 @@ showusetips = on
#
[Qt]
-; control whether to show icons instead of checkboxes in the package list
+; control whether to show icons instead of checkboxes in the package list - boolean values
packageicons = off
# vim:ts=4:sw=4:ft=cfg
diff --git a/portato/gui/gtk/windows.py b/portato/gui/gtk/windows.py
index 88d9a18..7c6f41b 100644
--- a/portato/gui/gtk/windows.py
+++ b/portato/gui/gtk/windows.py
@@ -186,9 +186,11 @@ class PreferenceWindow (AbstractDialog):
"deepCheck" : "deep_opt",
"newUseCheck" : "newuse_opt",
"maskPerVersionCheck" : "maskPerVersion_opt",
+ "minimizeCheck" : ("minimize_opt", "gui_sec"),
+ "systrayCheck" : ("systray_opt", "gui_sec"),
+ "testPerVersionCheck" : "testingPerVersion_opt",
"usePerVersionCheck" : "usePerVersion_opt",
- "useTipsCheck" : ("useTips_opt", "gtk_sec"),
- "testPerVersionCheck" : "testingPerVersion_opt"
+ "useTipsCheck" : ("useTips_opt", "gtk_sec")
}
# all edits in the window
@@ -800,6 +802,15 @@ class MainWindow (Window):
# popups
self.queuePopup = self.create_popup("queuePopup")
self.consolePopup = self.create_popup("consolePopup")
+ self.trayPopup = self.create_popup("systrayPopup")
+
+ # systray
+ if self.cfg.get_boolean("systray_opt", self.cfg.const["gui_sec"]):
+ self.tray = gtk.status_icon_new_from_file(APP_ICON)
+ self.tray.connect("activate", self.cb_systray_activated)
+ self.tray.connect("popup-menu", lambda icon, btn, time: self.trayPopup.popup(None, None, None, btn, time))
+ else:
+ self.tray = None
# set emerge queue
self.queueTree = GtkTree(self.queueList.get_model())
@@ -903,8 +914,13 @@ class MainWindow (Window):
def title_update (self, title):
- if title == None: title = "Console"
- else: title = ("Console (%s)" % title)
+ if self.tray:
+ self.tray.set_tooltip(title)
+
+ if title == None:
+ title = "Console"
+ else:
+ title = ("Console (%s)" % title)
gobject.idle_add(self.notebook.set_tab_label_text, self.termHB, title)
@@ -1127,6 +1143,27 @@ class MainWindow (Window):
return False
+ def cb_minimized (self, window, event):
+ if self.tray and self.cfg.get_boolean("minimize_opt", self.cfg.const["gui_sec"]):
+ if event.changed_mask & gtk.gdk.WINDOW_STATE_ICONIFIED:
+ if event.new_window_state & gtk.gdk.WINDOW_STATE_ICONIFIED:
+ self.window.hide()
+ return True
+
+ return False
+
+ def cb_systray_activated (self, tray):
+ if self.window.iconify_initially:
+ self.window.deiconify()
+ self.window.show()
+ self.window.window.show()
+ else:
+ self.window.iconify()
+
+ def cb_close (self, *args):
+ if not self.cb_delete(): # do the checks
+ self.window.destroy()
+
def cb_destroy (self, widget):
"""Calls main_quit()."""
gtk.main_quit()
diff --git a/portato/gui/gui_helper.py b/portato/gui/gui_helper.py
index 656b83a..a898ea7 100644
--- a/portato/gui/gui_helper.py
+++ b/portato/gui/gui_helper.py
@@ -36,6 +36,7 @@ class Config: # XXX: This needs to be replaced - the const-dict is just messy
"main_sec" : "Main",
"gtk_sec" : "Gtk",
"qt_sec" : "Qt",
+ "gui_sec" : "Gui",
"usePerVersion_opt" : "usePerVersion",
"useFile_opt" : "usefile",
"maskFile_opt" : "maskfile",
@@ -49,7 +50,9 @@ class Config: # XXX: This needs to be replaced - the const-dict is just messy
"syncCmd_opt" : "synccommand",
"useTips_opt" : "showusetips",
"pkgIcons_opt" : "packageIcons",
- "system_opt" : "system"
+ "system_opt" : "system",
+ "systray_opt" : "showsystray",
+ "minimize_opt" : "hideonminimize"
}
def __init__ (self, cfgFile):
diff --git a/portato/gui/qt/windows.py b/portato/gui/qt/windows.py
index 420b9e1..e131bdd 100644
--- a/portato/gui/qt/windows.py
+++ b/portato/gui/qt/windows.py
@@ -181,7 +181,9 @@ class PreferenceWindow (Window):
"maskCheck" : "maskPerVersion_opt",
"useCheck" : "usePerVersion_opt",
"testingCheck" : "testingPerVersion_opt",
- "pkgIconsCheck" : ("pkgIcons_opt", "qt_sec")
+ "pkgIconsCheck" : ("pkgIcons_opt", "qt_sec"),
+ "minimizeCheck" : ("minimize_opt", "gui_sec"),
+ "systrayCheck" : ("systray_opt", "gui_sec")
}
# all edits in the window
@@ -602,7 +604,7 @@ class MainWindow (Window):
plugin.load_plugins("qt")
menus = plugin.get_plugins().get_plugin_menus()
if menus:
- self.pluginMenu = Qt.QMenu("&Plugins")
+ self.pluginMenu = Qt.QMenu("&Plugins", self)
self.menubar.insertMenu(self.helpMenu.menuAction(), self.pluginMenu)
for m in menus:
action = self.pluginMenu.addAction(m.label.replace("_","&"))
@@ -631,6 +633,9 @@ class MainWindow (Window):
Qt.QObject.connect(self.queueList, Qt.SIGNAL("itemActivated (QTreeWidgetItem*, int)"), self.cb_queue_list_item_selected)
Qt.QObject.connect(self.queueList, Qt.SIGNAL("itemDoubleClicked (QTreeWidgetItem*, int)"), self.cb_queue_list_item_selected)
+ # build systray
+ self.build_systray()
+
# set emerge queue
self.queue = EmergeQueue(console = self.console, tree = self.queueTree, db = self.db, title_update = self.title_update)
@@ -640,8 +645,13 @@ class MainWindow (Window):
self.emit(Qt.SIGNAL("doTitleUpdate"), title)
def _title_update (self, title):
- if title == None: title = "Console"
- else: title = ("Console (%s)" % title)
+
+ if title is None:
+ if self.systray: self.systray.setToolTip("")
+ title = "Console"
+ else:
+ if self.systray: self.systray.setToolTip(title)
+ title = ("Console (%s)" % title)
self.tabWidget.setTabText(self.CONSOLE_PAGE, title)
@@ -678,6 +688,18 @@ class MainWindow (Window):
self.catList.setModel(self.catListModel)
self.catList.setSelectionModel(self.selCatListModel)
+ def build_systray (self):
+ if self.cfg.get_boolean("systray_opt", self.cfg.const["gui_sec"]):
+ self.systray = Qt.QSystemTrayIcon(Qt.QIcon(APP_ICON), self)
+ self.trayIconMenu = Qt.QMenu(self)
+ self.trayIconMenu.addAction(self.quitAction)
+ self.systray.setContextMenu(self.trayIconMenu)
+ self.systray.show()
+
+ Qt.QObject.connect(self.systray, Qt.SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), self.cb_systray_activated)
+ else:
+ self.systray = None
+
@Qt.pyqtSignature("")
def on_aboutAction_triggered (self):
queue = plugin.get_plugins()
@@ -854,14 +876,33 @@ class MainWindow (Window):
if not index is None:
self.pkgDetails.update(self.selCatName+"/"+str(index.text()), self.queue)
+ def cb_systray_activated (self, reason):
+ if reason != Qt.QSystemTrayIcon.Context: # do not react on context menu calls
+ if self.windowState() & Qt.Qt.WindowMinimized: # window is minimized
+ self.show()
+ self.showNormal()
+ else: # window is not minimized
+ self.setWindowState(self.windowState() | Qt.Qt.WindowMinimized)
+
def closeEvent (self, event):
if not self.queue.is_empty():
ret = queue_not_empty_dialog(self)
if ret == Qt.QMessageBox.Cancel:
- event.ignore()
return
else:
self.queue.kill_emerge()
- event.accept()
+ if self.systray and self.systray.isVisible():
+ self.systray.hide()
+
+ Qt.QMainWindow.closeEvent(self, event)
+
+ def changeEvent (self, event):
+ if event.type() == Qt.QEvent.WindowStateChange:
+ if self.systray and self.cfg.get_boolean("minimize_opt", self.cfg.const["gui_sec"]):
+ if self.windowState() & Qt.Qt.WindowMinimized: # going to be minimized
+ self.hide()
+ return
+
+ Qt.QMainWindow.changeEvent(self,event)
diff --git a/portato/gui/templates/portato.glade b/portato/gui/templates/portato.glade
index 2443bd1..8037ca9 100644
--- a/portato/gui/templates/portato.glade
+++ b/portato/gui/templates/portato.glade
@@ -7,6 +7,7 @@
<property name="window_position">GTK_WIN_POS_CENTER</property>
<signal name="destroy" handler="cb_destroy"/>
<signal name="delete_event" handler="cb_delete"/>
+ <signal name="window_state_event" handler="cb_minimized"/>
<child>
<widget class="GtkVBox" id="mainVB">
<property name="visible">True</property>
@@ -66,7 +67,7 @@
<property name="visible">True</property>
<property name="label" translatable="yes">_Close</property>
<property name="use_underline">True</property>
- <signal name="activate" handler="cb_destroy"/>
+ <signal name="activate" handler="cb_close"/>
<child internal-child="image">
<widget class="GtkImage" id="image3">
<property name="visible">True</property>
@@ -877,24 +878,76 @@
<property name="draw_indicator">True</property>
</widget>
</child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;General Options&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkFrame" id="visualFrame">
+ <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_xalign">0</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment7">
+ <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="left_padding">12</property>
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <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>
<child>
<widget class="GtkCheckButton" id="useTipsCheck">
<property name="visible">True</property>
<property name="label" translatable="yes">Turn Use-Tips on</property>
<property name="draw_indicator">True</property>
</widget>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="systrayCheck">
+ <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="label" translatable="yes">Enable systray</property>
+ <property name="draw_indicator">True</property>
+ </widget>
<packing>
<property name="position">1</property>
</packing>
</child>
+ <child>
+ <widget class="GtkCheckButton" id="minimizeCheck">
+ <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="label" translatable="yes">Hide on minimization (only if systray is enabled)</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
</widget>
</child>
</widget>
</child>
<child>
- <widget class="GtkLabel" id="label1">
+ <widget class="GtkLabel" id="label10">
<property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;General Options&lt;/b&gt;</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">&lt;b&gt;Visual Options&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
@@ -902,6 +955,9 @@
</packing>
</child>
</widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
</child>
<child>
<widget class="GtkFrame" id="systemFrame">
@@ -963,7 +1019,7 @@
</child>
</widget>
<packing>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
<child>
@@ -1012,7 +1068,7 @@
</child>
</widget>
<packing>
- <property name="position">2</property>
+ <property name="position">3</property>
</packing>
</child>
<child>
@@ -1063,7 +1119,7 @@
</child>
</widget>
<packing>
- <property name="position">3</property>
+ <property name="position">4</property>
</packing>
</child>
<child>
@@ -1289,7 +1345,7 @@
</child>
</widget>
<packing>
- <property name="position">4</property>
+ <property name="position">5</property>
</packing>
</child>
<child>
@@ -1318,7 +1374,7 @@
</child>
</widget>
<packing>
- <property name="position">5</property>
+ <property name="position">6</property>
</packing>
</child>
</widget>
@@ -1337,4 +1393,17 @@
</widget>
</child>
</widget>
+ <widget class="GtkMenu" id="systrayPopup">
+ <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>
+ <child>
+ <widget class="GtkMenuItem" id="closeItemTray">
+ <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">_Close</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="cb_close"/>
+ </widget>
+ </child>
+ </widget>
</glade-interface>
diff --git a/portato/gui/templates/ui/PreferenceWindow.ui b/portato/gui/templates/ui/PreferenceWindow.ui
index fd4ccfa..fbc4a37 100644
--- a/portato/gui/templates/ui/PreferenceWindow.ui
+++ b/portato/gui/templates/ui/PreferenceWindow.ui
@@ -41,6 +41,21 @@
</property>
</widget>
</item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="guiBox" >
+ <property name="title" >
+ <string>Visual Options</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>0</number>
+ </property>
<item>
<widget class="QCheckBox" name="pkgIconsCheck" >
<property name="text" >
@@ -48,6 +63,20 @@
</property>
</widget>
</item>
+ <item>
+ <widget class="QCheckBox" name="systrayCheck" >
+ <property name="text" >
+ <string>Show systray icon</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="minimizeCheck" >
+ <property name="text" >
+ <string>Minimize to systray (only if systray icon is activated)</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>