Пример #1
0
 def __init__(self, metainfo, env, pymodule=None, is_notitle=False, panel=None):
     hippo.CanvasBox.__init__(self,  
                              orientation=hippo.ORIENTATION_VERTICAL,
                              spacing=4)
     self.__size = None
     self.__metainfo = metainfo
     self.__env = env
     self.__pymodule = pymodule
     self.__panel = panel
     self.__ticker_text = None
     self.__ticker_container = None
     self.__mini_more_button = None
     self.__sep = Separator()
     self.append(self.__sep)
     self.__expanded = True
     if not is_notitle:
         self.__ticker_container = Header()
         self.__ticker_text = ThemedText(theme_hints=['header'], text=metainfo.title, font="14px Bold", xalign=hippo.ALIGNMENT_START)
         self.__ticker_text.connect("button-press-event", lambda text, event: self.__toggle_expanded())  
         self.__ticker_container.append(self.__ticker_text, hippo.PACK_EXPAND)
         
         if pymodule and pymodule.has_more_button():
             more_button = HeaderButton()
             more_button.connect("activated", lambda l: pymodule.on_more_clicked())
             self.__ticker_container.append(more_button)
         
         self.append(self.__ticker_container)
     self.__stockbox = hippo.CanvasBox()
     self.append(self.__stockbox)
     if pymodule:
         pymodule.connect('visible', self.__render_pymodule)
         self.__render_pymodule()
     else:
         self.__render_google_gadget()    
Пример #2
0
 def __init__(self, ga):
     super(LabelSlideout, self).__init__()
     vbox = CanvasVBox(border_color=0x0000000ff, spacing=4)
     self.get_root().append(vbox)
     header = Header(topborder=False)
     account_text = ThemedText(theme_hints=['header'], text=ga.name, font="14px Bold")
     header.append(account_text, hippo.PACK_EXPAND)        
     vbox.append(header)
     folderCounts = ga.getFolderCounts()
     folderCounts["unread"] = ga.getUnreadMsgCount()
     for label, number in folderCounts.iteritems():
         box = PrelightingCanvasBox()
         box.connect('button-release-event', self.on_button_release_event, label)
         vbox.append(box)
         hbox = CanvasHBox(spacing=4, padding=4)
         text= hippo.CanvasText(text=label, xalign=hippo.ALIGNMENT_START)
         hbox.append(text)
         text= hippo.CanvasText(text=number, xalign=hippo.ALIGNMENT_START)
         hbox.append(text, flags=hippo.PACK_END)
         box.append(hbox)
Пример #3
0
class EmailSlideout(ThemedSlideout):
    def __init__(self, thread):
        super(EmailSlideout, self).__init__()
        vbox = CanvasVBox(border_color=0x0000000ff, spacing=4)
        self.get_root().append(vbox)
        self.__header = Header(topborder=False)
        
        subject = remove_strange_tags(thread.subject)
        
        subject_box = ThemedText(theme_hints=['header'], text=subject, font="14px Bold")
        self.__header.append(subject_box, hippo.PACK_EXPAND)
        vbox.append(self.__header)
        
        for key in ("date", "categories", "snippet"):
            value = getattr(thread, key, None)
            if value:
                if type(value) is list:
                    s = ", ".join(value)
                if type(value) is str:
                    s = remove_strange_tags(value)
                
                s = convert_entities(s)
                box = hippo.CanvasText(text=s, xalign=hippo.ALIGNMENT_START)
                vbox.append(box)
Пример #4
0
    def __init__(self, bus_name):
        dbus.service.Object.__init__(self, bus_name, '/bigboard/panel')
          
        _logger.info("constructing")
                
        self.__popped_out = False
        self.__shell = None
        
        gconf_client = gconf.client_get_default()
        self._dw = Sidebar(GCONF_PREFIX + 'visible')
        gconf_client.notify_add(GCONF_PREFIX + 'orientation', self.__sync_orient)        
        self.__sync_orient()            

        self.__keybinding = gconf_client.get_string('/apps/bigboard/focus_key')
        if self.__keybinding:
            bigboard.keybinder.tomboy_keybinder_bind(self.__keybinding, self.__on_focus)
    
        self.__autohide_id = 0
        
        self._exchanges = {} ## metainfo.srcurl to Exchange

        self._canvas = canvas = hippo.Canvas()
        self._dw.get_content().add(self._canvas)
        cwin = self._dw
        self.__compositing = gtk.gdk.display_get_default().supports_composite()
        _logger.debug("compositing: %s", self.__compositing)
