1 #!/usr/bin/env python2.5
2 # -*- coding: utf-8 -*-
5 @author: Nick Leppänen Larsson <frals@frals.se>
21 from wappushhandler import MMSSender
22 import fmms_config as fMMSconf
23 import contacts as ContactH
27 class fMMS_GUI(hildon.Program):
28 def __init__(self, spawner=None):
29 hildon.Program.__init__(self)
30 program = hildon.Program.get_instance()
32 self.config = fMMSconf.fMMS_config()
33 self.ch = ContactH.ContactHandler()
35 self.window = hildon.StackableWindow()
36 self.window.set_title("fMMS - New MMS")
37 program.add_window(self.window)
39 self.window.connect("delete_event", self.quit)
42 self.spawner = spawner
44 self.spawner = self.window
47 """ Begin top section """
50 bTo = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_HORIZONTAL, " To ")
51 bTo.connect('clicked', self.open_contacts_dialog)
52 self.eNumber = hildon.Entry(gtk.HILDON_SIZE_FINGER_HEIGHT)
56 topHBox1.pack_start(bTo, False, True, 0)
57 topHBox1.pack_start(self.eNumber, True, True, 0)
60 """ Begin midsection """
61 pan = hildon.PannableArea()
62 pan.set_property("mov-mode", hildon.MOVEMENT_MODE_BOTH)
65 self.tvMessage = hildon.TextView()
66 self.tvMessage.set_wrap_mode(gtk.WRAP_WORD)
68 #midHBox.pack_start(self.tvMessage, True, True, 0)
69 pan.add_with_viewport(self.tvMessage)
71 """ Begin botsection """
74 #self.bAttachment = gtk.FileChooserButton('')
75 #self.bAttachment.connect('file-set', self.update_size)
76 self.bAttachment = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_HORIZONTAL, "Attachment")
77 self.bAttachment.connect('clicked', self.open_file_dialog)
79 self.lSize = gtk.Label('')
81 self.bSend = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_HORIZONTAL, " Send ")
82 self.bSend.connect('clicked', self.send_mms)
84 botHBox.pack_start(self.bAttachment)
85 botHBox.pack_start(self.lSize)
86 botHBox.pack_end(self.bSend, False, False, 5)
90 allBox.pack_start(topHBox1, False, False)
91 #allBox.pack_start(topHBox2, False, False)
92 #allBox.pack_start(midHBox, True, True)
93 allBox.pack_start(pan, True, True)
94 allBox.pack_start(botHBox, False, False)
97 #self.pan.add_with_viewport(allBox)
98 #self.window.add(self.pan)
99 self.window.add(allBox)
100 self.window.show_all()
101 self.add_window(self.window)
103 # TODO: pass reference instead of making it available in the object?
104 def open_contacts_dialog(self, button):
105 selector = self.create_contacts_selector()
106 self.contacts_dialog = gtk.Dialog("Select a contact")
108 # TODO: remove hardcoded height
109 self.contacts_dialog.set_default_size(-1, 320)
111 self.contacts_dialog.vbox.pack_start(selector)
112 self.contacts_dialog.add_button("Done", 1)
113 self.contacts_dialog.show_all()
115 ret = self.contacts_dialog.run()
117 ret2 = self.contact_selector_changed(selector)
122 self.contacts_dialog.destroy()
124 """ forces ui update, kinda... god this is AWESOME """
125 def force_ui_update(self):
126 while gtk.events_pending():
127 gtk.main_iteration(False)
129 def contact_number_chosen(self, button, nrdialog):
130 print button.get_label()
131 nr = button.get_label().replace(" ", "")
132 nr = re.sub("[^0-9]\+", "", nr)
133 self.eNumber.set_text(nr)
135 self.contacts_dialog.response(0)
137 def contact_selector_changed(self, selector):
138 username = selector.get_current_text()
139 nrlist = self.ch.get_numbers_from_name(username)
141 nrdialog = gtk.Dialog("Pick a number")
142 for number in nrlist:
144 numberbox = gtk.HBox()
145 typelabel = gtk.Label(nrlist[number].capitalize())
146 typelabel.set_width_chars(24)
147 button = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
148 button.set_label(number)
149 button.connect('clicked', self.contact_number_chosen, nrdialog)
150 numberbox.pack_start(typelabel, False, False, 0)
151 numberbox.pack_start(button, True, True, 0)
152 nrdialog.vbox.pack_start(numberbox)
154 # this is blocking until we get a return
156 print "changed ret:", ret
160 def create_contacts_selector(self):
161 #Create a HildonTouchSelector with a single text column
162 selector = hildon.TouchSelectorEntry(text = True)
163 #selector.connect('changed', self.contact_selector_changed)
165 cl = self.ch.get_contacts_as_list()
170 # Add item to the column
171 #print "adding", contact
172 selector.append_text(contact)
174 # Set selection mode to allow multiple selection
175 selector.set_column_selection_mode(hildon.TOUCH_SELECTOR_SELECTION_MODE_SINGLE)
179 def open_file_dialog(self, button):
180 #fsm = hildon.FileSystemModel()
181 #fcd = hildon.FileChooserDialog(self.window, gtk.FILE_CHOOSER_ACTION_OPEN, fsm)
182 # this shouldnt issue a warning according to the pymaemo mailing list, but does
184 fcd = gobject.new(hildon.FileChooserDialog, action=gtk.FILE_CHOOSER_ACTION_OPEN)
185 fcd.set_default_response(gtk.RESPONSE_OK)
187 if ret == gtk.RESPONSE_OK:
189 ### TODO: dont hardcode
190 filesize = os.path.getsize(fcd.get_filename()) / 1024
192 banner = hildon.hildon_banner_show_information(self.window, "", "10MB attachment limit in effect, please try another file")
193 self.bAttachment.set_label("Attachment")
195 self.bAttachment.set_label(fcd.get_filename())
196 self.update_size(fcd.get_filename())
201 """ resize an image """
202 """ thanks tomaszf for this function """
203 """ slightly modified by frals """
204 def resize_img(self, filename):
206 if not os.path.isdir(self.config.get_imgdir()):
207 print "creating dir", self.config.get_imgdir()
208 os.makedirs(self.config.get_imgdir())
210 hildon.hildon_banner_show_information(self.window, "", "fMMS: Resizing image, this might take a while...")
211 self.force_ui_update()
213 img = Image.open(filename)
214 print "height", img.size[1]
215 print "width", img.size[0]
216 newWidth = int(self.config.get_img_resize_width())
217 if img.size[0] > newWidth:
219 newWidth = int(self.config.get_img_resize_width())
220 newHeight = int(newWidth * img.size[1] / img.size[0])
221 print "Resizing image:", str(newWidth), "*", str(newHeight)
223 # Image.BILINEAR, Image.BICUBIC, Image.ANTIALIASING
224 rimg = img.resize((newWidth, newHeight), Image.BILINEAR)
225 filename = filename.rpartition("/")
226 filename = filename[-1]
227 rattachment = self.config.get_imgdir() + filename
228 rimg.save(rattachment)
229 self.attachmentIsResized = True
232 rattachment = filename
237 print "resizing failed:", e, e.args
240 """ sends the message (no shit?) """
241 def send_mms(self, widget):
242 hildon.hildon_gtk_window_set_progress_indicator(self.window, 1)
243 # Disable send-button
244 self.bSend.set_sensitive(False)
245 self.force_ui_update()
247 self.osso_c = osso.Context("fMMS", "0.1.0", False)
249 attachment = self.bAttachment.get_label()
250 if attachment == "Attachment" or attachment == None:
252 self.attachmentIsResized = False
255 filetype = mimetypes.guess_type(attachment)[0]
256 print self.config.get_img_resize_width()
257 self.attachmentIsResized = False
258 print filetype.startswith("image")
259 if self.config.get_img_resize_width() != 0 and filetype.startswith("image"):
261 attachment = self.resize_img(attachment)
264 note = osso.SystemNote(self.osso_c)
266 note.system_note_dialog("Resizing failed:\nError: " + errmsg , 'notice')
269 to = self.eNumber.get_text()
270 sender = self.config.get_phonenumber()
271 tb = self.tvMessage.get_buffer()
272 message = tb.get_text(tb.get_start_iter(), tb.get_end_iter())
273 print sender, attachment, to, message
275 """ Construct and send the message, off you go! """
276 # TODO: remove hardcoded subject
278 sender = MMSSender(to, "MMS", message, attachment, sender)
279 (status, reason, output) = sender.sendMMS()
280 ### TODO: Clean up and make this look decent
281 message = str(status) + "_" + str(reason)
285 #note = osso.SystemNote(self.osso_c)
286 #ret = note.system_note_dialog("MMSC REPLIED:" + message + "\nBODY:" + reply, 'notice')
287 banner = hildon.hildon_banner_show_information(self.window, "", "MMSC REPLIED:" + message + "\nBODY: " + reply)
289 except TypeError, exc:
291 note = osso.SystemNote(self.osso_c)
292 errmsg = "Invalid attachment"
293 note.system_note_dialog("Sending failed:\nError: " + errmsg + " \nPlease make sure the file is valid" , 'notice')
295 except socket.error, exc:
297 code = str(exc.args[0])
298 text = str(exc.args[1])
299 note = osso.SystemNote(self.osso_c)
300 errmsg = code + " " + text
301 note.system_note_dialog("Sending failed:\nError: " + errmsg + " \nPlease make sure APN settings are correct" , 'notice')
303 except Exception, exc:
308 hildon.hildon_gtk_window_set_progress_indicator(self.window, 0)
309 self.bSend.set_sensitive(True)
311 if self.attachmentIsResized == True:
312 print "Removing temporary image..."
313 os.remove(attachment)
314 #self.window.destroy()
316 def update_size(self, fname):
318 size = os.path.getsize(fname) / 1024
319 self.lSize.set_markup("Size:\n<small>" + str(size) + "kB</small>")
321 self.lSize.set_markup("")
323 def quit(self, *args):
327 self.window.show_all()
330 if __name__ == "__main__":