summaryrefslogtreecommitdiff
path: root/portato/gui/windows/basic.py
blob: 330f82311ad5abac118748d499ac21f17fa4e05b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# -*- coding: utf-8 -*-
#
# File: portato/gui/windows/basic.py
# This file is part of the Portato-Project, a graphical portage-frontend.
#
# Copyright (C) 2006-2009 René 'Necoro' Neumann
# This is free software.  You may redistribute copies of it under the terms of
# the GNU General Public License version 2.
# There is NO WARRANTY, to the extent permitted by law.
#
# Written by René 'Necoro' Neumann <necoro@necoro.net>

from __future__ import absolute_import

# gtk stuff
import gtk
import gobject

from functools import wraps
import os.path

from ...constants import TEMPLATE_DIR, APP, LOCALE_DIR
from ...helper import error

class WrappedTree (object):
    __slots__ = ("klass", "tree", "get_widget")
    def __init__ (self, klass, tree):
        self.tree = tree
        self.klass = klass

    def __getattribute__ (self, name):
        if name in WrappedTree.__slots__:
            return object.__getattribute__(self, name)
        else:
            return getattr(self.tree, name)

    def get_widget(self, 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 UIBuilder (object):

    def __init__ (self, connector = None):
        if not hasattr(self, "__file__"):
            self.__file__ = self.__class__.__name__

        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

        self._builder.connect_signals(connector)

        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
    def watch_cursor (func):
        """This is a decorator for functions being so time consuming, that it is appropriate to show the watch-cursor.
        @attention: this function relies on the gtk.Window-Object being stored as self.window"""
        
        @wraps(func)
        def wrapper (self, *args, **kwargs):
            ret = None
            def cb_idle():
                try:
                    ret = func(self, *args, **kwargs)
                finally:
                    self.window.window.set_cursor(None)
                return False
            
            watch = gtk.gdk.Cursor(gtk.gdk.WATCH)
            self.window.window.set_cursor(watch)
            gobject.idle_add(cb_idle)
            return ret

        return wrapper

class AbstractDialog (Window):
    """A class all our dialogs get derived from. It sets useful default vars and automatically handles the ESC-Button."""

    def __init__ (self, parent):
        """Constructor.

        @param parent: the parent window
        @type parent: gtk.Window"""
        
        Window.__init__(self)

        # set parent
        self.window.set_transient_for(parent)
        self.parent = parent
        
        # catch the ESC-key
        self.window.connect("key-press-event", self.cb_key_pressed)

    def cb_key_pressed (self, widget, event):
        """Closes the window if ESC is pressed."""
        keyname = gtk.gdk.keyval_name(event.keyval)
        if keyname == "Escape":
            self.close()
            return True
        else:
            return False

    def close (self, *args):
        self.window.destroy()

class Popup (UIBuilder):

    __file__ = "popups"

    def __init__ (self, name, parent):

        UIBuilder.__init__(self, connector = parent)
        self._popup = self.tree.get_widget(name)

    def popup (self, *args):
        self._popup.popup(*args)