#            screen = cwin.get_screen()
#            rgba = screen.get_rgba_colormap()
#            cwin.set_colormap(rgba)
#            cwin.set_app_paintable(True)
#            def fitty_opacity(w, e):
#                ctx = w.window.cairo_create()
#                ctx.set_source_pixmap(canvas.window, canvas.allocation.x, canvas.allocation.y)
#                region = gtk.gdk.region_rectangle(canvas.allocation)
#                region.intersect(gtk.gdk.region_rectangle(e.area))
#                print >>sys.stderr, "e: %s" % (region,)            
#                ctx.region(region)
#                ctx.clip()
#            
#                ctx.set_operator(cairo.OPERATOR_OVER)
#                ctx.paint_with_alpha(0.5)
#            cwin.connect_after('expose-event', fitty_opacity)
#            cwin.realize()
#            cwin.window.set_composited(True)
        
        self._main_box = hippo.CanvasBox(border_right=1, border_color=0x999999FF, padding_bottom=4)
        self._canvas.set_root(self._main_box)
     
        self._header_box = Header()
        self._header_box.connect("button-press-event", self.__on_header_buttonpress)             

        self.__unpopout_button = Button(label='Hide', label_ypadding=-2)
        self.__unpopout_button.set_property('yalign', hippo.ALIGNMENT_CENTER)
        self.__unpopout_button.connect("activated", lambda button: self.__do_unpopout())
        self._header_box.append(self.__unpopout_button, hippo.PACK_END)
     
        self._title = ThemedText(text="My Desktop", font="Bold 14px", xalign=hippo.ALIGNMENT_START, padding_left=8)
     
        self._header_box.append(self._title, hippo.PACK_EXPAND)
        
        self._size_button = None
        
        self._main_box.append(self._header_box)
        
        self._stocks_box = hippo.CanvasBox(spacing=4)
        
        self._main_box.append(self._stocks_box)
        
        self.__theme_mgr = ThemeManager.getInstance()
        self.__theme_mgr.connect('theme-changed', self.__sync_theme)
        self.__sync_theme()    
  
        gconf_client.notify_add(GCONF_PREFIX + 'expand', self._sync_size)
        self._sync_size()
        
        try:
            self.__screensaver_proxy = dbus.SessionBus().get_object('org.gnome.ScreenSaver', '/org/gnome/ScreenSaver')
            self.__screensaver_proxy.connect_to_signal('SessionIdleChanged',
                                                       self.__on_session_idle_changed)
        except dbus.DBusException, e:
            _logger.warn("Couldn't find screensaver")
            pass
