コード例 #1
0
class AppList(CanvasVBox):
    __gsignals__ = {
        "selected" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),
        "launch" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        "more-info" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,))      
    }
    
    def __init__(self):
        super(AppList, self).__init__(padding=6)

        self.__table = OverviewTable(min_column_width=200, max_column_width=250)
        self.append(self.__table, hippo.PACK_EXPAND)

        self.__extras_section = AppExtras(self._filter_app, yalign=hippo.ALIGNMENT_END)
        self.__extras_section.connect("more-info", lambda e, app: self.emit("more-info", app))
        self.append(self.__extras_section)

        self.__repo = apps.get_apps_repo()

        self.__search = None
        self.__all_apps = set()
        self.__used_apps = set()
        self.__categorized = None
        self.__selected_app = None
        self.__selected_cat = None

        self.__repo.connect("local-apps-changed",
                            self.__on_apps_changed)
        self.__repo.connect("my-top-apps-changed",
                            self.__on_apps_changed)
        self.__repo.connect("global-top-apps-changed",
                            self.__on_apps_changed)
        self.__repo.connect("all-apps-loaded", 
                            lambda repo: self.__on_apps_changed(repo, []))        

        self.__on_apps_changed(self.__repo, [])

    ## whatever_apps is ignored, we pass junk for it usually, or whatever the signal
    ## provides
    def __on_apps_changed(self, repo, whatever_apps):
        self.__all_apps = self.__repo.get_all_apps()
        self.__used_apps = self.__repo.get_my_top_apps()
        self.__sync_display()

    @defer_idle_func(logger=_logger)
    def __sync_display(self):
        self.__table.remove_all()

        categories = categorize(filter(self.__filter_app_and_installed_or_used, self.__all_apps)) 

        # _logger.debug(str(categories))

        self.__categorized = categories
             
        cat_keys = categories.keys()
        cat_keys.sort()

        self.__extras_section.set_search_parameters(self.__selected_cat, self.__search)

        section_key = 0
        display_only_used = (len(self.__used_apps) > 0) and (not self.__selected_cat) and (not self.__search)
        for catname in (self.__selected_cat and not self.__search) and [self.__selected_cat] or cat_keys:
            cat_used_apps = filter(lambda app: app in self.__used_apps, categories[catname])
            cat_used_apps_count = len(cat_used_apps)
            if display_only_used:
                right_button = Button()
                right_button.set_label_text("More (%d)" % (len(categories[catname]) - cat_used_apps_count,))
                right_button.connect("activated", self.__handle_category_more, catname)
                left_link = None
            else:
                if self.__selected_cat:
                    left_link = ActionLink(text=u"All Applications /")
                    left_link.connect("activated", self.__handle_nocategory)
                    right_button = Button()
                    right_button.set_label_text("Back")
                    right_button.connect("activated", self.__handle_nocategory)
                else:
                    right_button = None
                    left_link = None
            self.__table.add_section_head(section_key, catname, left_control=left_link, right_control=right_button)
            if display_only_used:
                appsource = cat_used_apps
            else:
                appsource = categories[catname]
            for app in appsource:             
                overview = apps_widgets.AppDisplay(apps_widgets.AppLocation.APP_BROWSER, app)
                overview.connect("button-press-event", self.__on_overview_click) 
                self.__table.add_column_item(section_key, overview)
            section_key += 1

    def reset_category(self):
        self.__handle_nocategory(None)

    ## called when user chooses "all applications"
    def __handle_nocategory(self, l):
        _logger.debug("no category selected")
        self.__selected_cat = None
        self.__sync_display()

    ## called when user clicks a category filter
    def __handle_category_more(self, l, catname):
        _logger.debug("category %s selected", catname)
        self.__selected_cat = catname
        self.__sync_display()

    def __filter_app_and_installed_or_used(self, app):
        if not app.is_installed() and not app in self.__used_apps:
            return False
        return self._filter_app(app)
                
    def _filter_app(self, app):
        if not self.__search:
            return True
        search = self.__search.lower()
        keys = (app.get_name(), app.get_description(), app.get_generic_name(), app.get_tooltip())
        for key in keys:
            if key.lower().find(search) >= 0:
                return True
        return False
                
    def set_search(self, search):
        if search.strip() == "":
            self.__search = None
        else:
            self.__search = search.lower()

        self.__sync_display()
             
    def __on_overview_click(self, overview, event):
         _logger.debug("pressed %s %d", overview, event.count)
         
         if event.count == 1:
             if overview == self.__selected_app:
                 self.emit("launch")
                 return
             
             if self.__selected_app:
                 self.__selected_app.set_force_prelight(False)

             app = overview.get_app()
             self.__selected_app = overview
             self.__selected_app.set_force_prelight(True)
             self.emit("selected", app)
         elif event.count == 2:
             self.emit("launch")
