summaryrefslogtreecommitdiff
path: root/portato/gui/windows
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--portato/gui/windows/basic.py72
-rw-r--r--portato/gui/windows/main.py120
-rw-r--r--portato/gui/windows/preference.py76
3 files changed, 163 insertions, 105 deletions
diff --git a/portato/gui/windows/basic.py b/portato/gui/windows/basic.py
index 1117e5e..b3f210c 100644
--- a/portato/gui/windows/basic.py
+++ b/portato/gui/windows/basic.py
@@ -14,7 +14,6 @@ from __future__ import absolute_import
# gtk stuff
import gtk
-import gtk.glade
import gobject
from functools import wraps
@@ -23,11 +22,18 @@ import os.path
from ...constants import TEMPLATE_DIR, APP, LOCALE_DIR
from ...helper import error
-gtk.glade.bindtextdomain (APP, LOCALE_DIR)
-gtk.glade.textdomain (APP)
+# for the GtkBuilder to translate correctly :)
+import ctypes
+try:
+ getlib = ctypes.cdll.LoadLibrary("libgettextlib.so")
+except OSError:
+ error("'libgettextlib.so' cannot be loaded. Might be, that there are no translations available in the GUI.")
+else:
+ getlib.textdomain(APP)
+ getlib.bindtextdomain(APP, LOCALE_DIR)
class WrappedTree (object):
- __slots__ = ("klass", "tree", "get_widget")
+ __slots__ = ("klass", "tree", "get_widget", "get_ui")
def __init__ (self, klass, tree):
self.tree = tree
self.klass = klass
@@ -39,25 +45,52 @@ class WrappedTree (object):
return getattr(self.tree, name)
def get_widget(self, name):
- w = self.tree.get_widget(name)
+ w = self.tree.get_object(name)
if w is None:
error("Widget '%s' could not be found in class '%s'.", name, self.klass)
return w
-class Window (object):
- def __init__ (self):
+ def get_ui (self, name, ui = "uimanager"):
+ uiw = self.get_widget(ui)
+ if uiw is None:
+ return None
- if not hasattr(self, "__tree__"):
- self.__tree__ = self.__class__.__name__
+ if not name.startswith("ui/"):
+ name = "ui/%s" % name
- if not hasattr(self, "__window__"):
- self.__window__ = self.__class__.__name__
+ w = uiw.get_widget(name)
+ if w is None:
+ error("UIItem '%s' of UIManager '%s' could not be found in class '%s'.", name, ui, self.klass)
+ return w
+
+class UIBuilder (object):
+ def __init__ (self, connector = None):
if not hasattr(self, "__file__"):
self.__file__ = self.__class__.__name__
- self.tree = self.get_tree(self.__tree__)
- self.tree.signal_autoconnect(self)
+ self._builder = gtk.Builder()
+ self._builder.add_from_file(os.path.join(TEMPLATE_DIR, self.__file__+".ui"))
+ self._builder.set_translation_domain(APP)
+
+ if connector is None: connector = self
+
+ unconnected = self._builder.connect_signals(connector)
+
+ if unconnected is not None:
+ for uc in set(unconnected):
+ error("Signal '%s' not connected in class '%s'.", uc, self.__class__.__name__)
+
+ self.tree = WrappedTree(self.__class__.__name__, self._builder)
+
+class Window (UIBuilder):
+ def __init__ (self):
+
+ UIBuilder.__init__(self)
+
+ if not hasattr(self, "__window__"):
+ self.__window__ = self.__class__.__name__
+
self.window = self.tree.get_widget(self.__window__)
@staticmethod
@@ -82,9 +115,6 @@ class Window (object):
return wrapper
- def get_tree (self, name):
- return WrappedTree(self.__class__.__name__, gtk.glade.XML(os.path.join(TEMPLATE_DIR, self.__file__+".glade"), name))
-
class AbstractDialog (Window):
"""A class all our dialogs get derived from. It sets useful default vars and automatically handles the ESC-Button."""
@@ -114,13 +144,3 @@ class AbstractDialog (Window):
def close (self, *args):
self.window.destroy()
-
-class Popup (object):
-
- def __init__ (self, name, parent, file = "popups"):
- self.tree = WrappedTree(self.__class__.__name__, gtk.glade.XML(os.path.join(TEMPLATE_DIR, file+".glade"), root = name))
- self.tree.signal_autoconnect(parent)
- self._popup = self.tree.get_widget(name)
-
- def popup (self, *args):
- self._popup.popup(*args)
diff --git a/portato/gui/windows/main.py b/portato/gui/windows/main.py
index 443fa76..04a9995 100644
--- a/portato/gui/windows/main.py
+++ b/portato/gui/windows/main.py
@@ -43,7 +43,7 @@ from ..dialogs import (blocked_dialog, changed_flags_dialog, io_ex_dialog,
from ..exceptions import PreReqError
# even more GUI stuff
-from .basic import Window, Popup
+from .basic import Window
from .about import AboutWindow
from .plugin import PluginWindow
from .preference import PreferenceWindow
@@ -62,7 +62,6 @@ class PackageTable:
self.main = main
self.tree = main.tree
self.window = main.window
- self.tree.signal_autoconnect(self)
# all the package data is in this one VB
self.vb = self.tree.get_widget("packageVB")
@@ -77,8 +76,7 @@ class PackageTable:
self.maskedLabel = self.tree.get_widget("maskedLabel")
# labels
- generalVB = self.tree.get_widget("generalVB")
- generalVB.modify_bg(gtk.STATE_NORMAL, get_color(self.main.cfg, "packagetable"))
+ self.main.set_color(get_color(self.main.cfg, "packagetable"))
self.nameLabel = self.tree.get_widget("nameLabel")
self.descLabel = self.tree.get_widget("descLabel")
@@ -473,7 +471,7 @@ class MainWindow (Window):
# package db
splash(_("Creating Database"))
- self.db = Database()
+ self.db = Database(self.cfg.get("type", section = "DATABASE"))
# set plugins and plugin-menu
splash(_("Loading Plugins"))
@@ -481,13 +479,24 @@ class MainWindow (Window):
plugin.load_plugins()
menus = [p.menus for p in plugin.get_plugin_queue().get_plugins()]
if menus:
- self.tree.get_widget("pluginMenuItem").set_no_show_all(False)
- pluginMenu = self.tree.get_widget("pluginMenu")
+ uim = self.tree.get_widget("uimanager")
+ ag = self.tree.get_widget("pluginActionGroup")
+ ctr = 0
for m in itt.chain(*menus):
- item = gtk.MenuItem(m.label)
- item.connect("activate", m.call)
- pluginMenu.append(item)
+
+ # create action
+ aname = "plugin%d" % ctr
+ a = gtk.Action(aname, m.label, None, None)
+ a.connect("activate", m.call)
+ ag.add_action(a)
+
+ # add to UI
+ mid = uim.new_merge_id()
+ uim.add_ui(mid, "ui/menubar/pluginMenu", aname, aname, gtk.UI_MANAGER_MENUITEM, False)
+
+ ctr += 1
+
splash(_("Building frontend"))
# set paned position
@@ -554,18 +563,11 @@ class MainWindow (Window):
self.packageTable = PackageTable(self)
# popups
- self.consolePopup = Popup("consolePopup", self, self.__file__)
- self.trayPopup = Popup("systrayPopup", self)
+ self.consolePopup = self.tree.get_ui("consolePopup")
+ self.trayPopup = self.tree.get_ui("systrayPopup")
# pause menu items
self.emergePaused = False
- self.pauseItems = {}
- self.pauseItems["tray"] = self.trayPopup.tree.get_widget("pauseItemTray")
- self.pauseItems["popup"] = self.consolePopup.tree.get_widget("pauseItemPopup")
- self.pauseItems["menu"] = self.tree.get_widget("pauseItemMenu")
-
- for k,v in self.pauseItems.iteritems():
- self.pauseItems[k] = (v, v.connect_after("activate", self.cb_pause_emerge(k)))
# systray
if self.cfg.get_boolean("showSystray", "GUI"):
@@ -1256,6 +1258,17 @@ class MainWindow (Window):
self.catList.get_selection().select_path(pos)
self.catList.scroll_to_cell(pos)
+ def set_color (self, color):
+ """
+ Sets the color of the general VB (i.e. the thing that displays the package details)
+
+ @param color: color to set it to
+ @type color: gtk.gdk.Color
+ """
+
+ generalVB = self.tree.get_widget("generalVB")
+ generalVB.modify_bg(gtk.STATE_NORMAL, color)
+
def set_uri_hook (self, browser):
"""
Sets the browser command which is called when a URL is going to be opened.
@@ -1358,7 +1371,7 @@ class MainWindow (Window):
try:
self.fill_version_list(self.selCP)
except VersionsNotFoundException, e:
- warning(_("No versions of package '%s' found!.") % self.selCP)
+ warning(_("No versions of package '%s' found!") % self.selCP)
no_versions_dialog(self.selCP)
self.db.disable(self.selCP)
self.selCP = oldcp
@@ -1675,7 +1688,7 @@ class MainWindow (Window):
"""
User wants to open preferences.
"""
- PreferenceWindow(self.window, self.cfg, self.console.set_font_from_string, self.set_uri_hook, self.set_notebook_tabpos, self.fill_cat_store)
+ PreferenceWindow(self.window, self.cfg, self.console.set_font_from_string, self.set_uri_hook, self.set_notebook_tabpos, self.fill_cat_store, self.set_color)
return True
def cb_about_clicked (self, *args):
@@ -1772,50 +1785,13 @@ class MainWindow (Window):
self.queue.append(package, update = True, oneshot = set, forceUpdate = True)
- def cb_pause_emerge (self, curr):
- """
- This method returns a callback for a "pause emerge" toggle button.
- It is needed as there are different toggle buttons of this type and if one is clicked,
- the others should be marked too.
-
- @param curr: The button to return the callback for.
- @type curr: gtk.ToggleButton
- """
- def pause (cb):
- """
- The actual callback.
-
- Mark all other buttons too.
-
- @param cb: The button which got toggled.
- @type cb: gtk.ToggleButton
- """
-
- # pause or continue
- self.emergePaused = cb.get_active()
- if not self.emergePaused:
- self.queue.continue_emerge()
- #self.tray.set_from_file(APP_ICON)
- else:
- self.queue.stop_emerge()
- #self.tray.set_from_file(os.path.join(ICON_DIR, "pausing.png"))
-
- # block the handlers of the other buttons
- # so that calling "set_active" does not call this callback recursivly
- for v in self.pauseItems.itervalues():
- v[0].handler_block(v[1])
-
- # mark the others
- for k, v in self.pauseItems.iteritems():
- if k != curr:
- v[0].set_active(self.emergePaused)
-
- # unblock
- for v in self.pauseItems.itervalues():
- v[0].handler_unblock(v[1])
-
- return False
- return pause
+ def cb_pause_emerge (self, action):
+ # pause or continue
+ self.emergePaused = action.get_active()
+ if not self.emergePaused:
+ self.queue.continue_emerge()
+ else:
+ self.queue.stop_emerge()
def cb_kill_clicked (self, *args):
"""
@@ -1823,7 +1799,7 @@ class MainWindow (Window):
"""
self.queue.kill_emerge()
if self.emergePaused: # unmark the "pause emerge" buttons
- self.pauseItems["menu"][0].set_active(False) # calling one button is enough (see: cb_pause_emerge)
+ self.tree.get_widget("generalActionGroup").get_action("pauseAction").set_active(False)
def cb_copy_clicked (self, *args):
"""
@@ -1879,6 +1855,18 @@ class MainWindow (Window):
else:
self.window.iconify()
+ def cb_testing_toggled (self, *args):
+ return self.packageTable.cb_testing_toggled(*args)
+ def cb_masked_toggled (self, *args):
+ return self.packageTable.cb_masked_toggled(*args)
+ def cb_button_pressed (self, *args):
+ return self.packageTable.cb_button_pressed(*args)
+ def cb_package_revert_clicked (self, *args):
+ return self.packageTable.cb_package_revert_clicked(*args)
+ def cb_package_unmerge_clicked (self, *args):
+ return self.packageTable.cb_package_unmerge_clicked(*args)
+ def cb_package_emerge_clicked (self, *args):
+ return self.packageTable.cb_package_emerge_clicked(*args)
def cb_use_flag_toggled (self, *args):
return self.packageTable.cb_use_flag_toggled(*args)
diff --git a/portato/gui/windows/preference.py b/portato/gui/windows/preference.py
index df18e88..5b88b22 100644
--- a/portato/gui/windows/preference.py
+++ b/portato/gui/windows/preference.py
@@ -20,6 +20,7 @@ from .basic import AbstractDialog
from ..dialogs import io_ex_dialog
from ..utils import get_color
from ...helper import debug
+from ... import db
class PreferenceWindow (AbstractDialog):
"""Window displaying some preferences."""
@@ -60,7 +61,7 @@ class PreferenceWindow (AbstractDialog):
4 : gtk.POS_RIGHT
}
- def __init__ (self, parent, cfg, console_fn, linkbtn_fn, tabpos_fn, catmodel_fn):
+ def __init__ (self, parent, cfg, console_fn, linkbtn_fn, tabpos_fn, catmodel_fn, labelcolor_fn):
"""Constructor.
@param parent: parent window
@@ -74,7 +75,9 @@ class PreferenceWindow (AbstractDialog):
@param tabpos_fn: function to call to set the tabposition of the notebooks
@type tabpos_fn: function(gtk.ComboBox,int)
@param catmodel_fn: function to call to set the model of the cat list (collapsed/not collapsed)
- @type catmodel_fn: function()"""
+ @type catmodel_fn: function()
+ @param labelcolor_fn: function to call to set the color of the label
+ @type labelcolor_fn: function(gtk.gdk.Color)"""
AbstractDialog.__init__(self, parent)
@@ -101,6 +104,7 @@ class PreferenceWindow (AbstractDialog):
self.linkbtn_fn = linkbtn_fn
self.tabpos_fn = tabpos_fn
self.catmodel_fn = catmodel_fn
+ self.labelcolor_fn = labelcolor_fn
# set the bg-color of the hint
hintEB = self.tree.get_widget("hintEB")
@@ -109,20 +113,16 @@ class PreferenceWindow (AbstractDialog):
# the checkboxes
for box, val in self.checkboxes.iteritems():
if isinstance(val, tuple):
- self.tree.get_widget(box).\
- set_active(self.cfg.get_boolean(val[0], section = val[1]))
+ self.tree.get_widget(box).set_active(self.cfg.get_boolean(val[0], section = val[1]))
else:
- self.tree.get_widget(box).\
- set_active(self.cfg.get_boolean(val))
+ self.tree.get_widget(box).set_active(self.cfg.get_boolean(val))
# the edits
for edit, val in self.edits.iteritems():
if isinstance(val,tuple):
- self.tree.get_widget(edit).\
- set_text(self.cfg.get(val[0], section = val[1]))
+ self.tree.get_widget(edit).set_text(self.cfg.get(val[0], section = val[1]))
else:
- self.tree.get_widget(edit).\
- set_text(self.cfg.get(val))
+ self.tree.get_widget(edit).set_text(self.cfg.get(val))
# the set list
self.setList = self.tree.get_widget("setList")
@@ -138,19 +138,54 @@ class PreferenceWindow (AbstractDialog):
self.titleLengthSpinBtn = self.tree.get_widget("titleLengthSpinBtn")
self.titleLengthSpinBtn.set_value(int(self.cfg.get("titlelength", section = "GUI")))
+ # the color buttons
+ self.pkgTableColorBtn = self.tree.get_widget("pkgTableColorBtn")
+ self.pkgTableColorBtn.set_color(get_color(self.cfg, "packagetable"))
+
+ self.prefColorBtn = self.tree.get_widget("prefColorBtn")
+ self.prefColorBtn.set_color(get_color(self.cfg, "prefhint"))
+
# the comboboxes
self.systemTabCombo = self.tree.get_widget("systemTabCombo")
self.pkgTabCombo = self.tree.get_widget("packageTabCombo")
for c in (self.systemTabCombo, self.pkgTabCombo):
- m = c.get_model()
- m.clear()
+ model = gtk.ListStore(str)
for i in (_("Top"), _("Bottom"), _("Left"), _("Right")):
- m.append((i,))
+ model.append((i,))
+
+ c.set_model(model)
+
+ cell = gtk.CellRendererText()
+ c.pack_start(cell)
+ c.set_attributes(cell, text = 0)
self.systemTabCombo.set_active(int(self.cfg.get("systemTabPos", section = "GUI"))-1)
self.pkgTabCombo.set_active(int(self.cfg.get("packageTabPos", section = "GUI"))-1)
+ # the database combo
+ dbtype = self.cfg.get("type", section = "DATABASE")
+ self.databaseCombo = self.tree.get_widget("databaseCombo")
+ model = gtk.ListStore(str, str, str)
+
+ ctr = 0
+ active = 0
+ for k, (name, desc) in db.types.iteritems():
+ if k == dbtype:
+ active = ctr
+
+ model.append([name, desc, k])
+ ctr += 1
+
+ self.databaseCombo.set_model(model)
+ self.databaseCombo.set_active(active)
+
+ cell = gtk.CellRendererText()
+ self.databaseCombo.pack_start(cell)
+ self.databaseCombo.set_attributes(cell, text = 0)
+
+ self.cb_db_combo_changed()
+
self.window.show_all()
def _save(self):
@@ -189,6 +224,14 @@ class PreferenceWindow (AbstractDialog):
self.catmodel_fn()
+ # colors
+ c = self.pkgTableColorBtn.get_color()
+ self.cfg.set("packagetable", str(c)[1:], section = "COLORS")
+ self.labelcolor_fn(c)
+
+ c = self.prefColorBtn.get_color()
+ self.cfg.set("prefhint", str(c)[1:], section = "COLORS")
+
def fill_setlist (self):
store = gtk.ListStore(bool, str, str, str)
@@ -212,6 +255,13 @@ class PreferenceWindow (AbstractDialog):
self.setList.set_model(store)
+ def cb_db_combo_changed (self, *args):
+ model = self.databaseCombo.get_model()
+ active = self.databaseCombo.get_active()
+
+ descr = self.tree.get_widget("dbDescriptionLabel")
+ descr.set_markup("<i>%s</i>" % model[active][1])
+
def cb_ok_clicked(self, button):
"""Saves, writes to config-file and closes the window."""
self._save()