~ubuntu-branches/ubuntu/vivid/blueman/vivid-proposed

« back to all changes in this revision

Viewing changes to blueman/gui/Notification.py

  • Committer: Package Import Robot
  • Author(s): Artur Rona
  • Date: 2014-12-24 18:33:36 UTC
  • mfrom: (2.3.8 sid)
  • Revision ID: package-import@ubuntu.com-20141224183336-cyb82ot0y8tz8flq
Tags: 1.99~alpha1-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - debian/patches/01_dont_autostart_lxde.patch:
    + Don't autostart the applet in LXDE.
  - debian/patches/03_filemanager_fix.patch:
    + Add support for more filemanagers.
* debian/patches/02_dont_crash_on_non-bluetooth_card.patch:
  - Dropped, no longer applicable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2008 Valmantas Paliksa <walmis at balticum-tv dot lt>
2
 
# Copyright (C) 2008 Tadas Dailyda <tadas at dailyda dot com>
3
 
#
4
 
# Licensed under the GNU General Public License Version 3
5
 
#
6
 
# This program is free software: you can redistribute it and/or modify
7
 
# it under the terms of the GNU General Public License as published by
8
 
# the Free Software Foundation, either version 3 of the License, or
9
 
# (at your option) any later version.
10
 
#
11
 
# This program is distributed in the hope that it will be useful,
12
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
# GNU General Public License for more details.
15
 
#
16
 
# You should have received a copy of the GNU General Public License
17
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 
19
 
 
20
 
import pynotify
21
 
import gtk
 
1
from gi.repository import Notify
 
2
from gi.repository import Gtk
 
3
from gi.repository import Gdk
22
4
from blueman.Functions import dprint
23
 
from blueman.gui.GtkAnimation import AnimBase, BezierController
 
5
from blueman.gui.GtkAnimation import AnimBase
24
6
 
25
 
pynotify.init("blueman")
 
7
Notify.init("blueman")
26
8
 
27
9
OPACITY_START = 0.7
28
10
 
 
11
 
29
12
class Fade(AnimBase):
30
 
        def __init__(self, window):
31
 
                AnimBase.__init__(self, state=OPACITY_START)
32
 
                self.window = window
33
 
                
34
 
        def state_changed(self, state):
35
 
                self.window.props.opacity = state
36
 
 
37
 
class NotificationDialog(gtk.MessageDialog):
38
 
        def __init__(self, summary, message, timeout=-1, actions=None, actions_cb=None, pixbuf=None, status_icon=None):
39
 
                gtk.MessageDialog.__init__(self, parent=None, flags=0, type=gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_NONE, message_format=None)
40
 
                
41
 
                self.bubble = NotificationBubble(summary, message, pixbuf=pixbuf)
42
 
                
43
 
                i = 100
44
 
                self.actions = {}
45
 
                self.callback = actions_cb
46
 
                if actions:
47
 
                        for a in actions:
48
 
                                action_id = a[0]
49
 
                                action_name = a[1]
50
 
                                if len(a) == 3:
51
 
                                        icon_name = a[2]
52
 
                                else:
53
 
                                        icon_name = None
54
 
                                
55
 
                                self.actions[i] = action_id
56
 
                                button = self.add_button(action_name, i)
57
 
                                if icon_name:
58
 
                                        im = gtk.image_new_from_icon_name(icon_name, gtk.ICON_SIZE_BUTTON)
59
 
                                        im.show()
60
 
                                        button.props.image = im
61
 
                                i += 1
62
 
                                
63
 
                self.actions[gtk.RESPONSE_DELETE_EVENT] = "close"
64
 
                
65
 
                self.props.secondary_use_markup = True
66
 
                self.resize(350, 50)
67
 
                
68
 
                self.fader = Fade(self)
69
 
 
70
 
                self.props.skip_taskbar_hint = False
71
 
                
72
 
                self.props.title = summary
73
 
                self.props.text = summary
74
 
                self.props.secondary_text = message
75
 
                
76
 
                self.props.window_position = gtk.WIN_POS_CENTER
77
 
 
78
 
                if pixbuf:
79
 
                        self.set_icon_from_pixbuf(pixbuf)
80
 
                
81
 
                self.connect("response", self.dialog_response)
82
 
                self.props.icon_name = "blueman"                
83
 
                
84
 
                self.entered = False
85
 
                def on_enter(widget, event):
86
 
                        if self.window == gtk.gdk.window_at_pointer()[0] or not self.entered:
87
 
                                self.fader.animate(start=self.fader.get_state(), end=1.0, duration=500)
88
 
                                self.entered = True
89
 
                
90
 
                def on_leave(widget, event):
91
 
                        if not gtk.gdk.window_at_pointer():
92
 
                                self.entered = False
93
 
                                self.fader.animate(start=self.fader.get_state(), end=OPACITY_START, duration=500)
94
 
                
95
 
                self.connect("enter-notify-event", on_enter)
96
 
                self.connect("leave-notify-event", on_leave)
