class SearchPage(gtk.VBox): ''' class docs ''' def __init__(self, data_manager): ''' init docs ''' # Init. gtk.VBox.__init__(self) self.data_manager = data_manager self.keywords = [] self.all_pkg_names = [] self.message_bar = MessageBar(18) self.content_box = gtk.VBox() self.treeview = TreeView(enable_drag_drop=False, expand_column=0) self.cute_message_image = gtk.VBox() self.cute_message_pixbuf = utils.get_common_locale_image_pixbuf("info", "noresult.png") self.cute_message_image.connect("expose-event", self.expose_cute_message_image) self.content_box.pack_start(self.message_bar, False, False) self.content_box.pack_start(self.treeview) self.loading_box = LoadingBox() self.pack_start(self.loading_box, True, True) self.treeview.connect("items-change", self.update_message_bar) self.treeview.draw_mask = self.draw_mask def expose_cute_message_image(self, widget, event): if self.cute_message_pixbuf: cr = widget.window.cairo_create() rect = widget.allocation cr.set_source_rgba(1, 1, 1, 0) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.fill() draw_pixbuf( cr, self.cute_message_pixbuf, rect.x + (rect.width - self.cute_message_pixbuf.get_width()) / 2, rect.y + (rect.height - self.cute_message_pixbuf.get_height()) / 2, ) def update_message_bar(self, treeview): if len(treeview.visible_items) > 0: self.message_bar.set_message(_("%s: %s matched applications") % (' '.join(self.keywords), len(self.all_pkg_names))) container_remove_all(self) self.pack_start(self.content_box) global_event.emit("update-current-status-pkg-page", treeview) else: container_remove_all(self) self.pack_start(self.cute_message_image) def draw_mask(self, cr, x, y, w, h): ''' Draw mask interface. @param cr: Cairo context. @param x: X coordiante of draw area. @param y: Y coordiante of draw area. @param w: Width of draw area. @param h: Height of draw area. ''' draw_vlinear(cr, x, y, w, h, [(0, ("#FFFFFF", 0.9)), (1, ("#FFFFFF", 0.9)),] ) def update(self, keywords): self.keywords = keywords self.treeview.delete_all_items() self.all_pkg_names = self.data_manager.search_query(keywords) if self.all_pkg_names: if len(self.all_pkg_names) > LOAD_ITEMS_NUMBER: self.load_new_items(self.all_pkg_names[:LOAD_ITEMS_NUMBER]) else: self.load_new_items(self.all_pkg_names) else: self.update_message_bar(self.treeview) self.treeview.scrolled_window.connect('vscrollbar-state-changed', self.scrolled_window_vscrollbar_handler) def scrolled_window_vscrollbar_handler(self, widget, state): if state == "bottom": current_item_number = len(self.treeview.visible_items) all_pkgs_number = len(self.all_pkg_names) start = current_item_number if current_item_number < all_pkgs_number and (current_item_number+LOAD_ITEMS_NUMBER) < all_pkgs_number: end = current_item_number+LOAD_ITEMS_NUMBER elif current_item_number < all_pkgs_number and (current_item_number+LOAD_ITEMS_NUMBER) >= all_pkgs_number: end = all_pkgs_number else: return self.load_new_items(self.all_pkg_names[start:end]) def load_new_items(self, pkg_names): if pkg_names: results = self.data_manager.get_search_pkgs_info(pkg_names) self.data_manager.get_pkgs_install_status( pkg_names, reply_handler=lambda status: self.search_reply_handler(status, results), error_handler=handle_dbus_error) else: self.update_message_bar(self.treeview) def search_reply_handler(self, status, results): for (i, result) in enumerate(results): result.append(status[i]) self.render_search_info(results, self.keywords) def render_search_info(self, pkg_infos, keywords): self.keywords = keywords items = [] for pkg_info in pkg_infos: items.append(SearchItem(pkg_info, self.data_manager, keywords)) self.treeview.add_items(items)
class InstallPage(gtk.VBox): ''' class docs ''' def __init__(self, bus_interface, data_manager): ''' init docs ''' # Init. gtk.VBox.__init__(self) self.bus_interface = bus_interface self.data_manager = data_manager self.message_bar = MessageBar(32) self.message_box = gtk.HBox() self.treeview = TreeView(enable_drag_drop=False) self.treeview.set_expand_column(0) self.cute_message_image = gtk.VBox() self.content_box = gtk.VBox() self.pack_start(self.message_box, False, False) self.pack_start(self.content_box, True, True) self.cute_message_pixbuf = utils.get_common_locale_image_pixbuf( "info", "no_download.png") self.content_box.pack_start(self.cute_message_image, True, True) self.treeview.draw_mask = self.draw_mask self.cute_message_image.connect("expose-event", self.expose_cute_message_image) self.treeview.connect("items-change", self.update_message_bar) self.treeview.connect( "items-change", lambda treeview: global_event.emit( "update-install-notify-number", self.get_installing_pkgs_number())) #self.get_action_item("deepin-webapps-baidu-map") #self.download_failed("deepin-webapps-baidu-map") def expose_cute_message_image(self, widget, event): if self.cute_message_pixbuf: cr = widget.window.cairo_create() rect = widget.allocation cr.set_source_rgb(1, 1, 1) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.fill() draw_pixbuf( cr, self.cute_message_pixbuf, rect.x + (rect.width - self.cute_message_pixbuf.get_width()) / 2, rect.y + (rect.height - self.cute_message_pixbuf.get_height()) / 2, ) def update_install_status(self): global_event.emit("update-install-notify-number", self.get_installing_pkgs_number()) self.update_message_bar(self.treeview) def get_installing_pkgs_number(self): items = [] for item in self.treeview.visible_items: if not (item.status == item.STATUS_INSTALL_FINISH or \ item.status == item.STATUS_DOWNLOAD_FAILED): items.append(item) return len(items) def get_installed_pkgs_number(self): items = [] for item in self.treeview.visible_items: if item.status == item.STATUS_INSTALL_FINISH: items.append(item) return len(items) def delete_item_match_pkgname(self, pkg_name): for install_item in self.treeview.visible_items: if install_item.pkg_name == pkg_name: self.treeview.delete_items([install_item]) break def update_message_bar(self, treeview): if self.get_installing_pkgs_number() == 0: if self.get_installed_pkgs_number() == 0: container_remove_all(self.message_box) children = self.content_box.get_children() if len(children) == 0 or children[0] == self.treeview: if self.cute_message_pixbuf == None: self.cute_message_pixbuf = utils.get_common_locale_image_pixbuf( "info", "no_download.png") container_remove_all(self.content_box) self.content_box.pack_start(self.cute_message_image, True, True) self.show_all() else: self.message_bar.set_message("") else: container_remove_all(self.message_box) self.message_box.pack_start(self.message_bar, True, True) self.message_bar.set_message( _("%s applications are being installed") % self.get_installing_pkgs_number()) children = self.content_box.get_children() if len(children) == 0 or children[0] == self.cute_message_image: if self.cute_message_pixbuf: del self.cute_message_pixbuf self.cute_message_pixbuf = None container_remove_all(self.content_box) self.content_box.pack_start(self.treeview, True, True) self.show_all() def draw_mask(self, cr, x, y, w, h): ''' Draw mask interface. @param cr: Cairo context. @param x: X coordiante of draw area. @param y: Y coordiante of draw area. @param w: Width of draw area. @param h: Height of draw area. ''' draw_vlinear(cr, x, y, w, h, [ (0, ("#FFFFFF", 0.9)), (1, ("#FFFFFF", 0.9)), ]) def update_download_status(self, pkg_infos): pkg_items = [] for (pkg_name, download_status) in pkg_infos: pkg_item = None for item in self.treeview.visible_items: if item.pkg_name == pkg_name: pkg_item = item break if pkg_item == None: pkg_item = InstallItem( pkg_name, self.bus_interface.request_pkgs_install_version([pkg_name ])[0], self.data_manager) if download_status == "wait": pkg_item.download_wait() elif download_status == "start": pkg_item.download_start() elif download_status == "update": pkg_item.download_update(0, 0) pkg_items.append(pkg_item) pkg_items = filter( lambda item: item not in self.treeview.visible_items, pkg_items) self.treeview.add_items(pkg_items) def update_action_status(self, pkg_infos): pkg_items = [] for (pkg_name, action_status) in pkg_infos: pkg_item = None for item in self.treeview.visible_items: if item.pkg_name == pkg_name: pkg_item = item break if pkg_item == None: pkg_item = InstallItem( pkg_name, self.bus_interface.request_pkgs_install_version([pkg_name ])[0], self.data_manager) if action_status == "wait": pkg_item.download_finish() elif action_status == "start": pkg_item.action_start() elif action_status == "update": pkg_item.action_update(0) pkg_items.append(pkg_item) pkg_items = filter( lambda item: item not in self.treeview.visible_items, pkg_items) self.treeview.add_items(pkg_items) def add_install_actions(self, pkg_names): for pkg_name in pkg_names: self.get_action_item(pkg_name) def get_action_item(self, pkg_name): action_item = None for item in self.treeview.visible_items: if item.pkg_name == pkg_name: action_item = item break if action_item == None: action_item = InstallItem( pkg_name, self.bus_interface.request_pkgs_install_version([pkg_name])[0], self.data_manager) self.treeview.add_items([action_item]) return action_item def download_ready(self, pkg_name): self.get_action_item(pkg_name).download_ready() def download_wait(self, pkg_name): self.get_action_item(pkg_name).download_wait() def download_start(self, pkg_name): self.get_action_item(pkg_name).download_start() def download_update(self, pkg_name, percent, speed): self.get_action_item(pkg_name).download_update(percent, speed) def download_finish(self, pkg_name): self.get_action_item(pkg_name).download_finish() def download_stop(self, pkg_name): self.get_action_item(pkg_name).download_stop() def download_parse_failed(self, pkg_name): self.get_action_item(pkg_name).download_parse_failed() def download_failed(self, pkg_name): self.get_action_item(pkg_name).download_failed() def action_start(self, pkg_name): self.get_action_item(pkg_name).action_start() def action_update(self, pkg_name, percent): self.get_action_item(pkg_name).action_update(percent) def action_finish(self, pkg_name, pkg_info_list): self.get_action_item(pkg_name).action_finish()
class InstallPage(gtk.VBox): ''' class docs ''' def __init__(self, bus_interface, data_manager): ''' init docs ''' # Init. gtk.VBox.__init__(self) self.bus_interface = bus_interface self.data_manager = data_manager self.message_bar = MessageBar(32) self.message_box = gtk.HBox() self.treeview = TreeView(enable_drag_drop=False) self.treeview.set_expand_column(0) self.cute_message_image = gtk.VBox() self.content_box = gtk.VBox() self.pack_start(self.message_box, False, False) self.pack_start(self.content_box, True, True) self.cute_message_pixbuf = utils.get_common_locale_image_pixbuf("info", "no_download.png") self.content_box.pack_start(self.cute_message_image, True, True) self.treeview.draw_mask = self.draw_mask self.cute_message_image.connect("expose-event", self.expose_cute_message_image) self.treeview.connect("items-change", self.update_message_bar) self.treeview.connect("items-change", lambda treeview: global_event.emit("update-install-notify-number", self.get_installing_pkgs_number())) #self.get_action_item("deepin-webapps-baidu-map") #self.download_failed("deepin-webapps-baidu-map") def expose_cute_message_image(self, widget, event): if self.cute_message_pixbuf: cr = widget.window.cairo_create() rect = widget.allocation cr.set_source_rgb(1, 1, 1) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.fill() draw_pixbuf( cr, self.cute_message_pixbuf, rect.x + (rect.width - self.cute_message_pixbuf.get_width()) / 2, rect.y + (rect.height - self.cute_message_pixbuf.get_height()) / 2, ) def update_install_status(self): global_event.emit("update-install-notify-number", self.get_installing_pkgs_number()) self.update_message_bar(self.treeview) def get_installing_pkgs_number(self): items = [] for item in self.treeview.visible_items: if not (item.status == item.STATUS_INSTALL_FINISH or \ item.status == item.STATUS_DOWNLOAD_FAILED): items.append(item) return len(items) def get_installed_pkgs_number(self): items = [] for item in self.treeview.visible_items: if item.status == item.STATUS_INSTALL_FINISH: items.append(item) return len(items) def delete_item_match_pkgname(self, pkg_name): for install_item in self.treeview.visible_items: if install_item.pkg_name == pkg_name: self.treeview.delete_items([install_item]) break def update_message_bar(self, treeview): if self.get_installing_pkgs_number() == 0: if self.get_installed_pkgs_number() == 0: container_remove_all(self.message_box) children = self.content_box.get_children() if len(children) == 0 or children[0] == self.treeview: if self.cute_message_pixbuf == None: self.cute_message_pixbuf = utils.get_common_locale_image_pixbuf("info", "no_download.png") container_remove_all(self.content_box) self.content_box.pack_start(self.cute_message_image, True, True) self.show_all() else: self.message_bar.set_message("") else: container_remove_all(self.message_box) self.message_box.pack_start(self.message_bar, True, True) self.message_bar.set_message(_("%s applications are being installed") % self.get_installing_pkgs_number()) children = self.content_box.get_children() if len(children) == 0 or children[0] == self.cute_message_image: if self.cute_message_pixbuf: del self.cute_message_pixbuf self.cute_message_pixbuf = None container_remove_all(self.content_box) self.content_box.pack_start(self.treeview, True, True) self.show_all() def draw_mask(self, cr, x, y, w, h): ''' Draw mask interface. @param cr: Cairo context. @param x: X coordiante of draw area. @param y: Y coordiante of draw area. @param w: Width of draw area. @param h: Height of draw area. ''' draw_vlinear(cr, x, y, w, h, [(0, ("#FFFFFF", 0.9)), (1, ("#FFFFFF", 0.9)),] ) def update_download_status(self, pkg_infos): pkg_items = [] for (pkg_name, download_status) in pkg_infos: pkg_item = None for item in self.treeview.visible_items: if item.pkg_name == pkg_name: pkg_item = item break if pkg_item == None: pkg_item = InstallItem(pkg_name, self.bus_interface.request_pkgs_install_version([pkg_name])[0], self.data_manager) if download_status == "wait": pkg_item.download_wait() elif download_status == "start": pkg_item.download_start() elif download_status == "update": pkg_item.download_update(0, 0) pkg_items.append(pkg_item) pkg_items = filter(lambda item: item not in self.treeview.visible_items, pkg_items) self.treeview.add_items(pkg_items) def update_action_status(self, pkg_infos): pkg_items = [] for (pkg_name, action_status) in pkg_infos: pkg_item = None for item in self.treeview.visible_items: if item.pkg_name == pkg_name: pkg_item = item break if pkg_item == None: pkg_item = InstallItem(pkg_name, self.bus_interface.request_pkgs_install_version([pkg_name])[0], self.data_manager) if action_status == "wait": pkg_item.download_finish() elif action_status == "start": pkg_item.action_start() elif action_status == "update": pkg_item.action_update(0) pkg_items.append(pkg_item) pkg_items = filter(lambda item: item not in self.treeview.visible_items, pkg_items) self.treeview.add_items(pkg_items) def add_install_actions(self, pkg_names): for pkg_name in pkg_names: self.get_action_item(pkg_name) def get_action_item(self, pkg_name): action_item = None for item in self.treeview.visible_items: if item.pkg_name == pkg_name: action_item = item break if action_item == None: action_item = InstallItem(pkg_name, self.bus_interface.request_pkgs_install_version([pkg_name])[0], self.data_manager) self.treeview.add_items([action_item]) return action_item def download_ready(self, pkg_name): self.get_action_item(pkg_name).download_ready() def download_wait(self, pkg_name): self.get_action_item(pkg_name).download_wait() def download_start(self, pkg_name): self.get_action_item(pkg_name).download_start() def download_update(self, pkg_name, percent, speed): self.get_action_item(pkg_name).download_update(percent, speed) def download_finish(self, pkg_name): self.get_action_item(pkg_name).download_finish() def download_stop(self, pkg_name): self.get_action_item(pkg_name).download_stop() def download_parse_failed(self, pkg_name): self.get_action_item(pkg_name).download_parse_failed() def download_failed(self, pkg_name): self.get_action_item(pkg_name).download_failed() def action_start(self, pkg_name): self.get_action_item(pkg_name).action_start() def action_update(self, pkg_name, percent): self.get_action_item(pkg_name).action_update(percent) def action_finish(self, pkg_name, pkg_info_list): self.get_action_item(pkg_name).action_finish()
class SecondCategoryItem(TreeItem): ''' class docs ''' def __init__(self, first_category_name, second_category_name, data_manager): ''' init docs ''' TreeItem.__init__(self) self.first_category_name = first_category_name self.second_category_name = second_category_name self.data_manager = data_manager def render_name(self, cr, rect): text_color = "#333333" if self.is_select: cr.set_source_rgba(*color_hex_to_cairo( app_theme.get_color("sidebar_select").get_color())) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.fill() text_color = "#FFFFFF" elif self.is_hover: cr.set_source_rgba(*color_hex_to_cairo( app_theme.get_color("sidebar_hover").get_color())) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.fill() draw_text( cr, get_category_name(self.second_category_name), rect.x + SECOND_CATEGORY_PADDING_X, rect.y, rect.width, rect.height, text_size=SECOND_CATEGORY_ITEM_NAME_SIZE, text_color=text_color, ) def get_height(self): return SECOND_CATEGORY_ITEM_HEIGHT def get_column_widths(self): return [CATEGORY_ITEM_NAME_WIDTH] def get_column_renders(self): return [self.render_name] def hover(self, column, offset_x, offset_y): self.is_hover = True if self.redraw_request_callback: self.redraw_request_callback(self) def unhover(self, column, offset_x, offset_y): self.is_hover = False if self.redraw_request_callback: self.redraw_request_callback(self) def select(self): self.is_select = True if self.redraw_request_callback: self.redraw_request_callback(self) def unselect(self): self.is_select = False if self.redraw_request_callback: self.redraw_request_callback(self) def scrolled_window_vscrollbar_handler(self, widget, state): if state == "bottom": current_item_number = len(self.pkg_icon_view.items) all_pkgs_number = len(self.all_pkg_names) start = current_item_number if current_item_number < all_pkgs_number and ( current_item_number + LOAD_ITEMS_NUMBER) < all_pkgs_number: end = current_item_number + LOAD_ITEMS_NUMBER elif current_item_number < all_pkgs_number and ( current_item_number + LOAD_ITEMS_NUMBER) >= all_pkgs_number: end = all_pkgs_number else: return self.load_new_items(self.all_pkg_names[start:end]) def load_new_items(self, pkg_names): items = [] for pkg_name in pkg_names: info = self.data_manager.get_item_pkg_info(pkg_name) items.append( PkgIconItem(info[0], info[1], info[2], self.data_manager)) self.pkg_icon_view.add_items(items) global_event.emit("show-pkg-view", self.page_box) def handle_pkg_install_status_request(self, status, items): for (index, state) in enumerate(status): items[index].is_installed = state items[index].emit_redraw_request() def button_press(self, column, offset_x, offset_y): # init Loading widget loading_box = LoadingBox() global_event.emit("show-pkg-view", loading_box) self.page_box = gtk.VBox() self.all_pkg_names = self.data_manager.get_second_category_packages( self.second_category_name) self.message_bar = MessageBar(18) self.message_bar.set_message( _("%s > %s : %s applications") % ( get_category_name(self.first_category_name), get_category_name(self.second_category_name), len(self.all_pkg_names), )) self.pkg_icon_view = IconView() self.pkg_icon_view.connect("motion-notify-item", tooltip_aciton) if len(self.all_pkg_names) > LOAD_ITEMS_NUMBER: self.load_new_items(self.all_pkg_names[:LOAD_ITEMS_NUMBER]) else: self.load_new_items(self.all_pkg_names) self.pkg_icon_scrolled_window = ScrolledWindow() self.pkg_icon_scrolled_window.connect( "vscrollbar-state-changed", self.scrolled_window_vscrollbar_handler) self.pkg_icon_scrolled_window.add_child(self.pkg_icon_view) self.pkg_icon_view.draw_mask = self.draw_mask self.pkg_icon_view.draw_row_mask = self.draw_row_mask self.page_box.pack_start(self.message_bar, False, False) self.page_box.pack_start(self.pkg_icon_scrolled_window, True, True) global_event.emit("update-current-status-pkg-page", self.pkg_icon_view) def draw_row_mask(self, cr, rect, row): if row % 2 == 1: cr.set_source_rgba(1, 1, 1, 0.5) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.fill() def draw_mask(self, cr, x, y, w, h): ''' Draw mask interface. @param cr: Cairo context. @param x: X coordiante of draw area. @param y: Y coordiante of draw area. @param w: Width of draw area. @param h: Height of draw area. ''' draw_vlinear(cr, x, y, w, h, [ (0, ("#FFFFFF", 0.9)), (1, ("#FFFFFF", 0.9)), ])
class CategoryItem(TreeItem): ''' class docs ''' def __init__(self, index, first_category_name, data_manager): ''' init docs ''' TreeItem.__init__(self) self.index = index self.first_category_name = first_category_name self.data_manager = data_manager def render_name(self, cr, rect): text_color = "#333333" font_image_color = app_theme.get_color("sidebar_select").get_color() if self.is_select: cr.set_source_rgba(*color_hex_to_cairo( app_theme.get_color("sidebar_select").get_color())) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.fill() text_color = "#FFFFFF" font_image_color = "#FFFFFF" elif self.is_hover: cr.set_source_rgba(*color_hex_to_cairo( app_theme.get_color("sidebar_hover").get_color())) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.fill() pixbuf = app_theme.get_pixbuf("category/%s.png" % (self.index)).get_pixbuf() category_img_path = os.path.join(get_parent_dir(__file__, 2), "image", "category", "%s.png" % (self.index + 1, )) surface = cairo.ImageSurface.create_from_png(category_img_path) cr.set_source_rgb(*color_hex_to_cairo(font_image_color)) cr.mask_surface(surface, rect.x + 14, rect.y + (rect.height - 24) / 2) draw_text( cr, get_category_name(self.first_category_name), rect.x + pixbuf.get_width() + 22, rect.y, rect.width, rect.height, text_size=CATEGORY_ITEM_NAME_SIZE, text_color=text_color, ) if self.is_hover: if self.is_expand: pixbuf = app_theme.get_pixbuf("sidebar/close.png").get_pixbuf() else: pixbuf = app_theme.get_pixbuf("sidebar/open.png").get_pixbuf() draw_pixbuf(cr, pixbuf, rect.x + rect.width - CATEGORY_ITEM_EXPAND_PADDING_X, rect.y + (rect.height - pixbuf.get_height()) / 2) def get_height(self): return CATEGORY_ITEM_HEIGHT def get_column_widths(self): return [CATEGORY_ITEM_NAME_WIDTH] def get_column_renders(self): return [self.render_name] def hover(self, column, offset_x, offset_y): self.is_hover = True if self.redraw_request_callback: self.redraw_request_callback(self) def unhover(self, column, offset_x, offset_y): self.is_hover = False if self.redraw_request_callback: self.redraw_request_callback(self) def select(self): self.is_select = True if self.redraw_request_callback: self.redraw_request_callback(self) def unselect(self): self.is_select = False if self.redraw_request_callback: self.redraw_request_callback(self) def is_in_expand_button_area(self, column, offset_x, offset_y): pixbuf = app_theme.get_pixbuf("sidebar/close.png").get_pixbuf() return is_in_rect( (offset_x, offset_y), (CATEGORY_VIEW_WIDTH - CATEGORY_ITEM_EXPAND_PADDING_X, (self.get_height() - pixbuf.get_height()) / 2, pixbuf.get_width(), pixbuf.get_height())) def motion_notify(self, column, offset_x, offset_y): if self.is_in_expand_button_area(column, offset_x, offset_y): global_event.emit("set-cursor", gtk.gdk.HAND2) else: global_event.emit("set-cursor", None) def button_press(self, column, offset_x, offset_y): if self.is_in_expand_button_area(column, offset_x, offset_y): if self.is_expand: self.unexpand() else: self.expand() def scrolled_window_vscrollbar_handler(self, widget, state): if state == "bottom": current_item_number = len(self.pkg_icon_view.items) all_pkgs_number = len(self.all_pkg_names) start = current_item_number if current_item_number < all_pkgs_number and ( current_item_number + LOAD_ITEMS_NUMBER) < all_pkgs_number: end = current_item_number + LOAD_ITEMS_NUMBER elif current_item_number < all_pkgs_number and ( current_item_number + LOAD_ITEMS_NUMBER) >= all_pkgs_number: end = all_pkgs_number else: return self.load_new_items(self.all_pkg_names[start:end]) def load_new_items(self, pkg_names): items = [] for pkg_name in pkg_names: info = self.data_manager.get_item_pkg_info(pkg_name) items.append( PkgIconItem(info[0], info[1], info[2], self.data_manager)) self.pkg_icon_view.add_items(items) global_event.emit("show-pkg-view", self.page_box) def handle_pkg_install_status_request(self, status, items): for (index, state) in enumerate(status): items[index].is_installed = state items[index].emit_redraw_request() def single_click(self, column, offset_x, offset_y): # init Loading widget loading_box = LoadingBox() global_event.emit("show-pkg-view", loading_box) self.page_box = gtk.VBox() self.all_pkg_names = [] self.all_desktop_infos = {} self.all_pkg_names = self.data_manager.get_first_category_packages( self.first_category_name) self.message_bar = MessageBar(18) self.message_bar.set_message( _("%s: %s applications") % ( get_category_name(self.first_category_name), len(self.all_pkg_names), )) self.pkg_icon_view = IconView() self.pkg_icon_view.connect("motion-notify-item", tooltip_aciton) if len(self.all_pkg_names) > LOAD_ITEMS_NUMBER: self.load_new_items(self.all_pkg_names[:LOAD_ITEMS_NUMBER]) else: self.load_new_items(self.all_pkg_names) self.pkg_icon_view.draw_mask = self.draw_mask self.pkg_icon_view.draw_row_mask = self.draw_row_mask self.pkg_icon_scrolled_window = ScrolledWindow() self.pkg_icon_scrolled_window.connect( "vscrollbar-state-changed", self.scrolled_window_vscrollbar_handler) self.pkg_icon_scrolled_window.add_child(self.pkg_icon_view) self.page_box.pack_start(self.message_bar, False, False) self.page_box.pack_start(self.pkg_icon_scrolled_window, True, True) global_event.emit("update-current-status-pkg-page", self.pkg_icon_view) def draw_row_mask(self, cr, rect, row): if row % 2 == 1: cr.set_source_rgba(1, 1, 1, 0.5) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.fill() def draw_mask(self, cr, x, y, w, h): ''' Draw mask interface. @param cr: Cairo context. @param x: X coordiante of draw area. @param y: Y coordiante of draw area. @param w: Width of draw area. @param h: Height of draw area. ''' draw_vlinear(cr, x, y, w, h, [ (0, ("#FFFFFF", 0.9)), (1, ("#FFFFFF", 0.9)), ]) def double_click(self, column, offset_x, offset_y): if self.is_expand: self.unexpand() else: self.expand() def add_child_item(self): items = [] second_category_names = self.data_manager.get_second_category( self.first_category_name) for second_category_name in second_category_names: items.append( SecondCategoryItem(self.first_category_name, second_category_name, self.data_manager)) self.child_items = items self.add_items_callback(self.child_items, self.row_index + 1) def delete_chlid_item(self): self.delete_items_callback(self.child_items) def expand(self): self.is_expand = True self.add_child_item() if self.redraw_request_callback: self.redraw_request_callback(self) global_event.emit("category-expand", self) def unexpand(self): self.is_expand = False self.delete_chlid_item() if self.redraw_request_callback: self.redraw_request_callback(self)
class SecondCategoryItem(TreeItem): ''' class docs ''' def __init__(self, first_category_name, second_category_name, data_manager): ''' init docs ''' TreeItem.__init__(self) self.first_category_name = first_category_name self.second_category_name = second_category_name self.data_manager = data_manager def render_name(self, cr, rect): text_color = "#333333" if self.is_select: cr.set_source_rgba(*color_hex_to_cairo(app_theme.get_color("sidebar_select").get_color())) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.fill() text_color = "#FFFFFF" elif self.is_hover: cr.set_source_rgba(*color_hex_to_cairo(app_theme.get_color("sidebar_hover").get_color())) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.fill() draw_text(cr, get_category_name(self.second_category_name), rect.x + SECOND_CATEGORY_PADDING_X, rect.y, rect.width, rect.height, text_size=SECOND_CATEGORY_ITEM_NAME_SIZE, text_color=text_color, ) def get_height(self): return SECOND_CATEGORY_ITEM_HEIGHT def get_column_widths(self): return [CATEGORY_ITEM_NAME_WIDTH] def get_column_renders(self): return [self.render_name] def hover(self, column, offset_x, offset_y): self.is_hover = True if self.redraw_request_callback: self.redraw_request_callback(self) def unhover(self, column, offset_x, offset_y): self.is_hover = False if self.redraw_request_callback: self.redraw_request_callback(self) def select(self): self.is_select = True if self.redraw_request_callback: self.redraw_request_callback(self) def unselect(self): self.is_select = False if self.redraw_request_callback: self.redraw_request_callback(self) def scrolled_window_vscrollbar_handler(self, widget, state): if state == "bottom": current_item_number = len(self.pkg_icon_view.items) all_pkgs_number = len(self.all_pkg_names) start = current_item_number if current_item_number < all_pkgs_number and (current_item_number+LOAD_ITEMS_NUMBER) < all_pkgs_number: end = current_item_number+LOAD_ITEMS_NUMBER elif current_item_number < all_pkgs_number and (current_item_number+LOAD_ITEMS_NUMBER) >= all_pkgs_number: end = all_pkgs_number else: return self.load_new_items(self.all_pkg_names[start:end]) def load_new_items(self, pkg_names): items = [] for pkg_name in pkg_names: info = self.data_manager.get_item_pkg_info(pkg_name) items.append(PkgIconItem(info[0], info[1], info[2], self.data_manager)) self.pkg_icon_view.add_items(items) global_event.emit("show-pkg-view", self.page_box) def handle_pkg_install_status_request(self, status, items): for (index, state) in enumerate(status): items[index].is_installed = state items[index].emit_redraw_request() def button_press(self, column, offset_x, offset_y): # init Loading widget loading_box = LoadingBox() global_event.emit("show-pkg-view", loading_box) self.page_box = gtk.VBox() self.all_pkg_names = self.data_manager.get_second_category_packages(self.second_category_name) self.message_bar = MessageBar(18) self.message_bar.set_message(_("%s > %s : %s applications") % ( get_category_name(self.first_category_name), get_category_name(self.second_category_name), len(self.all_pkg_names), )) self.pkg_icon_view = IconView() self.pkg_icon_view.connect("motion-notify-item", tooltip_aciton) if len(self.all_pkg_names) > LOAD_ITEMS_NUMBER: self.load_new_items(self.all_pkg_names[:LOAD_ITEMS_NUMBER]) else: self.load_new_items(self.all_pkg_names) self.pkg_icon_scrolled_window = ScrolledWindow() self.pkg_icon_scrolled_window.connect("vscrollbar-state-changed", self.scrolled_window_vscrollbar_handler) self.pkg_icon_scrolled_window.add_child(self.pkg_icon_view) self.pkg_icon_view.draw_mask = self.draw_mask self.pkg_icon_view.draw_row_mask = self.draw_row_mask self.page_box.pack_start(self.message_bar, False, False) self.page_box.pack_start(self.pkg_icon_scrolled_window, True, True) global_event.emit("update-current-status-pkg-page", self.pkg_icon_view) def draw_row_mask(self, cr, rect, row): if row % 2 == 1: cr.set_source_rgba(1, 1, 1, 0.5) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.fill() def draw_mask(self, cr, x, y, w, h): ''' Draw mask interface. @param cr: Cairo context. @param x: X coordiante of draw area. @param y: Y coordiante of draw area. @param w: Width of draw area. @param h: Height of draw area. ''' draw_vlinear(cr, x, y, w, h, [(0, ("#FFFFFF", 0.9)), (1, ("#FFFFFF", 0.9)),] )
class CategoryItem(TreeItem): ''' class docs ''' def __init__(self, index, first_category_name, data_manager): ''' init docs ''' TreeItem.__init__(self) self.index = index self.first_category_name = first_category_name self.data_manager = data_manager def render_name(self, cr, rect): text_color = "#333333" font_image_color = app_theme.get_color("sidebar_select").get_color() if self.is_select: cr.set_source_rgba(*color_hex_to_cairo(app_theme.get_color("sidebar_select").get_color())) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.fill() text_color = "#FFFFFF" font_image_color = "#FFFFFF" elif self.is_hover: cr.set_source_rgba(*color_hex_to_cairo(app_theme.get_color("sidebar_hover").get_color())) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.fill() pixbuf = app_theme.get_pixbuf("category/%s.png" % (self.index)).get_pixbuf() category_img_path = os.path.join(get_parent_dir(__file__, 2), "image", "category", "%s.png" % (self.index+1, )) surface = cairo.ImageSurface.create_from_png(category_img_path) cr.set_source_rgb(*color_hex_to_cairo(font_image_color)) cr.mask_surface(surface, rect.x+14, rect.y+(rect.height-24)/2) draw_text(cr, get_category_name(self.first_category_name), rect.x + pixbuf.get_width() + 22, rect.y, rect.width, rect.height, text_size=CATEGORY_ITEM_NAME_SIZE, text_color=text_color, ) if self.is_hover: if self.is_expand: pixbuf = app_theme.get_pixbuf("sidebar/close.png").get_pixbuf() else: pixbuf = app_theme.get_pixbuf("sidebar/open.png").get_pixbuf() draw_pixbuf( cr, pixbuf, rect.x + rect.width - CATEGORY_ITEM_EXPAND_PADDING_X, rect.y + (rect.height - pixbuf.get_height()) / 2) def get_height(self): return CATEGORY_ITEM_HEIGHT def get_column_widths(self): return [CATEGORY_ITEM_NAME_WIDTH] def get_column_renders(self): return [self.render_name] def hover(self, column, offset_x, offset_y): self.is_hover = True if self.redraw_request_callback: self.redraw_request_callback(self) def unhover(self, column, offset_x, offset_y): self.is_hover = False if self.redraw_request_callback: self.redraw_request_callback(self) def select(self): self.is_select = True if self.redraw_request_callback: self.redraw_request_callback(self) def unselect(self): self.is_select = False if self.redraw_request_callback: self.redraw_request_callback(self) def is_in_expand_button_area(self, column, offset_x, offset_y): pixbuf = app_theme.get_pixbuf("sidebar/close.png").get_pixbuf() return is_in_rect((offset_x, offset_y), (CATEGORY_VIEW_WIDTH - CATEGORY_ITEM_EXPAND_PADDING_X, (self.get_height() - pixbuf.get_height()) / 2, pixbuf.get_width(), pixbuf.get_height())) def motion_notify(self, column, offset_x, offset_y): if self.is_in_expand_button_area(column, offset_x, offset_y): global_event.emit("set-cursor", gtk.gdk.HAND2) else: global_event.emit("set-cursor", None) def button_press(self, column, offset_x, offset_y): if self.is_in_expand_button_area(column, offset_x, offset_y): if self.is_expand: self.unexpand() else: self.expand() def scrolled_window_vscrollbar_handler(self, widget, state): if state == "bottom": current_item_number = len(self.pkg_icon_view.items) all_pkgs_number = len(self.all_pkg_names) start = current_item_number if current_item_number < all_pkgs_number and (current_item_number+LOAD_ITEMS_NUMBER) < all_pkgs_number: end = current_item_number+LOAD_ITEMS_NUMBER elif current_item_number < all_pkgs_number and (current_item_number+LOAD_ITEMS_NUMBER) >= all_pkgs_number: end = all_pkgs_number else: return self.load_new_items(self.all_pkg_names[start:end]) def load_new_items(self, pkg_names): items = [] for pkg_name in pkg_names: info = self.data_manager.get_item_pkg_info(pkg_name) items.append(PkgIconItem(info[0], info[1], info[2], self.data_manager)) self.pkg_icon_view.add_items(items) global_event.emit("show-pkg-view", self.page_box) def handle_pkg_install_status_request(self, status, items): for (index, state) in enumerate(status): items[index].is_installed = state items[index].emit_redraw_request() def single_click(self, column, offset_x, offset_y): # init Loading widget loading_box = LoadingBox() global_event.emit("show-pkg-view", loading_box) self.page_box = gtk.VBox() self.all_pkg_names = [] self.all_desktop_infos = {} self.all_pkg_names = self.data_manager.get_first_category_packages(self.first_category_name) self.message_bar = MessageBar(18) self.message_bar.set_message(_("%s: %s applications") % ( get_category_name(self.first_category_name), len(self.all_pkg_names), )) self.pkg_icon_view = IconView() self.pkg_icon_view.connect("motion-notify-item", tooltip_aciton) if len(self.all_pkg_names) > LOAD_ITEMS_NUMBER: self.load_new_items(self.all_pkg_names[:LOAD_ITEMS_NUMBER]) else: self.load_new_items(self.all_pkg_names) self.pkg_icon_view.draw_mask = self.draw_mask self.pkg_icon_view.draw_row_mask = self.draw_row_mask self.pkg_icon_scrolled_window = ScrolledWindow() self.pkg_icon_scrolled_window.connect("vscrollbar-state-changed", self.scrolled_window_vscrollbar_handler) self.pkg_icon_scrolled_window.add_child(self.pkg_icon_view) self.page_box.pack_start(self.message_bar, False, False) self.page_box.pack_start(self.pkg_icon_scrolled_window, True, True) global_event.emit("update-current-status-pkg-page", self.pkg_icon_view) def draw_row_mask(self, cr, rect, row): if row % 2 == 1: cr.set_source_rgba(1, 1, 1, 0.5) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.fill() def draw_mask(self, cr, x, y, w, h): ''' Draw mask interface. @param cr: Cairo context. @param x: X coordiante of draw area. @param y: Y coordiante of draw area. @param w: Width of draw area. @param h: Height of draw area. ''' draw_vlinear(cr, x, y, w, h, [(0, ("#FFFFFF", 0.9)), (1, ("#FFFFFF", 0.9)),] ) def double_click(self, column, offset_x, offset_y): if self.is_expand: self.unexpand() else: self.expand() def add_child_item(self): items = [] second_category_names = self.data_manager.get_second_category(self.first_category_name) for second_category_name in second_category_names: items.append(SecondCategoryItem(self.first_category_name, second_category_name, self.data_manager)) self.child_items = items self.add_items_callback(self.child_items, self.row_index + 1) def delete_chlid_item(self): self.delete_items_callback(self.child_items) def expand(self): self.is_expand = True self.add_child_item() if self.redraw_request_callback: self.redraw_request_callback(self) global_event.emit("category-expand", self) def unexpand(self): self.is_expand = False self.delete_chlid_item() if self.redraw_request_callback: self.redraw_request_callback(self)
class SearchPage(gtk.VBox): ''' class docs ''' def __init__(self, data_manager): ''' init docs ''' # Init. gtk.VBox.__init__(self) self.data_manager = data_manager self.keywords = [] self.all_pkg_names = [] self.message_bar = MessageBar(18) self.content_box = gtk.VBox() self.treeview = TreeView(enable_drag_drop=False, expand_column=0) global_event.register_event("delete-search-page-items", self.treeview.delete_items) self.cute_message_image = gtk.VBox() self.cute_message_pixbuf = utils.get_common_locale_image_pixbuf("info", "noresult.png") self.cute_message_image.connect("expose-event", self.expose_cute_message_image) self.content_box.pack_start(self.message_bar, False, False) self.content_box.pack_start(self.treeview) self.loading_box = LoadingBox() self.pack_start(self.loading_box, True, True) self.treeview.connect("items-change", self.update_message_bar) self.treeview.draw_mask = self.draw_mask def expose_cute_message_image(self, widget, event): if self.cute_message_pixbuf: cr = widget.window.cairo_create() rect = widget.allocation cr.set_source_rgba(1, 1, 1, 0) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.fill() draw_pixbuf( cr, self.cute_message_pixbuf, rect.x + (rect.width - self.cute_message_pixbuf.get_width()) / 2, rect.y + (rect.height - self.cute_message_pixbuf.get_height()) / 2, ) def update_message_bar(self, treeview): if len(treeview.visible_items) > 0: self.message_bar.set_message( " ".join(self.keywords) + ": " + _("%s applications searched") % len(self.all_pkg_names)) container_remove_all(self) self.pack_start(self.content_box) global_event.emit("update-current-status-pkg-page", treeview) else: container_remove_all(self) self.pack_start(self.cute_message_image) def draw_mask(self, cr, x, y, w, h): ''' Draw mask interface. @param cr: Cairo context. @param x: X coordiante of draw area. @param y: Y coordiante of draw area. @param w: Width of draw area. @param h: Height of draw area. ''' draw_vlinear(cr, x, y, w, h, [(0, ("#FFFFFF", 0.9)), (1, ("#FFFFFF", 0.9)),] ) def update(self, keywords): self.keywords = keywords self.treeview.delete_all_items() self.all_pkg_names = self.data_manager.search_query(keywords) if self.all_pkg_names: if len(self.all_pkg_names) > LOAD_ITEMS_NUMBER: self.load_new_items(self.all_pkg_names[:LOAD_ITEMS_NUMBER]) else: self.load_new_items(self.all_pkg_names) else: self.update_message_bar(self.treeview) self.treeview.scrolled_window.connect('vscrollbar-state-changed', self.scrolled_window_vscrollbar_handler) def scrolled_window_vscrollbar_handler(self, widget, state): if state == "bottom": current_item_number = len(self.treeview.visible_items) all_pkgs_number = len(self.all_pkg_names) start = current_item_number if current_item_number < all_pkgs_number and (current_item_number+LOAD_ITEMS_NUMBER) < all_pkgs_number: end = current_item_number+LOAD_ITEMS_NUMBER elif current_item_number < all_pkgs_number and (current_item_number+LOAD_ITEMS_NUMBER) >= all_pkgs_number: end = all_pkgs_number else: return self.load_new_items(self.all_pkg_names[start:end]) def load_new_items(self, pkg_names): if pkg_names: items = [] for pkg_name in pkg_names: items.append(SearchItem(pkg_name, self.data_manager, self.keywords)) self.treeview.add_items(items) #global_event.emit("show-pkg-view", self.page_box) else: self.update_message_bar(self.treeview)