Permalink
Browse files

[core] add function to change DP

[Gtk] implement the DP chooser and the file chooser with preview for image files.
  • Loading branch information...
1 parent 10ac7bd commit 11b923b802ffdc03b3967dff3455893748d36e0b @luckyluke luckyluke committed Sep 15, 2009
View
@@ -242,18 +242,52 @@ def contactCB(account):
self._gui.gui.aMSNContactDeleteWindow('Contact to remove: ', contactCB, ())
+ def changeDP(self):
+ def set_dp(view):
+ path = view.imgs[0][1]
+ f = open(path)
+ dp_obj = papyon.p2p.MSNObject(self._account.client.profile,
+ os.path.getsize(path),
+ papyon.p2p.MSNObjectType.DISPLAY_PICTURE,
+ f.name, f.name, data=f)
+ self._account.client.msn_object_store.publish(dp_obj)
+ self._personalinfo_manager._personalinfoview.dp = dp_obj
+
+ def open_file():
+ def update_dplist(file_path):
+ # TODO: fire up a window to choose the dp size and a friendly name
+ # TODO: save the new image in a local cache
+ dp_view = ImageView('Filename', file_path)
+ dpwin.update_dp_list((dp_view, ))
+ filters = {'Image files':("*.png", "*.jpeg", "*.jpg", "*.gif", "*.bmp"),
+ 'All files':('*.*')}
+ directory = os.path.join("amsn2", "themes", "displaypic", "default")
+ self._gui.gui.aMSNFileChooserWindow(filters, directory, update_dplist)
+
+ def capture():
+ pass
+
+ default_dps = ('dp_amsn', 'dp_female', 'dp_male', 'dp_nopic')
+ user_dps = [ImageView('Filename', self._theme_manager.get_dp(dp)[1]) for dp in default_dps]
+ dpwin = self._gui.gui.aMSNDPChooserWindow(user_dps,
+ (('Capture', capture),
+ ('Open file', open_file)),
+ set_dp)
+
def createMainMenuView(self):
menu = MenuView()
- quitMenuItem = MenuItemView(MenuItemView.COMMAND, label="Quit", command
- = self.quit)
+ quitMenuItem = MenuItemView(MenuItemView.COMMAND, label="Quit",
+ command = self.quit)
logOutMenuItem = MenuItemView(MenuItemView.COMMAND, label="Log out",
command = self.signOutOfAccount)
mainMenu = MenuItemView(MenuItemView.CASCADE_MENU, label="Main")
mainMenu.addItem(logOutMenuItem)
mainMenu.addItem(quitMenuItem)
- addContactItem = MenuItemView(MenuItemView.COMMAND, label="Add Contact", command=self.addContact)
- removeContact = MenuItemView(MenuItemView.COMMAND, label='Remove contact', command=self.removeContact)
+ addContactItem = MenuItemView(MenuItemView.COMMAND, label="Add Contact",
+ command=self.addContact)
+ removeContact = MenuItemView(MenuItemView.COMMAND, label='Remove contact',
+ command=self.removeContact)
contactsMenu = MenuItemView(MenuItemView.CASCADE_MENU, label="Contacts")
contactsMenu.addItem(addContactItem)
@@ -55,9 +55,8 @@ def _onDPChangeRequest(self):
# TODO: tell the core to invoke a file chooser and change DP
pass
- def _onDPChanged(self, new_dp):
- # TODO: manage msn_objects
- self._papyon_profile.msn_object = new_dp
+ def _onDPChanged(self, dp_msnobj):
+ self._papyon_profile.msn_object = dp_msnobj
""" Actions from the core """
def _onCMChanged(self, new_media):
@@ -78,7 +77,8 @@ def onPSMUpdated(self, psm):
def onDPUpdated(self, dp):
self._personalinfoview._image.reset()
- self._personalinfoview._image.load(dp)
+ # TODO: use backend manager
+ #self._personalinfoview._image.load(dp)
self._em.emit(self._em.events.PERSONALINFO_UPDATED, self._personalinfoview)
def onPresenceUpdated(self, presence):
@@ -41,8 +41,8 @@ def fset(self, psm):
def dp():
def fget(self):
return self._image
- def fset(self, imagev):
- self._personalinfo_manager._onDPChanged(imagev)
+ def fset(self, dp_msnobj):
+ self._personalinfo_manager._onDPChanged(dp_msnobj)
return locals()
@rw_property
View
@@ -4,35 +4,52 @@ class aMSNFileChooserWindow(object):
This Interface represent a window used to choose a file,
which could be an image for the dp, a file to send, a theme file, etc.
"""
- def __init__(self, filter, directory):
+ def __init__(self, filters, directory, callback):
"""
- @type filter: tuple
- @param filter: A tuple containing strings, that will represent the file
- formats to filter.
+ @type filter: dict of tuple
+ @param filter: A dict whose keys are the names of the filters,
+ and the values are a tuple containing strings,
+ that will represent the patterns to filter.
@type directory: str
@param directory: The path to start from.
+ @type callback: function
+ @param callback: The function called when the file has been choosed.
+ Its prototype is callback(file_path)
This will eventually call the related show() method, so the window is
displayed when created.
"""
raise NotImplementedError
-class aMSNDPChooser(object):
+class aMSNDPChooserWindow(object):
"""
This Interface represent a window used to choose a display picture,
should show a list of default dps and the possibility to catch a picture from a webcam.
"""
- def __init__(self, default_dps, actions):
+ def __init__(self, default_dps, actions, callback):
"""
- @type default_dps: tuple
- @params default_dps: a tuple containing strings representing the paths of the default dps.
+ @type default_dps: list
+ @params default_dps: a list containing strings representing the paths of the default dps.
@type actions: tuple
@param actions: A tuple containing the options between
which the user can choose. Every option is a tuple itself, of the form (name, callback),
where callback is the function that will be called if the option is selected.
+ @type callback: function
+ @param callback: The function called when the dp has been choosed.
+ Its prototype is callback(dp_path)
This will eventually call the related show() method, so the window is
displayed when created.
"""
raise NotImplementedError
+ def update_dp_list(self, default_dps):
+ """
+ @type default_dps: tuple
+ @params default_dps: a tuple containing strings representing the paths of the default dps.
+
+ This function updated the list of the dps that can be chosen,
+ for example after opening a file or taking a picture.
+ """
+ raise NotImplementedError
+
@@ -1,39 +1,144 @@
from amsn2.gui import base
+import image
import gtk
class aMSNFileChooserWindow(base.aMSNFileChooserWindow, gtk.FileChooserDialog):
- def __init__(self, filter, directory):
- """
- @type filter: tuple
- @param filter: A tuple containing strings, that will represent the file
- formats to filter.
- @type directory: str
- @param directory: The path to start from.
-
- This will eventually call the related show() method, so the window is
- displayed when created.
- """
- raise NotImplementedError
-
-class aMSNDPChooser(base.aMSNDPChooser, gtk.Window):
- def __init__(self, default_dps, actions):
- """
- @type default_dps: tuple
- @params default_dps: a tuple containing strings representing the paths of the default dps.
- @type actions: tuple
- @param actions: A tuple containing the options between
- which the user can choose. Every option is a tuple itself, of the form (name, callback),
- where callback is the function that will be called if the option is selected.
-
- This will eventually call the related show() method, so the window is
- displayed when created.
- """
+ def __init__(self, filters, directory, callback):
+ gtk.FileChooserDialog.__init__(self, title='aMSN2 -Choose a file',
+ action=gtk.FILE_CHOOSER_ACTION_OPEN,
+ buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+
+ for name in filters.keys():
+ filefilter = gtk.FileFilter()
+ filefilter.set_name(name)
+ for ext in filters[name]:
+ filefilter.add_pattern(ext)
+ self.add_filter(filefilter)
+
+ toggle = gtk.CheckButton("Show hidden files")
+ toggle.show()
+ toggle.connect('toggled', lambda toggle: self.set_show_hidden(toggle.get_active()))
+ self.set_extra_widget(toggle)
+
+ self.preview = gtk.Image()
+ self.set_preview_widget(self.preview)
+ self.set_use_preview_label(False)
+
+ self.callback = callback
+ #self.set_size_request(500, 400)
+ self.set_current_folder_uri(directory)
+
+ self.connect('selection-changed', self.activatePreview)
+ self.connect('response', self.onResponse)
+
+ self.run()
+
+ def activatePreview(self, chooser):
+ filename = self.get_preview_filename()
+ if filename:
+ info = gtk.gdk.pixbuf_get_file_info(filename)
+ if info:
+ pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(filename, -1, 96)
+ self.preview.set_from_pixbuf(pixbuf)
+ self.set_preview_widget_active(True)
+ return
+
+ self.set_preview_widget_active(False)
+
+ def onResponse(self, chooser, id):
+ if id ==gtk.RESPONSE_OK:
+ self.callback(self.get_filename())
+ elif id == gtk.RESPONSE_CANCEL:
+ pass
+ self.destroy()
+
+
+class aMSNDPChooserWindow(base.aMSNDPChooserWindow, gtk.Window):
+ def __init__(self, default_dps, actions, callback):
gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
- self.child = None
self.showed = False
self.set_default_size(550, 450)
self.set_position(gtk.WIN_POS_CENTER)
self.set_title("aMSN - Choose a Display Picture")
+ self.callback = callback
+ self.view = None
+
+ self.child = None
+ self._setup_boxes(actions)
+ self.update_dp_list(default_dps)
+
self.show()
+ self.show_all()
+
+ def _setup_boxes(self, actions):
+ tscroll = gtk.ScrolledWindow()
+ tscroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ tscroll.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+ self.iconview = gtk.IconView()
+ self._model = gtk.ListStore(gtk.gdk.Pixbuf, object)
+ self.iconview.set_model(self._model)
+ self.iconview.set_pixbuf_column(0)
+ self.iconview.set_selection_mode(gtk.SELECTION_SINGLE)
+ self.iconview.connect("item-activated", self.__on_dp_dblclick)
+ self.iconview.connect("button-press-event", self.__on_dp_click)
+ tscroll.add(self.iconview)
+ dpsbox = gtk.VBox()
+ dpsbox.pack_start(tscroll)
+
+ buttonbox = gtk.VBox(False)
+ buttonbox.set_size_request(100, 450)
+ currentdp = gtk.Image()
+ buttonbox.pack_start(currentdp, False)
+ cancel_button = gtk.Button('Cancel', gtk.STOCK_CANCEL)
+ cancel_button.connect('clicked', lambda button: self.destroy())
+ ok_button = gtk.Button('Ok', gtk.STOCK_OK)
+ ok_button.connect('clicked', self._dp_chosen)
+ buttonbox.pack_start(ok_button, False)
+ buttonbox.pack_start(cancel_button, False)
+ for name, cb in actions:
+ button = gtk.Button(name)
+ def callback(cb):
+ return lambda button: cb()
+ button.connect('clicked', callback(cb))
+ buttonbox.pack_start(button, False)
+
+ hbox = gtk.HBox()
+ hbox.pack_start(dpsbox)
+ hbox.pack_start(buttonbox, False)
+ self.add(hbox)
+
+ def _dp_chosen(self, button):
+ self.callback(self.view)
+ self.destroy()
+
+ def __on_dp_dblclick(self, widget, path):
+ if path:
+ iter = self._model.get_iter(path)
+ self.view = self._model.get_value(iter, 1)
+ self._dp_chosen(None)
+ return True
+
+ else:
+ return False
+
+ def __on_dp_click(self, source, event):
+ if event.type == gtk.gdk.BUTTON_PRESS and event.button == 1:
+ treepath = self.iconview.get_path_at_pos(int(event.x), int(event.y))
+
+ if treepath:
+ iter = self._model.get_iter(treepath)
+ self.view = self._model.get_value(iter, 1)
+
+ # Let the double click callback be called
+ return False
+ else:
+ return False
+
+ def update_dp_list(self, default_dps):
+ for dp in default_dps:
+ im = image.Image(None, dp)
+ self._model.append((im.to_pixbuf(96, 96), dp))
+
@@ -237,26 +237,7 @@ def __switchFromInput(self, source, isNew):
parentWidget.set_relief(gtk.RELIEF_NONE) # remove cool elevated effect
def __onDisplayClicked(self, source):
- print "Display clicked!"
- chooser = gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_OPEN,
- buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
-
- chooser.set_default_response(gtk.RESPONSE_OK)
-
- filter = gtk.FileFilter()
- filter.set_name("All files")
- filter.add_pattern("*")
- chooser.add_filter(filter)
-
- response = chooser.run()
- if(response == gtk.RESPONSE_OK):
- pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(chooser.get_filename(), 64, 64)
- self.display.set_from_pixbuf(pixbuf)
- del pixbuf
- gc.collect()
- elif (response == gtk.RESPONSE_CANCEL):
- pass
- chooser.destroy()
+ self._amsn_core.changeDP()
def show(self):
pass
Oops, something went wrong.

0 comments on commit 11b923b

Please sign in to comment.