Beispiel #1
0
    def __init__(self, pkg_name, data_manager, keywords):
        '''
        init docs
        '''
        TreeItem.__init__(self)
        self.pkg_name = pkg_name
        self.data_manager = data_manager
        self.keywords = keywords
        self.icon_pixbuf = None

        (self.alias_name, self.short_desc, self.long_desc, star) = data_manager.get_pkg_search_info(self.pkg_name)
        info = self.data_manager.get_item_pkg_info(self.pkg_name)
        self.alias_name = info[1]
        self.short_desc = info[2]
        self.long_desc = info[3]

        self.star_level = get_star_level(5.0)
        self.star_buffer = DscStarBuffer(pkg_name)

        self.grade_star = 0

        self.highlight_string = get_match_context('\n'.join([self.short_desc, self.long_desc]), self.keywords)

        self.button_status = BUTTON_NORMAL

        ### TODO: is_installed status
        self.install_status = "uninstalled"
        self.desktops = []
        self.data_manager.get_pkg_installed(self.pkg_name, self.handle_pkg_status)
    def __init__(self, pkg_name, pkg_version, data_manager):
        '''
        init docs
        '''
        TreeItem.__init__(self)
        self.pkg_name = pkg_name
        self.pkg_version = pkg_version
        self.data_manager = data_manager
        self.icon_pixbuf = None

        info = self.data_manager.get_item_pkg_info(self.pkg_name)
        self.alias_name = info[1]
        self.short_desc = info[2]
        self.star_level = get_star_level(5.0)
        self.star_buffer = DscStarBuffer(pkg_name)

        self.grade_star = 0

        self.status = self.STATUS_READY_DOWNLOAD
        self.status_text = _("Dependencies analyzing")
        self.progress_buffer = ProgressBuffer()

        button_pixbuf = app_theme.get_pixbuf(
            "button/start_normal.png").get_pixbuf()
        (self.button_width, self.button_height
         ) = button_pixbuf.get_width(), button_pixbuf.get_height()
        self.button_status = BUTTON_NORMAL

        ### TODO: is_installed status
        self.install_status = json.dumps([])
        self.desktops = []
Beispiel #3
0
    def __init__(self, pkg_name, alias_name, short_desc, data_manager):
        '''
        init docs
        '''
        IconItem.__init__(self)
        self.alias_name = alias_name
        self.pkg_name = pkg_name
        self.short_desc = short_desc
        self.data_manager = data_manager

        self.pkg_icon_pixbuf = None
        self.pkg_icon_width = 0
        self.pkg_icon_height = 0

        self.star_level = get_star_level(5.0)
        self.star_buffer = DscStarBuffer(pkg_name, self)
        self.grade_star = 0
        self.pkg_name_area = PkgName()

        self.width = 240
        self.height = 114

        self.button_status = BUTTON_NORMAL

        ### TODO: is_installed status
        self.install_status = "uninstalled"
        self.desktops = []
        self.data_manager.get_pkg_installed(self.pkg_name,
                                            self.handle_pkg_status)
    def __init__(self, pkg_name, pkg_version, data_manager):
        '''
        init docs
        '''
        TreeItem.__init__(self)
        self.pkg_name = pkg_name
        self.pkg_version = pkg_version
        self.data_manager = data_manager
        self.icon_pixbuf = None

        info = data_manager.get_item_pkg_info(self.pkg_name)
        self.alias_name = info[1]
        self.short_desc = info[2]
        self.star_level = get_star_level(5.0)
        self.star_buffer = DscStarBuffer(pkg_name)

        self.grade_star = 0

        button_pixbuf = app_theme.get_pixbuf(
            "button/uninstall_normal.png").get_pixbuf()
        (self.button_width, self.button_height
         ) = button_pixbuf.get_width(), button_pixbuf.get_height()
        self.button_status = BUTTON_NORMAL

        self.status = self.STATUS_NORMAL
        self.status_text = ""
        self.progress_buffer = ProgressBuffer()
Beispiel #5
0
    def __init__(self, pkg_name, pkg_version, data_manager):
        '''
        init docs
        '''
        TreeItem.__init__(self)
        self.pkg_name = pkg_name
        self.pkg_version = pkg_version
        self.data_manager = data_manager
        self.icon_pixbuf = None

        info = self.data_manager.get_item_pkg_info(self.pkg_name)
        self.alias_name = info[1]
        self.short_desc = info[2]
        self.star_level = get_star_level(5.0)
        self.star_buffer = DscStarBuffer(pkg_name)

        self.grade_star = 0

        self.status = self.STATUS_READY_DOWNLOAD
        self.status_text = _("Dependencies analyzing")
        self.progress_buffer = ProgressBuffer()

        button_pixbuf = app_theme.get_pixbuf("button/start_normal.png").get_pixbuf()
        (self.button_width, self.button_height) = button_pixbuf.get_width(), button_pixbuf.get_height()
        self.button_status = BUTTON_NORMAL

        ### TODO: is_installed status
        self.install_status = json.dumps([])
        self.desktops = []
    def __init__(self, pkg_name, alias_name, short_desc, data_manager):
        '''
        init docs
        '''
        IconItem.__init__(self)
        self.alias_name = alias_name
        self.pkg_name = pkg_name
        self.short_desc = short_desc
        self.data_manager = data_manager
        
        self.pkg_icon_pixbuf = None
        self.pkg_icon_width = 0
        self.pkg_icon_height = 0
        
        self.star_level = get_star_level(5.0)
        self.star_buffer = DscStarBuffer(pkg_name, self)
        self.grade_star = 0
        self.pkg_name_area = PkgName()
        
        self.width = 240
        self.height = 114
        
        self.button_status = BUTTON_NORMAL

        ### TODO: is_installed status
        self.install_status = "uninstalled"
        self.desktops = []
        self.data_manager.get_pkg_installed(self.pkg_name, self.handle_pkg_status)
    def __init__(self, pkg_name, pkg_version, data_manager):
        '''
        init docs
        '''
        TreeItem.__init__(self)
        self.pkg_name = pkg_name
        self.pkg_version = pkg_version
        self.data_manager = data_manager
        self.icon_pixbuf = None
        
        info = data_manager.get_item_pkg_info(self.pkg_name)
        self.alias_name = info[1]
        self.short_desc = info[2]
        self.star_level = get_star_level(5.0)
        self.star_buffer = DscStarBuffer(pkg_name)

        self.grade_star = 0
        
        button_pixbuf = app_theme.get_pixbuf("button/uninstall_normal.png").get_pixbuf()
        (self.button_width, self.button_height) = button_pixbuf.get_width(), button_pixbuf.get_height()
        self.button_status = BUTTON_NORMAL
        
        self.status = self.STATUS_NORMAL
        self.status_text = ""
        self.progress_buffer = ProgressBuffer()
    def __init__(self, pkg_name, alias_name, data_manager):
        '''
        Initialize ItemIcon class.

        @param pixbuf: Icon pixbuf.
        '''
        IconItem.__init__(self)
        self.pkg_name = pkg_name
        self.alias_name = alias_name
        self.data_manager = data_manager

        self.star_level = get_star_level(5.0)
        self.star_buffer = DscStarBuffer(pkg_name)

        self.grade_star = 0

        self.icon_padding_y = 10
        self.name_padding_y = 20
        self.star_padding_y = 5
        self.width = 132
        self.height = 150

        self.icon_pixbuf = None
        self.hover_flag = False
        self.highlight_flag = False

        self.button_status = BUTTON_NORMAL

        # TODO: fetch install_status
        self.install_status = "uninstalled"
        self.desktops = []
        gtk.timeout_add(2000, self.data_manager.get_pkg_installed,
                        self.pkg_name, self.handle_pkg_status)