Пример #5
0
class Exchange(hippo.CanvasBox, ThemedWidgetMixin):
    """A renderer for stocks."""
    
    def __init__(self, metainfo, env, pymodule=None, is_notitle=False, panel=None):
        hippo.CanvasBox.__init__(self,  
                                 orientation=hippo.ORIENTATION_VERTICAL,
                                 spacing=4)
        self.__size = None
        self.__metainfo = metainfo
        self.__env = env
        self.__pymodule = pymodule
        self.__panel = panel
        self.__ticker_text = None
        self.__ticker_container = None
        self.__mini_more_button = None
        self.__sep = Separator()
        self.append(self.__sep)
        self.__expanded = True
        if not is_notitle:
            self.__ticker_container = Header()
            self.__ticker_text = ThemedText(theme_hints=['header'], text=metainfo.title, font="14px Bold", xalign=hippo.ALIGNMENT_START)
            self.__ticker_text.connect("button-press-event", lambda text, event: self.__toggle_expanded())  
            self.__ticker_container.append(self.__ticker_text, hippo.PACK_EXPAND)
            
            if pymodule and pymodule.has_more_button():
                more_button = HeaderButton()
                more_button.connect("activated", lambda l: pymodule.on_more_clicked())
                self.__ticker_container.append(more_button)
            
            self.append(self.__ticker_container)
        self.__stockbox = hippo.CanvasBox()
        self.append(self.__stockbox)
        if pymodule:
            pymodule.connect('visible', self.__render_pymodule)
            self.__render_pymodule()
        else:
            self.__render_google_gadget()    

    def on_delisted(self):
        _logger.debug("on_delisted exchange %s" % (str(self)))
        self.__unrender_pymodule()

    def on_popped_out_changed(self, popped_out):
        self.__pymodule.on_popped_out_changed(popped_out)
    
    def __toggle_expanded(self):
        self.__expanded = not self.__expanded
        self.set_child_visible(self.__stockbox, self.__expanded)
    
    def get_metainfo(self):
        return self.__metainfo
    
    def get_pymodule(self):
        return self.__pymodule
    
    def __render_google_gadget(self):
        rendered = GoogleGadgetContainer(self.__metainfo, self.__env)
        self.__stockbox.append(rendered)
    
    def __render_pymodule(self, *args):
        self.__size = size = Stock.SIZE_BULL
        self.__stockbox.remove_all()
        self.__pymodule.set_size(size)
        content = self.__pymodule.get_content(size) 
        if self.__ticker_container:
            self.set_child_visible(self.__ticker_container, not not content)
        self.set_child_visible(self.__sep,
                               (not not content) and \
                               ((self.__ticker_container and size == Stock.SIZE_BEAR) \
                                or (size == Stock.SIZE_BULL
                                    and ((not self.__ticker_container) or (self.__pymodule.get_ticker() == "-")))))
        if self.__mini_more_button:
            self.set_child_visible(self.__mini_more_button, size == Stock.SIZE_BEAR)
        self.set_child_visible(self.__stockbox, not not content)
        if not content:
            _logger.debug("no content for stock %s", self.__pymodule)
            return
        self.__stockbox.append(content)
        padding = 4
        self.__stockbox.set_property("padding_left", padding)
        self.__stockbox.set_property("padding_right", padding)
        if self.__ticker_text:
            self.set_child_visible(self.__ticker_container, size == Stock.SIZE_BULL)

    def __unrender_pymodule(self):
        if not self.__pymodule:
            _logger.debug("Not a pymodule exchange")
            return

        _logger.debug("delisting pymodule %s" % (str(self.__pymodule)))
        self.__pymodule.on_delisted()
        self.__pymodule = None
