Imported Upstream version 0.0.3
[callnotify] / src / usr / lib / hildon-desktop / CallNotify.py
1 import gtk
2 import gobject
3 import hildondesktop
4 import sqlite3
5 import time
6 import dbus
7 import osso
8 import atexit
9 from dbus.mainloop.glib import DBusGMainLoop
10
11
12 class CallNotify(hildondesktop.StatusMenuItem):
13     def __init__(self):
14                 hildondesktop.StatusMenuItem.__init__(self)
15                 
16                 self.path = "/home/user/.rtcom-eventlogger/el.db"
17                 
18                 # Prevent multiple timers to refresh the status icon
19                 self.stop = False
20                 
21                 # Load images
22                 self.loadImages()
23                 self.msgType = ""               
24                 self.toShow = True
25                 self.missed = self.getMissedCallsCount(False)
26                 self.missedSMS = self.getMissedCallsCount(True)
27                 self.missedLastCall = self.missed
28                 self.missedLastSMS = self.missedSMS
29                 self.mainLoop = None            
30                 # Register to handle screen off/on events
31                 osso_c = osso.Context("osso_test_device_on", "0.0.1", False)
32                 device = osso.DeviceState(osso_c)
33                 device.set_display_event_cb(self.state_cb)
34
35                 self.tmr_main = gobject.timeout_add(5000, self.handleMissedCall) 
36                 
37                 # add d-bus listener for removing notification after viewing missed call
38                 # Doing timeout_add with return False instead of explicitly raising a thread
39                 gobject.timeout_add(500, self.startDbusListeners)
40                 atexit.register(self.cleanup)
41
42     def cleanup():
43                 gobject.source_remove(self.tmr_main)                           
44                 gobject.source_remove(self.tmr_ptr)             
45                 self.mainLoop.quit()
46
47     def loadImages(self):
48                 # Load phone image
49                 #self.pixbuf = gtk.gdk.pixbuf_new_from_file_at_size("/home/user/phone.png",18,18)
50                 icon_theme = gtk.icon_theme_get_default()
51                 self.callPicture = icon_theme.load_icon("general_call", 18, gtk.ICON_LOOKUP_NO_SVG)
52                 self.smsPicture = gtk.gdk.pixbuf_new_from_file_at_size("/usr/share/CallNotify/sms.png",18,18)
53                 
54                 # Load 5 numbers and the "+5" 
55                 self.imgList = []
56                 #self.imgList.append(gtk.gdk.pixbuf_new_from_file_at_size("/home/user/1.png",18,18))
57                 self.imgList.append(gtk.gdk.pixbuf_new_from_file_at_size("/usr/share/CallNotify/1.png",18,18))
58                 self.imgList.append(gtk.gdk.pixbuf_new_from_file_at_size("/usr/share/CallNotify/2.png",18,18))
59                 self.imgList.append(gtk.gdk.pixbuf_new_from_file_at_size("/usr/share/CallNotify/3.png",18,18))
60                 self.imgList.append(gtk.gdk.pixbuf_new_from_file_at_size("/usr/share/CallNotify/4.png",18,18))
61                 self.imgList.append(gtk.gdk.pixbuf_new_from_file_at_size("/usr/share/CallNotify/5.png",18,18))
62                 self.imgList.append(gtk.gdk.pixbuf_new_from_file_at_size("/usr/share/CallNotify/more.png",18,18))
63                 
64         # Screen off event-handler
65     def state_cb(self, state):
66         if state == osso.device_state.OSSO_DISPLAY_OFF:
67                 gobject.source_remove(self.tmr_main)
68                 gobject.source_remove(self.tmr_ptr)
69         elif state == osso.device_state.OSSO_DISPLAY_ON:
70                 self.tmr_main = gobject.timeout_add(5000, self.handleMissedCall)
71                 self.show()
72         return False
73                 
74         # Method to define the way to add dbus signal receiver
75
76     def smsrec(self):
77         self.stop_notification(self)
78
79     def startDbusListeners(self):
80                 DBusGMainLoop(set_as_default=True)                             
81                 bus = dbus.SessionBus()                                        
82                 #bus.add_signal_receiver(self.stop_notification, "NotificationClosed", "org.freedesktop.Notifications", "org.freedesktop.Notifications", "/org/freedesktop/Notifications") 
83                 #bus.add_signal_receiver(self.handleMissedCall, "Notify", None, None, None)
84                 #bus.add_signal_receiver(self.handleMissedCall, "MembersChanged", None, None, None)
85                 bus.add_signal_receiver(self.smsReceived, "MessageReceived", None, None, None)
86                 bus.add_signal_receiver(self.smsRead, "NotificationClosed", "org.freedesktop.Notifications", None, "/org/freedesktop/Notifications")
87                 bus.add_signal_receiver(self.smsrec, "Closed", None, None, None)
88
89                 self.mainLoop = gobject.MainLoop()
90                 self.mainLoop.run()                                       
91                 return False
92     
93     def smsReceived(self, a):
94         if a[0].has_key('message-type'):
95                 if self.missedLastSMS == self.getMissedCallsCount(True):
96                         if self.msgType == "Call":
97                                 self.msgType = "Both"
98                         else:
99                                 self.msgType = "SMS"
100                         self.show()
101                 self.missedLastSMS = self.getMissedCallsCount(True)
102         
103     def smsRead(self, a):
104         self.stop_notification(a)
105         
106     def handleMissedCall(self): 
107                 if self.missedLastCall != self.getMissedCallsCount(False):
108                         if self.msgType == "SMS":
109                                 self.msgType = "Both"
110                         else:
111                                 self.msgType = "Call"
112                         self.show()
113                         self.missedLastCall = self.getMissedCallsCount(False)
114                 return True
115         
116     def stop_notification(self, a):
117                 self.set_status_area_icon(None)
118                 gobject.source_remove(self.tmr_ptr)
119                 self.set_status_area_icon(None)
120                 # Reset the notification (get recent missed call count)
121                 self.missed = self.getMissedCallsCount(False)
122                 self.missedSMS = self.getMissedCallsCount(True)
123                 self.missedLastCall = self.missed
124                 self.missedLastSMS = self.missedSMS
125                 self.stop = False
126                 self.msgType = ""
127
128     def theLoop(self):
129                 missedCalls = self.getMissedCallsCount(False)
130                 if self.missedLastCall != missedCalls:
131                         self.show()
132                         self.missedLastCall  = missedCalls
133                 return True
134
135     def getMissedCallsCount(self, isSms):
136                 eType = 3
137                 if isSms:
138                         eType=7
139                 conn = sqlite3.connect(self.path)
140                 cur = conn.cursor()
141                 cur.execute("select count(id) from Events where event_type_id = " + str(eType))
142                 return cur.fetchone()[0]
143
144     def show(self):
145                 # blink the icon every 1 second
146                 if not(self.stop):
147                         self.tmr_ptr = gobject.timeout_add(1000, self.blinkIcon)
148                         self.stop = True
149                         
150     def blinkIcon(self):
151                 if self.toShow:
152                         self.toShow = False
153                         img = self.callPicture
154                         if self.msgType == "SMS":
155                                 img = self.smsPicture
156                         self.set_status_area_icon(img)
157                         return True
158                 else:
159                         img = self.smsPicture
160                         isSMS = False
161                         counter = self.missed
162                         if self.msgType == "SMS":
163                                 counter = self.missedSMS
164                                 isSMS = True
165                         index = self.getMissedCallsCount(isSMS) - counter - 1
166                         if index >= 5:
167                                 index = 5
168                                 if index < 0:
169                                         index = 0
170                         if self.msgType != "Both":
171                                 img = self.imgList[index]
172                         self.toShow = True
173                         self.set_status_area_icon(img)
174                         return True
175                 
176 hd_plugin_type = CallNotify
177