class InstallItem(TreeItem):
    '''
    class docs
    '''

    STATUS_READY_DOWNLOAD = 1
    STATUS_PARSE_DOWNLOAD_FAILED = 2
    STATUS_DOWNLOAD_FAILED = 3
    STATUS_WAIT_DOWNLOAD = 4
    STATUS_IN_DOWNLOAD = 5
    STATUS_STOP_DOWNLOAD = 6

    STATUS_WAIT_INSTALL = 7
    STATUS_STOP_WAIT_INSTALL = 8
    STATUS_IN_INSTALL = 9
    STATUS_INSTALL_FINISH = 10
    STATUS_INSTALL_FAILED = 11

    STATUS_PADDING_X = 15

    def __init__(self, pkg_name, pkg_version, data_manager):
        '''
        init docs
        '''
        TreeItem.__init__(self)
        self.pkg_name = pkg_name
        self.pkg_version = pkg_version
        self.data_manager = data_manager
        self.icon_pixbuf = None

        info = self.data_manager.get_item_pkg_info(self.pkg_name)
        self.alias_name = info[1]
        self.short_desc = info[2]
        self.star_level = get_star_level(5.0)
        self.star_buffer = DscStarBuffer(pkg_name)

        self.grade_star = 0

        self.status = self.STATUS_READY_DOWNLOAD
        self.status_text = _("Dependencies analyzing")
        self.progress_buffer = ProgressBuffer()

        button_pixbuf = app_theme.get_pixbuf(
            "button/start_normal.png").get_pixbuf()
        (self.button_width, self.button_height
         ) = button_pixbuf.get_width(), button_pixbuf.get_height()
        self.button_status = BUTTON_NORMAL

        ### TODO: is_installed status
        self.install_status = json.dumps([])
        self.desktops = []

    def handle_pkg_status(self, status, success):
        if success:
            self.install_status = str(status)
            try:
                self.desktops = json.loads(self.install_status)
                self.desktops = self.data_manager.get_pkg_desktop_info(
                    self.desktops)
            except:
                pass
            self.emit_redraw_request()
        else:
            utils.global_logger.error(
                "%s: get_pkg_installed handle_dbus_error" % self.pkg_name)
            utils.global_logger.error(status)

    def render_pkg_info(self, cr, rect):
        if self.row_index % 2 == 1:
            cr.set_source_rgba(1, 1, 1, 0.5)
            cr.rectangle(rect.x, rect.y, rect.width, rect.height)
            cr.fill()

        if self.icon_pixbuf == None:
            self.icon_pixbuf = gtk.gdk.pixbuf_new_from_file(
                get_icon_pixbuf_path(self.pkg_name))

        render_pkg_info(cr, rect, self.alias_name, self.pkg_name,
                        self.icon_pixbuf, self.pkg_version, self.short_desc,
                        ITEM_PKG_OFFSET_X)

    def render_pkg_status(self, cr, rect):
        if self.row_index % 2 == 1:
            cr.set_source_rgba(1, 1, 1, 0.5)
            cr.rectangle(rect.x, rect.y, rect.width, rect.height)
            cr.fill()

        if self.status == self.STATUS_READY_DOWNLOAD:
            draw_text(
                cr,
                self.status_text,
                rect.x + rect.width - ITEM_STATUS_TEXT_PADDING_RIGHT,
                rect.y,
                rect.width - ITEM_STAR_AREA_WIDTH - self.STATUS_PADDING_X,
                ITEM_HEIGHT,
            )
        elif self.status == self.STATUS_WAIT_DOWNLOAD:
            # Draw star.
            self.star_buffer.render(
                cr,
                gtk.gdk.Rectangle(rect.x, rect.y, ITEM_STAR_AREA_WIDTH,
                                  ITEM_HEIGHT))

            draw_text(
                cr,
                self.status_text,
                rect.x + rect.width - ITEM_STATUS_TEXT_PADDING_RIGHT,
                rect.y,
                rect.width - ITEM_STAR_AREA_WIDTH - self.STATUS_PADDING_X,
                ITEM_HEIGHT,
            )

            pixbuf = app_theme.get_pixbuf("button/stop.png").get_pixbuf()
            draw_pixbuf(
                cr,
                pixbuf,
                rect.x + rect.width - ITEM_CANCEL_BUTTON_PADDING_RIGHT,
                rect.y + (rect.height - pixbuf.get_height()) / 2,
            )
        elif self.status == self.STATUS_IN_DOWNLOAD:
            self.progress_buffer.render(
                cr,
                gtk.gdk.Rectangle(
                    rect.x, rect.y + (ITEM_HEIGHT - PROGRESSBAR_HEIGHT) / 2,
                    ITEM_STAR_AREA_WIDTH, PROGRESSBAR_HEIGHT))

            draw_text(
                cr,
                self.status_text,
                rect.x + rect.width - ITEM_STATUS_TEXT_PADDING_RIGHT,
                rect.y,
                rect.width - ITEM_STAR_AREA_WIDTH - self.STATUS_PADDING_X,
                ITEM_HEIGHT,
            )

            pixbuf = app_theme.get_pixbuf("button/stop.png").get_pixbuf()
            draw_pixbuf(
                cr,
                pixbuf,
                rect.x + rect.width - ITEM_CANCEL_BUTTON_PADDING_RIGHT,
                rect.y + (rect.height - pixbuf.get_height()) / 2,
            )
        elif self.status == self.STATUS_STOP_DOWNLOAD:
            # Draw star.
            self.star_buffer.render(
                cr,
                gtk.gdk.Rectangle(rect.x, rect.y, ITEM_STAR_AREA_WIDTH,
                                  ITEM_HEIGHT))

            draw_text(
                cr,
                self.status_text,
                rect.x + rect.width - ITEM_STATUS_TEXT_PADDING_RIGHT,
                rect.y,
                rect.width - ITEM_STAR_AREA_WIDTH - self.STATUS_PADDING_X,
                ITEM_HEIGHT,
            )
        elif self.status == self.STATUS_DOWNLOAD_FAILED:
            # Draw star.
            draw_text(
                cr,
                self.status_text,
                rect.x,
                rect.y,
                get_content_size(self.status_text)[0],
                ITEM_HEIGHT,
                text_color="#ff0000",
            )

            if self.button_status == BUTTON_NORMAL:
                status = "normal"
            elif self.button_status == BUTTON_HOVER:
                status = "hover"
            elif self.button_status == BUTTON_PRESS:
                status = "press"

            pixbuf = app_theme.get_pixbuf("button/install_%s.png" %
                                          (status, )).get_pixbuf()
            draw_pixbuf(
                cr, pixbuf, rect.x + rect.width - ITEM_BUTTON_PADDING_RIGHT -
                pixbuf.get_width(),
                rect.y + (rect.height - pixbuf.get_height()) / 2)

        elif self.status == self.STATUS_WAIT_INSTALL:
            self.progress_buffer.render(
                cr,
                gtk.gdk.Rectangle(
                    rect.x, rect.y + (ITEM_HEIGHT - PROGRESSBAR_HEIGHT) / 2,
                    ITEM_STAR_AREA_WIDTH, PROGRESSBAR_HEIGHT))

            draw_text(
                cr,
                self.status_text,
                rect.x + rect.width - ITEM_STATUS_TEXT_PADDING_RIGHT,
                rect.y,
                rect.width - ITEM_STAR_AREA_WIDTH - self.STATUS_PADDING_X,
                ITEM_HEIGHT,
            )

            pixbuf = app_theme.get_pixbuf("button/stop.png").get_pixbuf()
            draw_pixbuf(
                cr,
                pixbuf,
                rect.x + rect.width - ITEM_CANCEL_BUTTON_PADDING_RIGHT,
                rect.y + (rect.height - pixbuf.get_height()) / 2,
            )
        elif self.status == self.STATUS_STOP_WAIT_INSTALL:
            # Draw star.
            self.star_buffer.render(
                cr,
                gtk.gdk.Rectangle(rect.x, rect.y, ITEM_STAR_AREA_WIDTH,
                                  ITEM_HEIGHT))

            draw_text(
                cr,
                self.status_text,
                rect.x + rect.width - ITEM_STATUS_TEXT_PADDING_RIGHT,
                rect.y,
                rect.width - ITEM_STAR_AREA_WIDTH - self.STATUS_PADDING_X,
                ITEM_HEIGHT,
            )
        elif self.status == self.STATUS_IN_INSTALL:
            self.progress_buffer.render(
                cr,
                gtk.gdk.Rectangle(
                    rect.x, rect.y + (ITEM_HEIGHT - PROGRESSBAR_HEIGHT) / 2,
                    ITEM_STAR_AREA_WIDTH, PROGRESSBAR_HEIGHT))

            draw_text(
                cr,
                self.status_text,
                rect.x + rect.width - ITEM_STATUS_TEXT_PADDING_RIGHT,
                rect.y,
                rect.width - ITEM_STAR_AREA_WIDTH - self.STATUS_PADDING_X,
                ITEM_HEIGHT,
            )
        elif self.status == self.STATUS_INSTALL_FINISH:
            # Draw star.
            self.star_buffer.render(
                cr,
                gtk.gdk.Rectangle(rect.x, rect.y, ITEM_STAR_AREA_WIDTH,
                                  ITEM_HEIGHT))

            # Draw button.
            name = ""
            draw_str = ""
            if self.install_status == "uninstalled":
                name = "button/install"
            elif self.install_status == "unknown":
                draw_str = _("Installed")
            else:
                if self.desktops:
                    name = "button/start"
                else:
                    draw_str = _("Installed")

            if name:
                if self.button_status == BUTTON_NORMAL:
                    status = "normal"
                elif self.button_status == BUTTON_HOVER:
                    status = "hover"
                elif self.button_status == BUTTON_PRESS:
                    status = "press"

                pixbuf = app_theme.get_pixbuf("%s_%s.png" %
                                              (name, status)).get_pixbuf()
                draw_pixbuf(
                    cr,
                    pixbuf,
                    rect.x + rect.width - ITEM_BUTTON_PADDING_RIGHT -
                    pixbuf.get_width(),
                    rect.y + (ITEM_HEIGHT - self.button_height) / 2,
                )
            else:
                str_width, str_height = get_content_size(draw_str, 10)
                draw_text(
                    cr,
                    draw_str,
                    rect.x + rect.width - ITEM_BUTTON_PADDING_RIGHT -
                    str_width,
                    rect.y + (rect.height - str_height) / 2,
                    str_width,
                    str_height,
                    alignment=pango.ALIGN_CENTER,
                )
        elif self.status == self.STATUS_PARSE_DOWNLOAD_FAILED:
            # Draw star.
            self.star_buffer.render(
                cr,
                gtk.gdk.Rectangle(rect.x, rect.y, ITEM_STAR_AREA_WIDTH,
                                  ITEM_HEIGHT))

            draw_text(
                cr,
                self.status_text,
                rect.x + rect.width - ITEM_STATUS_TEXT_PADDING_RIGHT,
                rect.y,
                rect.width - ITEM_STAR_AREA_WIDTH - self.STATUS_PADDING_X,
                ITEM_HEIGHT,
            )

    def get_height(self):
        return ITEM_HEIGHT

    def get_column_widths(self):
        return [
            ITEM_INFO_AREA_WIDTH, ITEM_STAR_AREA_WIDTH + ITEM_BUTTON_AREA_WIDTH
        ]

    def get_column_renders(self):
        return [self.render_pkg_info, self.render_pkg_status]

    def unselect(self):
        pass

    def select(self):
        pass

    def unhover(self, column, offset_x, offset_y):
        pass

    def hover(self, column, offset_x, offset_y):
        pass

    def motion_notify(self, column, offset_x, offset_y):
        if column == 0:
            if self.is_in_icon_area(column, offset_x, offset_y):
                global_event.emit("set-cursor", gtk.gdk.HAND2)
            elif self.is_in_name_area(column, offset_x, offset_y):
                global_event.emit("set-cursor", gtk.gdk.HAND2)
            else:
                global_event.emit("set-cursor", None)
        else:
            if self.status == self.STATUS_INSTALL_FINISH:
                if self.desktops:
                    if self.is_in_button_area(column, offset_x, offset_y):
                        self.button_status = BUTTON_HOVER

                        if self.redraw_request_callback:
                            self.redraw_request_callback(self)
                    elif self.button_status != BUTTON_NORMAL:
                        self.button_status = BUTTON_NORMAL

                        if self.redraw_request_callback:
                            self.redraw_request_callback(self)

                if self.is_in_star_area(column, offset_x, offset_y):
                    global_event.emit("set-cursor", gtk.gdk.HAND2)

                    times = offset_x / STAR_SIZE
                    self.grade_star = times * 2 + 2

                    self.grade_star = min(self.grade_star, 10)
                    self.star_buffer.star_level = self.grade_star

                    if self.redraw_request_callback:
                        self.redraw_request_callback(self)
                else:
                    global_event.emit("set-cursor", None)

                    if self.star_buffer.star_level != self.star_level:
                        self.star_buffer.star_level = self.star_level

                        if self.redraw_request_callback:
                            self.redraw_request_callback(self)

            elif self.status == self.STATUS_DOWNLOAD_FAILED:
                if self.is_in_button_area(column, offset_x, offset_y):
                    self.button_status = BUTTON_HOVER
                    if self.redraw_request_callback:
                        self.redraw_request_callback(self)
                elif self.button_status != BUTTON_NORMAL:
                    self.button_status = BUTTON_NORMAL
                    if self.redraw_request_callback:
                        self.redraw_request_callback(self)

            elif self.status == self.STATUS_READY_DOWNLOAD:
                if self.is_in_star_area(column, offset_x, offset_y):
                    global_event.emit("set-cursor", gtk.gdk.HAND2)

                    times = offset_x / STAR_SIZE
                    self.grade_star = times * 2 + 2

                    self.grade_star = min(self.grade_star, 10)
                    self.star_buffer.star_level = self.grade_star

                    if self.redraw_request_callback:
                        self.redraw_request_callback(self)
                else:
                    global_event.emit("set-cursor", None)

                    if self.star_buffer.star_level != self.star_level:
                        self.star_buffer.star_level = self.star_level

                        if self.redraw_request_callback:
                            self.redraw_request_callback(self)

    def button_press(self, column, offset_x, offset_y):
        if column == 0:
            if self.is_in_icon_area(column, offset_x, offset_y):
                global_event.emit("switch-to-detail-page", self.pkg_name)
                global_event.emit("set-cursor", None)
            elif self.is_in_name_area(column, offset_x, offset_y):
                global_event.emit("switch-to-detail-page", self.pkg_name)
                global_event.emit("set-cursor", None)
        else:
            if self.status == self.STATUS_WAIT_DOWNLOAD:
                if self.is_stop_button_can_click(column, offset_x, offset_y):
                    self.status = self.STATUS_STOP_DOWNLOAD
                    self.status_text = _("Download was interrupted")
                    if self.redraw_request_callback:
                        self.redraw_request_callback(self)
                    global_event.emit("remove-wait-download", [self.pkg_name])
                    global_event.emit("request-stop-install-actions",
                                      [self.pkg_name])
                elif self.is_in_star_area(column, offset_x, offset_y):
                    global_event.emit("grade-pkg", self.pkg_name,
                                      self.grade_star)

            elif self.status == self.STATUS_IN_DOWNLOAD:
                if self.is_stop_button_can_click(column, offset_x, offset_y):
                    self.status = self.STATUS_STOP_DOWNLOAD
                    self.status_text = _("Download was interrupted")
                    if self.redraw_request_callback:
                        self.redraw_request_callback(self)
                    global_event.emit("stop-download-pkg", [self.pkg_name])
                    global_event.emit("request-stop-install-actions",
                                      [self.pkg_name])

            elif self.status == self.STATUS_DOWNLOAD_FAILED:
                if self.is_in_button_area(column, offset_x, offset_y):
                    global_event.emit("install-pkg", [self.pkg_name])

            elif self.status == self.STATUS_WAIT_INSTALL:
                if self.is_stop_button_can_click(column, offset_x, offset_y):
                    self.status = self.STATUS_STOP_WAIT_INSTALL
                    self.status_text = _("Installation was interrupted")
                    if self.redraw_request_callback:
                        self.redraw_request_callback(self)
                    global_event.emit("remove-wait-action",
                                      [(self.pkg_name, ACTION_INSTALL)])
                    global_event.emit("request-stop-install-actions",
                                      [self.pkg_name])

            elif self.status == self.STATUS_INSTALL_FINISH:
                if self.is_in_star_area(column, offset_x, offset_y):
                    global_event.emit("grade-pkg", self.pkg_name,
                                      self.grade_star)
                elif self.is_in_button_area(column, offset_x, offset_y):
                    if self.desktops:
                        global_event.emit(
                            "start-pkg", self.alias_name, self.desktops,
                            self.get_offset_with_button(offset_x, offset_y))

    def get_offset_with_button(self, offset_x, offset_y):
        pixbuf = app_theme.get_pixbuf("button/start_normal.png").get_pixbuf()
        popup_x = self.get_column_widths(
        )[1] - ITEM_BUTTON_PADDING_RIGHT - pixbuf.get_width() / 2
        popup_y = (ITEM_HEIGHT - pixbuf.get_height()) / 2
        return (offset_x, offset_y, popup_x, popup_y)

    def button_release(self, column, offset_x, offset_y):
        pass

    def single_click(self, column, offset_x, offset_y):
        pass

    def double_click(self, column, offset_x, offset_y):
        pass

    def is_in_star_area(self, column, offset_x, offset_y):
        return (column == 1 and is_in_rect(
            (offset_x, offset_y),
            (0,
             (ITEM_HEIGHT - STAR_SIZE) / 2, ITEM_STAR_AREA_WIDTH, STAR_SIZE)))

    def is_in_button_area(self, column, offset_x, offset_y):
        return (column == 1 and is_in_rect(
            (offset_x, offset_y),
            (self.get_column_widths()[column] - ITEM_BUTTON_PADDING_RIGHT -
             self.button_width, (ITEM_HEIGHT - self.button_height) / 2,
             self.button_width, self.button_height)))

    def is_stop_button_can_click(self, column, offset_x, offset_y):
        pixbuf = app_theme.get_pixbuf("button/stop.png").get_pixbuf()
        return (column == 1 and is_in_rect(
            (offset_x, offset_y), (self.get_column_widths()[column] -
                                   ITEM_CANCEL_BUTTON_PADDING_RIGHT,
                                   (ITEM_HEIGHT - pixbuf.get_height()) / 2,
                                   pixbuf.get_width(), pixbuf.get_height())))

    def download_ready(self):
        self.status = self.STATUS_READY_DOWNLOAD
        self.status_text = _("Dependencies analyzing")

        if self.redraw_request_callback:
            self.redraw_request_callback(self)

    def download_wait(self):
        self.status = self.STATUS_WAIT_DOWNLOAD
        self.status_text = _("Waiting for download")

        if self.redraw_request_callback:
            self.redraw_request_callback(self)

    def download_start(self):
        self.status = self.STATUS_IN_DOWNLOAD
        self.status_text = _("Downloading")

        if self.redraw_request_callback:
            self.redraw_request_callback(self)

    def download_failed(self):
        self.status = self.STATUS_DOWNLOAD_FAILED
        self.status_text = _("Download failed")

        if self.redraw_request_callback:
            self.redraw_request_callback(self)

    def download_update(self, percent, speed):
        self.status = self.STATUS_IN_DOWNLOAD
        self.progress_buffer.progress = percent
        self.status_text = "%s/s" % (format_file_size(speed))

        if self.redraw_request_callback:
            self.redraw_request_callback(self)

    def download_finish(self):
        self.status = self.STATUS_WAIT_INSTALL
        self.progress_buffer.progress = 0
        self.status_text = _("Waiting for installation")

        if self.redraw_request_callback:
            self.redraw_request_callback(self)

    def download_stop(self):
        pass

    def download_parse_failed(self):
        self.status = self.STATUS_PARSE_DOWNLOAD_FAILED
        self.status_text = _("Dependencies analysis failed")

        if self.redraw_request_callback:
            self.redraw_request_callback(self)

        global_event.emit("request-clear-failed-action", self.pkg_name,
                          ACTION_INSTALL)

    def action_start(self):
        self.status = self.STATUS_IN_INSTALL
        self.status_text = _("Installing")

        if self.redraw_request_callback:
            self.redraw_request_callback(self)

    def action_update(self, percent):
        self.status = self.STATUS_IN_INSTALL
        self.status_text = _("Installing")
        self.progress_buffer.progress = percent

        if self.redraw_request_callback:
            self.redraw_request_callback(self)

    def action_finish(self):
        self.status = self.STATUS_INSTALL_FINISH
        self.progress_buffer.progress = 100
        self.status_text = _("Installation completed")

        if self.redraw_request_callback:
            self.redraw_request_callback(self)

        self.data_manager.get_pkg_installed(self.pkg_name,
                                            self.handle_pkg_status)

    def is_in_name_area(self, column, offset_x, offset_y):
        (name_width, name_height) = get_content_size(self.alias_name,
                                                     NAME_SIZE)
        return (column == 0 and is_in_rect(
            (offset_x, offset_y),
            (ITEM_PADDING_X + ITEM_PKG_OFFSET_X + ICON_SIZE +
             ITEM_PADDING_MIDDLE, ITEM_PADDING_Y, name_width, NAME_SIZE)))

    def is_in_icon_area(self, column, offset_x, offset_y):
        return (column == 0 and self.icon_pixbuf != None and is_in_rect(
            (offset_x, offset_y),
            (ITEM_PADDING_X + ITEM_PKG_OFFSET_X, ITEM_PADDING_Y,
             self.icon_pixbuf.get_width(), self.icon_pixbuf.get_height())))

    def release_resource(self):
        '''
        Release item resource.

        If you have pixbuf in item, you should release memory resource like below code:

        >>> if self.pixbuf:
        >>>     del self.pixbuf
        >>>     self.pixbuf = None
        >>>
        >>> return True

        This is TreeView interface, you should implement it.

        @return: Return True if do release work, otherwise return False.

        When this function return True, TreeView will call function gc.collect() to release object to release memory.
        '''
        if self.icon_pixbuf:
            del self.icon_pixbuf
            self.icon_pixbuf = None

        return True