Пример #6
0
    def __init__(self, fobj):
        super(FileSlideout, self).__init__()
        vbox = CanvasVBox(border_color=0x0000000ff, spacing=4)
        self.get_root().append(vbox)
        self.__header = Header(topborder=False)
        text = ThemedText(theme_hints=['header'], text=fobj.get_name(), font="14px Bold", xalign=hippo.ALIGNMENT_START)
        self.__header.append(text, hippo.PACK_EXPAND)        
        vbox.append(self.__header)
        
        hbox = CanvasHBox(spacing=4, padding=4)
        img = hippo.CanvasImage(scale_width=60, scale_height=60, xalign=hippo.ALIGNMENT_START, yalign=hippo.ALIGNMENT_START)
        img.set_property('image-name', fobj.get_image_name())
        hbox.append(img)
        vbox.append(hbox)
        
        detailvbox = CanvasVBox(spacing=3)
        hbox.append(detailvbox) 
        mime = fobj.get_mimetype()
        if mime:
            mimename = gnomevfs.mime_get_description(mime)
            text = ThemedText(theme_hints=['subforeground'], text=mimename, font='12px', xalign=hippo.ALIGNMENT_START)                  
            detailvbox.append(text)
        size = fobj.get_size()            
        if size is not None:
            sizestr = format_file_size(size)
            text = ThemedText(theme_hints=['subforeground'], text=sizestr, font='12px', xalign=hippo.ALIGNMENT_START)             
            detailvbox.append(text)
        fname = os.path.dirname(fobj.get_full_name())
        if fname.startswith('file://'):
            fname = fname[7:]
        home = os.path.expanduser('~')
        if fname.startswith(home):
            fname = fname[:len(home)]
        fname = urllib.unquote(fname)            
        text = ThemedText(theme_hints=['subforeground'], text=fname, font='12px', xalign=hippo.ALIGNMENT_START)          
        detailvbox.append(text)
        apps = gnomevfs.mime_get_all_applications(mime)
        if apps:
            text = ThemedText(text='Open With: ', font='14px')
            detailvbox.append(text)
            def on_app_clicked(button, app):
                self.emit('close', True)
                _logger.debug("launching app %s", app)
                _launch_vfsmimeapp(app, fobj.get_url())      
            directory = apps_directory.get_app_directory()
            for app in apps:
                _logger.debug("mime type: %s got app %s", mime, app)
                button = hippo.CanvasButton()
                labelhbox = gtk.HBox()
                labelhbox.set_border_width(1)
                labelhbox.set_spacing(2)
                
                try:
                    menu = directory.lookup(app[0])
                except KeyError, e:
                    _logger.debug("failed to find desktop file %s", app[0])
                    menu = None

                img = gtk.Image()
                    
                if menu:
                    pixbuf = get_menu_pixbuf(menu, size=16)
                    img.set_from_pixbuf(pixbuf)
                else:
                    img.set_size_request(16, 16)

                labelhbox.pack_start(img, False, False)
                
                textlabel = gtk.Label(app[1])
                labelhbox.pack_start(textlabel, False)
                labelhbox.show_all()

                button.get_property('widget').add(labelhbox)
                button.get_property('widget').connect('clicked', on_app_clicked, app)
                button.get_property('widget').set_name('bigboard-nopad-button')
                detailvbox.append(button)
Пример #7
0
    def __init__(self, person, themed=False, **kwargs):
        kwargs['orientation'] = hippo.ORIENTATION_VERTICAL
        hippo.CanvasBox.__init__(self, **kwargs)
        self.person = person

        self.__themed = themed
        if themed:
            self.__header = Header(topborder=False)
        else:
            self.__header = hippo.CanvasGradient(orientation=hippo.ORIENTATION_HORIZONTAL,
                                                 start_color=0xf2f2f2f2,
                                                 end_color=0xc8c8c8ff)            

        self.append(self.__header)
        
        textklass = themed and ThemedText or hippo.CanvasText
        linkklass = themed and ThemedLink or ActionLink

        name_vbox = hippo.CanvasBox(padding=6)
        self.__name = textklass(font="22px")
        name_vbox.append(self.__name)
        rename_link = linkklass(text='rename', font="10px", xalign=hippo.ALIGNMENT_END)
        name_vbox.append(rename_link)

        rename_link.connect('activated', self.__on_rename_activated)

        self.__header.append(name_vbox)

        if person.is_contact:
            try:
                user = person.resource.user
            except AttributeError:
                user = None
            if user:
                mugshot_link = linkklass(text="Mugshot", padding=6)
                self.__header.append(mugshot_link, flags=hippo.PACK_END)
                mugshot_link.connect("activated", self.__on_activate_web)

        self.__top_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL)
        self.append(self.__top_box)

        self.__photo = CanvasMugshotURLImage(scale_width=60,
                                            scale_height=60,
                                            border=5)

        if person.is_contact:
            try:
                user = person.resource.user
            except AttributeError:
                user = None
            if user:
                self.__photo.set_clickable(True)
                self.__photo.connect("activated", self.__on_activate_web)

        self.__top_box.append(self.__photo)

        self.__address_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL)
        self.__top_box.append(self.__address_box)

        self.__contact_status_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
                                                    spacing=4, border=4)
        self.append(self.__contact_status_box)

        if person.is_contact:
            self.__add_link = None
            self.__remove_link = linkklass()
            self.__remove_link.connect('activated', self.__remove_from_network_clicked)
            self.append(self.__remove_link)
        else:
            self.__remove_link = None
            self.__add_link = linkklass(text=('Add %s to network' % self.person.display_name))
            self.__add_link.connect('activated', self.__add_to_network_clicked)
            self.append(self.__add_link)
        