コード例 #2
0
class FileBrowser(hippo.CanvasWindow):
    __gsignals__ = {
        "activated" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,))
    }
    def __init__(self, stock):
        super(FileBrowser, self).__init__(gtk.WINDOW_TOPLEVEL)
        
        self.__stock = stock
        self.__single_selected_item = None
        self.__multiple_items_visible = False    
        
        self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(65535,65535,65535))        

        self.set_title('Files')
        self.set_default_size(750, 600)
    
        self.__box = CanvasVBox(xalign=hippo.ALIGNMENT_FILL, yalign=hippo.ALIGNMENT_FILL)
        self.__box.set_property('background-color', 0xEEEEEEFF)

        browse_box = CanvasHBox(xalign=hippo.ALIGNMENT_START, yalign=hippo.ALIGNMENT_START, padding_top=4)
        self.__box.append(browse_box)

        browse_text = hippo.CanvasText(text="Browse:", font="Bold 12px", color=0x3F3F3FFF, padding_right=6, xalign=hippo.ALIGNMENT_START, yalign=hippo.ALIGNMENT_START)
        browse_box.append(browse_text)

        browse_options = CanvasVBox(xalign=hippo.ALIGNMENT_START, yalign=hippo.ALIGNMENT_START)
        browse_box.append(browse_options)

        local_files_link = ActionLink(text="Local Files", font="14px", padding_bottom=4, xalign=hippo.ALIGNMENT_START, yalign=hippo.ALIGNMENT_START)
        local_files_link.connect("activated", self.__on_browse_local_files_clicked)
        browse_options.append(local_files_link)
 
        for google_account in self.__stock.googles:
            # don't list invalid accounts we might have picked up from the signons file
            if google_account.get_current_auth_credentials_known_bad():
                continue  
            google_docs_link = ActionLink(text=google_account.get_account().get_username_as_google_email() + " Docs", font="14px", padding_bottom=4, xalign=hippo.ALIGNMENT_START, yalign=hippo.ALIGNMENT_START)
            google_docs_link.connect("activated", webbrowser.open, create_account_url(google_account.get_account().get_username_as_google_email()))
            browse_options.append(google_docs_link)

        self.__search_box = CanvasHBox(padding_top=4, padding_bottom=4)        
        self.__search_text = hippo.CanvasText(text="Search Recent Files:", font="Bold 12px",
                                              color=0x3F3F3FFF, xalign=hippo.ALIGNMENT_START, padding_right=4)
        self.__search_box.append(self.__search_text)
        self.__search_input = hippo.CanvasEntry(box_width=250)
        self.__search_input.connect("notify::text", self.__on_search_changed)
        self.__search_input.connect("key-press-event", self.__on_search_keypress)
        self.__idle_search_id = 0
        self.__search_box.append(self.__search_input)

        search_local_files_link = ActionLink(text="Search All Local Files", font="14px", padding_left=10)
        search_local_files_link.connect("activated", self.__on_search_local_files_clicked)
        self.__search_box.append(search_local_files_link)
        
        self.__box.append(self.__search_box)

        self.__section_head = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL, color=0xAAAAAAFF, border_bottom=1, border_color=0xAAAAAAFF)
        self.__section_head.append(hippo.CanvasText(text="Recent Files", font="Bold 14px", xalign=hippo.ALIGNMENT_START))
        self.__box.append(self.__section_head)

        self.__files_outter_box = CanvasVBox(background_color=0xFFFFFFFF)
        self.__box.append(self.__files_outter_box, hippo.PACK_EXPAND)

        self.__right_scroll = hippo.CanvasScrollbars()
        self.__right_scroll.set_policy(hippo.ORIENTATION_HORIZONTAL,
                                       hippo.SCROLLBAR_NEVER)
        self.__files_box = CanvasVBox(border=0, background_color=0xFFFFFFFF, padding=2)
        self.__files_outter_box.append(self.__right_scroll, hippo.PACK_EXPAND)
        
        self.__file_list = OverviewTable()
        self.__files_box.append(self.__file_list, hippo.PACK_EXPAND)

        self.__right_scroll.set_root(self.__files_box) 

        self.__file_items = []
        self.refresh_files()

        self.connect("delete-event", lambda *args: self.__hide() or True)
        self.connect("key-press-event", lambda win, event: self.__on_keypress(event))

        self.set_root(self.__box)

    def __set_visibility(self, item):
        search = self.__get_search_text()
        visible = search == None or item.link.get_property("text").lower().find(search) >= 0    
        item.set_force_prelight(False)      
        item.set_visible(visible)           
        if self.__single_selected_item is None and visible:
            self.__single_selected_item = item
        elif visible:
            self.__multiple_items_visible = True    

    def __prelight_single_selected_item(self): 
        if not self.__multiple_items_visible and self.__single_selected_item is not None:
            self.__single_selected_item.set_force_prelight(True)      

    def refresh_files(self):
        self.__single_selected_item = None
        self.__multiple_items_visible = False    

        self.__file_list.remove_all()
        self.__file_items = []
        for a_file in self.__stock.get_files():         
            if a_file.is_valid():                          
                link = a_file.create_icon_link()
                self.__file_list.add_column_item(0, link)
                self.__file_items.append(link)
                self.__set_visibility(link)

        self.__prelight_single_selected_item()

    def __on_search_changed(self, input, text):
        if self.__idle_search_id > 0:
            return
        self.__idle_search_id = gobject.timeout_add(500, self.__idle_do_search)
        
    def __on_search_keypress(self, entry, event):
        if event.key == hippo.KEY_RETURN:
            search = self.__get_search_text()
            # if there is only one file that matches the search, we'll open it
            # don't open the file if the search has changed, but we haven't updated the results yet
            if self.__single_selected_item is not None and (len(self.__stock.get_files()) == 1 or search is not None and self.__single_selected_item.link.get_property("text").lower().find(search) >= 0):
                self.__single_selected_item.link.emit("activated")

    def __get_search_text(self):
        search = self.__search_input.get_property("text")
        if search.strip() == "":
            return None
        else:
            return search.lower()

    def __idle_do_search(self):
        self.__single_selected_item = None
        self.__multiple_items_visible = False          

        for item in self.__file_items:
            self.__set_visibility(item)

        self.__prelight_single_selected_item()

        self.__idle_search_id = 0          

    def __on_browse_local_files_clicked(self, canvas_item):
        subprocess.Popen(['nautilus', '--browser', self.__stock.desktop_path])

    def __on_search_local_files_clicked(self, canvas_item):
        # we don't want to turn "" into None, or change everything to be lowercase
        search = self.__search_input.get_property("text")
        if not command_works(['beagle-search', search]):
            if not command_works(['tracker-search-tool', search]):
                subprocess.Popen(['gnome-search-tool', '--named', search])

    def __on_link_clicked(self, canvas_item, url):
        subprocess.Popen(['gnome-open', url])

    def __hide(self):
        self.hide()
        
    def __on_keypress(self, event):
        if event.keyval == 65307:
            self.__hide()