Beispiel #10
0
class PkgIconItem(IconItem):
    '''
    class docs
    '''

    ALIAS_NAME_SIZE = 12

    PADDING_X = 10
    PADDING_Y = 10
    PADDING_MIDDLE = 10

    BUTTON_PADDING_X = ITEM_PADDING_X
    BUTTON_PADDING_Y = 60
    BUTTON_WIDTH = 48
    BUTTON_HEIGHT = 18

    DRAW_ICON_SIZE = 48
    DRAW_PADDING_LEFT = 20
    DRAW_PADDING_RIGHT = 10
    DRAW_PADDING_Y = 16
    DRAW_BUTTON_PADDING_Y = 13
    DRAW_INFO_PADDING_X = 15
    DRAW_STAR_PADDING_Y = 40
    DRAW_LONG_DESC_PADDING_Y = 68

    def __init__(self, pkg_name, alias_name, short_desc, data_manager):
        '''
        init docs
        '''
        IconItem.__init__(self)
        self.alias_name = alias_name
        self.pkg_name = pkg_name
        self.short_desc = short_desc
        self.data_manager = data_manager

        self.pkg_icon_pixbuf = None
        self.pkg_icon_width = 0
        self.pkg_icon_height = 0

        self.star_level = get_star_level(5.0)
        self.star_buffer = DscStarBuffer(pkg_name, self)
        self.grade_star = 0
        self.pkg_name_area = PkgName()

        self.width = 240
        self.height = 114

        self.button_status = BUTTON_NORMAL

        ### TODO: is_installed status
        self.install_status = "uninstalled"
        self.desktops = []
        self.data_manager.get_pkg_installed(self.pkg_name,
                                            self.handle_pkg_status)

    def handle_pkg_status(self, status, success):
        if success:
            self.install_status = str(status)
            try:
                self.desktops = json.loads(self.install_status)
                self.desktops = self.data_manager.get_pkg_desktop_info(
                    self.desktops)
            except:
                pass
            self.emit_redraw_request()
        else:
            global_logger.error("%s: get_pkg_installed handle_dbus_error" %
                                self.pkg_name)
            global_logger.error(status)

    def get_width(self):
        '''
        Get item width.

        This is IconView interface, you should implement it.
        '''
        return self.width

    def get_height(self):
        '''
        Get item height.

        This is IconView interface, you should implement it.
        '''
        return self.height

    def init_pkg_icon_pixbuf(self):
        if self.pkg_icon_pixbuf == None:
            self.pkg_icon_pixbuf = gtk.gdk.pixbuf_new_from_file(
                get_icon_pixbuf_path(self.pkg_name))
            if self.pkg_icon_pixbuf:
                self.pkg_icon_width = self.pkg_icon_pixbuf.get_width()
                self.pkg_icon_height = self.pkg_icon_pixbuf.get_height()

    def render(self, cr, rect):
        # Draw icon.
        self.init_pkg_icon_pixbuf()

        draw_pixbuf(
            cr, self.pkg_icon_pixbuf, rect.x + self.DRAW_PADDING_LEFT +
            (ICON_SIZE - self.pkg_icon_width) / 2,
            rect.y + self.DRAW_PADDING_Y)

        # Draw button.
        name = ""
        draw_str = ""
        if self.install_status == "uninstalled":
            name = "button/install_small"
        elif self.install_status == "unknown":
            draw_str = _("Not found")
        else:
            if self.desktops:
                name = "button/start_small"
            else:
                draw_str = _("Installed")

        if name:
            pixbuf = app_theme.get_pixbuf(
                "%s_%s.png" %
                (name, button_status_dict[self.button_status])).get_pixbuf()
            draw_pixbuf(
                cr, pixbuf, rect.x + self.DRAW_PADDING_LEFT,
                rect.y + self.DRAW_PADDING_Y + self.DRAW_ICON_SIZE +
                self.DRAW_BUTTON_PADDING_Y)
        else:
            str_width, str_height = get_content_size(draw_str, 10)
            draw_text(
                cr,
                draw_str,
                rect.x + self.DRAW_PADDING_LEFT,
                rect.y + self.DRAW_PADDING_Y + self.DRAW_ICON_SIZE +
                self.DRAW_BUTTON_PADDING_Y,
                rect.width,
                str_height,
                wrap_width=rect.width,
            )

        # Draw name.
        self.text_width = rect.width - self.DRAW_PADDING_LEFT - self.DRAW_PADDING_RIGHT - self.DRAW_INFO_PADDING_X - self.pkg_icon_width
        self.pkg_name_area.render(
            cr, self.alias_name,
            gtk.gdk.Rectangle(
                rect.x + self.DRAW_PADDING_LEFT + ICON_SIZE +
                self.DRAW_INFO_PADDING_X, rect.y + self.DRAW_PADDING_Y,
                self.text_width, NAME_SIZE))

        # Draw star.
        self.star_buffer.render(
            cr,
            gtk.gdk.Rectangle(
                rect.x + self.DRAW_PADDING_LEFT + ICON_SIZE +
                self.DRAW_INFO_PADDING_X, rect.y + self.DRAW_STAR_PADDING_Y,
                STAR_SIZE * 5, STAR_SIZE))

        # Draw long desc.
        long_desc_height = 32
        if self.short_desc == None:
            self.short_desc = "FIX ME"
        with cairo_state(cr):
            cr.rectangle(
                rect.x + self.DRAW_PADDING_LEFT + ICON_SIZE +
                self.DRAW_INFO_PADDING_X,
                rect.y + self.DRAW_LONG_DESC_PADDING_Y,
                self.text_width,
                long_desc_height,
            )
            cr.clip()
            draw_text(
                cr,
                self.short_desc,
                rect.x + self.DRAW_PADDING_LEFT + ICON_SIZE +
                self.DRAW_INFO_PADDING_X,
                rect.y + self.DRAW_LONG_DESC_PADDING_Y,
                self.text_width,
                long_desc_height,
                wrap_width=self.text_width,
            )

    def is_in_star_area(self, x, y):
        return is_in_rect((x, y),
                          (self.DRAW_PADDING_LEFT + self.pkg_icon_width +
                           self.DRAW_INFO_PADDING_X, self.DRAW_STAR_PADDING_Y,
                           STAR_SIZE * 5, STAR_SIZE))

    def is_in_button_area(self, x, y):
        return is_in_rect((x, y), (
            self.DRAW_PADDING_LEFT,
            self.DRAW_PADDING_Y + self.DRAW_ICON_SIZE +
            self.DRAW_BUTTON_PADDING_Y,
            self.BUTTON_WIDTH,
            self.BUTTON_HEIGHT,
        ))

    def is_in_icon_area(self, x, y):
        self.init_pkg_icon_pixbuf()

        return is_in_rect((x, y), (self.DRAW_PADDING_LEFT, self.DRAW_PADDING_Y,
                                   self.pkg_icon_width, self.pkg_icon_height))

    def is_in_name_area(self, x, y):
        (text_width, text_height) = get_content_size(self.alias_name,
                                                     text_size=NAME_SIZE)
        return is_in_rect(
            (x, y), (self.DRAW_PADDING_LEFT + self.pkg_icon_width +
                     self.DRAW_INFO_PADDING_X, self.DRAW_PADDING_Y, text_width,
                     NAME_SIZE))

    def icon_item_motion_notify(self, x, y):
        '''
        Handle `motion-notify-event` signal.

        This is IconView interface, you should implement it.
        '''
        self.hover_flag = True

        self.emit_redraw_request()

        if self.is_in_star_area(x, y):
            global_event.emit("set-cursor", gtk.gdk.HAND2)

            offset_x = x - (self.DRAW_PADDING_LEFT +
                            self.pkg_icon_pixbuf.get_width() +
                            self.DRAW_INFO_PADDING_X)
            times = offset_x / STAR_SIZE
            self.grade_star = times * 2 + 2

            self.grade_star = min(self.grade_star, 10)
            self.star_buffer.star_level = self.grade_star

            self.emit_redraw_request()
        elif self.is_in_icon_area(x, y) or self.is_in_name_area(x, y):
            global_event.emit("set-cursor", gtk.gdk.HAND2)
        else:
            global_event.emit("set-cursor", None)

            if self.star_buffer.star_level != self.star_level:
                self.star_buffer.star_level = self.star_level
                self.emit_redraw_request()

            if self.is_in_button_area(x, y):
                self.button_status = BUTTON_HOVER
                self.emit_redraw_request()
            elif self.button_status != BUTTON_NORMAL:
                self.button_status = BUTTON_NORMAL
                self.emit_redraw_request()

    def get_offset_with_button(self, offset_x, offset_y):
        pixbuf = app_theme.get_pixbuf("button/start_normal.png").get_pixbuf()
        popup_x = self.DRAW_PADDING_LEFT + pixbuf.get_width() / 2
        popup_y = self.DRAW_PADDING_Y + self.DRAW_ICON_SIZE + self.DRAW_BUTTON_PADDING_Y
        return (offset_x, offset_y, popup_x, popup_y)

    def icon_item_button_press(self, x, y):
        global timeout_tooltip_action_id
        '''
        Handle button-press event.

        This is IconView interface, you should implement it.
        '''
        if self.is_in_star_area(x, y):
            global_event.emit("grade-pkg", (self.pkg_name, self.star_buffer),
                              self.grade_star)
        elif self.is_in_button_area(x, y):
            if self.desktops:
                global_event.emit("start-pkg", self.alias_name, self.desktops,
                                  self.get_offset_with_button(x, y))
            else:
                global_event.emit("install-pkg", [self.pkg_name])

            self.button_status = BUTTON_PRESS
            self.emit_redraw_request()
        elif self.is_in_icon_area(x, y):
            global_event.emit("switch-to-detail-page", self.pkg_name)
        elif self.is_in_name_area(x, y):
            if timeout_tooltip_action_id:
                gobject.source_remove(timeout_tooltip_action_id)
                timeout_tooltip_action_id = None
            global_event.emit('hide-pkg-name-tooltip')
            global_event.emit("switch-to-detail-page", self.pkg_name)

    def icon_item_button_release(self, x, y):
        '''
        Handle button-release event.

        This is IconView interface, you should implement it.
        '''
        if self.is_in_button_area(x, y):
            self.button_status = BUTTON_HOVER
            self.emit_redraw_request()
        elif self.button_status != BUTTON_NORMAL:
            self.button_status = BUTTON_NORMAL
            self.emit_redraw_request()

    def icon_item_release_resource(self):
        '''
        Release item resource.

        If you have pixbuf in item, you should release memory resource like below code:

        >>> del self.pixbuf
        >>> self.pixbuf = None

        This is IconView interface, you should implement it.

        @return: Return True if do release work, otherwise return False.

        When this function return True, IconView will call function gc.collect() to release object to release memory.
        '''
        if self.pkg_icon_pixbuf:
            del self.pkg_icon_pixbuf
            self.pkg_icon_pixbuf = None

        return True