#        self.__online = hippo.CanvasText(text='Offline')
#        self.append(self.__online)

        separator = hippo.CanvasBox(box_height=1, background_color=0xAAAAAAFF)
        self.append(separator)

        self.__ribbon_bar = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
                                           spacing=2, border=4)
        self.append(self.__ribbon_bar)

        self.__link_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
                                          spacing=2, border=4)
        self.append(self.__link_box)
        
        self.__local_files_link = None

        self.person.connect('display-name-changed', self.__update)
        self.person.connect('icon-url-changed', self.__update)
        self.person.connect('aim-changed', self.__update)
        self.person.connect('local-buddy-changed', self.__update_local_buddy)
        self.person.connect('xmpp-changed', self.__update)
        if person.is_contact:
            self.person.resource.connect(lambda *args: self.__update(self.person), 'emails')
            self.person.resource.connect(self.__update_contact_status, "status")
            try:
                user = person.resource.user
            except AttributeError:
                user = None
            
            if user:
                user.connect(self.__update_loved_accounts, "lovedAccounts")
        
        query = DataModel(bigboard.globals.server_name).query_resource(self.person.resource, "lovedAccounts +")
        query.add_handler(self.__update_loved_accounts)
        query.execute()

        self.__update(self.person)
        self.__update_local_buddy(self.person)
        
        if self.person.is_contact:
            self.__update_contact_status(self.person.resource)

            try:
                user = person.resource.user
            except AttributeError:
                user = None
            
            if user:
                self.__update_loved_accounts(user)
Пример #8
0
class ProfileItem(hippo.CanvasBox):
    __gsignals__ = {
        "close": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (bool,))
       }
        
    def __init__(self, person, themed=False, **kwargs):
        kwargs['orientation'] = hippo.ORIENTATION_VERTICAL
        hippo.CanvasBox.__init__(self, **kwargs)
        self.person = person

        self.__themed = themed
        if themed:
            self.__header = Header(topborder=False)
        else:
            self.__header = hippo.CanvasGradient(orientation=hippo.ORIENTATION_HORIZONTAL,
                                                 start_color=0xf2f2f2f2,
                                                 end_color=0xc8c8c8ff)            

        self.append(self.__header)
        
        textklass = themed and ThemedText or hippo.CanvasText
        linkklass = themed and ThemedLink or ActionLink

        name_vbox = hippo.CanvasBox(padding=6)
        self.__name = textklass(font="22px")
        name_vbox.append(self.__name)
        rename_link = linkklass(text='rename', font="10px", xalign=hippo.ALIGNMENT_END)
        name_vbox.append(rename_link)

        rename_link.connect('activated', self.__on_rename_activated)

        self.__header.append(name_vbox)

        if person.is_contact:
            try:
                user = person.resource.user
            except AttributeError:
                user = None
            if user:
                mugshot_link = linkklass(text="Mugshot", padding=6)
                self.__header.append(mugshot_link, flags=hippo.PACK_END)
                mugshot_link.connect("activated", self.__on_activate_web)

        self.__top_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL)
        self.append(self.__top_box)

        self.__photo = CanvasMugshotURLImage(scale_width=60,
                                            scale_height=60,
                                            border=5)

        if person.is_contact:
            try:
                user = person.resource.user
            except AttributeError:
                user = None
            if user:
                self.__photo.set_clickable(True)
                self.__photo.connect("activated", self.__on_activate_web)

        self.__top_box.append(self.__photo)

        self.__address_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL)
        self.__top_box.append(self.__address_box)

        self.__contact_status_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
                                                    spacing=4, border=4)
        self.append(self.__contact_status_box)

        if person.is_contact:
            self.__add_link = None
            self.__remove_link = linkklass()
            self.__remove_link.connect('activated', self.__remove_from_network_clicked)
            self.append(self.__remove_link)
        else:
            self.__remove_link = None
            self.__add_link = linkklass(text=('Add %s to network' % self.person.display_name))
            self.__add_link.connect('activated', self.__add_to_network_clicked)
            self.append(self.__add_link)
        