97
 
 
98
 
                
99
 
                self.set_opacity(OPACITY_START)
100
 
                self.present()
101
 
                self.set_opacity(OPACITY_START)
102
 
 
103
 
                
104
 
        def get_id(self):
105
 
                if self.bubble:
106
 
                        return self.bubble.props.id
107
 
                
108
 
        def dialog_response(self, dialog, response):
109
 
                if self.callback:
110
 
                        self.callback(self, self.actions[response])
111
 
                self.hide()
112
 
                
113
 
        def close(self):
114
 
                self.hide()
115
 
                
116
 
        def set_hint(*args):
117
 
                dprint("stub")
118
 
                
119
 
        def set_timeout(*args):
120
 
                dprint("stub")
121
 
                
122
 
        def add_action(*args):
123
 
                dprint("stub")
124
 
                
125
 
        def clear_actions(*args):
126
 
                dprint("stub")
127
 
                
128
 
        def set_urgency(*args):
129
 
                dprint("stub")
130
 
                
131
 
        def update(self, summary, message):
132
 
                self.props.title = summary
133
 
                
134
 
                self.props.text = summary
135
 
                self.props.secondary_text = message
136
 
                self.present()
137
 
                
138
 
        def set_icon_from_pixbuf(self, pixbuf):
139
 
                im = gtk.image_new_from_pixbuf(pixbuf)
140
 
                self.set_image(im)
141
 
                im.show()
142
 
        
143
 
 
144
 
class NotificationBubble(pynotify.Notification):
145
 
        def __init__(self, summary, message, timeout=-1, actions= None, actions_cb=None, pixbuf=None, status_icon=None):
146
 
                pynotify.Notification.__init__(self, summary, message)
147
 
 
148
 
                def on_notification_closed(n, *args):
149
 
                        self.disconnect(closed_sig)
150
 
                        if actions_cb:
151
 
                                actions_cb(n, "closed")
152
 
                
153
 
                def on_action(*args):
154
 
                        self.disconnect(closed_sig)
155
 
                        actions_cb(*args)       
156
 
                
157
 
                if pixbuf:
158
 
                        self.set_icon_from_pixbuf(pixbuf)
159
 
                
160
 
                if actions:
161
 
                        for action in actions:
162
 
                                self.add_action(action[0], action[1], on_action)
163
 
                        self.add_action("default", "Default Action", on_action)
164
 
                
165
 
                closed_sig = self.connect("closed", on_notification_closed)
166
 
                if timeout != -1:
167
 
                        self.set_timeout(timeout)
168
 
                if status_icon:
169
 
                        screen, area, orientation = status_icon.get_geometry()
170
 
                        self.set_hint("x", area.x + area.width/2)
171
 
                        self.set_hint("y", area.y + area.height/2)
172
 
                
173
 
                self.show()     
174
 
                
175
 
        def get_id(self):
176
 
                return self.props.id
177
 
        
 
13
    def __init__(self, window):
 
14
        AnimBase.__init__(self, state=OPACITY_START)
 
15
        self.window = window
 
16
 
 
17
    def state_changed(self, state):
 
18
        self.window.props.opacity = state
 
19
 
 
20
 
 
21
class NotificationDialog(Gtk.MessageDialog):
 
22
    def __init__(self, summary, message, timeout=-1, actions=None, actions_cb=None, pixbuf=None, status_icon=None):
 
23
        GObject.GObject.__init__(self, parent=None, flags=0, type=Gtk.MessageType.QUESTION,
 
24
                                 buttons=Gtk.ButtonsType.NONE, message_format=None)
 
25
 
 
26
        self.bubble = NotificationBubble(summary, message, pixbuf=pixbuf)
 
27
 
 
28
        i = 100
 
29
        self.actions = {}
 
30
        self.callback = actions_cb
 
31
        if actions:
 
32
            for a in actions:
 
33
                action_id = a[0]
 
34
                action_name = a[1]
 
35
                if len(a) == 3:
 
36
                    icon_name = a[2]
 
37
                else:
 
38
                    icon_name = None
 
39
 
 
40
                self.actions[i] = action_id
 
41
                button = self.add_button(action_name, i)
 
42
                if icon_name:
 
43
                    im = Gtk.Image.new_from_icon_name(icon_name, Gtk.IconSize.BUTTON)
 
44
                    im.show()
 
45
                    button.props.image = im
 
46
                i += 1
 
47
 
 
48
        self.actions[Gtk.ResponseType.DELETE_EVENT] = "close"
 
49
 
 
50
        self.props.secondary_use_markup = True
 
51
        self.resize(350, 50)
 
52
 
 
53
        self.fader = Fade(self)
 
54
 
 
55
        self.props.skip_taskbar_hint = False
 
56
 
 
57
        self.props.title = summary
 
58
        self.props.text = summary
 
59
        self.props.secondary_text = message
 
60
 
 
61
        self.props.window_position = Gtk.WindowPosition.CENTER
 
62
 
 
63
        if pixbuf:
 
64
            self.set_icon_from_pixbuf(pixbuf)
 