Beispiel #11
0
class SearchItem(TreeItem):
    '''
    class docs
    '''

    def __init__(self, pkg_name, data_manager, keywords):
        '''
        init docs
        '''
        TreeItem.__init__(self)
        self.pkg_name = pkg_name
        self.data_manager = data_manager
        self.keywords = keywords
        self.icon_pixbuf = None

        (self.alias_name, self.short_desc, self.long_desc, star) = data_manager.get_pkg_search_info(self.pkg_name)
        info = self.data_manager.get_item_pkg_info(self.pkg_name)
        self.alias_name = info[1]
        self.short_desc = info[2]
        self.long_desc = info[3]

        self.star_level = get_star_level(5.0)
        self.star_buffer = DscStarBuffer(pkg_name)

        self.grade_star = 0

        self.highlight_string = get_match_context('\n'.join([self.short_desc, self.long_desc]), self.keywords)

        self.button_status = BUTTON_NORMAL

        ### TODO: is_installed status
        self.install_status = "uninstalled"
        self.desktops = []
        self.data_manager.get_pkg_installed(self.pkg_name, self.handle_pkg_status)

    def handle_pkg_status(self, status, success):
        if success:
            self.install_status= str(status)
            if self.install_status == "unknown":
                global_event.emit("delete-search-page-items", [self])
            else:
                try:
                    self.desktops = json.loads(self.install_status)
                    self.desktops = self.data_manager.get_pkg_desktop_info(self.desktops)
                except:
                    pass
                self.emit_redraw_request()
        else:
            utils.global_logger.error("%s: get_pkg_installed handle_dbus_error" % self.pkg_name)
            utils.global_logger.error(status)

    def render_info(self, cr, rect):
        if self.row_index % 2 == 1:
            cr.set_source_rgba(1, 1, 1, 0.5)
            cr.rectangle(rect.x, rect.y, rect.width, rect.height)
            cr.fill()

        # Render icon.
        if self.icon_pixbuf == None:
            self.icon_pixbuf = gtk.gdk.pixbuf_new_from_file(
                    get_icon_pixbuf_path(utils.get_origin_name(self.pkg_name)))

        render_pkg_icon(cr, rect, self.icon_pixbuf)

        # Render name.
        render_pkg_name(cr, rect, get_match_context(self.alias_name, self.keywords), rect.width)

        # Render search result.
        with cairo_state(cr):
            text_padding_left = ITEM_PADDING_X + ICON_SIZE + ITEM_PADDING_MIDDLE
            text_padding_right = 10
            text_padding_y = ITEM_PADDING_Y + DEFAULT_FONT_SIZE * 2
            text_width = rect.width - text_padding_left - text_padding_right
            text_height = 30

            cr.rectangle(rect.x, rect.y + text_padding_y, rect.width, text_height)
            cr.clip()

            draw_text(
                cr,
                self.highlight_string,
                rect.x + text_padding_left,
                rect.y + text_padding_y,
                text_width,
                text_height,
                text_size=DEFAULT_FONT_SIZE,
                wrap_width=text_width,
                )

    def render_pkg_status(self, cr, rect):
        if self.row_index % 2 == 1:
            cr.set_source_rgba(1, 1, 1, 0.5)
            cr.rectangle(rect.x, rect.y, rect.width, rect.height)
            cr.fill()

        # Render star.
        self.star_buffer.render(cr, gtk.gdk.Rectangle(rect.x, rect.y, ITEM_STAR_AREA_WIDTH, ITEM_HEIGHT))

        # Draw button.
        name = ""
        draw_str = ""
        if self.install_status == "uninstalled":
            name = "button/install_small"
        elif self.install_status == "unknown":
            draw_str = _("Not found")
        else:
            if self.desktops:
                name = "button/start_small"
            else:
                draw_str = _("Installed")

        # Render button.

        if name:
            if self.button_status == BUTTON_NORMAL:
                status = "normal"
            elif self.button_status == BUTTON_HOVER:
                status = "hover"
            elif self.button_status == BUTTON_PRESS:
                status = "press"

            pixbuf = app_theme.get_pixbuf("%s_%s.png" % (name, status)).get_pixbuf()
            draw_pixbuf(
                cr,
                pixbuf,
                rect.x + rect.width - ITEM_BUTTON_PADDING_RIGHT - pixbuf.get_width(),
                rect.y + (rect.height - pixbuf.get_height()) / 2
                )
        else:
            str_width, str_height = get_content_size(draw_str, 10)
            draw_text(
                cr,
                draw_str,
                rect.x + rect.width - ITEM_BUTTON_PADDING_RIGHT - str_width,
                rect.y + (rect.height - str_height) / 2,
                rect.width,
                str_height,
                wrap_width=rect.width
                )

    def is_in_button_area(self, column, offset_x, offset_y):
        pixbuf = app_theme.get_pixbuf("button/start_normal.png").get_pixbuf()
        return (column == 1
                and is_in_rect((offset_x, offset_y),
                               (self.get_column_widths()[column] - ITEM_BUTTON_PADDING_RIGHT - pixbuf.get_width(),
                                (ITEM_HEIGHT - pixbuf.get_height()) / 2,
                                pixbuf.get_width(),
                                pixbuf.get_height()
                                )))

    def is_in_star_area(self, column, offset_x, offset_y):
        return (column == 1
                and is_in_rect((offset_x, offset_y),
                               (0,
                                (ITEM_HEIGHT - STAR_SIZE) / 2,
                                ITEM_STAR_AREA_WIDTH,
                                STAR_SIZE)))

    def is_in_icon_area(self, column, offset_x, offset_y):
        return (column == 0
                and is_in_rect((offset_x, offset_y),
                               (ITEM_PADDING_X,
                                ITEM_PADDING_Y,
                                self.icon_pixbuf.get_width(),
                                self.icon_pixbuf.get_height()
                                )))

    def is_in_name_area(self, column, offset_x, offset_y):
        (name_width, name_height) = get_content_size(self.alias_name, NAME_SIZE)
        return (column == 0
                and is_in_rect((offset_x, offset_y),
                               (ITEM_PADDING_X + ICON_SIZE + ITEM_PADDING_MIDDLE,
                                ITEM_PADDING_Y,
                                name_width,
                                name_height,
                                )))

    def get_height(self):
        return ITEM_HEIGHT

    def get_column_widths(self):
        return [ITEM_INFO_AREA_WIDTH,
                ITEM_STAR_AREA_WIDTH + ITEM_BUTTON_AREA_WIDTH]

    def get_column_renders(self):
        return [self.render_info,
                self.render_pkg_status]

    def unselect(self):
        pass

    def select(self):
        pass

    def unhover(self, column, offset_x, offset_y):
        pass

    def hover(self, column, offset_x, offset_y):
        pass

    def motion_notify(self, column, offset_x, offset_y):
        if column == 0:
            if self.is_in_icon_area(column, offset_x, offset_y) or self.is_in_name_area(column, offset_x, offset_y):
                global_event.emit("set-cursor", gtk.gdk.HAND2)
            else:
                global_event.emit("set-cursor", None)
        else:
            if self.is_in_star_area(column, offset_x, offset_y):
                global_event.emit("set-cursor", gtk.gdk.HAND2)

                times = offset_x / STAR_SIZE
                self.grade_star = times * 2 + 2

                self.grade_star = min(self.grade_star, 10)
                self.star_buffer.star_level = self.grade_star

                if self.redraw_request_callback:
                    self.redraw_request_callback(self)
            else:
                if self.desktops:
                    if self.is_in_button_area(column, offset_x, offset_y):
                        self.button_status = BUTTON_HOVER

                        if self.redraw_request_callback:
                            self.redraw_request_callback(self, True)
                    else:
                        self.button_status = BUTTON_NORMAL

                        if self.redraw_request_callback:
                            self.redraw_request_callback(self, True)

                global_event.emit("set-cursor", None)

                if self.star_buffer.star_level != self.star_level:
                    self.star_buffer.star_level = self.star_level

                    if self.redraw_request_callback:
                        self.redraw_request_callback(self)

    def get_offset_with_button(self, offset_x, offset_y):
        pixbuf = app_theme.get_pixbuf("button/start_normal.png").get_pixbuf()
        popup_x = self.get_column_widths()[1] - ITEM_BUTTON_PADDING_RIGHT - pixbuf.get_width() / 2
        popup_y = (ITEM_HEIGHT - pixbuf.get_height()) / 2
        return (offset_x, offset_y, popup_x, popup_y)

    def button_press(self, column, offset_x, offset_y):
        if column == 0:
            if self.is_in_icon_area(column, offset_x, offset_y) or self.is_in_name_area(column, offset_x, offset_y):
                global_event.emit("switch-to-detail-page", self.pkg_name)
                global_event.emit("set-cursor", None)
        else:
            if self.is_in_star_area(column, offset_x, offset_y):
                global_event.emit("grade-pkg", self.pkg_name, self.grade_star)
            elif self.is_in_button_area(column, offset_x, offset_y):
                if self.desktops:
                    global_event.emit("start-pkg", self.alias_name, self.desktops, self.get_offset_with_button(offset_x, offset_y))

                    self.button_status = BUTTON_PRESS
                    if self.redraw_request_callback:
                        self.redraw_request_callback(self, True)
                else:
                    global_event.emit("install-pkg", [self.pkg_name])

                    self.button_status = BUTTON_PRESS
                    if self.redraw_request_callback:
                        self.redraw_request_callback(self, True)
            else:
                global_event.emit("switch-to-detail-page", self.pkg_name)

    def button_release(self, column, offset_x, offset_y):
        if self.desktops:
            if self.is_in_button_area(column, offset_x, offset_y):
                if self.button_status != BUTTON_HOVER:
                    self.button_status = BUTTON_HOVER

                    if self.redraw_request_callback:
                        self.redraw_request_callback(self, True)
            else:
                if self.button_status != BUTTON_NORMAL:
                    self.button_status = BUTTON_NORMAL

                    if self.redraw_request_callback:
                        self.redraw_request_callback(self, True)

    def single_click(self, column, offset_x, offset_y):
        pass

    def double_click(self, column, offset_x, offset_y):
        pass

    def release_resource(self):
        '''
        Release item resource.

        If you have pixbuf in item, you should release memory resource like below code:

        >>> if self.pixbuf:
        >>>     del self.pixbuf
        >>>     self.pixbuf = None
        >>>
        >>> return True

        This is TreeView interface, you should implement it.

        @return: Return True if do release work, otherwise return False.

        When this function return True, TreeView will call function gc.collect() to release object to release memory.
        '''
        if self.icon_pixbuf:
            del self.icon_pixbuf
            self.icon_pixbuf = None

        return True