#        self.__online = hippo.CanvasText(text='Offline')
#        self.append(self.__online)

        separator = hippo.CanvasBox(box_height=1, background_color=0xAAAAAAFF)
        self.append(separator)

        self.__ribbon_bar = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
                                           spacing=2, border=4)
        self.append(self.__ribbon_bar)

        self.__link_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
                                          spacing=2, border=4)
        self.append(self.__link_box)
        
        self.__local_files_link = None

        self.person.connect('display-name-changed', self.__update)
        self.person.connect('icon-url-changed', self.__update)
        self.person.connect('aim-changed', self.__update)
        self.person.connect('local-buddy-changed', self.__update_local_buddy)
        self.person.connect('xmpp-changed', self.__update)
        if person.is_contact:
            self.person.resource.connect(lambda *args: self.__update(self.person), 'emails')
            self.person.resource.connect(self.__update_contact_status, "status")
            try:
                user = person.resource.user
            except AttributeError:
                user = None
            
            if user:
                user.connect(self.__update_loved_accounts, "lovedAccounts")
        
        query = DataModel(bigboard.globals.server_name).query_resource(self.person.resource, "lovedAccounts +")
        query.add_handler(self.__update_loved_accounts)
        query.execute()

        self.__update(self.person)
        self.__update_local_buddy(self.person)
        
        if self.person.is_contact:
            self.__update_contact_status(self.person.resource)

            try:
                user = person.resource.user
            except AttributeError:
                user = None
            
            if user:
                self.__update_loved_accounts(user)

    def __add_status_link(self, text, current_status, new_status):
        textklass = self.__themed and ThemedText or hippo.CanvasText        
        linkklass = self.__themed and ThemedLink or ActionLink        
        if current_status == new_status:
            link = textklass(text=text)
        else:
            def set_new_status(object):
                model = globals.get_data_model()
                query = model.update(("http://mugshot.org/p/contacts", "setContactStatus"),
                                     contact=self.person.resource,
                                     status=new_status)
                query.execute()
        
            link = linkklass(text=text)
            link.connect("activated", set_new_status)
        
        self.__contact_status_box.append(link)

    def __remove_from_network_clicked(self, link):

        dialog = gtk.MessageDialog(type=gtk.MESSAGE_QUESTION)
        dialog.set_markup("<b>Remove %s from your network?</b>" % (self.person.display_name))
        dialog.format_secondary_text("This will delete %s's contact information and remove %s from your sidebar" % (self.person.display_name, self.person.display_name))
        dialog.add_buttons("Cancel", gtk.RESPONSE_CANCEL, "Remove", gtk.RESPONSE_ACCEPT)

        def remove_from_network_response(dialog, response_id, person):
            dialog.destroy()

            if response_id == gtk.RESPONSE_ACCEPT:
                _logger.debug("removing from network")

                model = globals.get_data_model()
                query = model.update(("http://mugshot.org/p/contacts", "deleteContact"),
                                     contact=person.resource)
                query.execute()

            else:
                _logger.debug("not removing from network")

        dialog.connect("response", lambda dialog, response_id: remove_from_network_response(dialog, response_id, self.person))                

        # action_taken = False to leave the stock open which seems nicer in this case
        self.emit("close", False)

        dialog.show()

    def __on_rename_activated(self, link):
        dialog = gtk.Dialog(title="Rename a contact")
        
        entry = gtk.Entry()
        entry.set_text(self.person.display_name)
        entry.set_activates_default(True)

        hbox = gtk.HBox(spacing=10)
        hbox.pack_start(gtk.Label('Name:'), False, False)
        hbox.pack_end(entry, True, True)
        
        hbox.show_all()

        dialog.vbox.pack_start(hbox)

        dialog.add_buttons("Cancel", gtk.RESPONSE_CANCEL, "Rename", gtk.RESPONSE_ACCEPT)
        dialog.set_default_response(gtk.RESPONSE_ACCEPT)

        def rename_response(dialog, response_id, person):
            dialog.destroy()

            if response_id == gtk.RESPONSE_ACCEPT:
                _logger.debug("renaming this person")

                name = entry.get_text()

                model = globals.get_data_model()
                query = model.update(("http://mugshot.org/p/contacts", "setContactName"),
                                     contact=person.resource, name=name)
                query.execute()

            else:
                _logger.debug("not renaming")

        dialog.connect("response", lambda dialog, response_id: rename_response(dialog, response_id, self.person))                

        # action_taken = False to leave the stock open which seems nicer in this case
        self.emit("close", False)

        dialog.show()

    def __create_contact(self, addressType, address):
        _logger.debug("creating contact %s %s" % (addressType, address))
        
        model = globals.get_data_model()
        query = model.update(("http://mugshot.org/p/contacts", "createContact"),
                             addressType=addressType,
                             address=address)
        query.execute()

    def __create_user_contact(self, user_resource):
        _logger.debug("creating contact %s" % (str(user_resource)))
        
        model = globals.get_data_model()
        query = model.update(("http://mugshot.org/p/contacts", "createUserContact"),
                             user=user_resource);
        query.execute()

    def __add_to_network_clicked(self, link):
        if self.person.aim:
            self.__create_contact('aim', self.person.aim)
        elif self.person.xmpp:
            self.__create_contact('xmpp', self.person.xmpp)
        elif self.person.local_buddy:
            self.__create_user_contact(self.person.local_buddy.user)

        # action_taken = False to leave the stock open which seems nicer in this case
        self.emit("close", False)

    def __update_contact_status(self, person):
        self.__contact_status_box.remove_all()
        try:
            status = self.person.resource.status
        except AttributeError:
            status = 0

        if status == 0:
            status = 3 

        textklass = self.__themed and ThemedText or hippo.CanvasText
        self.__contact_status_box.append(textklass(text="In sidebar: "))
        
        self.__add_status_link("Top", status, 4)
        self.__add_status_link("Middle", status, 3)
        self.__add_status_link("Bottom", status, 2)

    def __update_loved_accounts(self, person):
        try:
            accounts = self.person.resource.lovedAccounts
        except AttributeError:
            accounts = []
        
        self.__ribbon_bar.clear()
        for a in accounts:
            icon = ExternalAccountIcon(a)
            self.__ribbon_bar.append(icon)

    def __update_local_buddy(self, person):
        if self.__local_files_link:
            self.__local_files_link.destroy()
            self.__local_files_link = None

        try:
            buddy = person.local_buddy
        except AttributeError:
            return

        if buddy != None:
            self.__local_files_link = LocalFilesLink(buddy)
            self.__link_box.append(self.__local_files_link)

    def __update(self, person):
        textklass = self.__themed and ThemedText or hippo.CanvasText
        linkklass = self.__themed and ThemedLink or ActionLink
                
        self.__name.set_property('text', self.person.display_name)
        self.__photo.set_url(self.person.icon_url)

        self.__address_box.remove_all()

        if self.__remove_link:
            self.__remove_link.set_property('text', 
                                            "Remove %s from network" % self.person.display_name)

        emails = None
        if person.is_contact:
            try:
                emails = self.person.resource.emails
            except AttributeError:
                pass
         
        if emails != None and len(emails) > 0:
            email = linkklass(text=emails[0], xalign=hippo.ALIGNMENT_START)
            email.connect('activated', self.__on_activate_email)
            self.__address_box.append(email)

        if person.aim != None:
            aim = linkklass(text=person.aim, xalign=hippo.ALIGNMENT_START)
            aim.connect('activated', self.__on_activate_aim)
            self.__address_box.append(aim)

        if person.xmpp != None:
            xmpp = linkklass(text=person.aim, xalign=hippo.ALIGNMENT_START)
            xmpp.connect('activated', self.__on_activate_xmpp)
            self.__address_box.append(xmpp)

        add = linkklass(text='add address', xalign=hippo.ALIGNMENT_END, font_scale=0.8)
        add.connect('activated', self.__on_activate_add_address)
        self.__address_box.append(add)

    def __on_activate_web(self, canvas_item):
        self.emit("close", True)
        libbig.show_url(self.person.resource.user.homeUrl)

    def __on_activate_email(self, canvas_item):
        self.emit("close", True)
        # email should probably cgi.escape except it breaks if you escape the @
        os.spawnlp(os.P_NOWAIT, 'gnome-open', 'gnome-open', 'mailto:' + self.person.resource.email)

    def __on_activate_aim(self, canvas_item):
        self.emit("close", True)
        _open_aim(self.person.aim)
        
    def __on_activate_xmpp(self, canvas_item):
        self.emit("close", True)
        _open_xmpp(self.person.xmpp)

    def __on_activate_add_address(self, canvas_item):
        dialog = gtk.Dialog(title=("Add an address for %s" % self.person.display_name))
        
        entry = gtk.Entry()
        entry.set_activates_default(True)

        hbox = gtk.HBox(spacing=10)
        hbox.pack_start(gtk.Label('Address:'), False, False)
        hbox.pack_end(entry, True, True)
        
        hbox.show_all()

        dialog.vbox.pack_start(hbox)

        type_combo = gtk.combo_box_new_text()
        type_combo.append_text('AIM')
        type_combo.append_text('Email')
        type_combo.append_text('GTalk/XMPP')
        type_combo.set_active(0)

        hbox = gtk.HBox(spacing=10)
        hbox.pack_start(gtk.Label('Type:'), False, False)
        hbox.pack_end(type_combo, True, True)
        
        hbox.show_all()

        dialog.vbox.pack_start(hbox)

        dialog.add_buttons("Cancel", gtk.RESPONSE_CANCEL, "Add", gtk.RESPONSE_ACCEPT)
        dialog.set_default_response(gtk.RESPONSE_ACCEPT)


        def combo_get_address_type(combo):
            visible_type = type_combo.get_active_text()
            addressType = None
            if visible_type == 'Email':
                addressType = 'email'
            elif visible_type == 'AIM':
                addressType = 'aim'
            elif visible_type == 'GTalk/XMPP':
                addressType = xmpp
            else:
                _logger.warn('Bug: unknown combox box text for address type')
                if '@' in entry.get_text():
                    addressType = 'email'
                else:
                    addressType = 'aim'

            return addressType

        def address_entry_changed(entry):
            address = entry.get_text()
            type = combo_get_address_type(type_combo)
            
            if '@' in address and type == 'aim':
                type_combo.set_active(1) ## set to email if an @ is typed
            elif '@' not in address and type == 'email':
                type_combo.set_active(0) ## set to AIM if no @ is found

            ## remember that @ can mean either email or xmpp

        entry.connect('changed', address_entry_changed)

        def add_address_response(dialog, response_id, person):
            dialog.destroy()

            if response_id == gtk.RESPONSE_ACCEPT:
                _logger.debug("adding address for this person")

                address = entry.get_text()
                addressType = combo_get_address_type(type_combo)

                model = globals.get_data_model()
                query = model.update(("http://mugshot.org/p/contacts", "addContactAddress"),
                                     contact=person.resource, addressType=addressType, address=address)
                query.execute()

            else:
                _logger.debug("not adding_address")

        dialog.connect("response", lambda dialog, response_id: add_address_response(dialog, response_id, self.person))

        # action_taken = False to leave the stock open which seems nicer in this case
        self.emit("close", False)

        dialog.show()