65
 
 
66
        self.connect("response", self.dialog_response)
 
67
        self.props.icon_name = "blueman"
 
68
 
 
69
        self.entered = False
 
70
 
 
71
        def on_enter(widget, event):
 
72
            if self.window == Gdk.Window.at_pointer()[0] or not self.entered:
 
73
                self.fader.animate(start=self.fader.get_state(), end=1.0, duration=500)
 
74
                self.entered = True
 
75
 
 
76
        def on_leave(widget, event):
 
77
            if not Gdk.Window.at_pointer():
 
78
                self.entered = False
 
79
                self.fader.animate(start=self.fader.get_state(), end=OPACITY_START, duration=500)
 
80
 
 
81
        self.connect("enter-notify-event", on_enter)
 
82
        self.connect("leave-notify-event", on_leave)
 
83
 
 
84
        self.set_opacity(OPACITY_START)
 
85
        self.present()
 
86
        self.set_opacity(OPACITY_START)
 
87
 
 
88
 
 
89
    def get_id(self):
 
90
        if self.bubble:
 
91
            return self.bubble.props.id
 
92
 
 
93
    def dialog_response(self, dialog, response):
 
94
        if self.callback:
 
95
            self.callback(self, self.actions[response])
 
96
        self.hide()
 
97
 
 
98
    def close(self):
 
99
        self.hide()
 
100
 
 
101
    def set_hint_int32(*args):
 
102
        dprint("stub")
 
103
 
 
104
    def set_timeout(*args):
 
105
        dprint("stub")
 
106
 
 
107
    def add_action(*args):
 
108
        dprint("stub")
 
109
 
 
110
    def clear_actions(*args):
 
111
        dprint("stub")
 
112
 
 
113
    def set_urgency(*args):
 
114
        dprint("stub")
 
115
 
 
116
    def update(self, summary, message):
 
117
        self.props.title = summary
 
118
 
 
119
        self.props.text = summary
 
120
        self.props.secondary_text = message
 
121
        self.present()
 
122
 
 
123
    def set_icon_from_pixbuf(self, pixbuf):
 
124
        im = Gtk.Image.new_from_pixbuf(pixbuf)
 
125
        self.set_image(im)
 
126
        im.show()
 
127
 
 
128
 
 
129
class NotificationBubble(Notify.Notification):
 
130
    def __new__(cls, summary, message, timeout=-1, actions=None, actions_cb=None, pixbuf=None, status_icon=None):
 
131
        self = Notify.Notification.new(summary, message, None)
 
132
 
 
133
        def on_notification_closed(n, *args):
 
134
            self.disconnect(closed_sig)
 
135
            if actions_cb:
 
136
                actions_cb(n, "closed")
 
137
 
 
138
        def on_action(n, action, *args):
 
139
            self.disconnect(closed_sig)
 
140
            actions_cb(n, action)
 
141
 
 
142
        if pixbuf:
 
143
            self.set_icon_from_pixbuf(pixbuf)
 
144
 
 
145
        if actions:
 
146
            for action in actions:
 
147
                self.add_action(action[0], action[1], on_action, None)
 
148
            self.add_action("default", "Default Action", on_action, None)
 
149
 
 
150
        closed_sig = self.connect("closed", on_notification_closed)
 
151
        if timeout != -1:
 
152
            self.set_timeout(timeout)
 
153
        if status_icon:
 
154
            _, screen, area, orientation = status_icon.get_geometry()
 
155
            self.set_hint_int32("x", area.x + area.width / 2)
 
156
            self.set_hint_int32("y", area.y + area.height / 2)
 
157
 
 
158
        self.show()
 
159
 
 
160
        return self
 
161
 
 
162
    def get_id(self):
 
163
        return self.props.id
 
164
 
178
165
 
179
166
class Notification(object):
180
 
        @staticmethod
181
 
        def actions_supported():
182
 
                return "actions" in pynotify.get_server_caps()
183
 
        
184
 
        def __new__(cls, summary, message, timeout=-1, actions= None, actions_cb=None, pixbuf=None, status_icon=None):
185
 
                if not "actions" in pynotify.get_server_caps():
186
 
                        if actions != None:
187
 
                                return NotificationDialog(summary, message, timeout, actions, actions_cb, pixbuf, status_icon)
188
 
                                
189
 
                return NotificationBubble(summary, message, timeout, actions, actions_cb, pixbuf, status_icon)
190
 
 
191
 
 
 
167
    @staticmethod
 
168
    def actions_supported():
 
169
        return "actions" in Notify.get_server_caps()
 
170
 
 
171
    def __new__(cls, summary, message, timeout=-1, actions=None, actions_cb=None, pixbuf=None, status_icon=None):
 
172
        if not "actions" in Notify.get_server_caps():
 
173
            if actions is not None:
 
174
                return NotificationDialog(summary, message, timeout, actions, actions_cb, pixbuf, status_icon)
 
175
 
 
176
        return NotificationBubble(summary, message, timeout, actions, actions_cb, pixbuf, status_icon)