class UninstallItem(TreeItem):
    '''
    class docs
    '''

    STATUS_NORMAL = 1
    STATUS_CONFIRM = 2
    STATUS_WAIT_ACTION = 3
    STATUS_IN_ACTION = 4

    STATUS_PADDING_X = 15

    def __init__(self, pkg_name, pkg_version, data_manager):
        '''
        init docs
        '''
        TreeItem.__init__(self)
        self.pkg_name = pkg_name
        self.pkg_version = pkg_version
        self.data_manager = data_manager
        self.icon_pixbuf = None

        info = data_manager.get_item_pkg_info(self.pkg_name)
        self.alias_name = info[1]
        self.short_desc = info[2]
        self.star_level = get_star_level(5.0)
        self.star_buffer = DscStarBuffer(pkg_name)

        self.grade_star = 0

        button_pixbuf = app_theme.get_pixbuf(
            "button/uninstall_normal.png").get_pixbuf()
        (self.button_width, self.button_height
         ) = button_pixbuf.get_width(), button_pixbuf.get_height()
        self.button_status = BUTTON_NORMAL

        self.status = self.STATUS_NORMAL
        self.status_text = ""
        self.progress_buffer = ProgressBuffer()
        #self.action_wait()

    def render_pkg_info(self, cr, rect):
        if self.row_index % 2 == 1:
            cr.set_source_rgba(1, 1, 1, 0.5)
            cr.rectangle(rect.x, rect.y, rect.width, rect.height)
            cr.fill()

        if self.icon_pixbuf == None:
            self.icon_pixbuf = gtk.gdk.pixbuf_new_from_file(
                get_icon_pixbuf_path(self.pkg_name))

        render_pkg_info(cr, rect, self.alias_name, self.pkg_name,
                        self.icon_pixbuf, self.pkg_version, self.short_desc,
                        ITEM_PKG_OFFSET_X)

    def render_pkg_status(self, cr, rect):
        if self.row_index % 2 == 1:
            cr.set_source_rgba(1, 1, 1, 0.5)
            cr.rectangle(rect.x, rect.y, rect.width, rect.height)
            cr.fill()

        if self.status == self.STATUS_CONFIRM:
            # Draw star.
            self.star_buffer.render(
                cr,
                gtk.gdk.Rectangle(rect.x, rect.y, ITEM_STAR_AREA_WIDTH,
                                  ITEM_HEIGHT))

            confirm_pixbuf = app_theme.get_pixbuf(
                "button/uninstall_confirm.png").get_pixbuf()
            cancel_pixbuf = app_theme.get_pixbuf(
                "button/uninstall_cancel.png").get_pixbuf()

            draw_pixbuf(
                cr,
                confirm_pixbuf,
                rect.x + rect.width - ITEM_CONFIRM_BUTTON_PADDING_RIGHT,
                rect.y + (ITEM_HEIGHT - confirm_pixbuf.get_height()) / 2,
            )

            draw_pixbuf(
                cr,
                cancel_pixbuf,
                rect.x + rect.width - ITEM_CANCEL_BUTTON_PADDING_RIGHT,
                rect.y + (ITEM_HEIGHT - cancel_pixbuf.get_height()) / 2,
            )
        elif self.status == self.STATUS_IN_ACTION:
            self.progress_buffer.render(
                cr,
                gtk.gdk.Rectangle(
                    rect.x, rect.y + (ITEM_HEIGHT - PROGRESSBAR_HEIGHT) / 2,
                    ITEM_STAR_AREA_WIDTH, PROGRESSBAR_HEIGHT))

            draw_text(
                cr,
                self.status_text,
                rect.x + rect.width - ITEM_STATUS_TEXT_PADDING_RIGHT,
                rect.y,
                rect.width - ITEM_STAR_AREA_WIDTH,
                ITEM_HEIGHT,
            )
        elif self.status == self.STATUS_WAIT_ACTION:
            # Draw star.
            self.star_buffer.render(
                cr,
                gtk.gdk.Rectangle(rect.x, rect.y, ITEM_STAR_AREA_WIDTH,
                                  ITEM_HEIGHT))

            draw_text(
                cr,
                self.status_text,
                rect.x + rect.width - ITEM_STATUS_TEXT_PADDING_RIGHT,
                rect.y,
                rect.width - ITEM_STAR_AREA_WIDTH,
                ITEM_HEIGHT,
            )

            cancel_pixbuf = app_theme.get_pixbuf(
                "button/uninstall_cancel.png").get_pixbuf()

            draw_pixbuf(
                cr,
                cancel_pixbuf,
                rect.x + rect.width - 50,
                rect.y + (ITEM_HEIGHT - cancel_pixbuf.get_height()) / 2,
            )
        elif self.status == self.STATUS_NORMAL:
            # Draw star.
            self.star_buffer.render(
                cr,
                gtk.gdk.Rectangle(rect.x, rect.y, ITEM_STAR_AREA_WIDTH,
                                  ITEM_HEIGHT))

            # Draw button.
            if self.button_status == BUTTON_NORMAL:
                pixbuf = app_theme.get_pixbuf(
                    "button/uninstall_normal.png").get_pixbuf()
            elif self.button_status == BUTTON_HOVER:
                pixbuf = app_theme.get_pixbuf(
                    "button/uninstall_hover.png").get_pixbuf()
            elif self.button_status == BUTTON_PRESS:
                pixbuf = app_theme.get_pixbuf(
                    "button/uninstall_press.png").get_pixbuf()
            draw_pixbuf(
                cr,
                pixbuf,
                rect.x + rect.width - ITEM_BUTTON_PADDING_RIGHT -
                pixbuf.get_width(),
                rect.y + (ITEM_HEIGHT - self.button_height) / 2,
            )

    def get_height(self):
        return ITEM_HEIGHT

    def get_column_widths(self):
        return [
            ITEM_INFO_AREA_WIDTH, ITEM_STAR_AREA_WIDTH + ITEM_BUTTON_AREA_WIDTH
        ]

    def get_column_renders(self):
        return [self.render_pkg_info, self.render_pkg_status]

    def unselect(self):
        pass

    def select(self):
        pass

    def unhover(self, column, offset_x, offset_y):
        pass

    def hover(self, column, offset_x, offset_y):
        pass

    def motion_notify(self, column, offset_x, offset_y):
        if column == 0:
            if self.is_in_icon_area(column, offset_x, offset_y):
                global_event.emit("set-cursor", gtk.gdk.HAND2)
            elif self.is_in_name_area(column, offset_x, offset_y):
                global_event.emit("set-cursor", gtk.gdk.HAND2)
            else:
                global_event.emit("set-cursor", None)
        else:
            if self.status == self.STATUS_NORMAL:
                if self.is_in_button_area(column, offset_x, offset_y):
                    self.button_status = BUTTON_HOVER

                    if self.redraw_request_callback:
                        self.redraw_request_callback(self)
                elif self.button_status != BUTTON_NORMAL:
                    self.button_status = BUTTON_NORMAL

                    if self.redraw_request_callback:
                        self.redraw_request_callback(self)

                if self.is_in_star_area(column, offset_x, offset_y):
                    global_event.emit("set-cursor", gtk.gdk.HAND2)

                    times = offset_x / STAR_SIZE
                    self.grade_star = times * 2 + 2

                    self.grade_star = min(self.grade_star, 10)
                    self.star_buffer.star_level = self.grade_star

                    if self.redraw_request_callback:
                        self.redraw_request_callback(self)
                else:
                    global_event.emit("set-cursor", None)

                    if self.star_buffer.star_level != self.star_level:
                        self.star_buffer.star_level = self.star_level

                        if self.redraw_request_callback:
                            self.redraw_request_callback(self)

    def button_press(self, column, offset_x, offset_y):
        if column == 0:
            if self.is_in_icon_area(column, offset_x, offset_y):
                global_event.emit("switch-to-detail-page", self.pkg_name)
                global_event.emit("set-cursor", None)
            elif self.is_in_name_area(column, offset_x, offset_y):
                global_event.emit("switch-to-detail-page", self.pkg_name)
                global_event.emit("set-cursor", None)
        else:
            if self.status == self.STATUS_NORMAL:
                if self.is_in_button_area(column, offset_x, offset_y):
                    self.status = self.STATUS_CONFIRM

                    if self.redraw_request_callback:
                        self.redraw_request_callback(self)
                elif self.is_in_star_area(column, offset_x, offset_y):
                    global_event.emit("grade-pkg", self.pkg_name,
                                      self.grade_star)
            elif self.status == self.STATUS_CONFIRM:
                if self.is_confirm_button_area(column, offset_x, offset_y):
                    self.status = self.STATUS_WAIT_ACTION
                    self.status_text = _("Waiting for uninstall")

                    if self.redraw_request_callback:
                        self.redraw_request_callback(self)

                    global_event.emit("uninstall-pkg", self.pkg_name,
                                      get_purg_flag())
                elif self.is_cancel_button_area(column, offset_x, offset_y):
                    self.status = self.STATUS_NORMAL

                    if self.redraw_request_callback:
                        self.redraw_request_callback(self)
            elif self.status == self.STATUS_WAIT_ACTION:
                if self.is_cancel_button_area(column, offset_x, offset_y):
                    self.status = self.STATUS_NORMAL

                    global_event.emit("remove-wait-action",
                                      [(self.pkg_name, ACTION_UNINSTALL)])

                    if self.redraw_request_callback:
                        self.redraw_request_callback(self)

    def button_release(self, column, offset_x, offset_y):
        pass

    def single_click(self, column, offset_x, offset_y):
        pass

    def double_click(self, column, offset_x, offset_y):
        pass

    def is_in_star_area(self, column, offset_x, offset_y):
        return (column == 1 and is_in_rect(
            (offset_x, offset_y),
            (0,
             (ITEM_HEIGHT - STAR_SIZE) / 2, ITEM_STAR_AREA_WIDTH, STAR_SIZE)))

    def is_in_button_area(self, column, offset_x, offset_y):
        return (column == 1 and is_in_rect(
            (offset_x, offset_y),
            (self.get_column_widths()[column] - ITEM_BUTTON_PADDING_RIGHT -
             self.button_width, (ITEM_HEIGHT - self.button_height) / 2,
             self.button_width, self.button_height)))

    def is_confirm_button_area(self, column, offset_x, offset_y):
        confirm_pixbuf = app_theme.get_pixbuf(
            "button/uninstall_confirm.png").get_pixbuf()
        return (column == 1 and is_in_rect(
            (offset_x, offset_y),
            (self.get_column_widths()[column] -
             ITEM_CONFIRM_BUTTON_PADDING_RIGHT,
             (ITEM_HEIGHT - confirm_pixbuf.get_height()) / 2,
             confirm_pixbuf.get_width(), confirm_pixbuf.get_height())))

    def is_cancel_button_area(self, column, offset_x, offset_y):
        cancel_pixbuf = app_theme.get_pixbuf(
            "button/uninstall_cancel.png").get_pixbuf()
        return (column == 1 and is_in_rect(
            (offset_x, offset_y),
            (self.get_column_widths()[column] -
             ITEM_CANCEL_BUTTON_PADDING_RIGHT,
             (ITEM_HEIGHT - cancel_pixbuf.get_height()) / 2,
             cancel_pixbuf.get_width(), cancel_pixbuf.get_height())))

    def is_in_name_area(self, column, offset_x, offset_y):
        (name_width, name_height) = get_content_size(self.alias_name,
                                                     NAME_SIZE)
        return (column == 0 and is_in_rect(
            (offset_x, offset_y),
            (ITEM_PADDING_X + ITEM_PKG_OFFSET_X + ICON_SIZE +
             ITEM_PADDING_MIDDLE, ITEM_PADDING_Y, name_width, NAME_SIZE)))

    def is_in_icon_area(self, column, offset_x, offset_y):
        return (column == 0 and self.icon_pixbuf != None and is_in_rect(
            (offset_x, offset_y),
            (ITEM_PADDING_X + ITEM_PKG_OFFSET_X, ITEM_PADDING_Y,
             self.icon_pixbuf.get_width(), self.icon_pixbuf.get_height())))

    def action_wait(self):
        self.status = self.STATUS_WAIT_ACTION
        self.status_text = _("Waiting for uninstall")

        if self.redraw_request_callback:
            self.redraw_request_callback(self)

    def action_start(self):
        self.status = self.STATUS_IN_ACTION
        self.status_text = _("Uninstalling")

        if self.redraw_request_callback:
            self.redraw_request_callback(self)

    def action_update(self, percent):
        self.progress_buffer.progress = percent
        self.status_text = _("Uninstalling")

        if self.redraw_request_callback:
            self.redraw_request_callback(self)

    def action_finish(self):
        self.progress_buffer.progress = 100
        self.status_text = _("Uninstallation completed")

        if self.redraw_request_callback:
            self.redraw_request_callback(self)

    def release_resource(self):
        '''
        Release item resource.

        If you have pixbuf in item, you should release memory resource like below code:

        >>> if self.pixbuf:
        >>>     del self.pixbuf
        >>>     self.pixbuf = None
        >>>
        >>> return True

        This is TreeView interface, you should implement it.

        @return: Return True if do release work, otherwise return False.

        When this function return True, TreeView will call function gc.collect() to release object to release memory.
        '''
        if self.icon_pixbuf:
            del self.icon_pixbuf
            self.icon_pixbuf = None

        return True