class StatusBar(gtk.HBox):
    '''docstring for StatusBar'''
    def __init__(self):
        super(StatusBar, self).__init__(False)
        self.__count = 0
        self.__timeout_id = None
        self.text_label = Label("", text_x_align=ALIGN_MIDDLE,
                                label_width=500,
                                enable_select=False,
                                enable_double_click=False)
        text_align = gtk.Alignment()
        text_align.set(0.0, 0.5, 0.0, 0.0)
        text_align.add(self.text_label)

        self.button_hbox = gtk.HBox(False)
        self.button_hbox.set_spacing(WIDGET_SPACING)
        button_align = gtk.Alignment()
        button_align.set(1.0, 0.5, 0.0, 0.0)
        button_align.set_padding(0, 0, 0, 10)
        button_align.add(self.button_hbox)

        self.pack_start(text_align)
        self.pack_start(button_align)

        self.set_size_request(WINDOW_WIDTH, STATUS_HEIGHT)
        self.connect("expose-event", self.draw_background)

    def draw_background(self, widget, event):
        cr = widget.window.cairo_create()
        x, y, w, h = widget.allocation
        cr.set_source_rgb(*color_hex_to_cairo(MODULE_BG_COLOR))
        cr.rectangle(x, y+1, w, h-1)
        cr.fill()

        cr.set_source_rgb(*color_hex_to_cairo(TREEVIEW_BORDER_COLOR))
        draw_line(cr, x, y + 1, x + w, y + 1)

    def set_text(self, text):
        self.__count += 1
        if self.__timeout_id:
            gtk.timeout_remove(self.__timeout_id)
        self.text_label.set_text(text)
        self.__timeout_id = gobject.timeout_add(3000, self.hide_text)

    def hide_text(self):
        self.__count -= 1
        self.__timeout_id = None
        self.text_label.set_text("")

    def set_buttons(self, buttons):
        self.clear_button()
        for bt in buttons:
            self.button_hbox.pack_start(bt, False, False)
        self.show_all()

    def get_buttons(self):
        return self.button_hbox.get_children()

    def clear_button(self):
        self.button_hbox.foreach(self.button_hbox.remove)
class StatusBox(gtk.HBox):
    def __init__(self, width=800):
        gtk.HBox.__init__(self)

        self.width = width

        self.status_label = Label(
            text="", text_size=CONTENT_FONT_SIZE, text_x_align=ALIGN_MIDDLE, label_width=600, enable_select=False
        )

        self.set_size_request(self.width, -1)
        self.pack_start(self.status_label, False, False)

        self.connect("expose-event", self.__expose)

    def hide_status(self):
        self.status_label.set_text("")

    def set_status(self, text):
        self.status_label.set_text(text)
        gobject.timeout_add(3000, self.hide_status)

    def __expose(self, widget, event):
        cr = widget.window.cairo_create()
        rect = widget.allocation

        cr.set_source_rgb(*color_hex_to_cairo(TREEVIEW_BORDER_COLOR))
        draw_line(cr, rect.x, rect.y + 1, rect.x + self.width, rect.y + 1)
Ejemplo n.º 3
0
class StatusBox(gtk.HBox):
    def __init__(self, width=800):
        gtk.HBox.__init__(self)

        self.width = width

        self.status_label = Label(text="",
                                  text_size=CONTENT_FONT_SIZE,
                                  text_x_align=ALIGN_MIDDLE,
                                  label_width=600,
                                  enable_select=False)

        self.set_size_request(self.width, -1)
        self.pack_start(self.status_label, False, False)

        self.connect("expose-event", self.__expose)

    def hide_status(self):
        self.status_label.set_text("")

    def set_status(self, text):
        self.status_label.set_text(text)
        gobject.timeout_add(3000, self.hide_status)

    def __expose(self, widget, event):
        cr = widget.window.cairo_create()
        rect = widget.allocation

        cr.set_source_rgb(*color_hex_to_cairo(TREEVIEW_BORDER_COLOR))
        draw_line(cr, rect.x, rect.y + 1, rect.x + self.width, rect.y + 1)
class MessageBar(CycleStrip):
    '''
    class docs
    '''
	
    def __init__(self, padding_left=0,):
        '''
        init docs
        '''
        # Init.
        CycleStrip.__init__(self, app_theme.get_pixbuf("strip/background.png"))
        
        self.label = Label()
        self.label_align = gtk.Alignment()
        self.label_align.set(0.0, 0.5, 0, 0)
        self.label_align.set_padding(0, 0, padding_left, 0)
        self.label_align.add(self.label)

        self.search_button = ImageButton(
            app_theme.get_pixbuf("entry/search_normal.png"),
            app_theme.get_pixbuf("entry/search_hover.png"),
            app_theme.get_pixbuf("entry/search_press.png"),
            )
        self.search_entry = InputEntry(action_button=self.search_button)
        self.search_entry.set_size(220, 24)
        entry_align = gtk.Alignment(0.5, 0.5, 0, 0)
        entry_align.set_padding(0, 0, 5, 5)
        entry_align.add(self.search_entry)

        self.pack_start(self.label_align, True, True)
        self.pack_start(entry_align, False, False)
        
    def set_message(self, message):
        self.label.set_text(message)
Ejemplo n.º 5
0
class MessageBar(CycleStrip):
    def __init__(
        self,
        padding_left=0,
    ):
        CycleStrip.__init__(self, app_theme.get_pixbuf("strip/background.png"))

        self.label = Label()
        self.label_align = gtk.Alignment()
        self.label_align.set(0.0, 0.5, 0, 0)
        self.label_align.set_padding(0, 0, padding_left, 0)
        self.label_align.add(self.label)

        self.search_button = ImageButton(
            app_theme.get_pixbuf("entry/search_normal.png"),
            app_theme.get_pixbuf("entry/search_hover.png"),
            app_theme.get_pixbuf("entry/search_press.png"),
        )
        self.search_entry = InputEntry(action_button=self.search_button)
        self.search_entry.set_size(220, 24)
        entry_align = gtk.Alignment(0.5, 0.5, 0, 0)
        entry_align.set_padding(0, 0, 5, 5)
        entry_align.add(self.search_entry)

        self.pack_start(self.label_align, True, True)
        self.pack_start(entry_align, False, False)

    def set_message(self, message):
        self.label.set_text(message)
Ejemplo n.º 6
0
class BottomTipBar(gtk.HBox):
    def __init__(self):
        gtk.HBox.__init__(self)

        self.info_image_box = gtk.VBox()
        self.info_image_box.set_size_request(24, 24)
        self.info_image_box.connect('expose-event', self.expose_info_image_box)

        self.info_label = Label("")
        self.end_info_label = Label("")
        self.info_callback_button = ActionButton('')

        self.close_button = CloseButton()

        self.pack_start(self.info_image_box, False, False)
        self.pack_start(self.info_label)

        self.pack_end(self.close_button, False, False)
        self.pack_end(self.info_callback_button, False, False)
        self.pack_end(self.end_info_label, False, False)

        self.connect('expose-event', self.expose)

    def expose(self, widget, event):
        cr = widget.window.cairo_create()
        rect = widget.allocation

        cr.set_source_rgb(*color_hex_to_cairo('#cccccc'))
        cr.rectangle(rect.x, rect.y, rect.width, 1)
        cr.fill()

        cr.set_source_rgb(*color_hex_to_cairo('#ffffff'))
        cr.rectangle(rect.x, rect.y + 1, rect.width, 1)
        cr.fill()

        cr.set_source_rgb(*color_hex_to_cairo('#fff9c9'))
        cr.rectangle(rect.x, rect.y + 2, rect.width, rect.height - 2)
        cr.fill()

    def expose_info_image_box(self, widget, event):
        cr = widget.window.cairo_create()
        rect = widget.allocation
        msg_pixbuf = get_common_image_pixbuf("msg/msg1.png")
        pix_width = msg_pixbuf.get_width()
        pix_height = msg_pixbuf.get_height()
        draw_pixbuf(
            cr,
            msg_pixbuf,
            rect.x + (rect.width - pix_width) / 2,
            rect.y + (rect.height - pix_height) / 2,
        )

    def update_end_info(self, info):
        self.end_info_label.set_text(info)

    def update_info(self, info, callback_name='', callback_action=None):
        self.info_label.set_text(info)
        self.info_callback_button.set_text(callback_name)
        self.info_callback_button.callback_action = callback_action
class BottomTipBar(gtk.HBox):
    def __init__(self):
        gtk.HBox.__init__(self)
        
        self.info_image_box = gtk.VBox()
        self.info_image_box.set_size_request(24, 24)
        self.info_image_box.connect('expose-event', self.expose_info_image_box)

        self.info_label = Label("")
        self.end_info_label = Label("")
        self.info_callback_button = ActionButton('')

        self.close_button = CloseButton()

        self.pack_start(self.info_image_box, False, False)
        self.pack_start(self.info_label)

        self.pack_end(self.close_button, False, False)
        self.pack_end(self.info_callback_button, False, False)
        self.pack_end(self.end_info_label, False, False)

        self.connect('expose-event', self.expose)

    def expose(self, widget, event):
        cr = widget.window.cairo_create()
        rect = widget.allocation

        cr.set_source_rgb(*color_hex_to_cairo('#cccccc'))
        cr.rectangle(rect.x, rect.y, rect.width, 1)
        cr.fill()

        cr.set_source_rgb(*color_hex_to_cairo('#ffffff'))
        cr.rectangle(rect.x, rect.y+1, rect.width, 1)
        cr.fill()

        cr.set_source_rgb(*color_hex_to_cairo('#fff9c9'))
        cr.rectangle(rect.x, rect.y+2, rect.width, rect.height-2)
        cr.fill()

    def expose_info_image_box(self, widget, event):
        cr = widget.window.cairo_create()
        rect = widget.allocation
        msg_pixbuf = get_common_image_pixbuf("msg/msg1.png")
        pix_width = msg_pixbuf.get_width()
        pix_height = msg_pixbuf.get_height()
        draw_pixbuf(cr,
                    msg_pixbuf,
                    rect.x + (rect.width-pix_width)/2,
                    rect.y + (rect.height-pix_height)/2,
                    )

    def update_end_info(self, info):
        self.end_info_label.set_text(info)

    def update_info(self, info, callback_name='', callback_action=None):
        self.info_label.set_text(info)
        self.info_callback_button.set_text(callback_name)
        self.info_callback_button.callback_action = callback_action
Ejemplo n.º 8
0
class SongSearchUI(DialogBox):
    
    def __init__(self):
        DialogBox.__init__(self, _("Search"), 460, 300, DIALOG_MASK_SINGLE_PAGE,
                           modal=False, window_hint=None, close_callback=self.hide_all)
        title_label = Label(_("Title:"))
        self.title_entry = TextEntry("")
        self.title_entry.set_size(300, 25)
        self.search_button = Button(_("Search"))
        self.search_button.connect("clicked", self.search_song)
        
        control_box = gtk.HBox(spacing=5)
        control_box.pack_start(title_label, False, False)
        control_box.pack_start(self.title_entry, False, False)
        control_box.pack_start(self.search_button, False, False)
        
        scrolled_window = ScrolledWindow(0, 0)
        scrolled_window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
        self.result_view = ListView()
        self.result_view.connect("double-click-item", self.double_click_cb)
        self.result_view.draw_mask = self.get_mask_func(self.result_view)
        self.result_view.add_titles([_("Title"), _("Artist"), _("Album"), _("Type"), _("Size")])
        scrolled_window.add_child(self.result_view)
        
        self.prompt_label = Label("")
        download_button = Button(_("Download"))
        download_button.connect("clicked", self.download_song)
        cancel_button = Button(_("Close"))
        cancel_button.connect("clicked", lambda w: self.hide_all())
        
        self.body_box.set_spacing(5)
        self.body_box.pack_start(control_box, False, False)
        self.body_box.pack_start(scrolled_window, True, True)
        self.left_button_box.set_buttons([self.prompt_label])
        self.right_button_box.set_buttons([download_button, cancel_button])
        
    def search_song(self, widget):    
        self.result_view.clear()
        title = self.title_entry.entry.get_text()
        if not title.strip():
            return 
        self.prompt_label.set_text(_("Now searching"))        
        # widget.set_sensitive(False)
        utils.ThreadRun(multi_ways_query_song, self.render_song_infos, [title]).start()
        
    @post_gui    
    def render_song_infos(self, song_infos):
        if song_infos:
            try:
                items = [QueryInfoItem(song_info) for song_info in song_infos]
            except Exception, e:    
                print e
            else:    
                self.result_view.add_items(items)
        self.prompt_label.set_text(_("Finish!"))        
Ejemplo n.º 9
0
class ShowTime(object):
    def __init__(self):
        self.time_font1 = ""
        self.time_font2 = ""
        self.time_box = Label("", enable_gaussian=True)

    def set_time_font(self, time_font2, time_font1):
        self.time_font1 = str(time_font1)  # 右边显示的时间.
        self.time_font2 = str(time_font2)  # 左边显示的时间.

        self.time_box.set_text(self.time_font2 + self.time_font1)
Ejemplo n.º 10
0
class ShowTime(object):
    
    def __init__(self):     
        self.time_font1 = ""
        self.time_font2 = ""
        self.time_box = Label("", enable_gaussian=True)
        
    def set_time_font(self, time_font2, time_font1):    
        self.time_font1 = str(time_font1) # 右边显示的时间.
        self.time_font2 = str(time_font2) # 左边显示的时间.
        
        self.time_box.set_text(self.time_font2 + self.time_font1)
class BluetoothProgressDialog(DialogBox):
    DIALOG_MASK_SINGLE_PAGE = 0

    def __init__(self, default_width=300, default_height=160, cancel_cb=None):
        DialogBox.__init__(self, "", default_width, default_height, self.DIALOG_MASK_SINGLE_PAGE)

        self.cancel_cb = cancel_cb

        self.message_align = gtk.Alignment()
        self.message_align.set(0, 0, 0, 0)
        self.message_align.set_padding(0, 0, 10, 0)
        self.message_label = Label("", label_width=300)
        self.message_align.add(self.message_label)
        self.progress_align = gtk.Alignment()
        self.progress_align.set(0, 0, 0, 0)
        self.progress_align.set_padding(20, 0, 10, 10)
        self.progress_bar = ProgressBar()
        self.progress_bar.set_size_request(default_width, -1)
        self.progress_align.add(self.progress_bar)
        self.percentage_align = gtk.Alignment()
        self.percentage_align.set(0, 0, 0, 0)
        self.percentage_align.set_padding(10, 0, 140, 0)
        self.percentage_label = Label("0%", label_width=300)
        self.percentage_label.set_size_request(default_width, -1)
        self.percentage_align.add(self.percentage_label)
        self.cancel_align = gtk.Alignment()
        self.cancel_align.set(0, 0, 0, 0)
        self.cancel_align.set_padding(20, 0, 200, 0)
        self.cancel_button = Button(_("Cancel"))
        self.cancel_button.set_size_request(70, WIDGET_HEIGHT)
        self.cancel_button.connect("clicked", self.__on_cancel_button_clicked)
        self.cancel_align.add(self.cancel_button)

        self.body_box.pack_start(self.message_align, False, False)
        self.body_box.pack_start(self.progress_align, False, False)
        self.body_box.pack_start(self.percentage_align, False, False)
        self.body_box.pack_start(self.cancel_align)

    def set_message(self, message):
        self.message_label.set_text(message)

    def set_progress(self, progress):
        self.progress_bar.set_progress(progress)
        self.percentage_label.set_text(_("Sent %d") % progress + "%")

    def __on_cancel_button_clicked(self, widget):
        if self.cancel_cb:
            self.cancel_cb()
            self.destroy()
Ejemplo n.º 12
0
class FootBox(gtk.HBox):

    def __init__(self):
        gtk.HBox.__init__(self)
        self.set_size_request(-1, 35)
        #self.connect("expose-event", self.expose_line)
        self.init_ui()

    def expose_line(self, widget, event):
        cr = widget.window.cairo_create()
        rect = widget.allocation
        style.draw_out_line(cr, rect)

    def init_ui(self):
        self.tip_align = gtk.Alignment(0, 0.5, 0, 1)
        self.tip = Label("")
        self.tip_align.set_padding(5, 5, 20, 0)
        self.tip_align.add(self.tip)

        self.button_box = gtk.HBox()
        self.buttons_align = gtk.Alignment(1, 0.5, 0, 0)
        self.buttons_align.set_padding(0, 0, 0, 10)
        self.buttons_align.add(self.button_box)
        
        self.pack(self, [self.tip_align], True, True)
        self.pack_end(self.buttons_align, False, False)
    
    def pack(self, parent, widgets, expand=False, fill=False):
        for widget in widgets:
            parent.pack_start(widget, expand, fill)

    def set_buttons(self, buttons_list):
        width = 0
        for button in buttons_list:
            width += button.get_size_request()[0]
        self.button_box.set_size_request(width, -1)
        self.pack(self.button_box, buttons_list)
        self.queue_draw()

    def set_tip(self, new_tip):
        self.tip.set_text(new_tip)
Ejemplo n.º 13
0
class MessageBar(CycleStrip):
    '''
    class docs
    '''

    def __init__(self, padding_left=0):
        '''
        init docs
        '''
        # Init.
        CycleStrip.__init__(self, app_theme.get_pixbuf("strip/background.png"))

        self.label = Label()
        self.label_align = gtk.Alignment()
        self.label_align.set(0.0, 0.5, 0, 0)
        self.label_align.set_padding(0, 0, padding_left, 0)
        self.label_align.add(self.label)
        self.pack_start(self.label_align, True, True)

    def set_message(self, message):
        self.label.set_text(message)
class MessageBar(CycleStrip):
    '''
    class docs
    '''
	
    def __init__(self, padding_left=0):
        '''
        init docs
        '''
        # Init.
        CycleStrip.__init__(self, app_theme.get_pixbuf("strip/background.png"))
        
        self.label = Label()
        self.label_align = gtk.Alignment()
        self.label_align.set(0.0, 0.5, 0, 0)
        self.label_align.set_padding(0, 0, padding_left, 0)
        self.label_align.add(self.label)
        self.pack_start(self.label_align, True, True)
        
    def set_message(self, message):
        self.label.set_text(message)
class FootBox(gtk.HBox):
    def __init__(self):
        gtk.HBox.__init__(self)
        self.set_size_request(-1, 35)
        #self.connect("expose-event", self.expose_line)
        self.init_ui()

    def expose_line(self, widget, event):
        cr = widget.window.cairo_create()
        rect = widget.allocation
        style.draw_out_line(cr, rect)

    def init_ui(self):
        self.tip_align = gtk.Alignment(0, 0.5, 0, 1)
        self.tip = Label("")
        self.tip_align.set_padding(5, 5, 20, 0)
        self.tip_align.add(self.tip)

        self.button_box = gtk.HBox()
        self.buttons_align = gtk.Alignment(1, 0.5, 0, 0)
        self.buttons_align.set_padding(0, 0, 0, 10)
        self.buttons_align.add(self.button_box)

        self.pack(self, [self.tip_align], True, True)
        self.pack_end(self.buttons_align, False, False)

    def pack(self, parent, widgets, expand=False, fill=False):
        for widget in widgets:
            parent.pack_start(widget, expand, fill)

    def set_buttons(self, buttons_list):
        width = 0
        for button in buttons_list:
            width += button.get_size_request()[0]
        self.button_box.set_size_request(width, -1)
        self.pack(self.button_box, buttons_list)
        self.queue_draw()

    def set_tip(self, new_tip):
        self.tip.set_text(new_tip)
Ejemplo n.º 16
0
class HumanTimeTip(gtk.VBox):
    def __init__(self, timestamp):
        gtk.VBox.__init__(self)
        self.timestamp = timestamp
        self.label = Label()
        self.pack_start(self.label, False, False)

        try:
            timestamp = float(self.timestamp)
            self.label.set_text(self.to_huamn_str(timestamp))
        except:
            self.label.set_text(self.timestamp)

        gtk.timeout_add(1000, self.tick)

    def to_huamn_str(self, timestamp):
        now = time.time()
        interval = int(now - timestamp)
        if interval < 60:
            return _("Just now")
        else:
            mins = interval / 60
            if mins < 60:
                if mins == 1:
                    return _("One minute ago")
                else:
                    return _("%s minutes ago") % mins
            else:
                hours = mins / 60
                if hours < 24:
                    if hours == 1:
                        return _("One hour ago")
                    else:
                        return _("%s hours ago") % hours
                else:
                    days = hours / 24
                    if days == 1:
                        return _("Yesterday")
                    else:
                        datetime_obj = datetime.fromtimestamp(timestamp)
                        return datetime_obj.strftime("%Y-%m-%d")

    def tick(self):
        try:
            timestamp = float(self.timestamp)
            self.label.set_text(self.to_huamn_str(timestamp))
        except:
            pass
        return True
class HumanTimeTip(gtk.VBox):
    def __init__(self, timestamp):
        gtk.VBox.__init__(self)
        self.timestamp = timestamp
        self.label = Label()
        self.pack_start(self.label, False, False)

        try:
            timestamp = float(self.timestamp)
            self.label.set_text(self.to_huamn_str(timestamp))
        except:
            self.label.set_text(self.timestamp)

        gtk.timeout_add(1000, self.tick)

    def to_huamn_str(self, timestamp):
        now = time.time()
        interval = int(now - timestamp)
        if interval < 60:
            return _("Just now")
        else:
            mins = interval / 60
            if mins < 60:
                if mins == 1:
                    return _("One minute ago")
                else:
                    return _("%s minutes ago") % mins
            else:
                hours = mins / 60
                if hours < 24:
                    if hours == 1:
                        return _("One hour ago")
                    else:
                        return _("%s hours ago") % hours
                else:
                    days = hours / 24
                    if days == 1:
                        return _("Yesterday")
                    else:
                        datetime_obj = datetime.fromtimestamp(timestamp)
                        return datetime_obj.strftime("%Y-%m-%d")

    def tick(self):
        try:
            timestamp = float(self.timestamp)
            self.label.set_text(self.to_huamn_str(timestamp))
        except:
            pass
        return True
Ejemplo n.º 18
0
class JobsManager(gtk.HBox):
    __jobs = []
    __id_updater = None

    def __init__(self):
        super(JobsManager, self).__init__(spacing=6)
        self.connect("expose-event", self.draw_bg_mask)

        self.jobs_label = Label("0 " + _("jobs waiting!"),
                                app_theme.get_color("labelText"), 8)
        self.jobs_label.set_size_request(150, 12)
        label_align = gtk.Alignment()
        label_align.set(0.5, 0.5, 0, 0)
        label_align.set_padding(0, 0, 10, 0)
        label_align.add(self.jobs_label)

        self.progress_label = Label("", app_theme.get_color("labelText"), 8)
        self.progress_label.set_size_request(500, 10)
        self.__paused = False
        btn_cancel = self.__create_simple_button("stop", self.stop)
        self.__btn_pause = self.__create_begin_button(self.pause)

        btn_pause_align = gtk.Alignment()
        btn_pause_align.set(0.5, 0.5, 0, 0)
        btn_pause_align.add(self.__btn_pause)

        btn_cancel_align = gtk.Alignment()
        btn_cancel_align.set(0.5, 0.5, 0, 0)
        btn_cancel_align.set_padding(0, 0, 0, 10)
        btn_cancel_align.add(btn_cancel)

        self.pack_start(label_align, False, False)
        # self.pack_start(self.throbber, False, False)
        self.pack_start(self.progress_label, True, True)
        self.pack_start(btn_pause_align, False, False)
        self.pack_start(btn_cancel_align, False, False)
        self.show_all()
        self.set_no_show_all(True)
        self.hide()

        self.jobs_label.hide_all()

    def draw_bg_mask(self, widget, event):
        cr = widget.window.cairo_create()
        rect = widget.allocation
        draw_alpha_mask(cr, rect.x, rect.y, rect.width, rect.height,
                        "frameLight")

    def __create_simple_button(self, name, callback):
        button = ImageButton(
            app_theme.get_pixbuf("jobs/%s_normal.png" % name),
            app_theme.get_pixbuf("jobs/%s_hover.png" % name),
            app_theme.get_pixbuf("jobs/%s_hover.png" % name),
        )
        if callback:
            button.connect("clicked", callback)
        return button

    def __create_begin_button(self, callback):
        toggle_button = ToggleButton(
            app_theme.get_pixbuf("jobs/pause_normal.png"),
            app_theme.get_pixbuf("jobs/begin_normal.png"),
            app_theme.get_pixbuf("jobs/pause_hover.png"),
            app_theme.get_pixbuf("jobs/begin_hover.png"))
        if callback:
            toggle_button.connect("toggled", callback)
        return toggle_button

    def add(self, job):
        job_id = job.connect("end", self.__job_end)
        self.__jobs.append((job, job_id))
        if len(self.__jobs) == 1:
            try:
                gobject.source_remove(self.__id_updater)
            except:
                pass
            self.__id_updater = gobject.timeout_add(250, self.__update)
            self.__jobs[0][0].start()
            if self.__paused:
                self.pause(self.__btn_pause)
            self.__update()

    def __job_end(self, ajob):
        gobject.idle_add(self.__job_end_cb, ajob)

    def __job_end_cb(self, ajob):
        job, job_id = self.__jobs.pop(0)
        job.disconnect(job_id)
        if self.__paused:
            self.pause(self.__btn_pause)
        if self.__jobs:
            jobs = [(job[0].priority, job) for job in self.__jobs]
            jobs.sort()
            self.__jobs = [job[1] for job in jobs]
            self.__jobs[0][0].start()
            self.__update()
        else:
            try:
                gobject.source_remove(self.__id_updater)
            except:
                pass
            self.__update()
        del job

    def pause(self, btn):
        if self.__jobs:
            if not self.__paused:
                self.__jobs[0][0].pause()
                self.__paused = True
            else:
                self.__jobs[0][0].unpause()
                self.__paused = False

    def stop(self, *args):
        if self.__jobs:
            if self.__paused:
                self.pause(self.__btn_pause)

            self.__jobs[0][0].stop()

    def __update(self):
        if len(self.__jobs) - 1 > 0:
            self.jobs_label.set_text("%d " % (len(self.__jobs) - 1) +
                                     _("jobs waiting!"))
            self.jobs_label.show_all()
        else:
            self.jobs_label.hide_all()

        if self.__jobs:
            Dispatcher.show_jobs()
            message = self.__jobs[0][0].get_info()
            self.progress_label.set_text(message)
            self.show()
            return True
        else:
            Dispatcher.hide_jobs()
            self.hide()
            self.__id_updater = None
            return False
Ejemplo n.º 19
0
class IconSetPage(gtk.VBox):
    def __init__(self, account_setting):
        super(IconSetPage, self).__init__(False)
        #self.set_spacing(BETWEEN_SPACING)
        self.account_setting = account_setting

        self.choose_menu_without_camera = Menu([
            (None, _("Local picture"), self.choose_from_picture),
            (None, _("Take a screeshot"), self.choose_from_screenshot),
        ], True)
        self.choose_menu_with_camera = Menu(
            [(None, _("Local picture"), self.choose_from_picture),
             (None, _("Take a screeshot"), self.choose_from_screenshot),
             (None, _("From camera"), self.choose_from_camera)], True)
        self.tips_label = Label("Set icon",
                                label_width=460,
                                enable_select=False,
                                enable_double_click=False)
        self.error_label = Label("",
                                 wrap_width=560,
                                 enable_select=False,
                                 enable_double_click=False)

        set_page_sw = ScrolledWindow()
        self.pack_start(set_page_sw)
        main_vbox = gtk.VBox(False)
        set_page_sw.add_child(main_vbox)
        self.icon_list_tabel = gtk.Table()
        self.icon_list_tabel.set_row_spacings(4)
        self.icon_list_tabel.set_col_spacings(4)
        main_vbox.pack_start(tools.make_align(self.tips_label), False, False)
        main_vbox.pack_start(tools.make_align(height=20), False, False)

        self.history_list_hbox = gtk.HBox(False)
        self.history_list_hbox.set_size_request(-1, 56)
        self.history_list_hbox.set_spacing(4)

        main_vbox.pack_start(
            tools.make_align(Label(_("Choose a new picture for your account"),
                                   label_width=460,
                                   enable_select=False,
                                   enable_double_click=False),
                             height=CONTAINNER_HEIGHT), False, False)
        main_vbox.pack_start(tools.make_align(self.icon_list_tabel), False,
                             False)
        main_vbox.pack_start(tools.make_align(height=20), False, False)

        main_vbox.pack_start(
            tools.make_align(Label(_("Previously used pictures"),
                                   label_width=460,
                                   enable_select=False,
                                   enable_double_click=False),
                             height=CONTAINNER_HEIGHT), False, False)
        main_vbox.pack_start(tools.make_align(self.history_list_hbox), False,
                             False)
        main_vbox.pack_start(tools.make_align(height=20), False, False)

        main_vbox.pack_start(tools.make_align(self.error_label), False, False)

        # public picture list
        #face_dir = '/usr/share/pixmaps/faces'
        face_dir = '/var/lib/AccountsService/icons'
        if os.path.exists(face_dir):
            pic_list = os.listdir(face_dir)
        else:
            pic_list = []
        pic_list.sort()
        self.public_icon_list = []
        inital_list = [
            '001.jpg', '002.jpg', '003.jpg', '004.jpg', '005.jpg', '006.jpg',
            '007.jpg', '008.jpg', '009.jpg', '010.jpg', '011.jpg', '012.jpg',
            '013.jpg', '014.jpg', '015.jpg', '016.jpg', '017.jpg', '018.jpg',
            '019.jpg', '020.jpg'
        ]

        for pic in pic_list:
            if pic not in inital_list:
                continue
            try:
                icon_pixbuf = gtk.gdk.pixbuf_new_from_file(
                    "%s/%s" % (face_dir, pic)).scale_simple(
                        48, 48, gtk.gdk.INTERP_TILES)
            except:
                continue
            icon_bt = IconButton(icon_pixbuf,
                                 "%s/%s" % (face_dir, pic),
                                 has_frame=True)
            icon_bt.connect("pressed", self.on_icon_bt_pressed_cb)
            self.public_icon_list.append(icon_bt)

        self.more_icon_button = IconButton(app_theme.get_pixbuf(
            "%s/more.png" % MODULE_NAME).get_pixbuf(),
                                           has_frame=True)
        self.more_icon_button.connect("button-press-event",
                                      self.choose_more_picture)
        main_vbox.connect("expose-event", self.draw_white_background)

    def refresh(self):
        self.error_label.set_text("")
        if not self.account_setting.current_set_user:
            return
        if self.account_setting.current_set_user.get_real_name():
            show_name = self.account_setting.current_set_user.get_real_name()
        else:
            show_name = self.account_setting.current_set_user.get_user_name()
        self.tips_label.set_text("<b>%s</b>" % _("Set <u>%s</u>'s picture") %
                                 tools.escape_markup_string(show_name))
        self.history_icon = HistroyIcon(self.account_setting.current_set_user)
        self.history_icon.get_history()
        self.history_list_hbox.foreach(lambda w: w.destroy())

        # the private history icon files
        history_dir = os.path.join(
            self.account_setting.current_set_user.get_home_directory(),
            ".config/deepin-system-settings/account/icons")
        if os.path.exists(history_dir):
            pic_list = os.listdir(history_dir)
        else:
            pic_list = []
        pic_list.sort()
        private_icon_list = []
        for pic in pic_list:
            try:
                icon_pixbuf = gtk.gdk.pixbuf_new_from_file(
                    "%s/%s" % (history_dir, pic)).scale_simple(
                        48, 48, gtk.gdk.INTERP_TILES)
            except:
                continue
            pic_file_path = "%s/%s" % (history_dir, pic)
            icon_bt = IconButton(icon_pixbuf,
                                 pic_file_path,
                                 has_frame=True,
                                 can_del=check_file_writable(pic_file_path))
            icon_bt.connect("pressed", self.on_icon_bt_pressed_cb)
            private_icon_list.append(icon_bt)
        container_remove_all(self.icon_list_tabel)

        pic_list = self.public_icon_list + private_icon_list
        total_pic = len(pic_list)
        rows = (total_pic + 1) / 10 + 1
        self.icon_list_tabel.resize(rows, 10)
        i = j = 0
        for pic in pic_list:
            self.icon_list_tabel.attach(pic, i, i + 1, j, j + 1, 4)
            if pic.can_del:
                pic.row = j
                pic.col = i
                pic.connect("del-pressed", self.on_icon_bt_del_icon_file_cb)
            i += 1
            if i >= 10:
                i = 0
                j += 1
        self.icon_list_tabel.attach(self.more_icon_button, i, i + 1, j, j + 1,
                                    4)

        # history pic IconButton
        icon_button_list = pic_list
        i = 0
        for pic in self.history_icon.history:
            if not os.path.exists(pic):
                continue
            icon_pixbuf = None
            for bt in icon_button_list:
                if pic == bt.get_image_path():
                    icon_pixbuf = bt.pixbuf
                    break
            if not icon_pixbuf:
                try:
                    icon_pixbuf = gtk.gdk.pixbuf_new_from_file(
                        pic).scale_simple(48, 48, gtk.gdk.INTERP_TILES)
                except Exception, e:
                    print e
                    continue
            if i >= 10:
                break
            i += 1
            icon_bt = IconButton(icon_pixbuf,
                                 pic,
                                 has_frame=True,
                                 can_del=True)
            icon_bt.connect("pressed", self.on_icon_bt_pressed_cb)
            icon_bt.connect("del-pressed", self.on_icon_bt_del_pressed_cb)
            self.history_list_hbox.pack_start(icon_bt, False, False)
        self.history_list_hbox.show_all()
Ejemplo n.º 20
0
class UpdateManager(dbus.service.Object):
    def __init__(self, session_bus):
        dbus.service.Object.__init__(self, session_bus, DSC_UPDATE_MANAGER_PATH)

        self.in_update_list = False
        self.in_upgrade_packages = False
        self.upgrade_pkg_infos = []

        self.application = Application()
        self.application.set_default_size(400, 250)
        self.application.add_titlebar(
                button_mask=['min', 'close'],
                app_name='Software Update Manager',
                )

        self.application.window.set_title("Software Update Manager")
        self.application.set_icon(get_common_image('update.png'))


        # Init page box.
        self.page_box = gtk.VBox()
        
        # Init page align.
        self.page_align = gtk.Alignment()
        self.page_align.set(0.5, 0.5, 1, 1)
        self.page_align.set_padding(0, 0, 2, 2)
        
        self.page_align.add(self.page_box)
        self.application.main_box.pack_start(self.page_align, True, True)
        
        # Init status bar.
        self.statusbar = Statusbar(28)
        status_box = gtk.HBox()

        self.statusbar.status_box.pack_start(status_box, True, True)
        self.application.main_box.pack_start(self.statusbar, False, False)

        self.background = BackgroundBox()
        self.background.draw_mask = self.draw_mask
        self.page_box.pack_start(self.background)

        self.upgrade_button = Button('更新软件')
        self.upgrade_button.set_sensitive(False)

        button_box = gtk.HBox()
        button_box.pack_start(self.upgrade_button, False, False)

        button_box_align = gtk.Alignment(0.5, 0.5, 0, 0)
        button_box_align.set_padding(3, 8, 4, 4)
        button_box_align.add(button_box)

        self.statusbar.status_item_box.pack_start(button_box_align)

        self.update_info_label = Label("初始化...")
        self.update_info_label_align = create_align((0.5, 0.5, 0, 0))
        self.update_info_label_align.add(self.update_info_label)
        
        self.upgrade_button.connect('clicked', self.upgrade_packages)


    def draw_mask(self, cr, x, y, w, h):
        sidebar_color = ui_theme.get_color("menu_select_font").get_color()
        draw_vlinear(cr, x, y, w, h,
                     [(0, (sidebar_color, 0.9)),
                      (1, (sidebar_color, 0.9)),]
                     )

    def start_dsc_backend(self):
        self.system_bus = dbus.SystemBus()
        bus_object = self.system_bus.get_object(DSC_SERVICE_NAME, DSC_SERVICE_PATH)
        self.bus_interface = dbus.Interface(bus_object, DSC_SERVICE_NAME)
        self.system_bus.add_signal_receiver(
                self.backend_signal_receiver, 
                signal_name="update_signal", 
                dbus_interface=DSC_SERVICE_NAME, 
                path=DSC_SERVICE_PATH)

    def backend_signal_receiver(self, messages):
        for message in messages:
            (signal_type, action_content) = message
            
            if signal_type == "update-list-update":
                self.in_update_list = True
                message_str = "正在检查更新,请稍等...(%s%%)" % int(float(action_content[0]))
                self.update_info_label.set_text(message_str)
                self.upgrade_button.set_sensitive(False)
            elif signal_type == 'update-list-finish':
                message_str = "正在检查更新,请稍等..."
                self.update_info_label.set_text(message_str)
                self.in_update_list = False

                self.bus_interface.request_upgrade_pkgs(
                        reply_handler=self.render_upgrade_info, 
                        error_handler=lambda e:handle_dbus_error("request_upgrade_pkgs", e))
            elif signal_type == 'update-list-failed':
                message_str = '检查更新失败!'
                self.update_info_label.set_text(message_str)

            elif signal_type == 'upgrade-commit-update':
                pkg_names, action_type, percent, status = action_content
                message_str = "[%s%%]%s" % (percent, status)
                self.update_info_label.set_text(message_str)
                self.upgrade_button.set_sensitive(False)
                self.in_upgrade_packages = True

            elif signal_type == 'upgrade-commit-finish':
                self.in_upgrade_packages = False
                message_str = '软件更新完成!'
                self.update_info_label.set_text(message_str)

    def upgrade_packages(self, widget):
        if self.in_update_list:
            print 'Check update, please wait...'
        elif self.in_upgrade_packages:
            print 'Upgrade packages, please wait...'
        else:
            self.upgrade_button.set_sensitive(False)
            self.in_upgrade_packages = True
            all_upgrade_pkgs = []
            for info in self.upgrade_pkg_infos:
                all_upgrade_pkgs.append(str(eval(info)[0]))
            self.bus_interface.upgrade_pkgs_with_new_policy(
                    all_upgrade_pkgs,
                    reply_handler=lambda :handle_dbus_reply("upgrade_pkgs_with_new_policy"), 
                    error_handler=lambda e:handle_dbus_error("upgrade_pkgs_with_new_policy", e),
                    )

    def render_upgrade_info(self, pkg_infos):
        self.upgrade_pkg_infos = pkg_infos
        if len(pkg_infos) > 0:
            msg_str = '您的系统有%s个更新!' % (len(pkg_infos),)
            self.upgrade_button.set_sensitive(True)
        else:
            msg_str = '您的系统已经最新状态了~'
            self.upgrade_button.set_sensitive(False)

        self.update_info_label.set_text(msg_str)
        self.application.window.show_all()

    def run(self):
        self.start_dsc_backend()
        container_remove_all(self.background)
        self.background.pack_start(self.update_info_label_align)

        gtk.timeout_add(1000, lambda:self.bus_interface.start_update_list(
                reply_handler=lambda :handle_dbus_reply("start_update_list"),
                error_handler=lambda e:handle_dbus_error("start_update_list", e)))

        self.application.run()
        self.bus_interface.request_quit(
                reply_handler=lambda :handle_dbus_reply("request_quit"), 
                error_handler=lambda e:handle_dbus_error("request_quit", e))

    def quit(self):
        gtk.main_quit()

    @dbus.service.method(DSC_UPDATE_MANAGER_NAME, in_signature="", out_signature="")    
    def hello(self):
        self.application.window.present()
Ejemplo n.º 21
0
class AccelEntry(ShortcutKeyEntry):
    ''' '''
    TYPE_DP_GSETTINGS = 0
    TYPE_CMP_GSETTINGS = 1
    TYPE_GSETTINGS = 2
    TYPE_GCONF = 3
    TYPE_STRING = 4
    TYPE_STRV = 5
    __gsignals__ = {
        "accel-key-change":
        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str, )),
        "accel-del": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
    }

    def __init__(self,
                 content="",
                 check_conflict_func=None,
                 resolve_conflict_func=resolve_accel_entry_conflict,
                 process_unmodifier_func=process_unmodifier_key,
                 can_del=False):
        '''
        @param content: a string container accelerator
        @param check_conflict_func: a function return a AccelEntry object, if their AccelBuffer is equal
        @param resolve_conflict_func: a function to resolve conflict
        @param process_unmodifier_func: a function to check the Accelerator is whether valid
        '''
        super(AccelEntry, self).__init__()
        self.accel_buffer = AccelBuffer()
        self.accel_buffer.set_from_accel(content)
        self.accel_str = self.accel_buffer.get_accel_label()
        if not self.accel_str:
            self.accel_str = _('disable')
        self.accel_label = Label(self.accel_str,
                                 enable_select=False,
                                 enable_double_click=False)
        self.accel_align = gtk.Alignment()
        self.accel_align.set(0.0, 0.5, 0.0, 0.0)
        self.accel_align.set_padding(0, 0, 6, 0)
        self.accel_align.add(self.accel_label)
        self.grab_area = gtk.EventBox()
        #self.grab_area.set_size_request(1, -1)
        self.grab_area.set_can_focus(True)
        self.grab_area.add_events(gtk.gdk.BUTTON_PRESS_MASK)
        self.grab_area.add_events(gtk.gdk.KEY_PRESS_MASK)
        self.del_button = ImageButton(
            app_theme.get_pixbuf("keyboard/delete-normal.png"),
            app_theme.get_pixbuf("keyboard/delete-hover.png"),
            app_theme.get_pixbuf("keyboard/delete-hover.png"))
        #self.del_button.set_no_show_all(True)
        self.h_box.remove(self.entry)
        self.h_box.pack_start(self.accel_align)
        self.h_box.pack_start(self.grab_area, False, False)
        #self.h_box.pack_start(self.del_button, False, False)
        self.grab_area.connect("button-press-event",
                               self.__on_grab_area_button_press_cb)
        self.grab_area.connect("key-press-event",
                               self.__on_grab_area_key_press_cb)
        self.grab_area.connect("key-release-event",
                               self.__on_grab_area_key_release_cb)
        self.accel_label.connect("button-press-event",
                                 self.__on_label_button_press_cb)

        #self.accel_label.connect("enter-notify-event", self.__on_label_enter_cb)
        #self.accel_label.connect("leave-notify-event", self.__on_label_leave_cb)
        #self.del_button.connect("leave-notify-event", self.__on_del_button_leave_cb)

        self.del_button.connect("clicked", lambda w: self.emit("accel-del"))
        self.accel_label.keymap = {}

        self.check_conflict_func = check_conflict_func
        self.resolve_conflict_func = resolve_conflict_func
        self.process_unmodifier_func = process_unmodifier_func
        self.can_del = can_del

        widget_width = 200
        if self.can_del:
            widget_width = 220
            new_hbox = gtk.HBox()
            new_align = gtk.Alignment(0.5, 0.5, 1.0, 1.0)
            new_align.add(self.del_button)
            self.remove(self.align)
            self.pack_start(new_hbox, False, False)
            new_hbox.pack_start(self.align, False, False)
            new_hbox.pack_start(new_align, False, False)

        self.set_size(widget_width, 24)

        self.settings_description = ""
        self.settings_key = ""
        self.settings_obj = None
        self.settings_type = None
        self.settings_value_type = None
        self.connect("accel-key-change", self.__on_accel_key_change_cb)

    def __on_label_button_press_cb(self, widget, event):
        self.accel_label.set_text(_("Please input new shortcuts"))
        if gtk.gdk.keyboard_grab(self.grab_area.window, False,
                                 0) != gtk.gdk.GRAB_SUCCESS:
            self.accel_label.set_text(self.accel_str)
            return None
        if gtk.gdk.pointer_grab(self.grab_area.window, False,
                                gtk.gdk.BUTTON_PRESS_MASK, None, None,
                                0) != gtk.gdk.GRAB_SUCCESS:
            gtk.gdk.keyboard_ungrab(0)
            self.accel_label.set_text(self.accel_str)
            return None
        self.grab_area.grab_focus()
        if self.can_del and self.del_button in self.h_box.get_children():
            self.del_button.hide()
            self.h_box.remove(self.del_button)
        self.emit("wait-key-input", self.shortcut_key)

    def __on_grab_area_button_press_cb(self, widget, event):
        gtk.gdk.keyboard_ungrab(0)
        gtk.gdk.pointer_ungrab(0)
        self.accel_label.set_text(self.accel_str)

    def __on_grab_area_key_release_cb(self, widget, event):
        if not event.is_modifier:
            return False
        if not gtk.gdk.pointer_is_grabbed():
            return False
        event.state = event.state & (~gtk.gdk.MOD2_MASK) & (
            ~gtk.gdk.MOD3_MASK) & (~gtk.gdk.MOD4_MASK) & (~gtk.gdk.MOD5_MASK)
        # is not Super key
        if not (event.keyval == gtk.keysyms.Super_R or event.keyval
                == gtk.keysyms.Super_L and event.state == gtk.gdk.SUPER_MASK):
            return False
        gtk.gdk.keyboard_ungrab(0)
        gtk.gdk.pointer_ungrab(0)

        tmp_accel_buf = AccelBuffer()
        tmp_accel_buf.set_keyval(0)
        tmp_accel_buf.set_state(gtk.gdk.SUPER_MASK)

        if self.check_conflict_func and self.resolve_conflict_func:
            conflict_entry = self.check_conflict_func(self, tmp_accel_buf)
            if conflict_entry:
                self.resolve_conflict_func(self, conflict_entry, tmp_accel_buf)
                return
        self.set_keyval_and_state(0, gtk.gdk.SUPER_MASK)

    def __on_grab_area_key_press_cb(self, widget, event):
        if event.is_modifier:
            return False
        if not gtk.gdk.pointer_is_grabbed():
            return False
        gtk.gdk.keyboard_ungrab(0)
        gtk.gdk.pointer_ungrab(0)

        # HACK: we don't want to use SysRq as a keybinding, so we avoid  its translation from Alt+Print.
        if event.keyval == gtk.keysyms.Sys_Req and event.state & gtk.gdk.MOD1_MASK:
            event.keyval = gtk.keysyms.Print
        keyval = event.keyval
        state = event.state = event.state & (~gtk.gdk.MOD2_MASK
                                             )  # ignore MOD2_MASK
        # cancel edit
        if keyval == gtk.keysyms.Escape:
            self.accel_label.set_text(self.accel_str)
            return
        # clear edit
        if keyval == gtk.keysyms.BackSpace:
            self.set_keyval_and_state(0, 0)
            return
        tmp_accel_buf = AccelBuffer()
        tmp_accel_buf.set_keyval(keyval)
        tmp_accel_buf.set_state(state)
        if self.check_unmodified_keys(event) and self.process_unmodifier_func:
            self.accel_label.set_text(self.accel_str)
            self.process_unmodifier_func(tmp_accel_buf)
            return
        if self.check_conflict_func and self.resolve_conflict_func:
            conflict_entry = self.check_conflict_func(self, tmp_accel_buf)
            if conflict_entry:
                self.resolve_conflict_func(self, conflict_entry, tmp_accel_buf)
                return
        self.set_keyval_and_state(keyval, state)

    def reassign_cancel(self, widget=None):
        ''' cancel reassign when it conflict '''
        if widget:
            widget.destroy()
        self.accel_label.set_text(self.accel_str)

    def reassign(self, accel_buf, conflict_entry, widget=None):
        if widget:
            widget.destroy()
        conflict_entry.set_keyval_and_state(0, 0)
        self.set_keyval_and_state(accel_buf.get_keyval(),
                                  accel_buf.get_state())

    def check_unmodified_keys(self, event):
        #Check for unmodified keys
        state = event.state
        keyval = event.keyval
        state = event.state & (~gtk.gdk.MOD2_MASK)  # ignore MOD2_MASK
        forbidden_keyvals = [
            # Navigation keys
            gtk.keysyms.Home,
            gtk.keysyms.Left,
            gtk.keysyms.Up,
            gtk.keysyms.Right,
            gtk.keysyms.Down,
            gtk.keysyms.Page_Up,
            gtk.keysyms.Page_Down,
            gtk.keysyms.End,
            gtk.keysyms.Tab,
            # Return
            gtk.keysyms.KP_Enter,
            gtk.keysyms.Return,
            gtk.keysyms.space,
            gtk.keysyms.Mode_switch
        ]
        return (state == 0 or state == gtk.gdk.SHIFT_MASK) and (
            gtk.keysyms.a <= keyval <= gtk.keysyms.z
            or gtk.keysyms.A <= keyval <= gtk.keysyms.Z
            or gtk.keysyms._0 <= keyval <= gtk.keysyms._9 or
            gtk.keysyms.kana_fullstop <= keyval <= gtk.keysyms.semivoicedsound
            or gtk.keysyms.Arabic_comma <= keyval <= gtk.keysyms.Arabic_sukun
            or gtk.keysyms.Serbian_dje <= keyval <=
            gtk.keysyms.Cyrillic_HARDSIGN or
            gtk.keysyms.Greek_ALPHAaccent <= keyval <= gtk.keysyms.Greek_omega
            or gtk.keysyms.hebrew_doublelowline <= keyval <=
            gtk.keysyms.hebrew_taf
            or gtk.keysyms.Thai_kokai <= keyval <= gtk.keysyms.Thai_lekkao
            or gtk.keysyms.Hangul <= keyval <= gtk.keysyms.Hangul_Special
            or gtk.keysyms.Hangul_Kiyeog <= keyval <=
            gtk.keysyms.Hangul_J_YeorinHieuh or keyval in forbidden_keyvals)

    def set_keyval_and_state(self, keyval, state):
        self.accel_buffer.set_keyval(keyval)
        self.accel_buffer.set_state(state)
        self.emit("accel-key-change", self.accel_buffer.get_accel_name())
        self.accel_str = self.accel_buffer.get_accel_label()
        if not self.accel_str:
            self.accel_str = _('disable')
        self.accel_label.set_text(self.accel_str)

    def set_size(self, width, height):
        super(AccelEntry, self).set_size(width, height)
        if self.can_del:
            self.accel_align.set_size_request(width - 20, height)
            self.accel_label.label_width = width - 20
            self.accel_label.set_size_request(width - 20, height)
        else:
            self.accel_align.set_size_request(width, height)
            self.accel_label.label_width = width
            self.accel_label.set_size_request(width, height)

    def __on_accel_key_change_cb(self, widget, accel_name):
        if not self.settings_obj:
            return
        if self.settings_type == self.TYPE_GSETTINGS:
            if self.settings_value_type == self.TYPE_STRV:
                if accel_name:
                    self.settings_obj.set_strv(self.settings_key, [accel_name])
                else:
                    self.settings_obj.set_strv(self.settings_key, [])
            elif self.settings_value_type == self.TYPE_STRING:
                self.settings_obj.set_string(self.settings_key, accel_name)
        elif self.settings_type == self.TYPE_DP_GSETTINGS:
            self.settings_obj.set_string(
                self.settings_key,
                "%s;%s" % (self.settings_value_type, accel_name))
        elif self.settings_type == self.TYPE_CMP_GSETTINGS:
            settings.shortcuts_compiz_set(self.settings_plugin,
                                          self.settings_key, accel_name)
        elif self.settings_type == self.TYPE_GCONF:
            self.settings_obj.set_string("%s/binding" % (self.settings_key),
                                         accel_name)

    def __on_label_enter_cb(self, widget, event):
        if self.can_del:
            if self.del_button not in self.h_box.get_children():
                self.h_box.pack_start(self.del_button, False, False)
                self.del_button.show()

    def __on_label_leave_cb(self, widget, event):
        x, y, w, h = widget.allocation
        if not (0 < event.y < h) or event.x <= 0:
            if self.del_button in self.h_box.get_children():
                self.h_box.remove(self.del_button)
                self.del_button.hide()

    def __on_del_button_leave_cb(self, widget, event):
        x, y, w, h = widget.allocation
        if not (0 < event.y <
                h) or event.x >= w and self.del_button.get_visible():
            if widget in self.h_box.get_children():
                widget.hide()
                self.h_box.remove(self.del_button)
class AccelEntry(ShortcutKeyEntry):
    ''' '''
    TYPE_DP_GSETTINGS = 0
    TYPE_CMP_GSETTINGS = 1
    TYPE_GSETTINGS = 2
    TYPE_GCONF = 3
    TYPE_STRING = 4
    TYPE_STRV = 5
    __gsignals__ = {
        "accel-key-change" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str,)),
        "accel-del" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
    }
    
    def __init__(self, content="",
                 check_conflict_func=None,
                 resolve_conflict_func=resolve_accel_entry_conflict,
                 process_unmodifier_func=process_unmodifier_key,
                 can_del=False):
        '''
        @param content: a string container accelerator
        @param check_conflict_func: a function return a AccelEntry object, if their AccelBuffer is equal
        @param resolve_conflict_func: a function to resolve conflict
        @param process_unmodifier_func: a function to check the Accelerator is whether valid
        '''
        super(AccelEntry, self).__init__()
        self.accel_buffer = AccelBuffer()
        self.accel_buffer.set_from_accel(content)
        self.accel_str = self.accel_buffer.get_accel_label()
        if not self.accel_str:
            self.accel_str = _('disable')
        self.accel_label = Label(self.accel_str, enable_select=False, enable_double_click=False)
        self.accel_align = gtk.Alignment()
        self.accel_align.set(0.0, 0.5, 0.0, 0.0)
        self.accel_align.set_padding(0, 0, 6, 0)
        self.accel_align.add(self.accel_label)
        self.grab_area = gtk.EventBox()
        #self.grab_area.set_size_request(1, -1)
        self.grab_area.set_can_focus(True)
        self.grab_area.add_events(gtk.gdk.BUTTON_PRESS_MASK)
        self.grab_area.add_events(gtk.gdk.KEY_PRESS_MASK)
        self.del_button = ImageButton(app_theme.get_pixbuf("keyboard/delete-normal.png"),
                                      app_theme.get_pixbuf("keyboard/delete-hover.png"),
                                      app_theme.get_pixbuf("keyboard/delete-hover.png"))
        #self.del_button.set_no_show_all(True)
        self.h_box.remove(self.entry)
        self.h_box.pack_start(self.accel_align)
        self.h_box.pack_start(self.grab_area, False, False)
        #self.h_box.pack_start(self.del_button, False, False)
        self.grab_area.connect("button-press-event", self.__on_grab_area_button_press_cb)
        self.grab_area.connect("key-press-event", self.__on_grab_area_key_press_cb)
        self.grab_area.connect("key-release-event", self.__on_grab_area_key_release_cb)
        self.accel_label.connect("button-press-event", self.__on_label_button_press_cb)

        #self.accel_label.connect("enter-notify-event", self.__on_label_enter_cb)
        #self.accel_label.connect("leave-notify-event", self.__on_label_leave_cb)
        #self.del_button.connect("leave-notify-event", self.__on_del_button_leave_cb)

        self.del_button.connect("clicked", lambda w:self.emit("accel-del"))
        self.accel_label.keymap = {}

        self.check_conflict_func = check_conflict_func
        self.resolve_conflict_func = resolve_conflict_func
        self.process_unmodifier_func = process_unmodifier_func
        self.can_del = can_del

        widget_width = 200
        if self.can_del:
            widget_width = 220
            new_hbox = gtk.HBox()
            new_align = gtk.Alignment(0.5, 0.5, 1.0, 1.0)
            new_align.add(self.del_button)
            self.remove(self.align)
            self.pack_start(new_hbox, False, False)
            new_hbox.pack_start(self.align, False, False)
            new_hbox.pack_start(new_align, False, False)

        self.set_size(widget_width, 24)

        self.settings_description = ""
        self.settings_key = ""
        self.settings_obj = None
        self.settings_type = None
        self.settings_value_type = None
        self.connect("accel-key-change", self.__on_accel_key_change_cb)

    def __on_label_button_press_cb(self, widget, event):
        self.accel_label.set_text(_("Please input new shortcuts"))
        if gtk.gdk.keyboard_grab(self.grab_area.window, False, 0) != gtk.gdk.GRAB_SUCCESS:
            self.accel_label.set_text(self.accel_str)
            return None
        if gtk.gdk.pointer_grab(self.grab_area.window, False, gtk.gdk.BUTTON_PRESS_MASK, None, None, 0) != gtk.gdk.GRAB_SUCCESS:
            gtk.gdk.keyboard_ungrab(0)
            self.accel_label.set_text(self.accel_str)
            return None
        self.grab_area.grab_focus()
        if self.can_del and self.del_button in self.h_box.get_children():
            self.del_button.hide()
            self.h_box.remove(self.del_button)
        self.emit("wait-key-input", self.shortcut_key)
        
    def __on_grab_area_button_press_cb(self, widget, event):
        gtk.gdk.keyboard_ungrab(0)
        gtk.gdk.pointer_ungrab(0)
        self.accel_label.set_text(self.accel_str)

    def __on_grab_area_key_release_cb(self, widget, event):
        if not event.is_modifier:
            return False
        if not gtk.gdk.pointer_is_grabbed():
            return False
        event.state = event.state & (~gtk.gdk.MOD2_MASK) & (~gtk.gdk.MOD3_MASK) & (~gtk.gdk.MOD4_MASK) & (~gtk.gdk.MOD5_MASK)
        # is not Super key
        if not (event.keyval == gtk.keysyms.Super_R or event.keyval == gtk.keysyms.Super_L and 
                event.state == gtk.gdk.SUPER_MASK):
            return False
        gtk.gdk.keyboard_ungrab(0)
        gtk.gdk.pointer_ungrab(0)

        tmp_accel_buf = AccelBuffer()
        tmp_accel_buf.set_keyval(0)
        tmp_accel_buf.set_state(gtk.gdk.SUPER_MASK)

        if self.check_conflict_func and self.resolve_conflict_func:
            conflict_entry = self.check_conflict_func(self, tmp_accel_buf)
            if conflict_entry:
                self.resolve_conflict_func(self, conflict_entry, tmp_accel_buf)
                return
        self.set_keyval_and_state(0, gtk.gdk.SUPER_MASK)

    def __on_grab_area_key_press_cb(self, widget, event):
        if event.is_modifier:
            return False
        if not gtk.gdk.pointer_is_grabbed():
            return False
        gtk.gdk.keyboard_ungrab(0)
        gtk.gdk.pointer_ungrab(0)

        # HACK: we don't want to use SysRq as a keybinding, so we avoid  its translation from Alt+Print.
        if event.keyval == gtk.keysyms.Sys_Req and event.state & gtk.gdk.MOD1_MASK:
            event.keyval = gtk.keysyms.Print
        keyval = event.keyval
        state = event.state = event.state & (~gtk.gdk.MOD2_MASK)  # ignore MOD2_MASK
        # cancel edit
        if keyval == gtk.keysyms.Escape:
            self.accel_label.set_text(self.accel_str)
            return
        # clear edit
        if keyval == gtk.keysyms.BackSpace:
            self.set_keyval_and_state(0, 0)
            return
        tmp_accel_buf = AccelBuffer()
        tmp_accel_buf.set_keyval(keyval)
        tmp_accel_buf.set_state(state)
        if self.check_unmodified_keys(event) and self.process_unmodifier_func:
            self.accel_label.set_text(self.accel_str)
            self.process_unmodifier_func(tmp_accel_buf)
            return
        if self.check_conflict_func and self.resolve_conflict_func:
            conflict_entry = self.check_conflict_func(self, tmp_accel_buf)
            if conflict_entry:
                self.resolve_conflict_func(self, conflict_entry, tmp_accel_buf)
                return
        self.set_keyval_and_state(keyval, state)

    def reassign_cancel(self, widget=None):
        ''' cancel reassign when it conflict '''
        if widget:
            widget.destroy()
        self.accel_label.set_text(self.accel_str)
    
    def reassign(self, accel_buf, conflict_entry, widget=None):
        if widget:
            widget.destroy()
        conflict_entry.set_keyval_and_state(0, 0)
        self.set_keyval_and_state(accel_buf.get_keyval(), accel_buf.get_state())
    
    def check_unmodified_keys(self, event):
        #Check for unmodified keys
        state = event.state
        keyval = event.keyval
        state = event.state & (~gtk.gdk.MOD2_MASK)  # ignore MOD2_MASK
        forbidden_keyvals = [
            # Navigation keys
            gtk.keysyms.Home,
            gtk.keysyms.Left,
            gtk.keysyms.Up,
            gtk.keysyms.Right,
            gtk.keysyms.Down,
            gtk.keysyms.Page_Up,
            gtk.keysyms.Page_Down,
            gtk.keysyms.End,
            gtk.keysyms.Tab,
            # Return 
            gtk.keysyms.KP_Enter,
            gtk.keysyms.Return,
            gtk.keysyms.space,
            gtk.keysyms.Mode_switch]
        return (state == 0 or state == gtk.gdk.SHIFT_MASK) and (
                gtk.keysyms.a <= keyval <= gtk.keysyms.z or
                gtk.keysyms.A <= keyval <= gtk.keysyms.Z or
                gtk.keysyms._0 <= keyval <= gtk.keysyms._9 or
                gtk.keysyms.kana_fullstop <= keyval <= gtk.keysyms.semivoicedsound or
                gtk.keysyms.Arabic_comma <= keyval <= gtk.keysyms.Arabic_sukun or
                gtk.keysyms.Serbian_dje <= keyval <= gtk.keysyms.Cyrillic_HARDSIGN or
                gtk.keysyms.Greek_ALPHAaccent <= keyval <= gtk.keysyms.Greek_omega or
                gtk.keysyms.hebrew_doublelowline <= keyval <= gtk.keysyms.hebrew_taf or
                gtk.keysyms.Thai_kokai <= keyval <= gtk.keysyms.Thai_lekkao or
                gtk.keysyms.Hangul <= keyval <= gtk.keysyms.Hangul_Special or
                gtk.keysyms.Hangul_Kiyeog <= keyval <= gtk.keysyms.Hangul_J_YeorinHieuh or
                keyval in forbidden_keyvals)

    def set_keyval_and_state(self, keyval, state):
        self.accel_buffer.set_keyval(keyval)
        self.accel_buffer.set_state(state)
        self.emit("accel-key-change", self.accel_buffer.get_accel_name())
        self.accel_str = self.accel_buffer.get_accel_label()
        if not self.accel_str:
            self.accel_str = _('disable')
        self.accel_label.set_text(self.accel_str)
    
    def set_size(self, width, height):
        super(AccelEntry, self).set_size(width, height)
        if self.can_del:
            self.accel_align.set_size_request(width-20, height)
            self.accel_label.label_width = width - 20
            self.accel_label.set_size_request(width-20, height)
        else:
            self.accel_align.set_size_request(width, height)
            self.accel_label.label_width = width
            self.accel_label.set_size_request(width, height)

    def __on_accel_key_change_cb(self, widget, accel_name):
        if not self.settings_obj:
            return
        if self.settings_type == self.TYPE_GSETTINGS:
            if self.settings_value_type == self.TYPE_STRV:
                if accel_name:
                    self.settings_obj.set_strv(self.settings_key, [accel_name])
                else:
                    self.settings_obj.set_strv(self.settings_key, [])
            elif self.settings_value_type == self.TYPE_STRING:
                self.settings_obj.set_string(self.settings_key, accel_name)
        elif self.settings_type == self.TYPE_DP_GSETTINGS:
            self.settings_obj.set_string(self.settings_key, "%s;%s" %(self.settings_value_type, accel_name))
        elif self.settings_type == self.TYPE_CMP_GSETTINGS:
            settings.shortcuts_compiz_set(self.settings_plugin, self.settings_key, accel_name)
        elif self.settings_type == self.TYPE_GCONF:
            self.settings_obj.set_string("%s/binding" % (self.settings_key), accel_name)

    def __on_label_enter_cb(self, widget, event):
        if self.can_del:
            if self.del_button not in self.h_box.get_children():
                self.h_box.pack_start(self.del_button, False, False)
                self.del_button.show()

    def __on_label_leave_cb(self, widget, event):
        x, y, w, h = widget.allocation
        if not (0 < event.y < h) or event.x <= 0:
            if self.del_button in self.h_box.get_children():
                self.h_box.remove(self.del_button)
                self.del_button.hide()

    def __on_del_button_leave_cb(self, widget, event):
        x, y, w, h = widget.allocation
        if not (0 < event.y < h) or event.x >= w and self.del_button.get_visible():
            if widget in self.h_box.get_children():
                widget.hide()
                self.h_box.remove(self.del_button)
Ejemplo n.º 23
0
class SongEditor(DialogBox):    
    
    def __init__(self, songs, init_index=0):
        super(SongEditor, self).__init__(_("Property"), 500, 400, mask_type=DIALOG_MASK_TAB_PAGE)
        self.set_position(gtk.WIN_POS_CENTER)
        
        close_button = Button(_("Close"))
        close_button.connect("clicked", self.click_close_button)
        
        previous_button = Button(_("Previous"))
        previous_button.connect("clicked", lambda w : self.update_previous_song())
        next_button = Button(_("Next"))
        next_button.connect("clicked", lambda w : self.update_next_song())
        
        self.record_label = Label("0/0")
        
        action_box = gtk.HBox(spacing=5)
        action_box.pack_start(previous_button, False, False)
        action_box.pack_start(self.record_label, False, False)
        action_box.pack_start(next_button, False, False)
        
        MediaDB.connect("simple-changed", self.db_simple_changed)
        
        # action_box.
        if len(songs) <= 1:
            action_box.set_no_show_all(True)
        else:    
            self.record_label.set_text("%d/%d" % (init_index + 1, len(songs)))
        
        # tabs
        self.song_info = SongInfo(songs[init_index])
        self.info_setting = InfoSetting(songs[init_index])
        self.cover_setting = CoverSetting(songs[init_index])
        
        self.tab_box = TabBox()
        self.tab_box.add_items([(_("Track Infomation"), self.song_info),
                                (_("Edit tags"), self.info_setting),
                                (_("Edit cover"), self.cover_setting)])
        
        # DialogBox code, simple, ah? :)
        self.left_button_box.set_buttons([action_box])
        self.right_button_box.set_buttons([close_button])
        self.body_box.pack_start(self.tab_box, True, True)
        
        # Constants.
        self.current_index = init_index
        self.songs = songs
        
    def update_previous_song(self):    
        new_index = self.current_index - 1
        if self.is_vaild_index(new_index):
            self.current_index = new_index
            self.update_song(self.songs[new_index])
            self.update_record_label()
            
    def update_next_song(self):        
        new_index = self.current_index + 1
        if self.is_vaild_index(new_index):
            self.current_index = new_index
            self.update_song(self.songs[new_index])
            self.update_record_label()
        
    def is_vaild_index(self, index):    
        if 0 <= index < len(self.songs):
            return True
        return False
    
    def update_record_label(self):
        self.record_label.set_text("%d/%d" % (self.current_index + 1, len(self.songs)))
            
    def update_song(self, song):        
        self.song_info.update_song(song)
        self.info_setting.update_song(song)
        self.cover_setting.update_song(song)
        
    def db_simple_changed(self, widget, songs):    
        current_song = self.songs[self.current_index]
        if isinstance(songs, list):
            if self.songs[self.current_index] in songs:
                self.song_info.update_song(songs[songs.index(current_song)])
                self.cover_setting.update_song(songs[songs.index(current_song)])
        
    def click_close_button(self, widget):    
        self.destroy()
Ejemplo n.º 24
0
class GuideBox(gtk.VBox):
    def __init__(self):
        super(GuideBox, self).__init__()

        self.scrolled_window = ScrolledWindow()
        self.backgroundbox = BackgroundBox()
        self.backgroundbox.draw_mask = self.draw_mask

        self.guide_pixbuf = utils.get_common_image_pixbuf('guide.png')

        self.top_title = gtk.HBox()

        self.top_left_icon = gtk.VBox()
        self.top_left_icon.set_size_request(self.guide_pixbuf.get_width(), self.guide_pixbuf.get_height())
        self.top_left_icon.connect('expose-event', self.expose_top_left_icon)
        top_left_icon_align = gtk.Alignment(0.5, 0.5, 0, 0)
        top_left_icon_align.set_padding(15, 3, 13, 3)
        top_left_icon_align.add(self.top_left_icon)

        self.top_right_text = Label(_("Introduction"), ui_theme.get_color('label_select_background'), 14)
        top_right_text_align = gtk.Alignment(0.5, 0.5, 0, 0)
        top_right_text_align.set_padding(18, 3, 3, 3)
        top_right_text_align.add(self.top_right_text)

        self.top_title.pack_start(top_left_icon_align, False, False)
        self.top_title.pack_start(top_right_text_align, False, False)

        self.content_box = gtk.VBox()
        self.guide_label = Label('', enable_select=False, wrap_width=200, text_size=9, text_color=DynamicColor('#808080'))
        guide_label_align = gtk.Alignment(0.5, 0.5, 1, 1)
        guide_label_align.set_padding(5, 5, 10, 10)
        guide_label_align.add(self.guide_label)
        self.content_box.pack_start(guide_label_align, False, False)

        self.backgroundbox.pack_start(self.top_title, False, False)
        self.backgroundbox.pack_start(self.content_box)

        self.scrolled_window.add_child(self.backgroundbox)
        self.add(self.scrolled_window)

        global_event.register_event('download-app-info-finish', self.update_content)

    @post_gui
    def update_content(self, js):
        js = json.loads(js)
        self.guide_label.set_text(js['summary'])

    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.
        '''
        sidebar_color = "#ffffff"
        draw_vlinear(cr, x, y, w, h,
                     [(0, (sidebar_color, 0.9)),
                      (1, (sidebar_color, 0.9)),]
                     )
        
    def expose_top_left_icon(self, widget, event):
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation
        
        # Draw pkg icon.
        draw_pixbuf(cr,
                    self.guide_pixbuf,
                    rect.x,
                    rect.y)
Ejemplo n.º 25
0
class SearchUI(DialogBox):
    def __init__(self):
        DialogBox.__init__(
            self, _("Lyrics search"), 460, 300, DIALOG_MASK_MULTIPLE_PAGE, close_callback=self.hide_all, 
            modal=False, window_hint=None, skip_taskbar_hint=False, window_pos=gtk.WIN_POS_CENTER)
        
        self.artist_entry = InputEntry()
        self.artist_entry.set_size(130, 23)
        self.title_entry = InputEntry()
        self.title_entry.set_size(130, 23)
        artist_label = Label(_("Artist:"))
        title_label = Label(_("Title:"))
        right_align = gtk.Alignment()
        right_align.set(0, 0, 0, 1)
        
        self.search_button = Button(_("Search"))
        self.search_button.connect("clicked", self.search_lyric_cb)
        self.process_id = 0
        
        info_box = gtk.HBox(spacing=25)
        
        control_box = gtk.HBox(spacing=5)
        title_box = gtk.HBox(spacing=5)        
        title_box.pack_start(title_label, False, False)
        title_box.pack_start(self.title_entry)
        artist_box = gtk.HBox(spacing=5)
        artist_box.pack_start(artist_label, False, False)
        artist_box.pack_start(self.artist_entry)
        control_box.pack_start(title_box, False, False)
        control_box.pack_start(artist_box, False, False)
        
        info_box.pack_start(control_box, False, False)
        info_box.pack_start(self.search_button, False, False)
        
        sort_items = [ lambda items, reverse : self.sort_by_key(items, reverse, "title"),
                       lambda items, reverse : self.sort_by_key(items, reverse, "artist")]
        self.result_view = TreeView()
        self.result_view.set_expand_column(0)
        self.result_view.connect("double-click-item", self.double_click_cb)
        self.result_view.set_column_titles([_("Title"), _("Artist")], sort_items)
        self.result_view.draw_mask = self.draw_view_mask
        
        self.prompt_label = Label("")
        download_button = Button(_("Download"))
        download_button.connect("clicked", self.download_lyric_cb)
        cancel_button = Button(_("Close"))
        cancel_button.connect("clicked", lambda w: self.hide_all())
        
        info_box_align = gtk.Alignment()
        info_box_align.set_padding(5, 0, 5, 0)
        info_box_align.add(info_box)
        
        self.body_box.set_spacing(5)
        self.body_box.pack_start(info_box_align, False, False)
        self.body_box.pack_start(self.result_view, True, True)
        self.left_button_box.set_buttons([self.prompt_label])
        self.right_button_box.set_buttons([download_button, cancel_button])
        self.lrc_manager = LrcManager()
        
    def show_window(self):    
        DialogBox.show_window(self)
        self.present()
                
    def draw_view_mask(self, cr, x, y, width, height):            
        draw_alpha_mask(cr, x, y, width, height, "layoutMiddle")
        
    def sort_by_key(self, items, sort_reverse, sort_key):    
        return sorted(items, reverse=sort_reverse, key=lambda item: getattr(item, sort_key))
        
    def double_click_cb(self, widget, item, colume, x, y):   
        self.download_lyric_cb(widget)
        
    def search_engine(self, artist, title, pid):    
        
        ting_result = poster.query_lrc_info(artist, title)
        self.render_lyrics(ting_result, pid=pid)
        
        ttplayer_result = TTPlayer().request(artist, title)
        self.render_lyrics(ttplayer_result, pid=pid)
        
        ttpod_result = TTPod().request(artist, title)        
        self.render_lyrics(ttpod_result, pid=pid)
        
        duomi_result = DUOMI().request(artist, title)
        self.render_lyrics(duomi_result, pid=pid, last=True)
        
        
    def search_lyric_cb(self, widget):
        self.result_view.clear()
        artist = self.artist_entry.entry.get_text()
        title = self.title_entry.entry.get_text()
        # widget.set_sensitive(False)
        self.prompt_label.set_text(_("Now searching..."))
        if artist == "" and title == "":
            self.prompt_label.set_text(_("Not found!"))
            return
        self.process_id += 1
        utils.ThreadLoad(self.search_engine, artist, title, self.process_id).start()
        
    @post_gui
    def render_lyrics(self, result, last=False, pid=1):
        '''docs'''
        if pid != self.process_id:
            return
        
        if result != None:
            try:
                items = [SearchItem(each_info) for each_info in result]
            except:    
                pass
            else:
                self.result_view.add_items(items)

            self.prompt_label.set_text(_("%d lyrics found") % len(self.result_view.get_items()))
        else:    
            if last:
                if len(self.result_view.get_items()) > 0:
                    self.prompt_label.set_text(_("%d lyrics found") % len(self.result_view.get_items()))
                else:
                    self.prompt_label.set_text(_("Not found!"))
                    

    def download_lyric_cb(self, widget):
        select_items = self.result_view.select_rows
        save_filepath = self.lrc_manager.get_lrc_filepath(Player.song)
        if len(select_items) > 0:
            self.prompt_label.set_text(_("Downloading lyrics..."))
            item = self.result_view.get_items()[select_items[0]]
            url = item.get_url()
            net_encode = item.get_netcode()
            utils.ThreadRun(utils.download, self.render_download, [url, save_filepath, net_encode]).start()
            
    @post_gui        
    def render_download(self, result):
        if result:
            Dispatcher.reload_lrc(Player.song)
            self.prompt_label.set_text("%s %s" % (_("File save to"), config.get("lyrics", "save_lrc_path")))
        else:    
            self.prompt_label.set_text(_("Download failed."))
class LocalPicturePage(gtk.VBox):
    def __init__(self, monitor_dir):

        gtk.VBox.__init__(self)
        self.set_spacing(10)
        self.select_view = SelectView(monitor_dir, filter_dir=["deepin-wallpapers"], add_system=True)
        self.select_view.connect("items-change", self.select_view_item_changed)
        self.select_view.connect("double-click-item", self.select_view_double_clicked)
        self.select_view_sw = self.select_view.get_scrolled_window()               

        no_favorites_label = Label(_("Your Local Pictures folder is empty"))
        self.no_favorites_align = gtk.Alignment(0.5, 0.5, 0, 0)
        self.no_favorites_align.add(no_favorites_label)

        self.notice_label = Label("")

        set_wallpapper_button = Button(_("Set as wallpaper"))
        set_wallpapper_button.connect("clicked", self.__on_set_as_wallpapper)

        favorite_button = Button(_("Add to Favorites"))
        favorite_button.connect("clicked", self.__on_add_favorites)

        delete_button = Button(_("Delete"))
        delete_button.connect("clicked", self.__on_delete)

        self.button_box = gtk.HBox(spacing=10)
        self.button_box.pack_start(set_wallpapper_button, False, False)
        self.button_box.pack_start(favorite_button, False, False)
        self.button_box.pack_start(delete_button, False, False)
                                                                                   
        self.control_box = gtk.HBox()
        self.control_box.set_size_request(-1, 20)
        self.control_box.pack_start(self.notice_label, False, False)
                                                                                
        self.control_align = gtk.Alignment()                                         
        self.control_align.set(0.5, 0.5, 1, 1)
        self.control_align.set_padding(0, 5, 20, 10)
        self.control_align.add(self.control_box)

        if len(self.select_view.items) == 0:
            self.pack_start(self.no_favorites_align, True, True)
        else:
            self.pack_start(self.select_view_sw, True, True)
        self.pack_start(self.control_align, False, True)
  
        event_manager.add_callback("select-select-wallpaper", self.__on_select_select_wallpaper)

        self.timeout_notice_hide_id = None

    def __on_set_as_wallpapper(self, widget, data=None):
        self.select_view.set_multi_wallpapper()
        n = self.select_view.get_select_number()
        if n > 1:
            notice_text = _("%s pictures are set as wallpaper") % n
        else:
            notice_text = _("%s picture is set as wallpaper") % n
        self.notice_label.set_text(notice_text)
        self.timeout_notice_hide()

    def select_view_double_clicked(self, widget, item, x, y):
        image_path_string = "file://%s;" % item.image_path
        background_gsettings.set_string("picture-uris", image_path_string)        

    def select_view_item_changed(self, widget):
        if len(self.select_view.items) == 0:
            container_remove_all(self)
            self.pack_start(self.no_favorites_align, True, True)
            self.pack_end(self.control_align, False, True)
        else:
            container_remove_all(self)
            self.pack_start(self.select_view_sw, True, True)
            self.pack_end(self.control_align, False, True)

    def timeout_notice_hide(self, time=3000):
        if self.timeout_notice_hide_id:
            gtk.timeout_remove(self.timeout_notice_hide_id)
        gtk.timeout_add(time, lambda: self.notice_label.set_text(""))

    def __on_add_favorites(self, widget, data=None):
        self.select_view.add_favorites()
        n = self.select_view.get_select_number()
        if n > 1:
            notice_text = _("add %s pictures to Favorites") % n
        else:
            notice_text = _("add %s picture to Favorites") % n
        self.notice_label.set_text(notice_text)
        self.timeout_notice_hide()

    def __delete_confirm(self):
        self.select_view.delete()
        n = self.select_view.get_select_number()
        if n > 1:
            notice_text = _("delete %s pictures") % n
        else:
            notice_text = _("delete %s picture") % n
        self.notice_label.set_text(notice_text)
        self.timeout_notice_hide()
        if self.button_box in self.control_box.get_children():
            self.control_box.remove(self.button_box)

    def __on_delete(self, widget):
        dlg = ConfirmDialog(_("Delete Wallpaper"),
                            _("Are you sure delete wallpaper?"), 
                            300,                                                
                            100,                                                
                            lambda : self.__delete_confirm(),
                            None,                                               
                            True, 
                            CONTENT_FONT_SIZE)                                               
        dlg.show_all()

    def __on_select_select_wallpaper(self, name, obj, select_item):             
        select_number = self.select_view.get_select_number()
        if select_number > 0:
            if select_number > 1:
                notice_text = _("choose %s pictures") % select_number
            else:
                notice_text = _("choose %s picture") % select_number
            self.notice_label.set_text(notice_text)
            if self.button_box not in self.control_box.get_children():
                self.control_box.pack_end(self.button_box, False, False)
        else:
            self.notice_label.set_text("")
            if self.button_box in self.control_box.get_children():
                self.control_box.remove(self.button_box)
        self.show_all()

    def on_add_wallpapers(self, widget):                                        
        event_manager.emit("add-local-wallpapers", None)
class IconSetPage(gtk.VBox):
    def __init__(self, account_setting):
        super(IconSetPage, self).__init__(False)
        #self.set_spacing(BETWEEN_SPACING)
        self.account_setting = account_setting

        self.choose_menu_without_camera = Menu(
            [(None, _("Local picture"), self.choose_from_picture), (None, _("Take a screeshot"), self.choose_from_screenshot),], True)
        self.choose_menu_with_camera = Menu(
            [(None, _("Local picture"), self.choose_from_picture),
             (None, _("Take a screeshot"), self.choose_from_screenshot),
             (None, _("From camera"), self.choose_from_camera)], True)
        self.tips_label = Label("Set icon", label_width=460, enable_select=False, enable_double_click=False)
        self.error_label = Label("", wrap_width=560, enable_select=False, enable_double_click=False)

        set_page_sw = ScrolledWindow()
        self.pack_start(set_page_sw)
        main_vbox = gtk.VBox(False)
        set_page_sw.add_child(main_vbox)
        self.icon_list_tabel = gtk.Table()
        self.icon_list_tabel.set_row_spacings(4)
        self.icon_list_tabel.set_col_spacings(4)
        main_vbox.pack_start(tools.make_align(self.tips_label), False, False)
        main_vbox.pack_start(tools.make_align(height=20), False, False)

        self.history_list_hbox = gtk.HBox(False)
        self.history_list_hbox.set_size_request(-1, 56)
        self.history_list_hbox.set_spacing(4)

        main_vbox.pack_start(tools.make_align(Label(_("Choose a new picture for your account"), label_width=460, enable_select=False, enable_double_click=False), height=CONTAINNER_HEIGHT), False, False)
        main_vbox.pack_start(tools.make_align(self.icon_list_tabel), False, False)
        main_vbox.pack_start(tools.make_align(height=20), False, False)

        main_vbox.pack_start(tools.make_align(Label(_("Previously used pictures"), label_width=460, enable_select=False, enable_double_click=False), height=CONTAINNER_HEIGHT), False, False)
        main_vbox.pack_start(tools.make_align(self.history_list_hbox), False, False)
        main_vbox.pack_start(tools.make_align(height=20), False, False)

        main_vbox.pack_start(tools.make_align(self.error_label), False, False)

        # public picture list
        #face_dir = '/usr/share/pixmaps/faces'
        face_dir = '/var/lib/AccountsService/icons'
        if os.path.exists(face_dir):
            pic_list = os.listdir(face_dir)
        else:
            pic_list = []
        pic_list.sort()
        self.public_icon_list = []
        inital_list = ['001.jpg', '002.jpg', '003.jpg', '004.jpg', '005.jpg',
                       '006.jpg', '007.jpg', '008.jpg', '009.jpg', '010.jpg',
                       '011.jpg', '012.jpg', '013.jpg', '014.jpg', '015.jpg',
                       '016.jpg', '017.jpg', '018.jpg', '019.jpg', '020.jpg']

        for pic in pic_list:
            if pic not in inital_list:
                continue
            try:
                icon_pixbuf = gtk.gdk.pixbuf_new_from_file(
                    "%s/%s" %(face_dir, pic)).scale_simple(48, 48, gtk.gdk.INTERP_TILES)
            except:
                continue
            icon_bt = IconButton(icon_pixbuf, "%s/%s" %(face_dir, pic), has_frame=True)
            icon_bt.connect("pressed", self.on_icon_bt_pressed_cb)
            self.public_icon_list.append(icon_bt)

        self.more_icon_button = IconButton(app_theme.get_pixbuf("%s/more.png" % MODULE_NAME).get_pixbuf(), has_frame=True)
        self.more_icon_button.connect("button-press-event", self.choose_more_picture)
        main_vbox.connect("expose-event", self.draw_white_background)

    def refresh(self):
        self.error_label.set_text("")
        if not self.account_setting.current_set_user:
            return
        if self.account_setting.current_set_user.get_real_name():
            show_name = self.account_setting.current_set_user.get_real_name()
        else:
            show_name = self.account_setting.current_set_user.get_user_name()
        self.tips_label.set_text("<b>%s</b>" % _("Set <u>%s</u>'s picture") % tools.escape_markup_string(show_name))
        self.history_icon = HistroyIcon(self.account_setting.current_set_user)
        self.history_icon.get_history()
        self.history_list_hbox.foreach(lambda w: w.destroy())

        # the private history icon files
        history_dir = os.path.join(self.account_setting.current_set_user.get_home_directory(), ".config/deepin-system-settings/account/icons")
        if os.path.exists(history_dir):
            pic_list = os.listdir(history_dir)
        else:
            pic_list = []
        pic_list.sort()
        private_icon_list = []
        for pic in pic_list:
            try:
                icon_pixbuf = gtk.gdk.pixbuf_new_from_file(
                    "%s/%s" %(history_dir, pic)).scale_simple(48, 48, gtk.gdk.INTERP_TILES)
            except:
                continue
            pic_file_path = "%s/%s" %(history_dir, pic)
            icon_bt = IconButton(icon_pixbuf, pic_file_path,
                                 has_frame=True, can_del=check_file_writable(pic_file_path))
            icon_bt.connect("pressed", self.on_icon_bt_pressed_cb)
            private_icon_list.append(icon_bt)
        container_remove_all(self.icon_list_tabel)

        pic_list = self.public_icon_list + private_icon_list
        total_pic = len(pic_list)
        rows = (total_pic + 1) / 10 + 1
        self.icon_list_tabel.resize(rows, 10)
        i = j = 0
        for pic in pic_list:
            self.icon_list_tabel.attach(pic, i, i+1, j, j+1, 4)
            if pic.can_del:
                pic.row = j
                pic.col = i
                pic.connect("del-pressed", self.on_icon_bt_del_icon_file_cb)
            i += 1
            if i >= 10:
                i = 0
                j += 1
        self.icon_list_tabel.attach(self.more_icon_button, i, i+1, j, j+1, 4)

        # history pic IconButton
        icon_button_list = pic_list
        i = 0
        for pic in self.history_icon.history:
            if not os.path.exists(pic):
                continue
            icon_pixbuf = None
            for bt in icon_button_list:
                if pic == bt.get_image_path():
                    icon_pixbuf = bt.pixbuf
                    break
            if not icon_pixbuf:
                try:
                    icon_pixbuf = gtk.gdk.pixbuf_new_from_file(pic).scale_simple(48, 48, gtk.gdk.INTERP_TILES)
                except Exception, e:
                    print e
                    continue
            if i >= 10:
                break
            i += 1
            icon_bt = IconButton(icon_pixbuf, pic, has_frame=True, can_del=True)
            icon_bt.connect("pressed", self.on_icon_bt_pressed_cb)
            icon_bt.connect("del-pressed", self.on_icon_bt_del_pressed_cb)
            self.history_list_hbox.pack_start(icon_bt, False, False)
        self.history_list_hbox.show_all()
class BlueToothView(gtk.VBox):
    '''
    class docs
    '''

    def __init__(self, module_frame):
        '''
        init docs
        '''
        gtk.VBox.__init__(self)

        self.module_frame = module_frame

        self.my_bluetooth = MyBluetooth(self.__on_adapter_removed,
                                        self.__on_default_adapter_changed,
                                        self.__device_found)
        self.periodic_timer = None
        self.is_discoverable = False
        self.is_searching = False
        '''
        enable open
        '''
        if self.my_bluetooth.adapter:
            self.my_bluetooth.adapter.connect("property-changed", self.__on_property_changed)
            if self.my_bluetooth.adapter.get_powered():
                self.title_align, self.title_label = self.__setup_title_align(
                    app_theme.get_pixbuf("bluetooth/enable_open.png"), _("Bluetooth"))
                self.title_label.set_sensitive(True)
            else:
                self.title_align, self.title_label = self.__setup_title_align(
                    app_theme.get_pixbuf("bluetooth/enable_open_disable.png"), _("Bluetooth"))
        else:
            self.title_align, self.title_label = self.__setup_title_align(
                app_theme.get_pixbuf("bluetooth/enable_open_disable.png"), _("Bluetooth"))
            self.title_label.set_sensitive(False)
        self.enable_align = self.__setup_align()
        self.enable_box = gtk.HBox(spacing=WIDGET_SPACING)
        self.enable_open_label = self.__setup_label(_("Enable bluetooth"))
        if self.my_bluetooth.adapter:
            self.my_bluetooth.adapter.set_powered(permanent_settings.get_powered())
            self.enable_open_label.set_sensitive(self.my_bluetooth.adapter.get_powered())
        else:
            self.enable_open_label.set_sensitive(False)
        self.enable_open_toggle_align = self.__setup_align(padding_top = 4, padding_left = 158)
        self.enable_open_toggle = self.__setup_toggle()
        if self.my_bluetooth.adapter:
            self.enable_open_toggle.set_active(self.my_bluetooth.adapter.get_powered())
        self.enable_open_toggle.connect("toggled", self.__toggled, "enable_open")
        self.enable_open_toggle_align.add(self.enable_open_toggle)
        self.__widget_pack_start(self.enable_box,
                                 [self.enable_open_label,
                                  self.enable_open_toggle_align])
        self.enable_align.add(self.enable_box)
        '''
        display
        '''
        self.display_align = self.__setup_align()
        self.display_box = gtk.HBox(spacing=WIDGET_SPACING)
        self.display_device_label = self.__setup_label(_("Device name"))
        if self.my_bluetooth.adapter:
            self.display_device_label.set_sensitive(self.my_bluetooth.adapter.get_powered())
        else:
            self.display_device_label.set_sensitive(False)
        self.display_device_entry = InputEntry()
        if self.my_bluetooth.adapter:
            self.display_device_entry.set_text(self.my_bluetooth.adapter.get_name())
            self.display_device_entry.set_sensitive(self.my_bluetooth.adapter.get_powered())
        else:
            self.display_device_entry.set_sensitive(False)
        self.display_device_entry.set_size(HSCALEBAR_WIDTH, WIDGET_HEIGHT)
        self.display_device_entry.entry.connect("changed", self.__display_device_changed)
        self.__widget_pack_start(self.display_box,
                                 [self.display_device_label, self.display_device_entry])
        self.display_align.add(self.display_box)
        '''
        enable searchable
        '''
        self.search_align = self.__setup_align()
        self.search_box = gtk.HBox(spacing=WIDGET_SPACING)
        self.search_label = self.__setup_label(_("Discoverable"))
        if self.my_bluetooth.adapter:
            self.search_label.set_sensitive(self.my_bluetooth.adapter.get_powered())
        else:
            self.search_label.set_sensitive(False)
        self.search_timeout_align = self.__setup_align(padding_top = 0, padding_left = 0)
        self.search_timeout_label = self.__setup_label("", width = 110, align = ALIGN_START)
        self.search_timeout_align.add(self.search_timeout_label)
        self.search_toggle_align = self.__setup_align(padding_top = 4, padding_left = 18)
        self.search_toggle = self.__setup_toggle()
        if self.my_bluetooth.adapter:
            self.search_toggle.set_active(self.my_bluetooth.adapter.get_discoverable())
        self.search_toggle.connect("toggled", self.__toggled, "search")
        self.search_toggle_align.add(self.search_toggle)
        self.__widget_pack_start(self.search_box,
                                 [self.search_label,
                                  self.search_timeout_align,
                                  self.search_toggle_align
                                 ])
        self.search_align.add(self.search_box)
        '''
        device iconview
        '''
        self.device_align = self.__setup_align()
        self.device_iconview = DeviceIconView()
        self.device_iconview.set_size_request(690, 228)
        self.device_align.add(self.device_iconview)
        '''
        operation
        '''
        self.oper_align = self.__setup_align()
        self.oper_box = gtk.HBox(spacing = WIDGET_SPACING)
        self.notice_label = Label("", text_x_align = ALIGN_START, label_width = 610)
        self.search_button = Button(_("Search"))
        if self.my_bluetooth.adapter:
            self.search_button.set_sensitive(self.my_bluetooth.adapter.get_powered())
        else:
            self.search_button.set_sensitive(False)
        self.search_button.connect("clicked", self.__on_search)
        self.__widget_pack_start(self.oper_box,
                [self.notice_label,
                 self.search_button,
                ])
        self.oper_align.add(self.oper_box)
        '''
        this->gtk.VBox pack_start
        '''
        self.__widget_pack_start(self,
                                 [self.title_align,
                                  self.enable_align,
                                  self.display_align,
                                  self.search_align,
                                  self.device_align,
                                  self.oper_align])

        if self.my_bluetooth.adapter == None:
            self.set_sensitive(False)

        self.connect("expose-event", self.__expose)

        if self.my_bluetooth.adapter and self.my_bluetooth.adapter.get_powered():
            self.__get_devices()

    def __on_property_changed(self, adapter, key, value):
        if key == "Powered":
            if value == 1:
                self.enable_open_toggle.set_active(True)
                # removed by hualet, this will cause devices are added twice.
                # self.__set_enable_open(True)
            else:
                self.enable_open_toggle.set_active(False)
                # self.__set_enable_open(False)
        if key == "Devices":    # fixbug: iconview didn't update accordingly 
                                # while adapter paired other devices in system tray. 
            self.device_iconview.clear()
            self.__get_devices()

    def sendfile(self, device_name):
        event_manager.emit("send-file", device_name)

    def cancel(self):
        event_manager.emit("cancel", None)

    def __on_adapter_removed(self):
        self.set_sensitive(False)

    def __on_default_adapter_changed(self):
        self.set_sensitive(True)
        self.display_device_entry.set_text(self.my_bluetooth.adapter.get_name())

    def __display_device_changed(self, widget, event):
        self.my_bluetooth.adapter.set_name(widget.get_text())

    def __setup_separator(self):
        hseparator = HSeparator(app_theme.get_shadow_color("hSeparator").get_color_info(), 0, 0)
        hseparator.set_size_request(500, HSEPARATOR_HEIGHT)
        return hseparator

    def __setup_title_label(self,
                            text="",
                            text_color=app_theme.get_color("globalTitleForeground"),
                            text_size=TITLE_FONT_SIZE,
                            text_x_align=ALIGN_START,
                            label_width=180):
        return Label(text = text,
                     text_color = text_color,
                     text_size = text_size,
                     text_x_align = text_x_align,
                     label_width = label_width,
                     enable_select = False,
                     enable_double_click = False)

    def __setup_title_align(self,
                            pixbuf,
                            text,
                            padding_top=TEXT_WINDOW_TOP_PADDING,
                            padding_left=TEXT_WINDOW_LEFT_PADDING):
        align = self.__setup_align(padding_top = padding_top, padding_left = padding_left)
        align_box = gtk.VBox(spacing = WIDGET_SPACING)
        title_box = gtk.HBox(spacing = WIDGET_SPACING)
        image = ImageBox(pixbuf)
        label = self.__setup_title_label(text)
        separator = self.__setup_separator()
        self.__widget_pack_start(title_box, [image, label])
        self.__widget_pack_start(align_box, [title_box, separator])
        align.add(align_box)
        return align, label

    def __get_devices(self):
        devices = self.my_bluetooth.get_devices()
        items = []
        i = 0

        while i < len(devices):
            items.append(DeviceItem(devices[i].get_name(),
                         app_theme.get_pixbuf("bluetooth/%s.png" % bluetooth_class_to_type(devices[i].get_class())).get_pixbuf(),
                         devices[i],
                         self.my_bluetooth.adapter,
                         devices[i].get_paired(),
                         self.module_frame))
            i += 1

        self.device_iconview.add_items(items)

    def __refresh_notice_label(self):
        searching_str = _("Discovering device")

        if self.notice_label.get_text().count(".") == 3:
            self.notice_label.set_text(searching_str + ".")
        else:
            self.notice_label.set_text(self.notice_label.get_text() + ".")

        return True

    def __on_search(self, widget):
        if not self.is_searching:
            self.my_bluetooth.adapter.start_discovery()
            self.notice_label.set_text(_("Discovering device"))
            self.refresh_lable_timeout = gobject.timeout_add_seconds(1, self.__refresh_notice_label)
            self.my_bluetooth.adapter.connect("property-changed", self.on_adapter_property_changed)
            self.is_searching = True
            
    def on_adapter_property_changed(self, obj, key, value):
        if key == "Discovering" and value == False:
            gobject.source_remove(self.refresh_lable_timeout)
            if self.is_searching:
                self.my_bluetooth.adapter.stop_discovery()
            self.is_searching = False
            self.notice_label.set_text("")

    def __device_found(self, adapter, address, values):
        print "address", address
        if address not in adapter.get_address_records():
            device_path = adapter.create_device(address)
            if device_path == "None":
                return 
            
            device = Device(device_path)
            items = []
        
            if not values.has_key("Name"):
                return
        
            print bluetooth_class_to_type(device.get_class())
            items.append(DeviceItem(values['Name'],
                                    app_theme.get_pixbuf("bluetooth/%s.png" 
                                                         % bluetooth_class_to_type(device.get_class())).get_pixbuf(), 
                                    device, 
                                    adapter))
            self.device_iconview.add_items(items)
                
    def __set_enable_open(self, is_open=True):
        self.enable_open_label.set_sensitive(is_open)
        self.display_device_label.set_sensitive(is_open)
        self.search_label.set_sensitive(is_open)
        self.display_align.set_sensitive(is_open)
        self.display_device_entry.set_sensitive(is_open)
        # self.device_iconview.set_sensitive(is_open)
        self.search_align.set_sensitive(is_open)
        self.search_timeout_label.set_child_visible(False)
        self.search_button.set_sensitive(is_open)
        # changed by hualet, to fix the bug that device icons stay while disabling the iconview widget
        if is_open:
            self.__get_devices()
        else:
            self.device_iconview.clear()

    def __toggled(self, widget, object):
        if self.my_bluetooth.adapter == None:
            return

        if object == "enable_open":
            self.__set_enable_open(widget.get_active())
            permanent_settings.set_powered(widget.get_active())
            self.my_bluetooth.adapter.set_powered(widget.get_active())
            return

        if object == "search":
            self.is_discoverable = widget.get_active()
            self.my_bluetooth.adapter.set_discoverable(self.is_discoverable)
            self.search_timeout_label.set_child_visible(self.is_discoverable)
            if self.is_discoverable:
                self.periodic_timer = PerodicTimer(self, 1)
            else:
                self.periodic_timer.stop()
            return

    def __expose(self, widget, event):
        cr = widget.window.cairo_create()
        rect = widget.allocation

        cr.set_source_rgb(*color_hex_to_cairo(MODULE_BG_COLOR))
        cr.rectangle(rect.x, rect.y, rect.width, rect.height)
        cr.fill()

    def __setup_label(self, text="", width=180, align=ALIGN_END):
        return Label(text, None, TITLE_FONT_SIZE, align, width, False, False, False)

    def __setup_combo(self, items=[], width=HSCALEBAR_WIDTH):
        combo = ComboBox(items, None, 0, width, width)
        combo.set_size_request(width, WIDGET_HEIGHT)
        return combo

    def __setup_toggle(self):
        return ToggleButton(
                app_theme.get_pixbuf("toggle_button/inactive_normal.png"),
                app_theme.get_pixbuf("toggle_button/active_normal.png"),
                inactive_disable_dpixbuf = app_theme.get_pixbuf("toggle_button/inactive_normal.png"),
                active_disable_dpixbuf = app_theme.get_pixbuf("toggle_button/inactive_normal.png"))

    def __setup_align(self, xalign=0, yalign=0, xscale=0, yscale=0,
                      padding_top=BETWEEN_SPACING,
                      padding_bottom=0,
                      padding_left=TEXT_WINDOW_LEFT_PADDING,
                      padding_right=20):
        align = gtk.Alignment()
        align.set(xalign, yalign, xscale, yscale)
        align.set_padding(padding_top, padding_bottom, padding_left, padding_right)
        return align

    def __widget_pack_start(self, parent_widget, widgets=[], expand=False, fill=False):
        if parent_widget == None:
            return
        for item in widgets:
            parent_widget.pack_start(item, expand, fill)
Ejemplo n.º 29
0
 volume_frame.set_padding(0, 0, 10, 0)
 volume_frame.add(volume_button)
 tab_1_box.pack_start(volume_frame, False, False)
 
 # Add entry widget.
 entry_button = ImageButton(
     app_theme.get_pixbuf("entry/search_normal.png"),
     app_theme.get_pixbuf("entry/search_hover.png"),
     app_theme.get_pixbuf("entry/search_press.png"),
     )
 # entry = TextEntry("Linux Deepin")
 entry = InputEntry("Linux Deepin")
 entry.connect("action-active", print_entry_action)
 entry.set_size(150, 24)
 entry_label = Label("标签测试, 内容非常长")
 entry_label.set_text("标签的内容")
 entry_label.set_size_request(100, 30)
 entry_box = gtk.HBox(spacing=10)
 entry_box.pack_start(entry_label, False, False)
 entry_box.pack_start(entry, True, True)
 
 shortcust_entry = ShortcutKeyEntry("Ctrl + Alt + Q")
 shortcust_entry.set_size(150, 24)
 entry_box.pack_start(shortcust_entry, False, False)
 
 test_button = Button("测试")
 test_button.connect("clicked", clicked_test)
 entry_box.pack_start(test_button, False, False)
 
 color_button = ColorButton()
 entry_box.pack_start(color_button, False, False)
Ejemplo n.º 30
0
class DetailPage(gtk.HBox):
    '''
    class docs
    '''

    PADDING_Y = 20

    ICON_SIZE = 64
    ICON_PADDING_X = 50

    STAR_PADDING_X = 36
    STAR_PADDING_Y = 12
    STAR_SIZE = 13

    MARK_NUMBER_SIZE = 11
    MARK_NUMBER_PADDING_X = 4
    MARK_NUMBER_PADDING_Y = 10

    INFO_RENDER_X = 10
    INFO_RENDER_Y = 140
    INFO_RENDER_HEIGHT = 18
    INFO_CATEGORY_RENDER_Y = INFO_RENDER_Y + INFO_RENDER_HEIGHT
    INFO_VERSION_RENDER_Y = INFO_RENDER_Y + INFO_RENDER_HEIGHT * 2
    INFO_SIZE_RENDER_Y = INFO_RENDER_Y + INFO_RENDER_HEIGHT * 3
    INFO_DOWNLOAD_RENDER_Y = INFO_RENDER_Y + INFO_RENDER_HEIGHT * 4
    INFO_HOMEPAGE_RENDER_Y = INFO_RENDER_Y + INFO_RENDER_HEIGHT * 5

    LEFT_INFO_PADDING_X = 18
    LEFT_INFO_PADDING_Y = 50

    LEFT_BUTTON_PADDING_Y = 50

    LEFT_INFO_WIDTH = 164

    RIGHT_INFO_PADDING_X = 30

    RIGHT_TITLE_BOX_HEIGHT = 70

    ALIAS_NAME_SIZE = 16
    ALIAS_NAME_PADDING_Y = 20

    LONG_DESC_PADDING_Y = 10
    LONG_DESC_WRAP_WIDTH = 630
    LONG_DESC_INIT_HEIGHT = 45

    MARK_SIZE = 11
    MARK_PADDING_X = 5
    MARK_PADDING_Y = -3

    def __init__(self, data_manager):
        '''
        init docs
        '''
        gtk.HBox.__init__(self)
        self.data_manager = data_manager
        self.pkg_name = None
        self.alias_name = ""
        self.pkg_pixbuf = None
        self.pkg_star_view = None

        self.left_view_box = gtk.VBox()
        self.left_view_box.set_size_request(self.LEFT_INFO_WIDTH, -1)

        self.left_logo_box = gtk.VBox()
        self.left_logo_box.set_size_request(-1, 90)

        self.star_box = gtk.HBox()
        self.star_align = gtk.Alignment(0.4, 0.5, 0, 0)
        self.star_align.set_padding(0, 5, 0, 0)
        self.star_align.add(self.star_box)

        self.left_action_box = gtk.HBox()
        self.left_action_align = gtk.Alignment()
        self.left_action_align.set(0.5, 0.5, 0, 0)
        self.left_action_align.set_padding(0, 30, 0, 0)
        self.left_action_align.add(self.left_action_box)

        self.left_label_table = gtk.Table(4, 1)
        self.left_label_table.set_row_spacings(4)

        self.left_label_align = gtk.Alignment()
        self.left_label_align.set(0.0, 0.5, 0, 0)
        self.left_label_align.set_padding(0, 0, 14, 0)

        self.left_category_name_label = Label()
        self.left_category_label = Label(
            hover_color=app_theme.get_color("homepage_hover"))
        self.left_category_label.set_clickable()
        self.left_category_label_align = gtk.Alignment()
        self.left_category_label_align.set(0.0, 0.5, 0, 0)
        self.left_category_label_align.add(self.left_category_label)
        self.left_category_label_box = gtk.HBox()
        self.left_category_label_box.pack_start(self.left_category_name_label,
                                                False, False)
        self.left_category_label_box.pack_start(self.left_category_label_align,
                                                True, True)
        self.left_category_box = gtk.VBox()
        self.left_version_label = Label(label_width=136)
        show_label_tooltip(self.left_version_label)
        self.left_version_label.set_ellipsize(pango.ELLIPSIZE_END)
        self.left_download_label = Label()
        self.left_size_label = Label()

        self.left_homepage_box = gtk.HBox()
        self.left_homepage_box_align = gtk.Alignment()
        self.left_homepage_box_align.set(0.0, 0.5, 0, 0)
        self.left_homepage_box_align.add(self.left_homepage_box)

        self.left_recommend_box = gtk.VBox()
        self.left_recommend_box_align = gtk.Alignment()
        self.left_recommend_box_align.set(0.0, 0.0, 0, 0)
        self.left_recommend_box_align.set_padding(30, 0, 14, 0)
        self.left_recommend_box_align.add(self.left_recommend_box)

        self.left_recommend_label = Label(_("Popular recommendations"))

        self.right_info_box = gtk.VBox()
        self.scrolled_window = ScrolledWindow(0, 0)
        self.right_view_box = gtk.VBox()

        self.right_top_box = gtk.HBox()
        self.right_top_box.set_size_request(-1, self.RIGHT_TITLE_BOX_HEIGHT)
        self.right_desc_box = gtk.VBox()
        self.right_slide_box = gtk.VBox()
        self.right_comment_box = gtk.VBox()

        self.right_title_box = gtk.VBox()

        self.return_button = ImageButton(
            app_theme.get_pixbuf("detail/normal.png"),
            app_theme.get_pixbuf("detail/hover.png"),
            app_theme.get_pixbuf("detail/press.png"),
        )
        self.return_align = gtk.Alignment()
        self.return_align.set(0.5, 0.5, 1, 1)
        self.return_align.set_padding(self.ALIAS_NAME_PADDING_Y, 0, 0,
                                      self.RIGHT_INFO_PADDING_X)
        self.return_align.add(self.return_button)

        self.return_button.connect(
            "clicked", lambda w: global_event.emit("switch-from-detail-page"))

        self.right_top_box.pack_start(self.right_title_box, True, True)
        self.right_top_box.pack_start(self.return_align, False, False)

        self.right_view_box.pack_start(self.right_top_box, False, False)
        self.right_view_box.pack_start(self.right_desc_box, False, False)
        self.right_view_box.pack_start(self.right_slide_box, False, False)
        self.right_view_box.pack_start(self.right_comment_box, False, False)
        self.scrolled_window.add_child(self.right_view_box)

        self.left_view_box.pack_start(self.left_logo_box, False, False)
        self.left_view_box.pack_start(self.star_align, False, False)
        self.left_view_box.pack_start(self.left_action_align, False, False)
        self.left_label_table.attach(self.left_category_box, 0, 1, 0, 1)
        self.left_label_table.attach(self.left_version_label, 0, 1, 1, 2)
        self.left_label_table.attach(self.left_size_label, 0, 1, 2, 3)
        self.left_label_table.attach(self.left_download_label, 0, 1, 3, 4)
        self.left_label_table.attach(self.left_homepage_box_align, 0, 1, 4, 5)
        self.left_label_align.add(self.left_label_table)
        self.left_view_box.pack_start(self.left_label_align, False, False)
        self.left_view_box.pack_start(self.left_recommend_box_align, False,
                                      False)
        self.right_info_box.pack_start(self.scrolled_window, True, True)
        self.pack_start(self.left_view_box, False, False)
        self.pack_start(self.right_info_box, True, True)

        self.left_view_box.connect("expose-event", self.expose_left_view)
        self.right_view_box.connect("expose-event", self.expose_right_view)
        self.left_logo_box.connect("expose-event", self.expose_left_logo_box)
        self.right_top_box.connect("expose-event", self.expose_right_top_box)
        self.right_title_box.connect("expose-event",
                                     self.expose_right_title_box)
        self.connect("hierarchy-changed", self.hierarchy_change)

        self.left_category_label.connect("button-press-event",
                                         lambda w, e: self.jump_to_category())

        global_event.register_event("download-screenshot-finish",
                                    self.download_screenshot_finish)

        self.loading_label = Label(_("Loading comments..."))
        self.loading_label_align = gtk.Alignment(0.5, 0, 0, 0)
        self.loading_label_align.add(self.loading_label)
        self.loading_label_align.set_padding(10, 0, 0, 0)

        self.update_pkg_time = 0
        self.update_pkg_interval = 0.2  # in seconds

    def hierarchy_change(self, widget, previous_toplevel):
        # When detail page remove from it's container, previous_toplevel is not None.
        if previous_toplevel != None:
            container_remove_all(
                self.right_slide_box
            )  # remove slide box first, to avoid screenshot area flash
            container_remove_all(
                self.right_comment_box
            )  # remove comment box first, to avoid comment area flash

    def grade_pkg(self):
        if self.pkg_star_view:
            global_event.emit("grade-pkg", (self.pkg_name, self.pkg_star_view),
                              self.pkg_star_view.star_buffer.star_level)
            self.pkg_star_view.set_star_level(int(self.star))
            self.pkg_star_view.queue_draw()

    def jump_to_category(self):
        global_event.emit("jump-to-category", self.category[0],
                          self.category[1])

    def expose_left_view(self, widget, event):
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation

        # Draw background.
        cr.set_source_rgb(*color_hex_to_cairo("#FFFFFF"))
        cr.rectangle(rect.x, rect.y, rect.width, rect.height)
        cr.fill()

        # Draw split line.
        cr.set_source_rgb(*color_hex_to_cairo("#AAAAAA"))
        cr.rectangle(rect.x + rect.width - 1, rect.y, 1, rect.height)
        cr.fill()

    def expose_right_view(self, widget, event):
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation

        # Draw background.
        cr.set_source_rgb(*color_hex_to_cairo("#FFFFFF"))
        cr.rectangle(rect.x, rect.y, rect.width, rect.height)
        cr.fill()

    def expose_left_logo_box(self, widget, event):
        if self.pkg_name != None:
            # Init.
            cr = widget.window.cairo_create()
            rect = widget.allocation

            # Draw pkg icon.
            self.pkg_pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
                get_icon_pixbuf_path(utils.get_origin_name(self.pkg_name)),
                self.ICON_SIZE, self.ICON_SIZE)
            draw_pixbuf(
                cr, self.pkg_pixbuf, rect.x + self.ICON_PADDING_X +
                (self.ICON_SIZE - self.pkg_pixbuf.get_width()) / 2,
                rect.y + self.PADDING_Y)

    def expose_right_top_box(self, widget, event):
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation

        # Draw background.
        cr.set_source_rgb(*color_hex_to_cairo("#FFFFFF"))
        cr.rectangle(rect.x, rect.y, rect.width, rect.height)
        cr.fill()

    def expose_right_title_box(self, widget, event):
        if self.pkg_name != None:
            # Init.
            cr = widget.window.cairo_create()
            rect = widget.allocation

            # Draw alias name.
            draw_text(cr,
                      "<b>%s</b>" % self.alias_name,
                      rect.x + self.RIGHT_INFO_PADDING_X,
                      rect.y + self.ALIAS_NAME_PADDING_Y,
                      rect.width - self.RIGHT_INFO_PADDING_X,
                      self.ALIAS_NAME_SIZE,
                      text_size=self.ALIAS_NAME_SIZE)

    def expose_resizable_label_background(self, widget, event):
        if self.pkg_name != None:
            # Init.
            cr = widget.window.cairo_create()
            rect = widget.allocation

            # Draw background.
            cr.set_source_rgb(*color_hex_to_cairo("#FFFFFF"))
            cr.rectangle(rect.x, rect.y, rect.width, rect.height)
            cr.fill()

    def button_press_start_button(self, widget, event, desktops):
        pixbuf = app_theme.get_pixbuf("button/start_normal.png").get_pixbuf()
        desktop_infos = self.data_manager.get_pkg_desktop_info(desktops)
        global_event.emit(
            "start-pkg", self.alias_name, desktop_infos,
            (int(event.x), int(event.y), pixbuf.get_width() / 2, 0))

    @post_gui
    def update_some_info(self, info):
        self.star = float(info[0]['mark'].encode('utf-8').strip())
        if self.pkg_star_view:
            self.pkg_star_view.star_buffer.star_level = int(self.star)
            self.pkg_star_view.queue_draw()
        self.pkg_star_mark.update_star(self.star)
        self.pkg_star_mark.queue_draw()

        self.downlad_number = info[0]['down_nums'].encode('utf-8').strip()
        self.left_download_label.set_text(
            _('Download: %s') % self.downlad_number)

    def update_pkg_info(self, pkg_name):
        current_time = time.time()
        if current_time - self.update_pkg_time < self.update_pkg_interval:
            return False
        else:
            self.update_pkg_time = current_time

        FetchPackageInfo(pkg_name, self.update_some_info).start()
        self.pkg_name = pkg_name

        detail_info = self.data_manager.get_pkg_detail_info(self.pkg_name)
        self.category = detail_info['category']
        self.long_desc = detail_info['long_desc']
        self.version = detail_info['version']
        self.homepage = detail_info['homepage']
        self.alias_name = detail_info['alias_name']
        self.recommend_pkgs = detail_info['recommend_pkgs']

        self.pkg_star_view = StarView()
        self.pkg_star_view.connect("clicked", lambda w: self.grade_pkg())
        self.pkg_star_mark = StarMark(5.0, self.MARK_SIZE, self.MARK_PADDING_X,
                                      self.MARK_PADDING_Y)
        container_remove_all(self.star_box)
        self.star_box.pack_start(self.pkg_star_view, False, False)
        self.star_box.pack_start(self.pkg_star_mark, False, False)

        self.fetch_pkg_status()

        container_remove_all(self.left_category_box)
        if self.category != None:
            self.left_category_name_label.set_text(_("Category: "))
            self.left_category_label.set_text(
                get_category_name(self.category[1]))
            self.left_category_box.add(self.left_category_label_box)

        self.left_version_label.set_text(_("Version: %s") % self.version)
        self.left_download_label.set_text(_("Download: 0"))
        self.left_size_label.set_text(_("Size: calculating..."))

        container_remove_all(self.left_homepage_box)
        if self.homepage != "":
            homepage_label = Label(
                _("Visit Homepage"),
                text_color=app_theme.get_color("homepage"),
                hover_color=app_theme.get_color("homepage_hover"))
            homepage_label.set_clickable()
            homepage_label.connect(
                "button-press-event",
                lambda w, e: run_command("xdg-open %s" % self.homepage))
            self.left_homepage_box.pack_start(homepage_label)

        container_remove_all(self.left_recommend_box)
        if len(self.recommend_pkgs) > 0:
            self.left_recommend_box.pack_start(self.left_recommend_label,
                                               False, False, 8)

            for (recommend_pkg_name, alias_name, star) in self.recommend_pkgs:
                self.left_recommend_box.pack_start(
                    RecommendPkgItem(self, recommend_pkg_name, alias_name,
                                     star), False, False, 4)

        container_remove_all(self.right_desc_box)
        resizable_label = ResizableLabel(
            self.long_desc.replace("&", "&amp;").replace("<", "&lt;").replace(
                ">", "&gt;"), self.LONG_DESC_WRAP_WIDTH,
            self.LONG_DESC_INIT_HEIGHT, 3)
        resizable_align = gtk.Alignment()
        resizable_align.set(0.5, 0.5, 1, 1)
        resizable_align.set_padding(0, 0, self.RIGHT_INFO_PADDING_X,
                                    self.RIGHT_INFO_PADDING_X)
        resizable_align.add(resizable_label)
        resizable_align.connect("expose-event",
                                self.expose_resizable_label_background)
        self.right_desc_box.pack_start(resizable_align, False, False)

        self.show_screenshot()

        self.fetch_comment()

        self.show_all()

    def handle_pkg_status(self, reply, success):
        container_remove_all(self.left_action_box)
        if success:
            install_status = str(reply)
            if install_status == "uninstalled":
                action_button = ImageButton(
                    app_theme.get_pixbuf("button/install_normal.png"),
                    app_theme.get_pixbuf("button/install_hover.png"),
                    app_theme.get_pixbuf("button/install_press.png"),
                )
                action_button.connect(
                    "clicked", lambda w: global_event.emit(
                        "install-pkg", [self.pkg_name]))
                self.left_action_box.pack_start(action_button)
            elif install_status == "unknown":
                status_label = Label(_("Not found"))
                self.left_action_box.pack_start(status_label)
            else:
                try:
                    desktops = json.loads(install_status)
                    if not desktops:
                        status_label = Label(_("Successfully installed"))
                        self.left_action_box.pack_start(status_label)
                    else:
                        action_button = ImageButton(
                            app_theme.get_pixbuf("button/start_normal.png"),
                            app_theme.get_pixbuf("button/start_hover.png"),
                            app_theme.get_pixbuf("button/start_press.png"),
                        )
                        action_button.connect(
                            "button-press-event",
                            lambda w, e: self.button_press_start_button(
                                w, e, desktops))
                        self.left_action_box.pack_start(action_button)
                except:
                    logging.error("detail install status: %s = %s" %
                                  (self.pkg_name, install_status))

            self.left_action_box.show_all()
            global_event.emit('update-current-status-pkg-page', self)
        else:
            global_logger.error("get_pkg_installed handle_dbus_error")
            global_logger.error(reply)

    def handle_pkg_download_size(self, reply, success):
        # FIXME: download information display
        if success:
            if reply[0] == PKG_SIZE_OWN or reply[0] == PKG_SIZE_DOWNLOAD:
                self.left_size_label.set_text(
                    _("Size: %s") % bit_to_human_str(reply[1]))
            elif reply[0] == PKG_SIZE_ERROR:
                self.left_size_label.set_text("")
                global_logger.error("Error for calculate pkg size!")
        else:
            global_logger.error(
                "request_pkgs_install_status handle_dbus_error")
            global_logger.error(reply)

    def fetch_pkg_status(self):
        self.data_manager.get_pkg_installed(self.pkg_name,
                                            self.handle_pkg_status)
        self.data_manager.get_pkg_download_size(self.pkg_name,
                                                self.handle_pkg_download_size)

    def open_url(self, webview, frame, network_request, nav_action,
                 policy_dec):
        webbrowser.open(network_request.get_uri())

    def webview_console_message_handler(self, webview, message, line,
                                        source_id):
        return True

    def fetch_comment(self):
        if is_network_connected():
            container_remove_all(self.right_comment_box)
            loading_label = Label(_("Loading comments..."))
            loading_label_align = gtk.Alignment(0.5, 0, 0, 0)
            loading_label_align.add(loading_label)
            loading_label_align.set_padding(10, 0, 0, 0)
            self.right_comment_box.pack_start(loading_label_align, False,
                                              False)
            web_view = WebView(os.path.join(CONFIG_DIR, "cookie.txt"))
            web_view.connect("new-window-policy-decision-requested",
                             self.open_url)
            web_view.connect('console-message',
                             self.webview_console_message_handler)
            web_view_align = gtk.Alignment()
            web_view_align.set(0.5, 0, 0, 0)
            web_view_align.set_padding(33, 33, 33, 33)
            web_view_align.add(web_view)
            web_settings = web_view.get_settings()
            web_settings.set_property("enable-plugins", False)
            web_settings.set_property("enable-scripts", True)
            web_view.open("%s/softcenter/v1/comment?n=%s&hl=%s" % (
                SERVER_ADDRESS,
                self.pkg_name,
                LANGUAGE,
            ))

            web_view.connect("load-finished", self.comment_load_finished_cb,
                             web_view_align)

            create_thread(self.fetch_screenshot).start()

    def comment_load_finished_cb(self, webview, frame, web_view_align):
        self.scrolled_window.connect(
            "vscrollbar-state-changed",
            lambda w, p: self.load_more_comment(p, webview))
        container_remove_all(self.right_comment_box)
        self.right_comment_box.pack_start(web_view_align, True, True)
        self.right_comment_box.show_all()

    def load_more_comment(self, postion, webview):
        if postion == "bottom":
            webview.execute_script('$("#nav_next").click();')

    def fetch_screenshot(self):
        screenshot_dir = os.path.join(SCREENSHOT_DOWNLOAD_DIR, self.pkg_name)
        screenshot_md5_path = os.path.join(screenshot_dir,
                                           "screenshot_md5.txt")
        remote_screenshot_md5_url = "%s/zh_CN/%s/screenshot_md5.txt" % (
            SCREENSHOT_HOST, self.pkg_name)
        remote_screenshot_zip_url = "%s/zh_CN/%s/screenshot.zip" % (
            SCREENSHOT_HOST, self.pkg_name)
        try:
            remote_md5 = urllib2.urlopen(remote_screenshot_md5_url).read()
            need_download = False

            if os.path.exists(screenshot_dir):
                if os.path.exists(screenshot_md5_path):
                    local_md5 = read_file(screenshot_md5_path)
                    if remote_md5 != local_md5:
                        need_download = True
                else:
                    need_download = True
            else:
                need_download = True

            if need_download:
                write_file(screenshot_md5_path, remote_md5, True)

                try:
                    urllib.urlretrieve(
                        remote_screenshot_zip_url,
                        os.path.join(SCREENSHOT_DOWNLOAD_DIR, self.pkg_name,
                                     "screenshot.zip"))
                    global_event.emit("download-screenshot-finish",
                                      self.pkg_name)
                except Exception, e:
                    global_logger.error("Download screenshot error: %s" % e)
        except Exception, e:
            global_logger.error("fetch_screenshot got error: %s" % e)
Ejemplo n.º 31
0
class Titlebar(EventBox):
    def __init__(
        self,
        button_mask=["theme", "menu", "max", "min", "close"],
        icon_path=None,
        app_name=None,
        title=None,
        add_separator=False,
        height=26,
        show_title=True,
        enable_gaussian=True,
        name_size=DEFAULT_FONT_SIZE,
        title_size=DEFAULT_FONT_SIZE,
    ):
        # Init.
        EventBox.__init__(self)
        self.set_size_request(-1, height)
        self.v_layout_box = gtk.VBox()
        self.h_layout_box = gtk.HBox()
        self.add(self.v_layout_box)
        self.v_layout_box.pack_start(self.h_layout_box, True, True)

        # Init separator.
        if add_separator:
            self.separator = gtk.HBox()
            self.separator.set_size_request(-1, 1)
            self.separator.connect("expose-event",
                                   self.expose_titlebar_separator)
            self.v_layout_box.pack_start(self.separator, True, True)

        # Add drag event box.
        self.drag_box = EventBox()
        self.h_layout_box.pack_start(self.drag_box, True, True)

        # Init left box to contain icon and title.
        self.left_box = gtk.HBox()
        self.drag_box.add(self.left_box)

        if show_title:
            # Add icon.
            if icon_path != None:
                self.icon_image_box = gtk.image_new_from_pixbuf(
                    gtk.gdk.pixbuf_new_from_file(icon_path))
                self.icon_align = gtk.Alignment()
                self.icon_align.set(0.5, 0.5, 0.0, 0.0)
                self.icon_align.set_padding(5, 5, 5, 0)
                self.icon_align.add(self.icon_image_box)
                self.left_box.pack_start(self.icon_align, False, False)

            # Add app name.
            if app_name == None:
                app_name_label = ""
            else:
                app_name_label = app_name
            self.app_name_box = Label(app_name_label,
                                      enable_gaussian=enable_gaussian,
                                      text_size=name_size)
            self.app_name_align = gtk.Alignment()
            self.app_name_align.set(0.5, 0.5, 0.0, 0.0)
            self.app_name_align.set_padding(2, 0, 5, 0)
            self.app_name_align.add(self.app_name_box)
            self.left_box.pack_start(self.app_name_align, False, False)

            # Add title.
            if title == None:
                title_label = ""
            else:
                title_label = title
            self.title_box = Label(
                title_label,
                enable_gaussian=enable_gaussian,
                text_x_align=pango.ALIGN_CENTER,
                text_size=title_size,
            )
            self.title_align = gtk.Alignment()
            self.title_align.set(0.5, 0.5, 0.0, 0.0)
            self.title_align.set_padding(2, 0, 30, 30)
            self.title_align.add(self.title_box)
            self.left_box.pack_start(self.title_align, True, True)

        # Add button box.
        self.button_box = gtk.HBox()
        self.button_align = gtk.Alignment()
        self.button_align.set(1.0, 0.0, 0.0, 0.0)
        self.button_align.set_padding(0, 0, 0, 0)
        self.button_align.add(self.button_box)
        self.right_box = gtk.VBox()
        self.right_box.pack_start(self.button_align, False, False)
        self.h_layout_box.pack_start(self.right_box, False, False)

        # Add buttons.
        for mask in button_mask:
            setattr(self, titlebar_button_dict[mask][0],
                    titlebar_button_dict[mask][1]())
            button = getattr(self, titlebar_button_dict[mask][0])
            self.button_box.pack_start(button, False, False)
            Tooltip.text(button, titlebar_button_dict[mask][2]).show_delay(
                button, 2000)

        # Show.
        self.show_all()

    def expose_titlebar_separator(self, widget, event):
        '''
        Expose the separation line between the titlebar and the body of the window.

        @param widget: A widget of type Gtk.Widget.
        @param event: Not used.
        @return: Always return True.
        '''
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation

        # Draw separator.
        cr.set_source_rgba(1, 1, 1, 0.5)
        draw_line(cr, rect.x + 1, rect.y + 2, rect.x + rect.width - 1,
                  rect.y + 1)

        return True

    def change_name(self, name):
        '''
        Change the name of the application, which is displayed on the center of the title bar.
        
        @param name: New name string that want to set.
        '''
        self.app_name_box.set_text(name)

    def change_title(self, title):
        '''
        Change the title of the application, which is displayed on the center of the title bar.
        
        @param title: New title string that want to set.
        '''
        self.title_box.set_text(title)
Ejemplo n.º 32
0
class SongEditor(DialogBox):
    def __init__(self, songs, init_index=0):
        super(SongEditor, self).__init__(_("Properties"),
                                         500,
                                         400,
                                         mask_type=DIALOG_MASK_TAB_PAGE)
        self.set_position(gtk.WIN_POS_CENTER)

        close_button = Button(_("Close"))
        close_button.connect("clicked", self.click_close_button)

        previous_button = Button(_("Previous"))
        previous_button.connect("clicked",
                                lambda w: self.update_previous_song())
        next_button = Button(_("Next"))
        next_button.connect("clicked", lambda w: self.update_next_song())

        self.record_label = Label("0/0")

        action_box = gtk.HBox(spacing=5)
        action_box.pack_start(previous_button, False, False)
        action_box.pack_start(self.record_label, False, False)
        action_box.pack_start(next_button, False, False)

        MediaDB.connect("simple-changed", self.db_simple_changed)

        # action_box.
        if len(songs) <= 1:
            action_box.set_no_show_all(True)
        else:
            self.record_label.set_text("%d/%d" % (init_index + 1, len(songs)))

        # tabs
        self.song_info = SongInfo(songs[init_index])
        self.info_setting = InfoSetting(songs[init_index])
        self.cover_setting = CoverSetting(songs[init_index])

        self.tab_box = TabBox()
        self.tab_box.add_items([(_("Track Infomation"), self.song_info),
                                (_("Tag Settings"), self.info_setting),
                                (_("Cover Settings"), self.cover_setting)])

        # DialogBox code, simple, ah? :)
        self.left_button_box.set_buttons([action_box])
        self.right_button_box.set_buttons([close_button])
        self.body_box.pack_start(self.tab_box, True, True)

        # Constants.
        self.current_index = init_index
        self.songs = songs

    def update_previous_song(self):
        new_index = self.current_index - 1
        if self.is_vaild_index(new_index):
            self.current_index = new_index
            self.update_song(self.songs[new_index])
            self.update_record_label()

    def update_next_song(self):
        new_index = self.current_index + 1
        if self.is_vaild_index(new_index):
            self.current_index = new_index
            self.update_song(self.songs[new_index])
            self.update_record_label()

    def is_vaild_index(self, index):
        if 0 <= index < len(self.songs):
            return True
        return False

    def update_record_label(self):
        self.record_label.set_text("%d/%d" %
                                   (self.current_index + 1, len(self.songs)))

    def update_song(self, song):
        self.song_info.update_song(song)
        self.info_setting.update_song(song)
        self.cover_setting.update_song(song)

    def db_simple_changed(self, widget, songs):
        current_song = self.songs[self.current_index]
        if isinstance(songs, list):
            if self.songs[self.current_index] in songs:
                self.song_info.update_song(songs[songs.index(current_song)])
                self.cover_setting.update_song(
                    songs[songs.index(current_song)])

    def click_close_button(self, widget):
        self.destroy()
Ejemplo n.º 33
0
class SongTimer(gtk.HBox):
    __gsignals__ = {
        "play-end" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())
    }
    def __init__(self, draw_time_callback=None):
        super(SongTimer, self).__init__()

        self.label_time = Label("00:00", app_theme.get_color("labelText"), 8, enable_gaussian=True)
        self.draw_time_callback = draw_time_callback
        if draw_time_callback:
            draw_time_callback(self.label_time.get_text())
            
        self.bar = ProgressBar()
        bar_align = gtk.Alignment()
        bar_align.set_padding(0, 0, 1, 1)
        bar_align.set(1, 1, 1, 1)
        bar_align.add(self.bar)
        self.bar.connect("button-press-event", self.on_bar_press)
        self.bar.connect("button-release-event", self.on_bar_release)
        self.__value_changed_id = self.bar.connect("value-changed", self.on_bar_value_changed)

        self.pack_start(bar_align, True, True)
        self.update_bar = 1
        self.duration = 0
        self.__idle_release_id = None
        self.delete = False
        self.__need_report = False
        self.press_flag = False

        Player.connect("instant-new-song", self.set_duration)
        Player.connect("init-status", self.on_player_init_status)

        Player.bin.connect("queue-running", self.on_queue_running)
        Player.bin.connect("tick", self.on_tick)
        Player.connect("seeked", self.on_seek)
        Player.connect("stopped", self.set_duration)
        if not Player.song:
            self.bar.set_sensitive(False)
            
    def on_queue_running(self, obj, uri):        
        self.update_bar = 1
            
    def on_player_init_status(self, player):        
        self.label_time.set_text("00:00")
        self.bar.set_value(0)
        self.bar.set_sensitive(True)
        if self.draw_time_callback:
            self.draw_time_callback(self.label_time.get_text())
            

    def get_label(self):
        return self.label_time
    
    def stop(self):
        self.delete = True

    def set_duration(self, player, song=None):
        self.update_bar = 1
        
        if not song:
            if player.song: song = player.song
            else: return
        else:
            self.__need_report = True
        
        self.duration = song.get("#duration", 0) / 1000
        self.set_current_time(0, self.duration)
        
    def on_tick(self, bin, pos, duration):
        if Player.song:
            if Player.song.get_type() == "webcast":
                duration = 0
        
        pos /= 1000.0
        duration /= 1000.0
        
        if Player.song and Player.song.get_type() == "cue":
            duration = Player.song.get("#duration") / 1000
            pos = pos - Player.song.get("seek", 0)
            
        self.duration = duration
        if self.update_bar == 1:
            self.set_current_time(pos, duration)
        return not self.delete

    def set_current_time(self, pos, duration):
        if self.update_bar == 1:
            if duration == 0 or pos >= duration:
                self.bar.set_range(0, 1000)
                self.bar.set_value(0)
                self.bar.set_sensitive(False)
            else :
                self.bar.set_sensitive(True)
                self.bar.set_range(0, duration)
                self.bar.set_value(pos)

        # total = utils.duration_to_string(duration * 1000, "00:00")                
        if pos > 0 and pos < duration:
            current = utils.duration_to_string(pos, "00:00", 1) 
        else:    
            current = "00:00"
            
        if pos >0 and Player.song and Player.song.get_type() == "webcast":    
            current = utils.duration_to_string(pos, "00:00", 1) 
            # total = "--:--"
        # text = "%s/%s" % (current, total)
        text = current
        self.label_time.set_text(text)
        if self.draw_time_callback:
            self.draw_time_callback(text)

    def on_seek(self, *args, **kwargs):
        self.__need_report = False
    
    def on_bar_value_changed(self, widget, value):        
        pos = self.bar.get_value()
        self.set_current_time(pos, self.duration)

    def on_bar_press(self, widget, event):
        if not self.press_flag:
            if self.__idle_release_id:
                gobject.source_remove(self.__idle_release_id)
                self.__idle_release_id = None
            self.update_bar = 0
            self.__need_report = False
            
            
            self.bar.disconnect(self.__value_changed_id)
            self.press_flag = True

    def __idle_release(self):
        if Player.song.get_type() in ("cue", "cdda", "local"):
            self.update_bar = 1
            
        self.__idle_release_id = None

    def on_bar_release(self, widget, event):
        if self.press_flag:
            self.__value_changed_id = self.bar.connect("value-changed", self.on_bar_value_changed)
            
            s = Player.song
            if not s :
                return
            if s.get_type() in [ "webcast",]:
                return
            
            if s.get_type() == "cue":
                Player.seek(s.get("seek", 0) + self.bar.get_value())
            else:    
                Player.seek(self.bar.get_value())
            
            # wait a bit that the player are really seek to update the progress bar
            # if not self.__idle_release_id:
            self.__idle_release()
            self.__idle_release_id = gobject.idle_add(self.__idle_release)
            self.press_flag = False
Ejemplo n.º 34
0
class SongTimer(gtk.HBox):
    __gsignals__ = {
        "play-end" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())
    }
    def __init__(self):
        super(SongTimer, self).__init__()

        self.label_time = Label("00:00/00:00", app_theme.get_color("labelText"), 8, enable_gaussian=True)

        self.bar = HScalebar()
        self.bar.set_draw_value(False)
        self.bar.set_range(0, 1000)
        self.bar.set_value(0)
        self.bar.connect("button_press_event", self.on_bar_press)
        self.bar.connect("button_release_event", self.on_bar_release)
        self.__value_changed_id = self.bar.connect("value-changed", self.on_bar_value_changed)
        self.bar.handler_block(self.__value_changed_id)
        self.pack_start(self.bar, True, True)
        self.update_bar = 1
        self.duration = 0
        self.__idle_release_id = None
        self.delete = False
        self.__need_report = False

        Player.connect("instant-new-song", self.set_duration)

        Player.bin.connect("tick", self.on_tick)
        Player.connect("seeked", self.on_seek)
        Player.connect("stopped", self.set_duration)
        if not Player.song:
            self.bar.set_sensitive(False)

    def get_label(self):
        return self.label_time
    
    def stop(self):
        self.delete = True

    def set_duration(self, player, song=None):
        if not song:
            if player.song: song = player.song
            else: return
        else:
            self.__need_report = True
        
        self.duration = song.get("#duration", 0) / 1000
        self.set_current_time(0, self.duration)
        
    def on_tick(self, bin, pos, duration):
        self.duration = duration
        if self.update_bar == 1:
            self.set_current_time(pos, duration)
        return not self.delete

    def set_current_time(self, pos, duration):
        if self.update_bar == 1:
            if duration == 0 or pos >= duration:
                self.bar.set_range(0, 1000)
                self.bar.set_value(0)
                self.bar.set_sensitive(False)
            else :
                self.bar.set_sensitive(True)
                self.bar.set_range(0, duration)
                self.bar.set_value(pos)

        total = utils.duration_to_string(duration * 1000, "00:00")                
        if pos > 0 and pos < duration:
            current = utils.duration_to_string(pos, "00:00", 1) 
        else:    
            current = "00:00"
        text = "%s/%s" % (current, total)
        self.label_time.set_text(text)

    def on_seek(self, *args, **kwargs):
        self.__need_report = False
    
    def on_bar_value_changed(self, widget):        
        pos = self.bar.get_value()
        self.set_current_time(pos, self.duration)

    def on_bar_press(self, widget, event):
        if self.__idle_release_id:
            gobject.source_remove(self.__idle_release_id)
            self.__idle_release_id = None
        self.update_bar = 0
        self.__need_report = False

        self.bar.handler_unblock(self.__value_changed_id)

    def __idle_release(self):
        self.update_bar = 1
        self.__idle_release_id = None

    def on_bar_release(self, widget, event):
        self.bar.handler_block(self.__value_changed_id)
        
        s = Player.song
        if s is not None and s.get_type() in [ "webradio", "volatile_webradio"]:
            return
        Player.seek(self.bar.get_value())

        # wait a bit that the player are really seek to update the progress bar
        if not self.__idle_release_id:
            self.__idle_release()
            self.__idle_release_id = gobject.idle_add(self.__idle_release)
Ejemplo n.º 35
0
class Titlebar(EventBox):
    def __init__(self, 
                 button_mask=["theme", "menu", "max", "min", "close"],
                 icon_path=None,
                 app_name=None,
                 title=None,
                 add_separator=False,
                 height=26,
                 show_title=True,
                 enable_gaussian=True,
                 name_size=DEFAULT_FONT_SIZE,
                 title_size=DEFAULT_FONT_SIZE,
                 ):
        # Init.
        EventBox.__init__(self)
        self.set_size_request(-1, height)
        self.v_layout_box = gtk.VBox()
        self.h_layout_box = gtk.HBox()
        self.add(self.v_layout_box)
        self.v_layout_box.pack_start(self.h_layout_box, True, True)
        
        # Init separator.
        if add_separator:
            self.separator = gtk.HBox()
            self.separator.set_size_request(-1, 1)
            self.separator.connect("expose-event", self.expose_titlebar_separator)
            self.v_layout_box.pack_start(self.separator, True, True)
        
        # Add drag event box.
        self.drag_box = EventBox()
        self.h_layout_box.pack_start(self.drag_box, True, True)
        
        # Init left box to contain icon and title.
        self.left_box = gtk.HBox()
        self.drag_box.add(self.left_box)
        
        if show_title:
            # Add icon.
            if icon_path != None:
                self.icon_image_box = gtk.image_new_from_pixbuf(gtk.gdk.pixbuf_new_from_file(icon_path))
                self.icon_align = gtk.Alignment()
                self.icon_align.set(0.5, 0.5, 0.0, 0.0)
                self.icon_align.set_padding(5, 5, 5, 0)
                self.icon_align.add(self.icon_image_box)
                self.left_box.pack_start(self.icon_align, False, False)
                        
            # Add app name.
            if app_name == None:
                app_name_label = ""
            else:
                app_name_label = app_name
            self.app_name_box = Label(app_name_label, enable_gaussian=enable_gaussian, text_size=name_size)
            self.app_name_align = gtk.Alignment()
            self.app_name_align.set(0.5, 0.5, 0.0, 0.0)
            self.app_name_align.set_padding(2, 0, 5, 0)
            self.app_name_align.add(self.app_name_box)
            self.left_box.pack_start(self.app_name_align, False, False)
            
            # Add title.
            if title == None:
                title_label = ""
            else:
                title_label = title
            self.title_box = Label(
                title_label, enable_gaussian=enable_gaussian, 
                text_x_align=pango.ALIGN_CENTER,
                text_size=title_size,
                )
            self.title_align = gtk.Alignment()
            self.title_align.set(0.5, 0.5, 0.0, 0.0)
            self.title_align.set_padding(2, 0, 30, 30)
            self.title_align.add(self.title_box)
            self.left_box.pack_start(self.title_align, True, True)
            
        # Add button box.
        self.button_box = gtk.HBox()
        self.button_align = gtk.Alignment()
        self.button_align.set(1.0, 0.0, 0.0, 0.0)
        self.button_align.set_padding(0, 0, 0, 0)
        self.button_align.add(self.button_box)
        self.right_box = gtk.VBox()
        self.right_box.pack_start(self.button_align, False, False)
        self.h_layout_box.pack_start(self.right_box, False, False)
        
        # Add buttons.
        for mask in button_mask:
            setattr(self, titlebar_button_dict[mask][0], titlebar_button_dict[mask][1]())
            button = getattr(self, titlebar_button_dict[mask][0])
            self.button_box.pack_start(button, False, False)
            Tooltip.text(button, titlebar_button_dict[mask][2]).show_delay(button, 2000)

        # Show.
        self.show_all()

    def expose_titlebar_separator(self, widget, event):
        '''
        Expose the separation line between the titlebar and the body of the window.

        @param widget: A widget of type Gtk.Widget.
        @param event: Not used.
        @return: Always return True.
        '''
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation
    
        # Draw separator.
        cr.set_source_rgba(1, 1, 1, 0.5)
        draw_line(cr, rect.x + 1, rect.y + 2, rect.x + rect.width - 1, rect.y + 1)
    
        return True
    
    def change_name(self, name):
        '''
        Change the name of the application, which is displayed on the center of the title bar.
        
        @param name: New name string that want to set.
        '''
        self.app_name_box.set_text(name)
        
    def change_title(self, title):
        '''
        Change the title of the application, which is displayed on the center of the title bar.
        
        @param title: New title string that want to set.
        '''
        self.title_box.set_text(title)
class IconEditPage(gtk.HBox):
    def __init__(self, account_setting):
        super(IconEditPage, self).__init__(False)
        self.account_setting = account_setting
        self.error_label = Label("", label_width=350, enable_select=False, enable_double_click=False)

        left_align = gtk.Alignment()
        right_align = gtk.Alignment()
        left_align.set_padding(0, 0, 0, 60)
        #right_align.set_padding(0, 0, 0, 60)

        left_vbox = gtk.VBox(False)
        right_vbox = gtk.VBox(False)
        left_vbox.set_spacing(BETWEEN_SPACING)
        right_vbox.set_spacing(BETWEEN_SPACING)

        left_align.add(left_vbox)
        right_align.add(right_vbox)

        self.draw_area = IconEditArea()
        hseparator = HSeparator(app_theme.get_shadow_color("hSeparator").get_color_info(), 0, 0)
        hseparator.set_size_request(-1, 10)
        left_vbox.pack_start(tools.make_align(Label(_("Clip"),
                             app_theme.get_color("globalTitleForeground"),
                             text_size=TITLE_FONT_SIZE, enable_select=False,
                             enable_double_click=False)), False, False)
        left_vbox.pack_start(hseparator, False, False)
        left_vbox.pack_start(tools.make_align(self.draw_area, yalign=0.0, width=300, height=300))

        self.thumbnail_large = gtk.Image()
        self.thumbnail_mid = gtk.Image()
        self.thumbnail_small = gtk.Image()
        self.thumbnail_large.set_size_request(150, 150)
        self.thumbnail_mid.set_size_request(48, 48)
        self.thumbnail_small.set_size_request(24, 24)

        hseparator = HSeparator(app_theme.get_shadow_color("hSeparator").get_color_info(), 0, 0)
        hseparator.set_size_request(-1, 10)
        right_vbox.pack_start(tools.make_align(Label(_("Preview"),
                              app_theme.get_color("globalTitleForeground"),
                              text_size=TITLE_FONT_SIZE, enable_select=False,
                              enable_double_click=False)), False, False)
        right_vbox.pack_start(hseparator, False, False)
        right_vbox.pack_start(tools.make_align(self.thumbnail_large), False, False)
        right_vbox.pack_start(tools.make_align(self.thumbnail_mid), False, False)
        right_vbox.pack_start(tools.make_align(self.thumbnail_small), False, False)
        right_vbox.pack_start(tools.make_align(self.error_label, yalign=0.0))

        self.pack_start(left_align, False, False)
        self.pack_start(right_align, False, False)
        self.connect("expose-event", self.draw_frame_border, left_align, right_align)
        self.draw_area.connect("pixbuf-changed", self.__on_pixbuf_changed_cb)

    def draw_frame_border(self, widget, event, la, ra):
        cr = widget.window.cairo_create()
        with cairo_disable_antialias(cr):
            cr.set_line_width(1)
            x, y, w, h = self.thumbnail_large.allocation
            cr.set_source_rgb(*color_hex_to_cairo(TREEVIEW_BORDER_COLOR))
            cr.rectangle(x-1, y-1, w+2, h+2)
            cr.stroke()
            x, y, w, h = self.thumbnail_mid.allocation
            cr.set_source_rgb(*color_hex_to_cairo(TREEVIEW_BORDER_COLOR))
            cr.rectangle(x-1, y-1, w+2, h+2)
            cr.stroke()
            x, y, w, h = self.thumbnail_small.allocation
            cr.set_source_rgb(*color_hex_to_cairo(TREEVIEW_BORDER_COLOR))
            cr.rectangle(x-1, y-1, w+2, h+2)
            cr.stroke()

    def set_pixbuf(self, pixbuf):
        self.error_label.set_text("")
        self.draw_area.set_edit_mode(pixbuf)
    
    def refresh(self):
        self.set_pixbuf(None)
        self.error_label.set_text("")

    def set_camera_mode(self):
        self.error_label.set_text("")
        self.draw_area.set_camera_mode()

    def stop_camera(self):
        self.draw_area.camera_stop()

    def save_edit_icon(self):
        pixbuf = self.thumbnail_large.get_pixbuf()
        if not pixbuf:
            #self.error_label.set_text("<span foreground='red'>%s%s</span>" % (
                #_("Error:"), _("no picture")))
            self.account_setting.set_status_error_text(_("no picture"))
            return
        tmp = mkstemp(".tmp", "account-settings")
        os.close(tmp[0])
        filename = tmp[1]
        pixbuf.save(filename, "png")
        try:
            self.account_setting.current_set_user.set_icon_file(filename)
            history_icon = self.account_setting.container_widgets["icon_set_page"].history_icon
            if not filename in history_icon.history:
                # backup picture to user home
                path = "/var/lib/AccountsService/icons/" + self.account_setting.current_set_user.get_user_name()
                backup_path = "%s/%s" % (history_icon.icons_dir, str(int(time())))
                fp1 = open(path, 'r')
                fp2 = open(backup_path, 'w')
                fp2.write(fp1.read())
                fp1.close()
                fp2.close()
                os.chmod(backup_path, S_IRWXU|S_IRWXG|S_IRWXO)
                history_icon.history.insert(0, backup_path)
                history_icon.set_history(history_icon.history)
        except Exception, e:
            print e
            if isinstance(e, (AccountsPermissionDenied, AccountsUserExists, AccountsFailed, AccountsUserDoesNotExist)):
                #self.error_label.set_text("<span foreground='red'>%s%s</span>" % (_("Error:"), e.msg))
                self.account_setting.set_status_error_text(e.msg)
                return
        self.stop_camera()
        self.draw_area.panel.hide_panel()
        self.account_setting.set_to_page(
            self.account_setting.alignment_widgets["main_hbox"], "left")
        self.account_setting.change_crumb(1)
Ejemplo n.º 37
0
class LocalPicturePage(gtk.VBox):
    def __init__(self, monitor_dir):

        gtk.VBox.__init__(self)
        self.set_spacing(10)
        self.select_view = SelectView(monitor_dir,
                                      filter_dir=["deepin-wallpapers"],
                                      add_system=True)
        self.select_view.connect("items-change", self.select_view_item_changed)
        self.select_view.connect("double-click-item",
                                 self.select_view_double_clicked)
        self.select_view_sw = self.select_view.get_scrolled_window()

        no_favorites_label = Label(_("Your Local Pictures folder is empty"))
        self.no_favorites_align = gtk.Alignment(0.5, 0.5, 0, 0)
        self.no_favorites_align.add(no_favorites_label)

        self.notice_label = Label("")

        set_wallpapper_button = Button(_("Set as wallpaper"))
        set_wallpapper_button.connect("clicked", self.__on_set_as_wallpapper)

        favorite_button = Button(_("Add to Favorites"))
        favorite_button.connect("clicked", self.__on_add_favorites)

        delete_button = Button(_("Delete"))
        delete_button.connect("clicked", self.__on_delete)

        self.button_box = gtk.HBox(spacing=10)
        self.button_box.pack_start(set_wallpapper_button, False, False)
        self.button_box.pack_start(favorite_button, False, False)
        self.button_box.pack_start(delete_button, False, False)

        self.control_box = gtk.HBox()
        self.control_box.set_size_request(-1, 20)
        self.control_box.pack_start(self.notice_label, False, False)

        self.control_align = gtk.Alignment()
        self.control_align.set(0.5, 0.5, 1, 1)
        self.control_align.set_padding(0, 5, 20, 10)
        self.control_align.add(self.control_box)

        if len(self.select_view.items) == 0:
            self.pack_start(self.no_favorites_align, True, True)
        else:
            self.pack_start(self.select_view_sw, True, True)
        self.pack_start(self.control_align, False, True)

        event_manager.add_callback("select-select-wallpaper",
                                   self.__on_select_select_wallpaper)

        self.timeout_notice_hide_id = None

    def __on_set_as_wallpapper(self, widget, data=None):
        self.select_view.set_multi_wallpapper()
        n = self.select_view.get_select_number()
        if n > 1:
            notice_text = _("%s pictures are set as wallpaper") % n
        else:
            notice_text = _("%s picture is set as wallpaper") % n
        self.notice_label.set_text(notice_text)
        self.timeout_notice_hide()

    def select_view_double_clicked(self, widget, item, x, y):
        image_path_string = "file://%s;" % item.image_path
        background_gsettings.set_string("picture-uris", image_path_string)

    def select_view_item_changed(self, widget):
        if len(self.select_view.items) == 0:
            container_remove_all(self)
            self.pack_start(self.no_favorites_align, True, True)
            self.pack_end(self.control_align, False, True)
        else:
            container_remove_all(self)
            self.pack_start(self.select_view_sw, True, True)
            self.pack_end(self.control_align, False, True)

    def timeout_notice_hide(self, time=3000):
        if self.timeout_notice_hide_id:
            gtk.timeout_remove(self.timeout_notice_hide_id)
        gtk.timeout_add(time, lambda: self.notice_label.set_text(""))

    def __on_add_favorites(self, widget, data=None):
        self.select_view.add_favorites()
        n = self.select_view.get_select_number()
        if n > 1:
            notice_text = _("add %s pictures to Favorites") % n
        else:
            notice_text = _("add %s picture to Favorites") % n
        self.notice_label.set_text(notice_text)
        self.timeout_notice_hide()

    def __delete_confirm(self):
        self.select_view.delete()
        n = self.select_view.get_select_number()
        if n > 1:
            notice_text = _("delete %s pictures") % n
        else:
            notice_text = _("delete %s picture") % n
        self.notice_label.set_text(notice_text)
        self.timeout_notice_hide()
        if self.button_box in self.control_box.get_children():
            self.control_box.remove(self.button_box)

    def __on_delete(self, widget):
        dlg = ConfirmDialog(_("Delete Wallpaper"),
                            _("Are you sure delete wallpaper?"), 300, 100,
                            lambda: self.__delete_confirm(), None, True,
                            CONTENT_FONT_SIZE)
        dlg.show_all()

    def __on_select_select_wallpaper(self, name, obj, select_item):
        select_number = self.select_view.get_select_number()
        if select_number > 0:
            if select_number > 1:
                notice_text = _("choose %s pictures") % select_number
            else:
                notice_text = _("choose %s picture") % select_number
            self.notice_label.set_text(notice_text)
            if self.button_box not in self.control_box.get_children():
                self.control_box.pack_end(self.button_box, False, False)
        else:
            self.notice_label.set_text("")
            if self.button_box in self.control_box.get_children():
                self.control_box.remove(self.button_box)
        self.show_all()

    def on_add_wallpapers(self, widget):
        event_manager.emit("add-local-wallpapers", None)
Ejemplo n.º 38
0
class SongPathBar(BaseBar):                
    
    def __init__(self, title_name):
        BaseBar.__init__(self, init_index=-1)
        self.set_spacing(3)
        self.child_box = gtk.VBox()
        self.child_item_height = 22
        self.current_page = 1
        self.page_items_num = 0        
        self.items = []
        
        title_item = SimpleLabel(
            app_theme.get_pixbuf("filter/local_normal.png"),
            title_name, 10, 25, 15, 10, 25, ALIGN_START)
        self.pack_start(title_item, False, False)
        self.pack_start(self.child_box, True, True)
        self.child_box.connect("size-allocate", self.size_change_cb)

        self.control_box = gtk.HBox()
        self.control_box.set_spacing(15)        
        previous_align = self.create_simple_button("previous", self.update_current_page, "previous")
        next_align = self.create_simple_button("next", self.update_current_page, "next")
        self.info_label = Label("0/0", app_theme.get_color("labelText"), text_x_align=ALIGN_MIDDLE)
        self.control_box.pack_start(previous_align, False, False)
        self.control_box.pack_start(self.info_label, False, False)
        self.control_box.pack_start(next_align, False, False)
        self.control_box.set_no_show_all(True)
        control_align = gtk.Alignment()
        control_align.set(1, 1, 0.5, 0.5)
        control_align.add(self.control_box)
        self.pack_start(control_align, False, False)
        
    def update_current_page(self, widget, name):    
        if not self.items or not self.page_items_num:
            return
        total_page = self.adjust_page()
        if name == "previous":
            new_current_page = self.current_page - 1
        else:    
            new_current_page = self.current_page + 1
            
        if new_current_page < 1:    
            new_current_page = 1
        elif new_current_page > total_page:    
            new_current_page = total_page
        if new_current_page == self.current_page:    
            return
        self.current_page = new_current_page
        self.update_items(None)
        self.set_index(-1)
        
    def get_item_num(self):    
        try:
            return self.child_box.allocation.height / self.child_item_height
        except:
            return 0
        
    def set_label(self, value):    
        self.info_label.set_text(value)
        
    def load_items(self, child_items):    
        if child_items:
            container_remove_all(self.child_box)
            for index, item in enumerate(child_items):
                simple_item = SimpleItem(
                    (app_theme.get_pixbuf("filter/folder_normal.png"),
                     app_theme.get_pixbuf("filter/folder_press.png"),
                     item[0], item[1], item[2]),
                    index + 1,   9, self.child_item_height, 25, 10, 15, self.set_index, self.get_index, ALIGN_START)
                self.child_box.pack_start(simple_item, False, False)
                
            if len(child_items) < self.page_items_num:    
                block_num = self.page_items_num - len(child_items)
                for i in range(block_num):
                    self.child_box.pack_start(self.create_block_box(), False, True)
            self.control_box.set_no_show_all(False)        
            self.control_box.show_all()
            self.show_all()        
            self.queue_draw()
            self.get_toplevel().queue_draw()

            
    def size_change_cb(self, widget, rect):        
        if rect.height > 0:
            new_num = rect.height / self.child_item_height
            if new_num == self.page_items_num:
                return
            else:
                self.page_items_num = new_num                                
                def fire():
                    self.update_items(None)
                gobject.idle_add(fire)    

    def update_items(self, new_items):            
        if new_items:
            self.items = new_items
            
        if not self.items or not self.page_items_num:
            return

        self.items.sort()
        self.update_label()
        total_page = self.adjust_page()
        if total_page == 1:
            page_items = self.items[:]
        elif self.current_page == 1:    
            page_items = self.items[:self.page_items_num]
        elif self.current_page == total_page and total_page > 1:
            page_items = self.items[(self.current_page - 1) * self.page_items_num:]
        else:    
            page_items = self.items[(self.current_page - 1) * self.page_items_num:self.current_page * self.page_items_num]

        self.load_items(page_items)
        
    def adjust_page(self):    
        if not self.items or not self.page_items_num:
            return
        
        total_num = len(self.items)
        if total_num <= self.page_items_num:    
            self.current_page = 1
            return 1
        
        mod_num = total_num % self.page_items_num        
        if mod_num:
            return total_num / self.page_items_num + 1
        else:
            return total_num / self.page_items_num
        
    def adjust_current_page(self, total_page):    
        if self.current_page > total_page:
            self.current_page = total_page

    def update_label(self):    
        total_page = self.adjust_page()
        self.adjust_current_page(total_page)
        self.set_label("%d/%d" % (self.current_page, total_page))
            
    def create_simple_button(self, name, callback, *args):        
        button = ImageButton(
            app_theme.get_pixbuf("filter/%s_normal.png" % name),
            app_theme.get_pixbuf("filter/%s_hover.png" % name),
            app_theme.get_pixbuf("filter/%s_press.png" % name)
            )
        if callback:
            button.connect("clicked", callback, *args)
        align = gtk.Alignment()    
        align.set(0.5, 0.5, 0, 0)
        align.add(button)
        return align 
    
    def create_block_box(self):
        box = gtk.EventBox()
        box.set_visible_window(False)
        box.set_size_request(-1, self.child_item_height)
        return box
Ejemplo n.º 39
0
class JobsManager(gtk.HBox):
    __jobs = []
    __id_updater = None
    
    def __init__(self):
        super(JobsManager,self).__init__(spacing=6)
        self.connect("expose-event", self.draw_bg_mask)
        
        self.jobs_label = Label("0 " + _("jobs waiting!"), app_theme.get_color("labelText"), 8)
        self.jobs_label.set_size_request(150, 12)
        label_align = gtk.Alignment()
        label_align.set(0.5, 0.5, 0, 0)
        label_align.set_padding(0, 0, 10, 0)
        label_align.add(self.jobs_label)
        
        self.progress_label = Label("", app_theme.get_color("labelText"), 8)
        self.progress_label.set_size_request(500, 10)
        self.__paused = False
        btn_cancel = self.__create_simple_button("stop", self.stop)
        self.__btn_pause = self.__create_begin_button(self.pause)
        
        btn_pause_align = gtk.Alignment()
        btn_pause_align.set(0.5, 0.5, 0, 0)
        btn_pause_align.add(self.__btn_pause)
        
        btn_cancel_align = gtk.Alignment()
        btn_cancel_align.set(0.5, 0.5, 0, 0)
        btn_cancel_align.set_padding(0, 0, 0, 10)
        btn_cancel_align.add(btn_cancel)
        
        self.pack_start(label_align, False, False)
        # self.pack_start(self.throbber, False, False)
        self.pack_start(self.progress_label,True,True)
        self.pack_start(btn_pause_align,False,False)
        self.pack_start(btn_cancel_align,False,False)
        self.show_all()
        self.set_no_show_all(True)
        self.hide()
        
        self.jobs_label.hide_all()
        
    def draw_bg_mask(self, widget, event):    
        cr = widget.window.cairo_create()
        rect = widget.allocation
        draw_alpha_mask(cr, rect.x, rect.y, rect.width, rect.height, "frameLight")
        
    def __create_simple_button(self, name, callback):    
        button = ImageButton(
            app_theme.get_pixbuf("jobs/%s_normal.png" % name),
            app_theme.get_pixbuf("jobs/%s_hover.png" % name),
            app_theme.get_pixbuf("jobs/%s_hover.png" % name),
            )
        if callback:
            button.connect("clicked", callback) 
        return button    
        
    def __create_begin_button(self, callback):    
        toggle_button = ToggleButton(
            app_theme.get_pixbuf("jobs/pause_normal.png"),            
            app_theme.get_pixbuf("jobs/begin_normal.png"),
            app_theme.get_pixbuf("jobs/pause_hover.png"),
            app_theme.get_pixbuf("jobs/begin_hover.png")            
            )
        if callback:
            toggle_button.connect("toggled", callback)
        return toggle_button    

    def add(self, job):
        job_id = job.connect("end",self.__job_end)
        self.__jobs.append((job, job_id))
        if len(self.__jobs) == 1:
            try: gobject.source_remove(self.__id_updater)
            except: pass
            self.__id_updater = gobject.timeout_add(250,self.__update)
            self.__jobs[0][0].start()
            if self.__paused:
                self.pause(self.__btn_pause)
            self.__update()

    def __job_end(self, ajob):
        gobject.idle_add(self.__job_end_cb, ajob)

    def __job_end_cb(self, ajob):
        job, job_id = self.__jobs.pop(0)
        job.disconnect(job_id)
        if self.__paused:
            self.pause(self.__btn_pause)
        if self.__jobs:
            jobs = [ (job[0].priority, job) for job in self.__jobs ]
            jobs.sort()
            self.__jobs = [ job[1] for job in jobs ]
            self.__jobs[0][0].start()
            self.__update()
        else:
            try: gobject.source_remove(self.__id_updater)
            except:pass
            self.__update()
        del job

    def pause(self, btn):
        if self.__jobs:
            if not self.__paused:
                self.__jobs[0][0].pause()
                self.__paused = True
            else:
                self.__jobs[0][0].unpause()
                self.__paused = False

    def stop(self,*args):
        if self.__jobs:
            if self.__paused:
                self.pause(self.__btn_pause)
                
            self.__jobs[0][0].stop()

    def __update(self):
        if len(self.__jobs)-1 > 0 :
            self.jobs_label.set_text("%d "% (len(self.__jobs)-1) + _("jobs waiting!"))
            self.jobs_label.show_all()
        else:    
            self.jobs_label.hide_all()

        if self.__jobs:
            Dispatcher.show_jobs()            
            message = self.__jobs[0][0].get_info()
            self.progress_label.set_text(message)
            self.show()
            return True
        else:
            Dispatcher.hide_jobs()            
            self.hide()
            self.__id_updater = None
            return False
Ejemplo n.º 40
0
class GuideBox(gtk.VBox):
    def __init__(self):
        super(GuideBox, self).__init__()

        self.scrolled_window = ScrolledWindow()
        self.backgroundbox = BackgroundBox()
        self.backgroundbox.draw_mask = self.draw_mask

        self.guide_pixbuf = utils.get_common_image_pixbuf('guide.png')

        self.top_title = gtk.HBox()

        self.top_left_icon = gtk.VBox()
        self.top_left_icon.set_size_request(self.guide_pixbuf.get_width(),
                                            self.guide_pixbuf.get_height())
        self.top_left_icon.connect('expose-event', self.expose_top_left_icon)
        top_left_icon_align = gtk.Alignment(0.5, 0.5, 0, 0)
        top_left_icon_align.set_padding(15, 3, 13, 3)
        top_left_icon_align.add(self.top_left_icon)

        self.top_right_text = Label(
            _("Introduction"), ui_theme.get_color('label_select_background'),
            14)
        top_right_text_align = gtk.Alignment(0.5, 0.5, 0, 0)
        top_right_text_align.set_padding(18, 3, 3, 3)
        top_right_text_align.add(self.top_right_text)

        self.top_title.pack_start(top_left_icon_align, False, False)
        self.top_title.pack_start(top_right_text_align, False, False)

        self.content_box = gtk.VBox()
        self.guide_label = Label('',
                                 enable_select=False,
                                 wrap_width=200,
                                 text_size=9,
                                 text_color=DynamicColor('#808080'))
        guide_label_align = gtk.Alignment(0.5, 0.5, 1, 1)
        guide_label_align.set_padding(5, 5, 10, 10)
        guide_label_align.add(self.guide_label)
        self.content_box.pack_start(guide_label_align, False, False)

        self.backgroundbox.pack_start(self.top_title, False, False)
        self.backgroundbox.pack_start(self.content_box)

        self.scrolled_window.add_child(self.backgroundbox)
        self.add(self.scrolled_window)

        global_event.register_event('download-app-info-finish',
                                    self.update_content)

    @post_gui
    def update_content(self, js):
        js = json.loads(js)
        self.guide_label.set_text(js['summary'])

    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.
        '''
        sidebar_color = "#ffffff"
        draw_vlinear(cr, x, y, w, h, [
            (0, (sidebar_color, 0.9)),
            (1, (sidebar_color, 0.9)),
        ])

    def expose_top_left_icon(self, widget, event):
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation

        # Draw pkg icon.
        draw_pixbuf(cr, self.guide_pixbuf, rect.x, rect.y)
class FootBox(gtk.HBox):
    def __init__(self):
        gtk.HBox.__init__(self)

        self.set_size_request(-1, 35)

        self.apply_method = None
        self.init_ui()

        self.timer = Timer(3000, self.__clear_tips)

        Dispatcher.connect("button-change", self.set_button)
        Dispatcher.connect("set-tip", self.set_tip)

        event_manager.add_callback("update-delete-button",
                                   self.__on_update_delete_button)

    def __on_update_delete_button(self, name, obj, data):
        #self.btn_delete.set_child_visible(data)
        self.queue_draw()

    def expose_line(self, widget, event):
        cr = widget.window.cairo_create()
        rect = widget.allocation
        style.draw_out_line(cr, rect)

    def init_ui(self):
        self.tip_align = gtk.Alignment(0, 0.5, 0, 1)
        self.tip = Label("", text_x_align=pango.ALIGN_CENTER, label_width=500)
        self.tip_align.set_padding(5, 5, 20, 0)
        self.tip_align.add(self.tip)

        self.btn_delete = Button(_("Delete"))
        self.btn_delete.connect("clicked", self.delete_click)
        self.btn_delete.set_no_show_all(True)
        self.btn_save = Button()
        self.btn_save.connect("clicked", self.button_click)

        button_box = gtk.HBox(spacing=10)
        button_box.pack_start(self.btn_delete)
        button_box.pack_start(self.btn_save)

        self.buttons_align = gtk.Alignment(1, 0.5, 0, 0)
        self.buttons_align.set_padding(0, 0, 0, 10)
        self.buttons_align.add(button_box)
        self.pack(self, [self.tip_align], True, True)
        self.pack_end(self.buttons_align, False, False)

    def pack(self, parent, widgets, expand=False, fill=False):
        for widget in widgets:
            parent.pack_start(widget, expand, fill)

    def set_lock(self, state):
        self.__setting_module.set_lock(state)

    def get_lock(self):
        return self.__setting_module.get_lock()

    def set_button(self, widget, content, state):
        self.btn_save.set_label(_("Save"))
        self.btn_save.set_sensitive(state)

    def delete_click(self, widget):
        if self.focus_connection:
            Dispatcher.delete_setting(self.focus_connection)
            Dispatcher.to_main_page()

    def show_delete(self, connection):
        self.btn_delete.show()
        self.focus_connection = connection

    def hide_delete(self):
        self.btn_delete.hide()
        self.focus_connection = None

        #if content == "save":
        #if state and not self.get_lock():
        #Dispatcher.emit("setting-saved")
        #else:
        #self.btn_save.set_label(_("connect"))
        #self.btn_save.set_sensitive(False)
        #else:
        #self.btn_save.set_label(_("connect"))
        #self.btn_save.set_sensitive(True)

    def get_button(self):
        return self.__setting_module.get_button_state()

    def set_setting(self, module):
        self.__setting_module = module

    def button_click(self, widget):
        #if self.btn_save.label == "save":
        Dispatcher.emit("setting-saved")
        #elif self.btn_save.label == _("connect"):
        #Dispatcher.set_tip("setting saved")
        #Dispatcher.emit("setting-appled")

    def __clear_tips(self):
        self.tip.set_text("")

    def set_tip(self, widget, new_tip):
        self.tip.set_text(_("Tip:") + new_tip)
        self.timer.restart()
Ejemplo n.º 42
0
class IconEditPage(gtk.HBox):
    def __init__(self, account_setting):
        super(IconEditPage, self).__init__(False)
        self.account_setting = account_setting
        self.error_label = Label("",
                                 label_width=350,
                                 enable_select=False,
                                 enable_double_click=False)

        left_align = gtk.Alignment()
        right_align = gtk.Alignment()
        left_align.set_padding(0, 0, 0, 60)
        #right_align.set_padding(0, 0, 0, 60)

        left_vbox = gtk.VBox(False)
        right_vbox = gtk.VBox(False)
        left_vbox.set_spacing(BETWEEN_SPACING)
        right_vbox.set_spacing(BETWEEN_SPACING)

        left_align.add(left_vbox)
        right_align.add(right_vbox)

        self.draw_area = IconEditArea()
        hseparator = HSeparator(
            app_theme.get_shadow_color("hSeparator").get_color_info(), 0, 0)
        hseparator.set_size_request(-1, 10)
        left_vbox.pack_start(
            tools.make_align(
                Label(_("Clip"),
                      app_theme.get_color("globalTitleForeground"),
                      text_size=TITLE_FONT_SIZE,
                      enable_select=False,
                      enable_double_click=False)), False, False)
        left_vbox.pack_start(hseparator, False, False)
        left_vbox.pack_start(
            tools.make_align(self.draw_area, yalign=0.0, width=300,
                             height=300))

        self.thumbnail_large = gtk.Image()
        self.thumbnail_mid = gtk.Image()
        self.thumbnail_small = gtk.Image()
        self.thumbnail_large.set_size_request(150, 150)
        self.thumbnail_mid.set_size_request(48, 48)
        self.thumbnail_small.set_size_request(24, 24)

        hseparator = HSeparator(
            app_theme.get_shadow_color("hSeparator").get_color_info(), 0, 0)
        hseparator.set_size_request(-1, 10)
        right_vbox.pack_start(
            tools.make_align(
                Label(_("Preview"),
                      app_theme.get_color("globalTitleForeground"),
                      text_size=TITLE_FONT_SIZE,
                      enable_select=False,
                      enable_double_click=False)), False, False)
        right_vbox.pack_start(hseparator, False, False)
        right_vbox.pack_start(tools.make_align(self.thumbnail_large), False,
                              False)
        right_vbox.pack_start(tools.make_align(self.thumbnail_mid), False,
                              False)
        right_vbox.pack_start(tools.make_align(self.thumbnail_small), False,
                              False)
        right_vbox.pack_start(tools.make_align(self.error_label, yalign=0.0))

        self.pack_start(left_align, False, False)
        self.pack_start(right_align, False, False)
        self.connect("expose-event", self.draw_frame_border, left_align,
                     right_align)
        self.draw_area.connect("pixbuf-changed", self.__on_pixbuf_changed_cb)

    def draw_frame_border(self, widget, event, la, ra):
        cr = widget.window.cairo_create()
        with cairo_disable_antialias(cr):
            cr.set_line_width(1)
            x, y, w, h = self.thumbnail_large.allocation
            cr.set_source_rgb(*color_hex_to_cairo(TREEVIEW_BORDER_COLOR))
            cr.rectangle(x - 1, y - 1, w + 2, h + 2)
            cr.stroke()
            x, y, w, h = self.thumbnail_mid.allocation
            cr.set_source_rgb(*color_hex_to_cairo(TREEVIEW_BORDER_COLOR))
            cr.rectangle(x - 1, y - 1, w + 2, h + 2)
            cr.stroke()
            x, y, w, h = self.thumbnail_small.allocation
            cr.set_source_rgb(*color_hex_to_cairo(TREEVIEW_BORDER_COLOR))
            cr.rectangle(x - 1, y - 1, w + 2, h + 2)
            cr.stroke()

    def set_pixbuf(self, pixbuf):
        self.error_label.set_text("")
        self.draw_area.set_edit_mode(pixbuf)

    def refresh(self):
        self.set_pixbuf(None)
        self.error_label.set_text("")

    def set_camera_mode(self):
        self.error_label.set_text("")
        self.draw_area.set_camera_mode()

    def stop_camera(self):
        self.draw_area.camera_stop()

    def save_edit_icon(self):
        pixbuf = self.thumbnail_large.get_pixbuf()
        if not pixbuf:
            #self.error_label.set_text("<span foreground='red'>%s%s</span>" % (
            #_("Error:"), _("no picture")))
            self.account_setting.set_status_error_text(_("no picture"))
            return
        tmp = mkstemp(".tmp", "account-settings")
        os.close(tmp[0])
        filename = tmp[1]
        pixbuf.save(filename, "png")
        try:
            self.account_setting.current_set_user.set_icon_file(filename)
            history_icon = self.account_setting.container_widgets[
                "icon_set_page"].history_icon
            if not filename in history_icon.history:
                # backup picture to user home
                path = "/var/lib/AccountsService/icons/" + self.account_setting.current_set_user.get_user_name(
                )
                backup_path = "%s/%s" % (history_icon.icons_dir,
                                         str(int(time())))
                fp1 = open(path, 'r')
                fp2 = open(backup_path, 'w')
                fp2.write(fp1.read())
                fp1.close()
                fp2.close()
                os.chmod(backup_path, S_IRWXU | S_IRWXG | S_IRWXO)
                history_icon.history.insert(0, backup_path)
                history_icon.set_history(history_icon.history)
        except Exception, e:
            print e
            if isinstance(e, (AccountsPermissionDenied, AccountsUserExists,
                              AccountsFailed, AccountsUserDoesNotExist)):
                #self.error_label.set_text("<span foreground='red'>%s%s</span>" % (_("Error:"), e.msg))
                self.account_setting.set_status_error_text(e.msg)
                return
        self.stop_camera()
        self.draw_area.panel.hide_panel()
        self.account_setting.set_to_page(
            self.account_setting.alignment_widgets["main_hbox"], "left")
        self.account_setting.change_crumb(1)
class FootBox(gtk.HBox):
    def __init__(self):
        gtk.HBox.__init__(self)

        self.set_size_request(-1, 35)

        self.apply_method = None
        self.init_ui()

        self.timer = Timer(3000, self.__clear_tips)

        Dispatcher.connect("button-change", self.set_button)
        Dispatcher.connect("set-tip", self.set_tip)

        event_manager.add_callback("update-delete-button", self.__on_update_delete_button)

    def __on_update_delete_button(self, name, obj, data):
        #self.btn_delete.set_child_visible(data)
        self.queue_draw()

    def expose_line(self, widget, event):
        cr = widget.window.cairo_create()
        rect = widget.allocation
        style.draw_out_line(cr, rect)

    def init_ui(self):
        self.tip_align = gtk.Alignment(0, 0.5, 0, 1)
        self.tip = Label("",
                         text_x_align=pango.ALIGN_CENTER,
                         label_width=500)
        self.tip_align.set_padding(5, 5, 20, 0)
        self.tip_align.add(self.tip)


        self.btn_delete = Button(_("Delete"))
        self.btn_delete.connect("clicked", self.delete_click)
        self.btn_delete.set_no_show_all(True)
        self.btn_save = Button()
        self.btn_save.connect("clicked", self.button_click)

        button_box = gtk.HBox(spacing=10)
        button_box.pack_start(self.btn_delete)
        button_box.pack_start(self.btn_save)

        self.buttons_align = gtk.Alignment(1, 0.5, 0, 0)
        self.buttons_align.set_padding(0, 0, 0, 10)
        self.buttons_align.add(button_box)
        self.pack(self, [self.tip_align], True, True)
        self.pack_end(self.buttons_align, False, False)
    
    def pack(self, parent, widgets, expand=False, fill=False):
        for widget in widgets:
            parent.pack_start(widget, expand, fill)

    def set_lock(self, state):
        self.__setting_module.set_lock(state)

    def get_lock(self):
        return self.__setting_module.get_lock()

    def set_button(self, widget, content, state):
        self.btn_save.set_label(_("Save"))
        self.btn_save.set_sensitive(state)

    def delete_click(self, widget):
        if self.focus_connection:
            Dispatcher.delete_setting(self.focus_connection)
            Dispatcher.to_main_page()

    def show_delete(self, connection):
        self.btn_delete.show()
        self.focus_connection = connection

    def hide_delete(self):
        self.btn_delete.hide()
        self.focus_connection = None
            

        #if content == "save":
            #if state and not self.get_lock():
                #Dispatcher.emit("setting-saved")
            #else:
                #self.btn_save.set_label(_("connect"))
                #self.btn_save.set_sensitive(False)
        #else:
            #self.btn_save.set_label(_("connect"))
            #self.btn_save.set_sensitive(True)

    def get_button(self):
        return self.__setting_module.get_button_state()

    def set_setting(self, module):
        self.__setting_module = module

    def button_click(self, widget):
        #if self.btn_save.label == "save":
        Dispatcher.emit("setting-saved")
        #elif self.btn_save.label == _("connect"):
            #Dispatcher.set_tip("setting saved")
            #Dispatcher.emit("setting-appled")

    def __clear_tips(self):
        self.tip.set_text("")

    def set_tip(self, widget, new_tip):
        self.tip.set_text(_("Tip:") + new_tip)
        self.timer.restart()
class TrayDialog(Window):
    def __init__(self):
        Window.__init__(self)

        self.show_pixbuf = vtk_theme.get_pixbuf("deepin_shutdown", 50)
        self.cancel_text = CANCEL_TEXT
        self.btn_text_size = 11
        self.btn_text_color = "#b9b9b9"
        self.draw_rectangle_bool = False

        self.timer = Timer(1000)
        self.second = 60
        self.timer.Enabled = False
        self.timer.connect("Tick", self.timer_tick_evnet)
        
        self.run_exec = None
        self.argv = None
        self.set_pango_list()
        self.ok_key_check = False
        self.cancel_key_check = False
        
        self.__init_widgets()
        self.__init_settings()
        
    def show_dialog_window(self, widget):
        for alpha in range(0, 11):
            self.set_opacity(alpha * 0.1)

    def show_warning(self,
                    info_text,
                    ok_text=OK_TEXT,
                    cancel_text=CANCEL_TEXT,
                    ok_button_first=False,
                    ):
        self.show_pixbuf = vtk_theme.get_pixbuf("deepin_warning", 50)
        self.info_text = info_text

        container_remove_all(self.bottom_hbox)
        self.ok_button = BottomButton(ok_text, self.btn_text_size)
        self.ok_button.connect("clicked", self.ok_btn_clicked)

        self.cancel_button = BottomButton(cancel_text, self.btn_text_size)
        self.cancel_button.connect("clicked", self.quit_dialog_window)
        self.cancel_button.set_check(True)
        if ok_button_first:
            self.bottom_hbox.pack_end(self.ok_button, False, False)
            self.bottom_hbox.pack_end(self.cancel_button, False, False)
        else:
            self.bottom_hbox.pack_end(self.cancel_button, False, False)
            self.bottom_hbox.pack_end(self.ok_button, False, False)

        self.argv = None
        self.run_exec = None
        
        self.set_pango_list()
        
        if self.show_pixbuf:
            self.show_image.set_from_pixbuf(self.show_pixbuf)
        self.tick_label.set_text(info_text)

        self.timer.Enabled = False

        self.show_all()
        self.cancel_button.grab_focus()

    def show_dialog(self,
                    show_pixbuf_name,
                    info_text,
                    ok_text=OK_TEXT,
                    cancel_text=CANCEL_TEXT,
                    ):
        self.show_pixbuf = vtk_theme.get_pixbuf(show_pixbuf_name, 50)
        self.info_text = info_text

        self.ok_button = BottomButton(ok_text, self.btn_text_size)
        self.ok_button.connect("clicked", self.ok_btn_clicked)
        self.ok_button.set_check(True)
        self.cancel_button = BottomButton(cancel_text, self.btn_text_size)
        self.cancel_button.connect("clicked", self.quit_dialog_window)
        container_remove_all(self.bottom_hbox)
        self.bottom_hbox.pack_end(self.ok_button, False, False)
        self.bottom_hbox.pack_end(self.cancel_button, False, False)

        self.second = 60
        self.argv = None
        self.run_exec = None
        
        self.set_pango_list()
        
        if self.show_pixbuf:
            self.show_image.set_from_pixbuf(self.show_pixbuf)
        self.tick_label.set_text(self.info_text % 60)

        self.timer.Enabled = True

        self.show_all()
        self.ok_button.grab_focus()

    def set_pango_list(self):
        self.pango_list = None
        '''
        r, g, b = (65535, 0, 0)
        self.pango_list = pango.AttrList()
        if cn_check():
            start_index, end_index = 8, 12
        else:
            start_index, end_index = EN_RED_TEXT[self.show_top_text] 
            
        self.pango_list.insert(pango.AttrForeground(r, g, b, start_index, end_index - 1))
        '''
        pass

    def focus_out_window(self, widget, event):
        if not hasattr(self, "lose_focus_quit"):
            self.quit_dialog_window(widget)

    def __dialog_realize_event(self, widget):
        self.cancel_btn.grab_focus()

    def __dialog_key_release_event(self, widget, e):
        KEY_LEFT  = 65361
        KEY_RIGHT = 65363
        KEY_ESC   = 65307
        if e.keyval == KEY_LEFT:
            self.ok_button.set_check(False)
            self.cancel_button.set_check(True)
            self.cancel_button.grab_focus()
        elif e.keyval == KEY_RIGHT:
            self.ok_button.set_check(True)
            self.cancel_button.set_check(False)
            self.ok_button.grab_focus()
        elif e.keyval == KEY_ESC: # 退出窗口.
            self.quit_dialog_window(widget)

    def __init_settings(self):
        self.set_bg_pixbuf(vtk_theme.get_pixbuf("deepin_on_off_bg", 372))
        self.set_size_request(APP_WIDTH, APP_HEIGHT)
        self.set_position(gtk.WIN_POS_CENTER)
        self.set_skip_pager_hint(True)
        self.set_skip_taskbar_hint(True)
        self.set_keep_above(True)
        self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
        self.connect("show", self.show_dialog_window)
        self.connect("focus-out-event", self.focus_out_window)
        self.connect("realize", self.__dialog_realize_event)
        self.connect("key-release-event", self.__dialog_key_release_event)

    def __init_widgets(self):
        self.main_vbox = gtk.VBox()
        self.mid_hbox = gtk.HBox()
        self.show_text_vbox = gtk.VBox()
        self.bottom_hbox_ali = gtk.Alignment(0, 0.5, 1, 0)
        self.bottom_hbox_ali.set_padding(3, 8, 15, 15)
        self.bottom_hbox = gtk.HBox(spacing=30)
        self.bottom_hbox_ali.add(self.bottom_hbox)
        
        self.init_titlebar()
        self.init_close_button()
        self.init_show_image()
        #self.init_show_text()
        self.init_bottom_button()
        
        self.titlebar_hbox.pack_start(self.close_btn, False, False)
        #self.show_text_vbox.pack_start(self.top_text_btn_ali, False, False)
        #self.show_text_vbox.pack_start(self.bottom_text_btn_ali, False, False)
        if LANGUAGE == 'en_US':
            text_size = 9
        else:
            text_size = 10
        self.tick_label = Label("", 
                text_color=DynamicColor("#FFFFFF"), wrap_width=230, text_size=text_size)
        self.show_text_vbox.pack_start(self.tick_label, False, False)

        self.mid_hbox.pack_start(self.show_image_ali, False, False)
        self.mid_hbox.pack_start(self.show_text_vbox, True, True)

        self.bottom_hbox.pack_end(self.ok_btn, False, False)
        self.bottom_hbox.pack_end(self.cancel_btn, False, False)

        self.main_vbox.pack_start(self.titlebar_ali, False, False)
        self.main_vbox.pack_start(self.mid_hbox, True, True)
        self.main_vbox.pack_start(self.bottom_hbox_ali, False, False)
        self.add_widget(self.main_vbox)

    def init_titlebar(self):
        self.titlebar_ali = gtk.Alignment(1, 0, 0, 0)
        self.titlebar_hbox = gtk.HBox()
        self.titlebar_ali.add(self.titlebar_hbox)

    def init_close_button(self):
        # init close button.
        self.close_btn = gtk.Button("x")
        self.close_btn.set_size_request(20, 20)
        self.close_btn.connect("button-press-event", self.close_btn_clicked)
        self.close_btn.connect("expose-event", self.close_btn_expose_event)

    def close_btn_clicked(self, widget, event):
        if event.button == 1:
            self.quit_dialog_window(widget)

    def close_btn_expose_event(self, widget, event):
        return True

    def init_show_image(self):
        size = 20
        left_padding = 10
        padding = (size, size, size + left_padding, size)
        #
        self.show_image_ali = gtk.Alignment(0, 0, 0, 0)
        self.show_image_ali.set_padding(*padding)
        self.show_image = gtk.Image()
        self.show_image_ali.add(self.show_image)
        #
        if self.show_pixbuf:
            self.show_image.set_from_pixbuf(self.show_pixbuf)

    def timer_tick_evnet(self, timer):
        self.second -= 1
        self.tick_label.set_text(self.info_text % self.second)
        if self.second == 0:
            timer.Enabled = False
            if self.run_exec:
                gtk.timeout_add(1, self.run_exec_timeout)
                gtk.timeout_add(100, lambda :self.quit_dialog_window(self))
            else:
                self.quit_dialog_window(self)

    def init_bottom_button(self):
        self.cancel_btn = gtk.Button(self.cancel_text)
        self.ok_btn = gtk.Button()

        self.cancel_btn.connect("clicked", self.quit_dialog_window)
        self.cancel_btn.connect("expose-event", self.label_expose_event, 30)
        self.cancel_btn.connect("enter-notify-event", self.label_enter_notify_event)

        self.ok_btn.connect("clicked", self.ok_btn_clicked)
        self.ok_btn.connect("expose-event", self.label_expose_event, 0)
        self.ok_btn.connect("enter-notify-event", self.label_enter_notify_event)

    def label_enter_notify_event(self, widget, event):
        self.ok_btn.queue_draw()
        self.cancel_btn.queue_draw()
        if self.ok_btn != widget:
            self.ok_key_check = False
        if self.cancel_btn != widget:
            self.cancel_key_check = False

    def ok_btn_clicked(self, widget):
        if self.run_exec:
            self.run_exec_timeout()
        self.quit_dialog_window(widget)

    def run_exec_timeout(self):
        if self.argv is None:
            self.run_exec()
        else:
            self.run_exec(self.argv)

    def label_expose_event(self, widget, event, width):
        color = self.btn_text_color
        if widget == self.ok_btn and self.ok_key_check:
            color = "#FFFFFF"
        elif widget == self.cancel_btn and self.cancel_key_check:
            color = "#FFFFFF"

        if widget.state == gtk.STATE_PRELIGHT:
            color = "#FFFFFF"
        
        cr = widget.window.cairo_create()
        rect = widget.allocation
        
        size = get_text_size(widget.get_label(), 
                             self.btn_text_size, 
                             DEFAULT_FONT)
        draw_text(cr, 
                  widget.get_label(),
                  rect.x, 
                  rect.y + rect.height/2 - size[1]/2, 
                  text_size=self.btn_text_size, 
                  text_color=color, 
                  text_font=DEFAULT_FONT)  
        widget.set_size_request(size[0] + width, size[1] + 10)
        
        return True

    def quit_dialog_window(self, widget):
        for alpha in range(10, -1, -1):
            self.set_opacity(alpha * 0.1)
        self.hide_all()
        self.timer.Enabled = False
        self.grab_remove()

        if hasattr(self, "quit_alone"):
            gtk.main_quit()
Ejemplo n.º 45
0
class SongTimer(gtk.HBox):
    __gsignals__ = {
        "play-end": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())
    }

    def __init__(self, draw_time_callback=None):
        super(SongTimer, self).__init__()

        self.label_time = Label("00:00",
                                app_theme.get_color("labelText"),
                                8,
                                enable_gaussian=True)
        self.draw_time_callback = draw_time_callback
        if draw_time_callback:
            draw_time_callback(self.label_time.get_text())

        self.bar = ProgressBar()
        bar_align = gtk.Alignment()
        bar_align.set_padding(0, 0, 1, 1)
        bar_align.set(1, 1, 1, 1)
        bar_align.add(self.bar)
        self.bar.connect("button-press-event", self.on_bar_press)
        self.bar.connect("button-release-event", self.on_bar_release)
        self.__value_changed_id = self.bar.connect("value-changed",
                                                   self.on_bar_value_changed)

        self.pack_start(bar_align, True, True)
        self.update_bar = 1
        self.duration = 0
        self.__idle_release_id = None
        self.delete = False
        self.__need_report = False
        self.press_flag = False

        Player.connect("instant-new-song", self.set_duration)
        Player.connect("init-status", self.on_player_init_status)

        Player.bin.connect("queue-running", self.on_queue_running)
        Player.bin.connect("tick", self.on_tick)
        Player.connect("seeked", self.on_seek)
        Player.connect("stopped", self.set_duration)
        if not Player.song:
            self.bar.set_sensitive(False)

    def on_queue_running(self, obj, uri):
        self.update_bar = 1

    def on_player_init_status(self, player):
        self.label_time.set_text("00:00")
        self.bar.set_value(0)
        self.bar.set_sensitive(True)
        if self.draw_time_callback:
            self.draw_time_callback(self.label_time.get_text())

    def get_label(self):
        return self.label_time

    def stop(self):
        self.delete = True

    def set_duration(self, player, song=None):
        self.update_bar = 1

        if not song:
            if player.song: song = player.song
            else: return
        else:
            self.__need_report = True

        self.duration = song.get("#duration", 0) / 1000
        self.set_current_time(0, self.duration)

    def on_tick(self, bin, pos, duration):
        if Player.song:
            if Player.song.get_type() == "webcast":
                duration = 0

        pos /= 1000.0
        duration /= 1000.0

        if Player.song and Player.song.get_type() == "cue":
            duration = Player.song.get("#duration") / 1000
            pos = pos - Player.song.get("seek", 0)

        self.duration = duration
        if self.update_bar == 1:
            self.set_current_time(pos, duration)
        return not self.delete

    def set_current_time(self, pos, duration):
        if self.update_bar == 1:
            if duration == 0 or pos >= duration:
                self.bar.set_range(0, 1000)
                self.bar.set_value(0)
                self.bar.set_sensitive(False)
            else:
                self.bar.set_sensitive(True)
                self.bar.set_range(0, duration)
                self.bar.set_value(pos)

        # total = utils.duration_to_string(duration * 1000, "00:00")
        if pos > 0 and pos < duration:
            current = utils.duration_to_string(pos, "00:00", 1)
        else:
            current = "00:00"

        if pos > 0 and Player.song and Player.song.get_type() == "webcast":
            current = utils.duration_to_string(pos, "00:00", 1)
            # total = "--:--"
        # text = "%s/%s" % (current, total)
        text = current
        self.label_time.set_text(text)
        if self.draw_time_callback:
            self.draw_time_callback(text)

    def on_seek(self, *args, **kwargs):
        self.__need_report = False

    def on_bar_value_changed(self, widget, value):
        pos = self.bar.get_value()
        self.set_current_time(pos, self.duration)

    def on_bar_press(self, widget, event):
        if not self.press_flag:
            if self.__idle_release_id:
                gobject.source_remove(self.__idle_release_id)
                self.__idle_release_id = None
            self.update_bar = 0
            self.__need_report = False

            self.bar.disconnect(self.__value_changed_id)
            self.press_flag = True

    def __idle_release(self):
        if Player.song.get_type() in ("cue", "cdda", "local"):
            self.update_bar = 1

        self.__idle_release_id = None

    def on_bar_release(self, widget, event):
        if self.press_flag:
            self.__value_changed_id = self.bar.connect(
                "value-changed", self.on_bar_value_changed)

            s = Player.song
            if not s:
                return
            if s.get_type() in [
                    "webcast",
            ]:
                return

            if s.get_type() == "cue":
                Player.seek(s.get("seek", 0) + self.bar.get_value())
            else:
                Player.seek(self.bar.get_value())

            # wait a bit that the player are really seek to update the progress bar
            # if not self.__idle_release_id:
            self.__idle_release()
            self.__idle_release_id = gobject.idle_add(self.__idle_release)
            self.press_flag = False
Ejemplo n.º 46
0
class ShareToWeibo(object):
    '''share picture to weibo'''
    def __init__(self, filename=""):
        '''
        init share
        @param filename: the file to share
        '''
        self.upload_image = filename
        self.thumb_width = 188
        self.thumb_height = 168
        self.MAX_CHAR = 140
        #self.__text_frame_color = (0.76, 0.76, 0.76)
        self.__win_width = 602
        open(COOKIE_FILE,'wb').close()

        self.window = DialogBox(_("Share to social networks"), close_callback=gtk.main_quit)
        self.window.set_keep_above(True)
        self.window.set_size_request(self.__win_width+20, 288)
        self.window.set_resizable(False)
        #self.window.titlebar.connect("expose-event", self.__expose_top_and_bottome)
        #self.window.button_box.connect("expose-event", self.__expose_top_and_bottome)

        # create slider
        self.slider = HSlider()
        self.slider_list = []

        self.share_box = gtk.VBox(False)     # first page, input context
        self.web_box = gtk.VBox(False, 10)      # second page, login
        self.result_box = gtk.VBox(False, 10)   # third page, share result

        share_align = gtk.Alignment()
        share_align.set(0.5, 0.5, 0, 0)
        share_align.add(self.share_box)
        share_align.connect("expose-event", self.__slider_expose)

        # go back button
        web_left_button = ImageButton(
            app_theme.get_pixbuf("share/back_normal.png"),
            app_theme.get_pixbuf("share/back_hover.png"),
            app_theme.get_pixbuf("share/back_press.png"))
        web_left_button.connect("clicked", lambda w: self.set_slide_index(0))
        web_left_button.set_can_focus(False)
        utils.set_clickable_cursor(web_left_button)
        # show url entry
        self.web_url_entry = InputEntry()
        self.web_url_entry.set_editable(False)
        self.web_url_entry.set_size(555, 20)
        self.web_url_entry.entry.right_menu_visible_flag = False
        # alig url entry
        web_navigate_vbox = gtk.VBox(False)
        web_navigate_vbox.pack_start(self.web_url_entry)
        web_navigate_t_align = gtk.Alignment()
        web_navigate_t_align.set(0.0, 0.5, 0, 0)
        web_navigate_t_align.add(web_navigate_vbox)
        # pack back button and url entry
        web_navigate_box = gtk.HBox(False, 7)
        web_navigate_box.pack_start(web_left_button, False, False)
        web_navigate_box.pack_start(web_navigate_t_align)

        web_navigate_align = gtk.Alignment()
        web_navigate_align.set(0.5, 0.5, 0, 0)
        web_navigate_align.set_padding(4, 0, 11, 13)
        web_navigate_align.add(web_navigate_box)

        # create a webkit
        self.web_view = WebView(COOKIE_FILE)
        self.web_view.connect("notify::load-status", self.web_view_load_status)
        self.web_view.connect("load-error", self.web_view_load_error)
        self.web_scrolled_window = ScrolledWindow()
        self.web_scrolled_window.add(self.web_view)
        self.web_scrolled_window.set_size_request(590, 228)

        self.web_box.pack_start(web_navigate_align, False, False)
        self.web_box.pack_start(self.web_scrolled_window)
        #self.web_box.set_size_request(-1, 258)
        web_align = gtk.Alignment()
        web_align.set(0.5, 0.0, 0, 1)
        web_align.add(self.web_box)
        web_align.connect("expose-event", self.__slider_expose)

        res_align = gtk.Alignment()
        res_align.set(0.5, 0.5, 0, 0)
        res_align.add(self.result_box)
        res_align.connect("expose-event", self.__slider_expose)

        self.slider.set_to_page(share_align)
        self.slider_list.append(share_align)
        self.slider_list.append(web_align)
        self.slider_list.append(res_align)

        self.__weibo_list = []
        self.sina = weibo.Sina(self.web_view)
        self.qq = weibo.Tencent(self.web_view)
        self.__weibo_list.append(self.sina)
        self.__weibo_list.append(self.qq)
        if default_locale != 'zh_CN':
            self.twitter = weibo.Twitter(self.web_view)
            #self.__weibo_list.append(self.twitter)
        self.__current_weibo = None

        self.weibo_name_l18n = {
                'Sina': _("Sina"),
                'Tencent': _("Tencent"),
                'Twitter': _("Twitter"),
                }

        self.window.body_box.pack_start(self.slider, True, True)
        self.init_share_box()

    # webkit load-status, login success, go back
    def web_view_load_status(self, web, status):
        '''web_view notify load-status callback'''
        state = web.get_property("load-status")
        url = web.get_property('uri')
        if url:
            self.web_url_entry.set_editable(True)
            self.web_url_entry.set_text(url)
            self.web_url_entry.entry.move_to_start()
            self.web_url_entry.set_editable(False)
        if state == webkit.LOAD_FAILED:  # load failed
            print "load failed",
            print web.get_property('uri')

        elif state == webkit.LOAD_COMMITTED:
            if self.__current_weibo and self.__current_weibo.is_callback_url(url):
                web.stop_loading()  # if go to  callback url, stop loading
                # access token
                #print "load committed", url
                t = threading.Thread(target=self.weibo_login_thread)
                t.setDaemon(True)
                t.start()

    def web_view_load_error(self, web, fram, url, error, data=None):
        web.load_string(
            "<html><body><p><h1>%s</h1></p>%s</body></html>" % (
            _("Unable to load page"),
            _("Problem occurred while loading the URL '%s'") % (url)),
            "text/html", "UTF-8", "")
        print url
        return True

    # login or switch user
    def weibo_login(self, widget, weibo):
        '''weibo button clicked callback'''
        self.web_view.load_uri("about:blank")
        utils.set_cursor(widget)
        self.set_slide_index(1)
        self.__current_weibo = weibo
        t = threading.Thread(target=self.__current_weibo.request_oauth)
        t.setDaemon(True)
        t.start()

    def weibo_login_thread(self):
        '''in webkit login finish, get user info again'''
        self.__current_weibo.access_token()
        self.get_user_info_again()
        gtk.gdk.threads_enter()
        self.set_slide_index(0)
        gtk.gdk.threads_leave()

    def get_user_info_again(self):
        ''' login or switch user, and get user info again'''
        box = self.__current_weibo.get_box()
        #print "cuurent weibo:", self.__current_weibo.t_type
        gtk.gdk.threads_enter()
        children = box.get_children()
        for child in children:
            if child in self.__weibo_check_button_list:
                self.__weibo_check_button_list.remove(child)
            if child in self.__weibo_image_button_list:
                self.__weibo_image_button_list.remove(child)
            child.destroy()
        gtk.gdk.threads_leave()

        self.get_user_info(self.__current_weibo)

        gtk.gdk.threads_enter()
        box.show_all()
        gtk.gdk.threads_leave()

    def set_slide_index(self, index):
        '''
        set slide to index
        @param index: the index of widget in slider, an int num
        '''
        if index >= len(self.slider_list):
            return
        direct = "right"
        if index == 1 and self.window.button_box in self.window.window_frame.get_children():
            #self.slider.set_size_request(-1, 260)
            win = self.window
            if win.left_button_box in win.button_box.get_children():
                win.button_box.remove(win.left_button_box)
            if win.right_button_box in win.button_box.get_children():
                win.button_box.remove(win.right_button_box)
            tmp = gtk.HSeparator()
            tmp.set_size_request(-1, 1)
            tmp.show()
            win.button_box.pack_start(tmp)
            direct = "right"
            #if self.window.button_box in self.window.window_frame.get_children():
                #self.window.window_frame.remove(self.window.button_box)
        elif index == 0:
            #self.slider.set_size_request(-1, 223)
            win = self.window
            for each in win.button_box.get_children():
                each.destroy()
            if win.left_button_box not in win.button_box.get_children():
                win.button_box.pack_start(win.left_button_box)
            if win.right_button_box not in win.button_box.get_children():
                win.button_box.pack_start(win.right_button_box)
            direct = "left"
            #if self.window.button_box not in self.window.window_frame.get_children():
                #self.window.window_frame.pack_start(self.window.button_box, False, False)
        elif index == 2:
            self.window.left_button_box.set_buttons([])
            l = Label("  ")
            l.show()
            self.window.right_button_box.set_buttons([l])
            direct = "right"
            #self.slider.set_size_request(-1, 223)

        self.slider.slide_to_page(self.slider_list[index], direct)

    def weibo_check_toggle(self, button, weibo):
        '''weibo check button toggled callback. check the weibo to share'''
        if button.get_active():
            self.to_share_weibo[weibo] = 1
        else:
            self.to_share_weibo[weibo] = 0

    def create_ico_image(self, name):
        ''' create image from file'''
        pix1 = app_theme_get_dynamic_pixbuf('image/share/%s.png' % name).get_pixbuf()
        pix2 = app_theme_get_dynamic_pixbuf('image/share/%s_no.png' % name).get_pixbuf()
        return (pix1, pix2)

    def get_user_info(self, weibo):
        '''get weibo user info'''
        info = weibo.get_user_name()
        gtk.gdk.threads_enter()
        #self.get_user_error_text = ""
        weibo_hbox = weibo.get_box()
        hbox = gtk.HBox(False)
        vbox = gtk.VBox(False)
        weibo_hbox.pack_start(vbox, False, False)
        vbox.pack_start(hbox)
        #print weibo.t_type, info
        if info:
            self.is_get_user_info[weibo] = 1
            label = Label(text=info, label_width=70, enable_select=False)
            check = CheckButton()
            #check = gtk.CheckButton()
            check.connect("toggled", self.weibo_check_toggle, weibo)
            check.set_active(True)
            check_vbox = gtk.VBox(False)
            check_align = gtk.Alignment(0.5, 0.5, 0, 0)
            check_align.add(check_vbox)
            check_vbox.pack_start(check, False, False)
            button = ImageButton(
                app_theme.get_pixbuf("share/" + weibo.t_type + ".png"),
                app_theme.get_pixbuf("share/" + weibo.t_type + ".png"),
                app_theme.get_pixbuf("share/" + weibo.t_type + ".png"))
            utils.set_clickable_cursor(button)
            button.connect("enter-notify-event", self.show_tooltip, _("Click to switch user"))
            hbox.pack_start(check_align, False, False)
            hbox.pack_start(button, False, False, 5)
            hbox.pack_start(label, False, False)
        else:
            self.is_get_user_info[weibo] = 0
            check = CheckButton()
            #check = gtk.CheckButton()
            check.set_sensitive(False)
            check_vbox = gtk.VBox(False)
            check_align = gtk.Alignment(0.5, 0.5, 0, 0)
            check_align.add(check_vbox)
            check_vbox.pack_start(check, False, False)
            button = ImageButton(
                app_theme.get_pixbuf("share/" + weibo.t_type + "_no.png"),
                app_theme.get_pixbuf("share/" + weibo.t_type + "_no.png"),
                app_theme.get_pixbuf("share/" + weibo.t_type + "_no.png"))
            utils.set_clickable_cursor(button)
            button.connect("enter-notify-event", self.show_tooltip, _("Click to login"))
            hbox.pack_start(check_align, False, False)
            hbox.pack_start(button, False, False, 5)
            # curl time out
            info_error = weibo.get_curl_error()
            if info_error:
                #self.get_user_error_text += "%s:%s." % (weibo.t_type, _(info_error))
                hbox.pack_start(
                    Label(text="(%s)" % _(info_error), label_width=70,enable_select=False,
                    text_color = ui_theme.get_color("category_item")), False, False)

        button.connect("clicked", self.weibo_login, weibo)
        self.__weibo_check_button_list.append(check)
        self.__weibo_image_button_list.append(button)
        gtk.gdk.threads_leave()
        return weibo_hbox

    def show_tooltip(self, widget, event, text):
        '''Create help tooltip.'''
        Tooltip.text(widget, text)

    def init_user_info_thread(self, button, text_view):
        '''get user name thread'''
        time.sleep(0.1)

        for weibo in self.__weibo_list:
            self.get_user_info(weibo)

        gtk.gdk.threads_enter()
        #self.share_box.set_sensitive(True)
        button.set_sensitive(True)
        text_view.set_editable(True)
        for weibo in self.__weibo_list:
            weibo.get_box().show_all()
            weibo.get_box().queue_draw()
        self.loading_label.destroy()
        gtk.gdk.threads_leave()

    # init share box, create share button, input
    def init_share_box(self):
        '''get weibo info, and create button'''
        self.to_share_weibo = {}
        self.to_share_weibo_res = {}
        self.deepin_info = {}
        self.is_get_user_info = {}
        self.__weibo_check_button_list = []
        self.__weibo_image_button_list = []

        # create Thumbnail
        if exists(self.upload_image):
            pixbuf = gtk.gdk.pixbuf_new_from_file(self.upload_image)
            pix_w = pixbuf.get_width()
            pix_h = pixbuf.get_height()
            if pix_w > pix_h:
                pix_s_w = self.thumb_width
                pix_s_h = int(pix_h / (float(pix_w) / self.thumb_width))
            else:
                pix_s_h = self.thumb_height
                pix_s_w = int(pix_w / (float(pix_h) / self.thumb_height))
            pixbuf = pixbuf.scale_simple(pix_s_w, pix_s_h, gtk.gdk.INTERP_TILES)
            thumb = gtk.image_new_from_pixbuf(pixbuf)
        else:
            thumb = gtk.Image()
        thumb.set_size_request(self.thumb_width, self.thumb_height)

        # weibo context input
        text_box = gtk.HBox(False, 2)
        text_vbox = gtk.VBox(False, 2)
        text_bg_vbox = gtk.VBox(False)
        text_bg_align = gtk.Alignment()
        text_bg_align.set(0.5, 0.5, 0, 0)
        text_bg_align.set_padding(5, 5, 16, 5)
        text_bg_align.connect("expose-event", self.text_view_bg_expose)
        text_scrolled_win = gtk.ScrolledWindow()
        text_scrolled_win.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER)
        text_scrolled_win.set_size_request(340, 157)

        text_view = gtk.TextView()
        text_view.set_left_margin(10)
        text_view.set_right_margin(10)
        text_view.set_pixels_above_lines(5)
        text_view.set_pixels_below_lines(5)
        text_view.set_wrap_mode(gtk.WRAP_WORD| gtk.WRAP_CHAR)
        text_view.connect("expose-event", self.text_view_expose)
        buf = text_view.get_buffer()
        text_scrolled_win.add(text_view)
        text_bg_vbox.pack_start(text_scrolled_win)
        text_bg_align.add(text_bg_vbox)

        text_align = gtk.Alignment()
        text_align.set(0.5, 0.5, 0, 0)
        text_align.set_padding(25, 30, 10, 10)

        text_box.pack_start(thumb, False, False, 10)
        text_box.pack_start(text_bg_align)
        text_vbox.pack_start(text_box, False, False, 10)

        text_align.add(text_vbox)
        #tmp_align = gtk.Alignment()
        #tmp_align.set(0.5, 0, 0, 1)
        #self.share_box.pack_start(tmp_align, False, False)
        self.share_box.pack_start(text_align, False, False)

        # dialog button box
        left_box = self.window.left_button_box
        right_box = self.window.right_button_box

        # input tip label
        self.input_num_label = Label("%d" % self.MAX_CHAR,
            text_size=16, text_x_align=pango.ALIGN_CENTER, label_width=50, enable_select=False)
        self.input_num_label.text_color = ui_theme.get_color("label_select_text")

        # login box
        #weibo_box = gtk.HBox(False, 1)
        #weibo_box.set_size_request(-1, 50)
        weibo_box_list = []
        self.loading_label = Label("%s..." % _("Loading"), text_size=12,
            label_width=70, enable_select=False)
        weibo_box_list.append(self.loading_label)

        for weibo in self.__weibo_list:
            box = gtk.HBox(False, 2)
            weibo.set_box(box)
            weibo_box_list.append(box)
        left_box.set_buttons(weibo_box_list)

        # share button
        button = Button(_("Share"))
        #button.set_size_request(75, 25)
        button.connect("clicked", self.share_button_clicked, text_view)
        buf.connect("changed", self.text_view_changed, button)  # check char num

        tmp_vbox = gtk.VBox(False)
        tmp_align = gtk.Alignment()
        tmp_align.set(0.5, 0.5, 0, 0)
        tmp_vbox.pack_start(button, False, False)
        #tmp_vbox.pack_start(tmp_align)
        tmp_align.add(tmp_vbox)
        right_box.set_buttons([self.input_num_label, tmp_align])

        # at first, set widget insensitive
        button.set_sensitive(False)
        text_view.set_editable(False)
        t = threading.Thread(target=self.init_user_info_thread, args=(button, text_view))
        t.setDaemon(True)
        t.start()

    # draw text view background
    def text_view_bg_expose(self, widget, event):
        '''draw text view bg'''
        cr = widget.window.cairo_create()
        rect = widget.allocation
        text_pixbuf = app_theme_get_dynamic_pixbuf('image/share/text_view.png').get_pixbuf()
        draw.draw_pixbuf(cr, text_pixbuf, rect.x, rect.y)

    # if text is empty, show tip info
    def text_view_expose(self, text_view, event):
        '''text_view expose'''
        buf = text_view.get_buffer()
        text = buf.get_text(*buf.get_bounds())

        if text == "" and text_view.get_editable() and not text_view.is_focus():
            win = text_view.get_window(gtk.TEXT_WINDOW_TEXT)
            cr = win.cairo_create()
            cr.move_to(10, 5)
            context = pangocairo.CairoContext(cr)
            layout = context.create_layout()
            layout.set_font_description(pango.FontDescription("Snas 10"))
            layout.set_alignment(pango.ALIGN_LEFT)
            layout.set_text(_("Please input text here"))
            cr.set_source_rgb(0.66, 0.66, 0.66)
            context.update_layout(layout)
            context.show_layout(layout)

    # show input char num
    def text_view_changed(self, buf, button):
        '''text_view changed callback'''
        count = buf.get_char_count()
        if count <= self.MAX_CHAR:
            #self.input_tip_label.set_text(_("left"))
            self.input_num_label.set_text("%d" % (self.MAX_CHAR - count))
            self.input_num_label.text_color = ui_theme.get_color("category_item")
            if not button.is_sensitive():
                button.set_sensitive(True)
        else:
            #self.input_tip_label.set_text(_("exceeds"))
            self.input_num_label.set_text("-%d" % (count - self.MAX_CHAR))
            self.input_num_label.text_color = ui_theme.get_color("category_item")
            if button.is_sensitive():
                button.set_sensitive(False)

    def show_confirm_dialog(self, title, content):
        d = ConfirmDialog(
                title,
                content,
                text_wrap_width=300,
                )
        d.show_all()
        d.set_transient_for(self.window)

    def share_button_clicked(self, button, text_view):
        '''share_button_clicked callback'''
        # file is not exist.
        if not exists(self.upload_image):
            self.show_confirm_dialog(
                    _("Error"),
                    _("Nonexistent picture"),
                    )
            return False
        has_share_web = False
        for weibo in self.to_share_weibo:
            if self.to_share_weibo[weibo]:
                has_share_web = True
                break
        # have no web selected
        if not has_share_web:
            self.show_confirm_dialog(
                    _("Error"),
                    _("Please choose at least one platform to share on"),
                    )
            return False
        # at first, set widget insensitive
        button.set_sensitive(False)
        text_view.set_editable(False)
        #self.window.left_button_box.set_sensitive(False)
        # set weibo checkbutton sensitive
        for check in self.__weibo_check_button_list:
            check.set_sensitive(False)
        # disconnect weibo ico button clicked function
        for img in self.__weibo_image_button_list:
            try:
                img.disconnect_by_func(self.weibo_login)
            except:
                pass
        button.set_label(_("Sharing"))
        t = threading.Thread(target=self.share_to_weibo_thread, args=(text_view, ))
        t.setDaemon(True)
        t.start()

    # upload image thread
    def share_to_weibo_thread(self, text_view):
        '''share in thread'''
        buf = text_view.get_buffer()
        text = buf.get_text(*buf.get_bounds())
        if text.strip() == "":
            text = _("from Deepin Game")
        # get deepin official info
        self.deepin_info[self.sina] = self.sina.get_deepin_info()
        self.deepin_info[self.qq] = self.qq.get_deepin_info()
        if default_locale != 'zh_CN':
            self.deepin_info[self.twitter] = self.twitter.get_deepin_info()
        # upload
        for weibo in self.to_share_weibo:
            if self.to_share_weibo[weibo]:
                self.to_share_weibo_res[weibo] = weibo.upload_image(self.upload_image, text)
        self.share_to_weibo_result()

    # show upload result
    @post_gui
    def share_to_weibo_result(self):
        '''result of share to weibo'''
        font_color = ui_theme.get_color("category_item")
        res_hbox = gtk.HBox(False)
        res_hbox.set_size_request(-1, 240)

        res_left_box = DialogLeftButtonBox()
        res_right_box = DialogRightButtonBox()

        res_left_box.button_align.set(0.5, 0.0, 0, 1)
        res_right_box.button_align.set(0.5, 0.0, 0, 1)
        res_left_box.button_align.set_padding(5, 9, 19, 0)
        res_right_box.button_align.set_padding(30, 0, 0, 0)

        res_left_box.set_size_request(405, -1)
        res_right_box.set_size_request(195, -1)

        res_hbox.pack_start(res_left_box)
        res_hbox.pack_start(
            VSeparator(app_theme.get_shadow_color("VSeparator").get_color_info(), 0, 0))
        res_hbox.pack_start(res_right_box)

        res_vbox = gtk.VBox(False)
        follow_vbox = gtk.VBox(False)

        tmp_img = gtk.Image()       # only use as a placeholder
        tmp_img.set_size_request(-1, 50)
        res_vbox.pack_start(tmp_img, False, False)

        follow_tip_hbox = gtk.HBox(False)
        img = gtk.image_new_from_icon_name("deepin-logo", 16)
        if img.get_pixel_size() == -1:
            img = gtk.image_new_from_file(app_theme.get_theme_file_path("image/share/deepin_logo.png"))
        follow_tip_hbox.pack_start(img, False, False, 5)
        follow_tip_hbox.pack_start(
            Label("%s %s" % (_("Follow"), "Linux Deepin"),
                text_color=app_theme_get_dynamic_color("#5f5f5f"),
                text_size=12, enable_select=False), False, False)
        follow_vbox.pack_start(follow_tip_hbox, False, False, 13)
        for weibo in self.to_share_weibo_res:
            vbox = gtk.VBox(False, 1)
            tip_box = gtk.HBox()
            error_box = gtk.HBox()
            vbox.pack_start(tip_box, False, False)
            vbox.pack_start(error_box, False, False)
            if self.to_share_weibo_res[weibo][0]:   # upload succeed
                img = gtk.image_new_from_file(app_theme.get_theme_file_path("image/share/share_succeed.png"))
                #link = LinkButton(_(weibo.t_type), text_size=13, self.to_share_weibo_res[weibo][1])
                link = Label(self.weibo_name_l18n[weibo.t_type], text_size=12,
                    text_color=ui_theme.get_color("link_text"))
                #, enable_gaussian=True, gaussian_radious=1, border_radious=0)
                link.add_events(gtk.gdk.BUTTON_PRESS_MASK)
                link.connect("enter-notify-event", lambda w, e: self.__draw_under_line(w))
                link.connect("leave-notify-event", lambda w, e: w.queue_draw())
                link.connect("button-press-event", self.goto_weibo_button_clicked, weibo)
                link_box = gtk.HBox(False)
                link_box.pack_start(link, False, False)
                utils.set_clickable_cursor(link)
                text = _("Share to")
                label = Label(text, text_size=12,
                    text_color=font_color, enable_select=False)
                text = _("Successful")
                label1 = Label(text, text_size=12,
                    text_color=font_color, enable_select=False)
                tip_box.pack_start(img, False, False, 15)
                tip_box.pack_start(label, False, False, 3)
                tip_box.pack_start(link_box, False, False, 3)
                tip_box.pack_start(label1, False, False)
                # only use as a placeholder
                img = gtk.Image()
                img.set_size_request(20, 1)
                error_box.pack_start(img, False, False, 16)
                tmp = Label(" ", text_size=9, label_width=200)
                tmp.set_size_request(200, 1)
                error_box.pack_start(tmp, False, False)
                #print text
            else:   # upload failed
                img = gtk.image_new_from_file(app_theme.get_theme_file_path("image/share/share_failed.png"))
                #text = "% %s %s." % (_(weibo.t_type), _("upload failed"))
                text = _("Share to")
                label1 = Label(text, text_size=12,
                    text_color=font_color, enable_select=False)
                label2 = Label(_(weibo.t_type), text_size=12,
                    text_color=font_color, enable_select=False)
                text = _("Failed")
                label3 = Label(text, text_size=12,
                    text_color=font_color, enable_select=False)
                if weibo.curl.error:
                    error = "(%s)" % _(weibo.curl.error)
                elif weibo.get_error_msg():
                    error = "(%s)" % _(weibo.get_error_msg())
                else:
                    error = "(%s)" % _("Unknown reason")
                #print "%s: %s" % (weibo.t_type, error)
                #print "%s: %s" % (weibo.t_type, weibo.get_error_msg())
                label = Label(text, text_size=12,
                    text_color=font_color, enable_select=False)
                tip_box.pack_start(img, False, False, 15)
                tip_box.pack_start(label1, False, False, 3)
                tip_box.pack_start(label2, False, False, 3)
                tip_box.pack_start(label3, False, False)
                img = gtk.Image()   # only use as a placeholder
                img.set_size_request(20, 20)
                error_box.pack_start(img, False, False, 16)
                error_box.pack_start(Label(error, text_size=9, label_width=200,
                    text_color=font_color, enable_select=False), False, False)
                #print text
            res_vbox.pack_start(vbox, False, False, 10)

        for weibo in self.deepin_info:
            box = gtk.HBox(False, 15)
            # followed
            img = gtk.image_new_from_pixbuf(app_theme.get_pixbuf("share/"+weibo.t_type+".png").get_pixbuf())
            box.pack_start(img, False, False)
            if self.deepin_info[weibo] is not None and self.deepin_info[weibo][3]:
                if not default_locale.startswith("zh_"):
                    button = gtk.image_new_from_pixbuf(
                        app_theme.get_pixbuf("share/followed_en.png").get_pixbuf())
                else:
                    button = gtk.image_new_from_pixbuf(
                        app_theme.get_pixbuf("share/followed.png").get_pixbuf())
            else:   # to follow
                if not default_locale.startswith("zh_"):
                    button = ImageButton(
                        app_theme.get_pixbuf("share/follow_normal_en.png"),
                        app_theme.get_pixbuf("share/follow_hover_en.png"),
                        app_theme.get_pixbuf("share/follow_press_en.png"))
                else:
                    button = ImageButton(
                        app_theme.get_pixbuf("share/follow_normal.png"),
                        app_theme.get_pixbuf("share/follow_hover.png"),
                        app_theme.get_pixbuf("share/follow_press.png"))
                button.connect("clicked", self.friendships_add_button_clicked, weibo, box)
            box.pack_start(button, False, False)
            align = gtk.Alignment()
            align.set(0.0, 0.5, 0, 0)
            align.set_padding(0, 0, 30, 0)
            align.add(box)
            follow_vbox.pack_start(align, False, False, 8)

        res_left_box.set_buttons([res_vbox])
        res_right_box.set_buttons([follow_vbox])

        self.result_box.pack_start(res_hbox, False, False)
        self.result_box.show_all()
        self.set_slide_index(2)

    def goto_weibo_button_clicked(self, widget, event, weibo):
        '''goto my weibo'''
        #print "goto weibo button clicked", weibo.t_type, "xdg-open %s" % self.to_share_weibo_res[weibo][1]
        if weibo in self.to_share_weibo_res:
            if self.to_share_weibo_res[weibo][1]:
                webbrowser.open(self.to_share_weibo_res[weibo][1])

    def friendships_add_button_clicked(self, widget, weibo, box):
        '''add friendships'''
        #self.result_box.set_sensitive(False)
        if not self.is_get_user_info[weibo]:
            utils.run_command("xdg-open %s" % weibo.index_url)
            return True

        widget.set_sensitive(False)
        t = threading.Thread(target=self.friendships_add_thread, args=(widget, weibo, box))
        t.setDaemon(True)
        t.start()

    def friendships_add_thread(self, button, weibo, box):
        '''add friendships'''
        if weibo.friendships_create() is not None:
            gtk.gdk.threads_enter()
            button.destroy()
            if not default_locale.startswith("zh_"):
                button = gtk.image_new_from_pixbuf(
                    app_theme.get_pixbuf("share/followed_en.png").get_pixbuf())
            else:
                button = gtk.image_new_from_pixbuf(
                    app_theme.get_pixbuf("share/followed.png").get_pixbuf())
            button.show()
            box.pack_start(button, False, False)
            #button.set_label("已关注")
            gtk.gdk.threads_leave()

    # show window
    def show(self):
        '''show'''
        self.window.show_window()

    # close widnow
    def quit(self, widget):
        ''' close '''
        gtk.main_quit()

    def __slider_expose(self, widget, event):
        ''' slider expose redraw'''
        cr = widget.window.cairo_create()
        rect = widget.allocation
        cr.set_source_rgba(1.0, 1.0, 1.0, 0.8)
        cr.rectangle(rect.x, rect.y, rect.width, rect.height)
        cr.fill()

    def __expose_top_and_bottome(self, widget, event):
        '''titlebar or button_box expose'''
        cr = widget.window.cairo_create()
        rect = widget.allocation
        cr.set_source_rgb(0.89, 0.89, 0.89)
        cr.rectangle(rect.x+2, rect.y+2, rect.width-4, rect.height-4)
        cr.fill()

    def __draw_under_line(self, widget):
        '''draw under line'''
        cr = widget.window.cairo_create()
        with utils.cairo_disable_antialias(cr):
            x, y, w, h = widget.allocation
            # #1A70b1
            cr.set_source_rgba(0.1, 0.43, 0.69, 1.0)
            cr.set_line_width(1)
            cr.move_to(x, y+h-3)
            cr.line_to(x+w, y+h-3)
            cr.stroke()
Ejemplo n.º 47
0
class TrayDialog(Window):
    def __init__(self):
        Window.__init__(self)

        self.show_pixbuf = vtk_theme.get_pixbuf("deepin_shutdown", 50)
        self.cancel_text = CANCEL_TEXT
        self.btn_text_size = 11
        self.btn_text_color = "#b9b9b9"
        self.draw_rectangle_bool = False

        self.timer = Timer(1000)
        self.second = 60
        self.timer.Enabled = False
        self.timer.connect("Tick", self.timer_tick_evnet)

        self.run_exec = None
        self.argv = None
        self.set_pango_list()
        self.ok_key_check = False
        self.cancel_key_check = False

        self.__init_widgets()
        self.__init_settings()

    def show_dialog_window(self, widget):
        for alpha in range(0, 11):
            self.set_opacity(alpha * 0.1)

    def show_warning(
        self,
        info_text,
        ok_text=OK_TEXT,
        cancel_text=CANCEL_TEXT,
        ok_button_first=False,
    ):
        self.show_pixbuf = vtk_theme.get_pixbuf("deepin_warning", 50)
        self.info_text = info_text

        container_remove_all(self.bottom_hbox)
        self.ok_button = BottomButton(ok_text, self.btn_text_size)
        self.ok_button.connect("clicked", self.ok_btn_clicked)

        self.cancel_button = BottomButton(cancel_text, self.btn_text_size)
        self.cancel_button.connect("clicked", self.quit_dialog_window)
        self.cancel_button.set_check(True)
        if ok_button_first:
            self.bottom_hbox.pack_end(self.ok_button, False, False)
            self.bottom_hbox.pack_end(self.cancel_button, False, False)
        else:
            self.bottom_hbox.pack_end(self.cancel_button, False, False)
            self.bottom_hbox.pack_end(self.ok_button, False, False)

        self.argv = None
        self.run_exec = None

        self.set_pango_list()

        if self.show_pixbuf:
            self.show_image.set_from_pixbuf(self.show_pixbuf)
        self.tick_label.set_text(info_text)

        self.timer.Enabled = False

        self.show_all()
        self.cancel_button.grab_focus()

    def show_dialog(
        self,
        show_pixbuf_name,
        info_text,
        ok_text=OK_TEXT,
        cancel_text=CANCEL_TEXT,
    ):
        self.show_pixbuf = vtk_theme.get_pixbuf(show_pixbuf_name, 50)
        self.info_text = info_text

        self.ok_button = BottomButton(ok_text, self.btn_text_size)
        self.ok_button.connect("clicked", self.ok_btn_clicked)
        self.ok_button.set_check(True)
        self.cancel_button = BottomButton(cancel_text, self.btn_text_size)
        self.cancel_button.connect("clicked", self.quit_dialog_window)
        container_remove_all(self.bottom_hbox)
        self.bottom_hbox.pack_end(self.ok_button, False, False)
        self.bottom_hbox.pack_end(self.cancel_button, False, False)

        self.second = 60
        self.argv = None
        self.run_exec = None

        self.set_pango_list()

        if self.show_pixbuf:
            self.show_image.set_from_pixbuf(self.show_pixbuf)
        self.tick_label.set_text(self.info_text % 60)

        self.timer.Enabled = True

        self.show_all()
        self.ok_button.grab_focus()

    def set_pango_list(self):
        self.pango_list = None
        '''
        r, g, b = (65535, 0, 0)
        self.pango_list = pango.AttrList()
        if cn_check():
            start_index, end_index = 8, 12
        else:
            start_index, end_index = EN_RED_TEXT[self.show_top_text] 
            
        self.pango_list.insert(pango.AttrForeground(r, g, b, start_index, end_index - 1))
        '''
        pass

    def focus_out_window(self, widget, event):
        if not hasattr(self, "lose_focus_quit"):
            self.quit_dialog_window(widget)

    def __dialog_realize_event(self, widget):
        self.cancel_btn.grab_focus()

    def __dialog_key_release_event(self, widget, e):
        KEY_LEFT = 65361
        KEY_RIGHT = 65363
        KEY_ESC = 65307
        if e.keyval == KEY_LEFT:
            self.ok_button.set_check(False)
            self.cancel_button.set_check(True)
            self.cancel_button.grab_focus()
        elif e.keyval == KEY_RIGHT:
            self.ok_button.set_check(True)
            self.cancel_button.set_check(False)
            self.ok_button.grab_focus()
        elif e.keyval == KEY_ESC:  # 退出窗口.
            self.quit_dialog_window(widget)

    def __init_settings(self):
        self.set_bg_pixbuf(vtk_theme.get_pixbuf("deepin_on_off_bg", 372))
        self.set_size_request(APP_WIDTH, APP_HEIGHT)
        self.set_position(gtk.WIN_POS_CENTER)
        self.set_skip_pager_hint(True)
        self.set_skip_taskbar_hint(True)
        self.set_keep_above(True)
        self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
        self.connect("show", self.show_dialog_window)
        self.connect("focus-out-event", self.focus_out_window)
        self.connect("realize", self.__dialog_realize_event)
        self.connect("key-release-event", self.__dialog_key_release_event)

    def __init_widgets(self):
        self.main_vbox = gtk.VBox()
        self.mid_hbox = gtk.HBox()
        self.show_text_vbox = gtk.VBox()
        self.bottom_hbox_ali = gtk.Alignment(0, 0.5, 1, 0)
        self.bottom_hbox_ali.set_padding(3, 8, 15, 15)
        self.bottom_hbox = gtk.HBox(spacing=30)
        self.bottom_hbox_ali.add(self.bottom_hbox)

        self.init_titlebar()
        self.init_close_button()
        self.init_show_image()
        #self.init_show_text()
        self.init_bottom_button()

        self.titlebar_hbox.pack_start(self.close_btn, False, False)
        #self.show_text_vbox.pack_start(self.top_text_btn_ali, False, False)
        #self.show_text_vbox.pack_start(self.bottom_text_btn_ali, False, False)
        if LANGUAGE == 'en_US':
            text_size = 9
        else:
            text_size = 10
        self.tick_label = Label("",
                                text_color=DynamicColor("#FFFFFF"),
                                wrap_width=230,
                                text_size=text_size)
        self.show_text_vbox.pack_start(self.tick_label, False, False)

        self.mid_hbox.pack_start(self.show_image_ali, False, False)
        self.mid_hbox.pack_start(self.show_text_vbox, True, True)

        self.bottom_hbox.pack_end(self.ok_btn, False, False)
        self.bottom_hbox.pack_end(self.cancel_btn, False, False)

        self.main_vbox.pack_start(self.titlebar_ali, False, False)
        self.main_vbox.pack_start(self.mid_hbox, True, True)
        self.main_vbox.pack_start(self.bottom_hbox_ali, False, False)
        self.add_widget(self.main_vbox)

    def init_titlebar(self):
        self.titlebar_ali = gtk.Alignment(1, 0, 0, 0)
        self.titlebar_hbox = gtk.HBox()
        self.titlebar_ali.add(self.titlebar_hbox)

    def init_close_button(self):
        # init close button.
        self.close_btn = gtk.Button("x")
        self.close_btn.set_size_request(20, 20)
        self.close_btn.connect("button-press-event", self.close_btn_clicked)
        self.close_btn.connect("expose-event", self.close_btn_expose_event)

    def close_btn_clicked(self, widget, event):
        if event.button == 1:
            self.quit_dialog_window(widget)

    def close_btn_expose_event(self, widget, event):
        return True

    def init_show_image(self):
        size = 20
        left_padding = 10
        padding = (size, size, size + left_padding, size)
        #
        self.show_image_ali = gtk.Alignment(0, 0, 0, 0)
        self.show_image_ali.set_padding(*padding)
        self.show_image = gtk.Image()
        self.show_image_ali.add(self.show_image)
        #
        if self.show_pixbuf:
            self.show_image.set_from_pixbuf(self.show_pixbuf)

    def timer_tick_evnet(self, timer):
        self.second -= 1
        self.tick_label.set_text(self.info_text % self.second)
        if self.second == 0:
            timer.Enabled = False
            if self.run_exec:
                gtk.timeout_add(1, self.run_exec_timeout)
                gtk.timeout_add(100, lambda: self.quit_dialog_window(self))
            else:
                self.quit_dialog_window(self)

    def init_bottom_button(self):
        self.cancel_btn = gtk.Button(self.cancel_text)
        self.ok_btn = gtk.Button()

        self.cancel_btn.connect("clicked", self.quit_dialog_window)
        self.cancel_btn.connect("expose-event", self.label_expose_event, 30)
        self.cancel_btn.connect("enter-notify-event",
                                self.label_enter_notify_event)

        self.ok_btn.connect("clicked", self.ok_btn_clicked)
        self.ok_btn.connect("expose-event", self.label_expose_event, 0)
        self.ok_btn.connect("enter-notify-event",
                            self.label_enter_notify_event)

    def label_enter_notify_event(self, widget, event):
        self.ok_btn.queue_draw()
        self.cancel_btn.queue_draw()
        if self.ok_btn != widget:
            self.ok_key_check = False
        if self.cancel_btn != widget:
            self.cancel_key_check = False

    def ok_btn_clicked(self, widget):
        if self.run_exec:
            self.run_exec_timeout()
        self.quit_dialog_window(widget)

    def run_exec_timeout(self):
        if self.argv is None:
            self.run_exec()
        else:
            self.run_exec(self.argv)

    def label_expose_event(self, widget, event, width):
        color = self.btn_text_color
        if widget == self.ok_btn and self.ok_key_check:
            color = "#FFFFFF"
        elif widget == self.cancel_btn and self.cancel_key_check:
            color = "#FFFFFF"

        if widget.state == gtk.STATE_PRELIGHT:
            color = "#FFFFFF"

        cr = widget.window.cairo_create()
        rect = widget.allocation

        size = get_text_size(widget.get_label(), self.btn_text_size,
                             DEFAULT_FONT)
        draw_text(cr,
                  widget.get_label(),
                  rect.x,
                  rect.y + rect.height / 2 - size[1] / 2,
                  text_size=self.btn_text_size,
                  text_color=color,
                  text_font=DEFAULT_FONT)
        widget.set_size_request(size[0] + width, size[1] + 10)

        return True

    def quit_dialog_window(self, widget):
        for alpha in range(10, -1, -1):
            self.set_opacity(alpha * 0.1)
        self.hide_all()
        self.timer.Enabled = False
        self.grab_remove()

        if hasattr(self, "quit_alone"):
            gtk.main_quit()
class BlueToothView(gtk.VBox):
    '''
    class docs
    '''
    def __init__(self, module_frame):
        '''
        init docs
        '''
        gtk.VBox.__init__(self)

        self.module_frame = module_frame

        self.my_bluetooth = MyBluetooth(self.__on_adapter_removed,
                                        self.__on_default_adapter_changed,
                                        self.__device_found)
        self.periodic_timer = None
        self.is_discoverable = False
        self.is_searching = False
        '''
        enable open
        '''
        if self.my_bluetooth.adapter:
            self.my_bluetooth.adapter.connect("property-changed",
                                              self.__on_property_changed)
            if self.my_bluetooth.adapter.get_powered():
                self.title_align, self.title_label = self.__setup_title_align(
                    app_theme.get_pixbuf("bluetooth/enable_open.png"),
                    _("Bluetooth"))
                self.title_label.set_sensitive(True)
            else:
                self.title_align, self.title_label = self.__setup_title_align(
                    app_theme.get_pixbuf("bluetooth/enable_open_disable.png"),
                    _("Bluetooth"))
        else:
            self.title_align, self.title_label = self.__setup_title_align(
                app_theme.get_pixbuf("bluetooth/enable_open_disable.png"),
                _("Bluetooth"))
            self.title_label.set_sensitive(False)
        self.enable_align = self.__setup_align()
        self.enable_box = gtk.HBox(spacing=WIDGET_SPACING)
        self.enable_open_label = self.__setup_label(_("Enable bluetooth"))
        if self.my_bluetooth.adapter:
            self.my_bluetooth.adapter.set_powered(
                permanent_settings.get_powered())
            self.enable_open_label.set_sensitive(
                self.my_bluetooth.adapter.get_powered())
        else:
            self.enable_open_label.set_sensitive(False)
        self.enable_open_toggle_align = self.__setup_align(padding_top=4,
                                                           padding_left=158)
        self.enable_open_toggle = self.__setup_toggle()
        if self.my_bluetooth.adapter:
            self.enable_open_toggle.set_active(
                self.my_bluetooth.adapter.get_powered())
        self.enable_open_toggle.connect("toggled", self.__toggled,
                                        "enable_open")
        self.enable_open_toggle_align.add(self.enable_open_toggle)
        self.__widget_pack_start(
            self.enable_box,
            [self.enable_open_label, self.enable_open_toggle_align])
        self.enable_align.add(self.enable_box)
        '''
        display
        '''
        self.display_align = self.__setup_align()
        self.display_box = gtk.HBox(spacing=WIDGET_SPACING)
        self.display_device_label = self.__setup_label(_("Device name"))
        if self.my_bluetooth.adapter:
            self.display_device_label.set_sensitive(
                self.my_bluetooth.adapter.get_powered())
        else:
            self.display_device_label.set_sensitive(False)
        self.display_device_entry = InputEntry()
        if self.my_bluetooth.adapter:
            self.display_device_entry.set_text(
                self.my_bluetooth.adapter.get_name())
            self.display_device_entry.set_sensitive(
                self.my_bluetooth.adapter.get_powered())
        else:
            self.display_device_entry.set_sensitive(False)
        self.display_device_entry.set_size(HSCALEBAR_WIDTH, WIDGET_HEIGHT)
        self.display_device_entry.entry.connect("changed",
                                                self.__display_device_changed)
        self.__widget_pack_start(
            self.display_box,
            [self.display_device_label, self.display_device_entry])
        self.display_align.add(self.display_box)
        '''
        enable searchable
        '''
        self.search_align = self.__setup_align()
        self.search_box = gtk.HBox(spacing=WIDGET_SPACING)
        self.search_label = self.__setup_label(_("Discoverable"))
        if self.my_bluetooth.adapter:
            self.search_label.set_sensitive(
                self.my_bluetooth.adapter.get_powered())
        else:
            self.search_label.set_sensitive(False)
        self.search_timeout_align = self.__setup_align(padding_top=0,
                                                       padding_left=0)
        self.search_timeout_label = self.__setup_label("",
                                                       width=110,
                                                       align=ALIGN_START)
        self.search_timeout_align.add(self.search_timeout_label)
        self.search_toggle_align = self.__setup_align(padding_top=4,
                                                      padding_left=18)
        self.search_toggle = self.__setup_toggle()
        if self.my_bluetooth.adapter:
            self.search_toggle.set_active(
                self.my_bluetooth.adapter.get_discoverable())
        self.search_toggle.connect("toggled", self.__toggled, "search")
        self.search_toggle_align.add(self.search_toggle)
        self.__widget_pack_start(self.search_box, [
            self.search_label, self.search_timeout_align,
            self.search_toggle_align
        ])
        self.search_align.add(self.search_box)
        '''
        device iconview
        '''
        self.device_align = self.__setup_align()
        self.device_iconview = DeviceIconView()
        self.device_iconview.set_size_request(690, 228)
        self.device_align.add(self.device_iconview)
        '''
        operation
        '''
        self.oper_align = self.__setup_align()
        self.oper_box = gtk.HBox(spacing=WIDGET_SPACING)
        self.notice_label = Label("",
                                  text_x_align=ALIGN_START,
                                  label_width=610)
        self.search_button = Button(_("Search"))
        if self.my_bluetooth.adapter:
            self.search_button.set_sensitive(
                self.my_bluetooth.adapter.get_powered())
        else:
            self.search_button.set_sensitive(False)
        self.search_button.connect("clicked", self.__on_search)
        self.__widget_pack_start(self.oper_box, [
            self.notice_label,
            self.search_button,
        ])
        self.oper_align.add(self.oper_box)
        '''
        this->gtk.VBox pack_start
        '''
        self.__widget_pack_start(self, [
            self.title_align, self.enable_align, self.display_align,
            self.search_align, self.device_align, self.oper_align
        ])

        if self.my_bluetooth.adapter == None:
            self.set_sensitive(False)

        self.connect("expose-event", self.__expose)

        if self.my_bluetooth.adapter and self.my_bluetooth.adapter.get_powered(
        ):
            self.__get_devices()

    def __on_property_changed(self, adapter, key, value):
        if key == "Powered":
            if value == 1:
                self.enable_open_toggle.set_active(True)
                # removed by hualet, this will cause devices are added twice.
                # self.__set_enable_open(True)
            else:
                self.enable_open_toggle.set_active(False)
                # self.__set_enable_open(False)
        if key == "Devices":  # fixbug: iconview didn't update accordingly
            # while adapter paired other devices in system tray.
            self.device_iconview.clear()
            self.__get_devices()

    def sendfile(self, device_name):
        event_manager.emit("send-file", device_name)

    def cancel(self):
        event_manager.emit("cancel", None)

    def __on_adapter_removed(self):
        self.set_sensitive(False)

    def __on_default_adapter_changed(self):
        self.set_sensitive(True)
        self.display_device_entry.set_text(
            self.my_bluetooth.adapter.get_name())

    def __display_device_changed(self, widget, event):
        self.my_bluetooth.adapter.set_name(widget.get_text())

    def __setup_separator(self):
        hseparator = HSeparator(
            app_theme.get_shadow_color("hSeparator").get_color_info(), 0, 0)
        hseparator.set_size_request(500, HSEPARATOR_HEIGHT)
        return hseparator

    def __setup_title_label(
            self,
            text="",
            text_color=app_theme.get_color("globalTitleForeground"),
            text_size=TITLE_FONT_SIZE,
            text_x_align=ALIGN_START,
            label_width=180):
        return Label(text=text,
                     text_color=text_color,
                     text_size=text_size,
                     text_x_align=text_x_align,
                     label_width=label_width,
                     enable_select=False,
                     enable_double_click=False)

    def __setup_title_align(self,
                            pixbuf,
                            text,
                            padding_top=TEXT_WINDOW_TOP_PADDING,
                            padding_left=TEXT_WINDOW_LEFT_PADDING):
        align = self.__setup_align(padding_top=padding_top,
                                   padding_left=padding_left)
        align_box = gtk.VBox(spacing=WIDGET_SPACING)
        title_box = gtk.HBox(spacing=WIDGET_SPACING)
        image = ImageBox(pixbuf)
        label = self.__setup_title_label(text)
        separator = self.__setup_separator()
        self.__widget_pack_start(title_box, [image, label])
        self.__widget_pack_start(align_box, [title_box, separator])
        align.add(align_box)
        return align, label

    def __get_devices(self):
        devices = self.my_bluetooth.get_devices()
        items = []
        i = 0

        while i < len(devices):
            items.append(
                DeviceItem(
                    devices[i].get_name(),
                    app_theme.get_pixbuf(
                        "bluetooth/%s.png" % bluetooth_class_to_type(
                            devices[i].get_class())).get_pixbuf(), devices[i],
                    self.my_bluetooth.adapter, devices[i].get_paired(),
                    self.module_frame))
            i += 1

        self.device_iconview.add_items(items)

    def __refresh_notice_label(self):
        searching_str = _("Discovering device")

        if self.notice_label.get_text().count(".") == 3:
            self.notice_label.set_text(searching_str + ".")
        else:
            self.notice_label.set_text(self.notice_label.get_text() + ".")

        return True

    def __on_search(self, widget):
        if not self.is_searching:
            self.my_bluetooth.adapter.start_discovery()
            self.notice_label.set_text(_("Discovering device"))
            self.refresh_lable_timeout = gobject.timeout_add_seconds(
                1, self.__refresh_notice_label)
            self.my_bluetooth.adapter.connect("property-changed",
                                              self.on_adapter_property_changed)
            self.is_searching = True

    def on_adapter_property_changed(self, obj, key, value):
        if key == "Discovering" and value == False:
            gobject.source_remove(self.refresh_lable_timeout)
            if self.is_searching:
                self.my_bluetooth.adapter.stop_discovery()
            self.is_searching = False
            self.notice_label.set_text("")

    def __device_found(self, adapter, address, values):
        print "address", address
        if address not in adapter.get_address_records():
            device_path = adapter.create_device(address)
            if device_path == "None":
                return

            device = Device(device_path)
            items = []

            if not values.has_key("Name"):
                return

            print bluetooth_class_to_type(device.get_class())
            items.append(
                DeviceItem(
                    values['Name'],
                    app_theme.get_pixbuf(
                        "bluetooth/%s.png" % bluetooth_class_to_type(
                            device.get_class())).get_pixbuf(), device,
                    adapter))
            self.device_iconview.add_items(items)

    def __set_enable_open(self, is_open=True):
        self.enable_open_label.set_sensitive(is_open)
        self.display_device_label.set_sensitive(is_open)
        self.search_label.set_sensitive(is_open)
        self.display_align.set_sensitive(is_open)
        self.display_device_entry.set_sensitive(is_open)
        # self.device_iconview.set_sensitive(is_open)
        self.search_align.set_sensitive(is_open)
        self.search_timeout_label.set_child_visible(False)
        self.search_button.set_sensitive(is_open)
        # changed by hualet, to fix the bug that device icons stay while disabling the iconview widget
        if is_open:
            self.__get_devices()
        else:
            self.device_iconview.clear()

    def __toggled(self, widget, object):
        if self.my_bluetooth.adapter == None:
            return

        if object == "enable_open":
            self.__set_enable_open(widget.get_active())
            permanent_settings.set_powered(widget.get_active())
            self.my_bluetooth.adapter.set_powered(widget.get_active())
            return

        if object == "search":
            self.is_discoverable = widget.get_active()
            self.my_bluetooth.adapter.set_discoverable(self.is_discoverable)
            self.search_timeout_label.set_child_visible(self.is_discoverable)
            if self.is_discoverable:
                self.periodic_timer = PerodicTimer(self, 1)
            else:
                self.periodic_timer.stop()
            return

    def __expose(self, widget, event):
        cr = widget.window.cairo_create()
        rect = widget.allocation

        cr.set_source_rgb(*color_hex_to_cairo(MODULE_BG_COLOR))
        cr.rectangle(rect.x, rect.y, rect.width, rect.height)
        cr.fill()

    def __setup_label(self, text="", width=180, align=ALIGN_END):
        return Label(text, None, TITLE_FONT_SIZE, align, width, False, False,
                     False)

    def __setup_combo(self, items=[], width=HSCALEBAR_WIDTH):
        combo = ComboBox(items, None, 0, width, width)
        combo.set_size_request(width, WIDGET_HEIGHT)
        return combo

    def __setup_toggle(self):
        return ToggleButton(
            app_theme.get_pixbuf("toggle_button/inactive_normal.png"),
            app_theme.get_pixbuf("toggle_button/active_normal.png"),
            inactive_disable_dpixbuf=app_theme.get_pixbuf(
                "toggle_button/inactive_normal.png"),
            active_disable_dpixbuf=app_theme.get_pixbuf(
                "toggle_button/inactive_normal.png"))

    def __setup_align(self,
                      xalign=0,
                      yalign=0,
                      xscale=0,
                      yscale=0,
                      padding_top=BETWEEN_SPACING,
                      padding_bottom=0,
                      padding_left=TEXT_WINDOW_LEFT_PADDING,
                      padding_right=20):
        align = gtk.Alignment()
        align.set(xalign, yalign, xscale, yscale)
        align.set_padding(padding_top, padding_bottom, padding_left,
                          padding_right)
        return align

    def __widget_pack_start(self,
                            parent_widget,
                            widgets=[],
                            expand=False,
                            fill=False):
        if parent_widget == None:
            return
        for item in widgets:
            parent_widget.pack_start(item, expand, fill)
Ejemplo n.º 49
0
class DetailPage(gtk.HBox):
    '''
    class docs
    '''

    PADDING_Y = 20

    ICON_SIZE = 64
    ICON_PADDING_X = 50

    STAR_PADDING_X = 36
    STAR_PADDING_Y = 12
    STAR_SIZE = 13

    MARK_NUMBER_SIZE = 11
    MARK_NUMBER_PADDING_X = 4
    MARK_NUMBER_PADDING_Y = 10

    INFO_RENDER_X = 10
    INFO_RENDER_Y = 140
    INFO_RENDER_HEIGHT = 18
    INFO_CATEGORY_RENDER_Y = INFO_RENDER_Y + INFO_RENDER_HEIGHT
    INFO_VERSION_RENDER_Y = INFO_RENDER_Y + INFO_RENDER_HEIGHT * 2
    INFO_SIZE_RENDER_Y = INFO_RENDER_Y + INFO_RENDER_HEIGHT * 3
    INFO_DOWNLOAD_RENDER_Y = INFO_RENDER_Y + INFO_RENDER_HEIGHT * 4
    INFO_HOMEPAGE_RENDER_Y = INFO_RENDER_Y + INFO_RENDER_HEIGHT * 5

    LEFT_INFO_PADDING_X = 18
    LEFT_INFO_PADDING_Y = 50

    LEFT_BUTTON_PADDING_Y = 50

    LEFT_INFO_WIDTH = 164

    RIGHT_INFO_PADDING_X = 30

    RIGHT_TITLE_BOX_HEIGHT = 70

    ALIAS_NAME_SIZE = 16
    ALIAS_NAME_PADDING_Y = 20

    LONG_DESC_PADDING_Y = 10
    LONG_DESC_WRAP_WIDTH = 630
    LONG_DESC_INIT_HEIGHT = 45

    MARK_SIZE = 11
    MARK_PADDING_X = 5
    MARK_PADDING_Y = -3

    def __init__(self, data_manager):
        '''
        init docs
        '''
        gtk.HBox.__init__(self)
        self.data_manager = data_manager
        self.pkg_name = None
        self.alias_name = ""
        self.pkg_pixbuf = None
        self.pkg_star_view = None

        self.left_view_box = gtk.VBox()
        self.left_view_box.set_size_request(self.LEFT_INFO_WIDTH, - 1)

        self.left_logo_box = gtk.VBox()
        self.left_logo_box.set_size_request(-1, 90)

        self.star_box = gtk.HBox()
        self.star_align = gtk.Alignment(0.4, 0.5, 0, 0)
        self.star_align.set_padding(0, 5, 0, 0)
        self.star_align.add(self.star_box)

        self.left_action_box = gtk.HBox()
        self.left_action_align = gtk.Alignment()
        self.left_action_align.set(0.5, 0.5, 0, 0)
        self.left_action_align.set_padding(0, 30, 0, 0)
        self.left_action_align.add(self.left_action_box)

        self.left_label_table = gtk.Table(4, 1)
        self.left_label_table.set_row_spacings(4)

        self.left_label_align = gtk.Alignment()
        self.left_label_align.set(0.0, 0.5, 0, 0)
        self.left_label_align.set_padding(0, 0, 14, 0)

        self.left_category_name_label = Label()
        self.left_category_label = Label(hover_color=app_theme.get_color("homepage_hover"))
        self.left_category_label.set_clickable()
        self.left_category_label_align = gtk.Alignment()
        self.left_category_label_align.set(0.0, 0.5, 0, 0)
        self.left_category_label_align.add(self.left_category_label)
        self.left_category_label_box = gtk.HBox()
        self.left_category_label_box.pack_start(self.left_category_name_label, False, False)
        self.left_category_label_box.pack_start(self.left_category_label_align, True, True)
        self.left_category_box = gtk.VBox()
        self.left_version_label = Label(label_width=136)
        show_label_tooltip(self.left_version_label)
        self.left_version_label.set_ellipsize(pango.ELLIPSIZE_END)
        self.left_download_label = Label()
        self.left_size_label = Label()

        self.left_homepage_box = gtk.HBox()
        self.left_homepage_box_align = gtk.Alignment()
        self.left_homepage_box_align.set(0.0, 0.5, 0, 0)
        self.left_homepage_box_align.add(self.left_homepage_box)

        self.left_recommend_box = gtk.VBox()
        self.left_recommend_box_align = gtk.Alignment()
        self.left_recommend_box_align.set(0.0, 0.0, 0, 0)
        self.left_recommend_box_align.set_padding(30, 0, 14, 0)
        self.left_recommend_box_align.add(self.left_recommend_box)

        self.left_recommend_label = Label(_("Popular recommendations"))

        self.right_info_box = gtk.VBox()
        self.scrolled_window = ScrolledWindow(0, 0)
        self.right_view_box = gtk.VBox()

        self.right_top_box = gtk.HBox()
        self.right_top_box.set_size_request(-1, self.RIGHT_TITLE_BOX_HEIGHT)
        self.right_desc_box = gtk.VBox()
        self.right_slide_box = gtk.VBox()
        self.right_comment_box = gtk.VBox()

        self.right_title_box = gtk.VBox()

        self.return_button = ImageButton(
            app_theme.get_pixbuf("detail/normal.png"),
            app_theme.get_pixbuf("detail/hover.png"),
            app_theme.get_pixbuf("detail/press.png"),
            )
        self.return_align = gtk.Alignment()
        self.return_align.set(0.5, 0.5, 1, 1)
        self.return_align.set_padding(self.ALIAS_NAME_PADDING_Y, 0, 0, self.RIGHT_INFO_PADDING_X)
        self.return_align.add(self.return_button)

        self.return_button.connect("clicked", lambda w: global_event.emit("switch-from-detail-page"))

        self.right_top_box.pack_start(self.right_title_box, True, True)
        self.right_top_box.pack_start(self.return_align, False, False)

        self.right_view_box.pack_start(self.right_top_box, False, False)
        self.right_view_box.pack_start(self.right_desc_box, False, False)
        self.right_view_box.pack_start(self.right_slide_box, False, False)
        self.right_view_box.pack_start(self.right_comment_box, False, False)
        self.scrolled_window.add_child(self.right_view_box)

        self.left_view_box.pack_start(self.left_logo_box, False, False)
        self.left_view_box.pack_start(self.star_align, False, False)
        self.left_view_box.pack_start(self.left_action_align, False, False)
        self.left_label_table.attach(self.left_category_box, 0, 1, 0, 1)
        self.left_label_table.attach(self.left_version_label, 0, 1, 1, 2)
        self.left_label_table.attach(self.left_size_label, 0, 1, 2, 3)
        self.left_label_table.attach(self.left_download_label, 0, 1, 3, 4)
        self.left_label_table.attach(self.left_homepage_box_align, 0, 1, 4, 5)
        self.left_label_align.add(self.left_label_table)
        self.left_view_box.pack_start(self.left_label_align, False, False)
        self.left_view_box.pack_start(self.left_recommend_box_align, False, False)
        self.right_info_box.pack_start(self.scrolled_window, True, True)
        self.pack_start(self.left_view_box, False, False)
        self.pack_start(self.right_info_box, True, True)

        self.left_view_box.connect("expose-event", self.expose_left_view)
        self.right_view_box.connect("expose-event", self.expose_right_view)
        self.left_logo_box.connect("expose-event", self.expose_left_logo_box)
        self.right_top_box.connect("expose-event", self.expose_right_top_box)
        self.right_title_box.connect("expose-event", self.expose_right_title_box)
        self.connect("hierarchy-changed", self.hierarchy_change)

        self.left_category_label.connect("button-press-event", lambda w, e: self.jump_to_category())

        global_event.register_event("download-screenshot-finish", self.download_screenshot_finish)

        self.loading_label = Label(_("Loading comments..."))
        self.loading_label_align = gtk.Alignment(0.5, 0, 0, 0)
        self.loading_label_align.add(self.loading_label)
        self.loading_label_align.set_padding(10, 0, 0, 0)

        self.update_pkg_time = 0
        self.update_pkg_interval = 0.2 # in seconds

    def hierarchy_change(self, widget, previous_toplevel):
        # When detail page remove from it's container, previous_toplevel is not None.
        if previous_toplevel != None:
            container_remove_all(self.right_slide_box) # remove slide box first, to avoid screenshot area flash
            container_remove_all(self.right_comment_box) # remove comment box first, to avoid comment area flash

    def grade_pkg(self):
        if self.pkg_star_view:
            global_event.emit("grade-pkg", (self.pkg_name, self.pkg_star_view), self.pkg_star_view.star_buffer.star_level)
            self.pkg_star_view.set_star_level(int(self.star))
            self.pkg_star_view.queue_draw()

    def jump_to_category(self):
        global_event.emit("jump-to-category", self.category[0], self.category[1])

    def expose_left_view(self, widget, event):
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation

        # Draw background.
        cr.set_source_rgb(*color_hex_to_cairo("#FFFFFF"))
        cr.rectangle(rect.x, rect.y, rect.width, rect.height)
        cr.fill()

        # Draw split line.
        cr.set_source_rgb(*color_hex_to_cairo("#AAAAAA"))
        cr.rectangle(rect.x + rect.width - 1, rect.y, 1, rect.height)
        cr.fill()

    def expose_right_view(self, widget, event):
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation

        # Draw background.
        cr.set_source_rgb(*color_hex_to_cairo("#FFFFFF"))
        cr.rectangle(rect.x, rect.y, rect.width, rect.height)
        cr.fill()

    def expose_left_logo_box(self, widget, event):
        if self.pkg_name != None:
            # Init.
            cr = widget.window.cairo_create()
            rect = widget.allocation

            # Draw pkg icon.
            self.pkg_pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
                    get_icon_pixbuf_path(
                        utils.get_origin_name(self.pkg_name)), self.ICON_SIZE, self.ICON_SIZE)
            draw_pixbuf(cr,
                        self.pkg_pixbuf,
                        rect.x + self.ICON_PADDING_X + (self.ICON_SIZE - self.pkg_pixbuf.get_width()) / 2,
                        rect.y + self.PADDING_Y)

    def expose_right_top_box(self, widget, event):
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation

        # Draw background.
        cr.set_source_rgb(*color_hex_to_cairo("#FFFFFF"))
        cr.rectangle(rect.x, rect.y, rect.width, rect.height)
        cr.fill()

    def expose_right_title_box(self, widget, event):
        if self.pkg_name != None:
            # Init.
            cr = widget.window.cairo_create()
            rect = widget.allocation

            # Draw alias name.
            draw_text(
                cr,
                "<b>%s</b>" % self.alias_name,
                rect.x + self.RIGHT_INFO_PADDING_X,
                rect.y + self.ALIAS_NAME_PADDING_Y,
                rect.width - self.RIGHT_INFO_PADDING_X,
                self.ALIAS_NAME_SIZE,
                text_size=self.ALIAS_NAME_SIZE)

    def expose_resizable_label_background(self, widget, event):
        if self.pkg_name != None:
            # Init.
            cr = widget.window.cairo_create()
            rect = widget.allocation

            # Draw background.
            cr.set_source_rgb(*color_hex_to_cairo("#FFFFFF"))
            cr.rectangle(rect.x, rect.y, rect.width, rect.height)
            cr.fill()

    def button_press_start_button(self, widget, event, desktops):
        pixbuf = app_theme.get_pixbuf("button/start_normal.png").get_pixbuf()
        desktop_infos = self.data_manager.get_pkg_desktop_info(desktops)
        global_event.emit("start-pkg",
                          self.alias_name,
                          desktop_infos,
                          (int(event.x), int(event.y), pixbuf.get_width() / 2, 0))

    @post_gui
    def update_some_info(self, info):
        self.star = float(info[0]['mark'].encode('utf-8').strip())
        if self.pkg_star_view:
            self.pkg_star_view.star_buffer.star_level = int(self.star)
            self.pkg_star_view.queue_draw()
        self.pkg_star_mark.update_star(self.star)
        self.pkg_star_mark.queue_draw()

        self.downlad_number = info[0]['down_nums'].encode('utf-8').strip()
        self.left_download_label.set_text(_('Download: %s') % self.downlad_number)

    def update_pkg_info(self, pkg_name):
        current_time = time.time()
        if current_time - self.update_pkg_time < self.update_pkg_interval:
            return False
        else:
            self.update_pkg_time = current_time

        FetchPackageInfo(pkg_name, self.update_some_info).start()
        self.pkg_name = pkg_name

        detail_info = self.data_manager.get_pkg_detail_info(self.pkg_name)
        self.category = detail_info['category']
        self.long_desc = detail_info['long_desc']
        self.version = detail_info['version']
        self.homepage = detail_info['homepage']
        self.alias_name = detail_info['alias_name']
        self.recommend_pkgs = detail_info['recommend_pkgs']

        self.pkg_star_view = StarView()
        self.pkg_star_view.connect("clicked", lambda w: self.grade_pkg())
        self.pkg_star_mark = StarMark(5.0, self.MARK_SIZE, self.MARK_PADDING_X, self.MARK_PADDING_Y)
        container_remove_all(self.star_box)
        self.star_box.pack_start(self.pkg_star_view, False, False)
        self.star_box.pack_start(self.pkg_star_mark, False, False)

        self.fetch_pkg_status()

        container_remove_all(self.left_category_box)
        if self.category != None:
            self.left_category_name_label.set_text(_("Category: "))
            self.left_category_label.set_text(get_category_name(self.category[1]))
            self.left_category_box.add(self.left_category_label_box)

        self.left_version_label.set_text(_("Version: %s") % self.version)
        self.left_download_label.set_text(_("Download: 0"))
        self.left_size_label.set_text(_("Size: calculating..."))

        container_remove_all(self.left_homepage_box)
        if self.homepage != "":
            homepage_label = Label(_("Visit Homepage"),
                                   text_color=app_theme.get_color("homepage"),
                                   hover_color=app_theme.get_color("homepage_hover"))
            homepage_label.set_clickable()
            homepage_label.connect("button-press-event", lambda w, e: run_command("xdg-open %s" % self.homepage))
            self.left_homepage_box.pack_start(homepage_label)

        container_remove_all(self.left_recommend_box)
        if len(self.recommend_pkgs) > 0:
            self.left_recommend_box.pack_start(self.left_recommend_label, False, False, 8)

            for (recommend_pkg_name, alias_name, star) in self.recommend_pkgs:
                self.left_recommend_box.pack_start(RecommendPkgItem(self, recommend_pkg_name, alias_name, star), False, False, 4)

        container_remove_all(self.right_desc_box)
        resizable_label = ResizableLabel(self.long_desc.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;"),
                                         self.LONG_DESC_WRAP_WIDTH,
                                         self.LONG_DESC_INIT_HEIGHT,
                                         3)
        resizable_align = gtk.Alignment()
        resizable_align.set(0.5, 0.5, 1, 1)
        resizable_align.set_padding(0, 0, self.RIGHT_INFO_PADDING_X, self.RIGHT_INFO_PADDING_X)
        resizable_align.add(resizable_label)
        resizable_align.connect("expose-event", self.expose_resizable_label_background)
        self.right_desc_box.pack_start(resizable_align, False, False)

        self.show_screenshot()

        self.fetch_comment()

        self.show_all()

    def handle_pkg_status(self, reply, success):
        container_remove_all(self.left_action_box)
        if success:
            install_status = str(reply)
            if install_status == "uninstalled":
                action_button = ImageButton(
                    app_theme.get_pixbuf("button/install_normal.png"),
                    app_theme.get_pixbuf("button/install_hover.png"),
                    app_theme.get_pixbuf("button/install_press.png"),
                    )
                action_button.connect("clicked", lambda w: global_event.emit("install-pkg", [self.pkg_name]))
                self.left_action_box.pack_start(action_button)
            elif install_status == "unknown":
                status_label = Label(_("Not found"))
                self.left_action_box.pack_start(status_label)
            else:
                try:
                    desktops = json.loads(install_status)
                    if not desktops:
                        status_label = Label(_("Successfully installed"))
                        self.left_action_box.pack_start(status_label)
                    else:
                        action_button = ImageButton(
                            app_theme.get_pixbuf("button/start_normal.png"),
                            app_theme.get_pixbuf("button/start_hover.png"),
                            app_theme.get_pixbuf("button/start_press.png"),
                        )
                        action_button.connect("button-press-event", lambda w, e:self.button_press_start_button(w, e, desktops))
                        self.left_action_box.pack_start(action_button)
                except:
                    logging.error("detail install status: %s = %s" % (self.pkg_name, install_status))

            self.left_action_box.show_all()
            global_event.emit('update-current-status-pkg-page', self)
        else:
            global_logger.logerror("get_pkg_installed handle_dbus_error")
            global_logger.logerror(reply)

    def handle_pkg_download_size(self, reply, success):
        # FIXME: download information display
        if success:
            if reply[0] == PKG_SIZE_OWN or reply[0] == PKG_SIZE_DOWNLOAD:
                self.left_size_label.set_text(_("Size: %s") % bit_to_human_str(reply[1]))
            elif reply[0] == PKG_SIZE_ERROR:
                self.left_size_label.set_text("")
                global_logger.logerror("Error for calculate pkg size!")
        else:
            global_logger.logerror("request_pkgs_install_status handle_dbus_error")
            global_logger.logerror(reply)

    def fetch_pkg_status(self):
        self.data_manager.get_pkg_installed(self.pkg_name, self.handle_pkg_status)
        self.data_manager.get_pkg_download_size(self.pkg_name, self.handle_pkg_download_size)

    def open_url(self, webview, frame, network_request, nav_action, policy_dec):
        webbrowser.open(network_request.get_uri())

    def webview_console_message_handler(self, webview, message, line, source_id):
        return True

    def fetch_comment(self):
        if is_network_connected():
            container_remove_all(self.right_comment_box)
            loading_label = Label(_("Loading comments..."))
            loading_label_align = gtk.Alignment(0.5, 0, 0, 0)
            loading_label_align.add(loading_label)
            loading_label_align.set_padding(10, 0, 0, 0)
            self.right_comment_box.pack_start(loading_label_align, False, False)
            web_view = WebView(os.path.join(CONFIG_DIR, "cookie.txt"))
            web_view.connect("new-window-policy-decision-requested", self.open_url)
            web_view.connect('console-message', self.webview_console_message_handler)
            web_view_align = gtk.Alignment()
            web_view_align.set(0.5, 0, 0, 0)
            web_view_align.set_padding(33, 33, 33, 33)
            web_view_align.add(web_view)
            web_settings = web_view.get_settings()
            web_settings.set_property("enable-plugins", False)
            web_settings.set_property("enable-scripts", True)
            web_view.open("%s/softcenter/v1/comment?n=%s&hl=%s" % (
                    SERVER_ADDRESS,
                    self.pkg_name,
                    LANGUAGE,
                    ))

            web_view.connect("load-finished", self.comment_load_finished_cb, web_view_align)

            create_thread(self.fetch_screenshot).start()

    def comment_load_finished_cb(self, webview, frame, web_view_align):
        self.scrolled_window.connect("vscrollbar-state-changed", lambda w, p: self.load_more_comment(p, webview))
        container_remove_all(self.right_comment_box)
        self.right_comment_box.pack_start(web_view_align, True, True)
        self.right_comment_box.show_all()

    def load_more_comment(self, postion, webview):
        if postion == "bottom":
            webview.execute_script('$("#nav_next").click();')

    def fetch_screenshot(self):
        screenshot_dir = os.path.join(SCREENSHOT_DOWNLOAD_DIR, self.pkg_name)
        screenshot_md5_path = os.path.join(screenshot_dir, "screenshot_md5.txt")
        remote_screenshot_md5_url = "%s/zh_CN/%s/screenshot_md5.txt" % (SCREENSHOT_HOST, self.pkg_name)
        remote_screenshot_zip_url = "%s/zh_CN/%s/screenshot.zip" % (SCREENSHOT_HOST, self.pkg_name)
        try:
            remote_md5 = urllib2.urlopen(remote_screenshot_md5_url).read()
            need_download = False

            if os.path.exists(screenshot_dir):
                if os.path.exists(screenshot_md5_path):
                    local_md5 = read_file(screenshot_md5_path)
                    if remote_md5 != local_md5:
                        need_download = True
                else:
                    need_download = True
            else:
                need_download = True

            if need_download:
                write_file(screenshot_md5_path, remote_md5, True)

                try:
                    urllib.urlretrieve(remote_screenshot_zip_url,
                                       os.path.join(SCREENSHOT_DOWNLOAD_DIR, self.pkg_name, "screenshot.zip")
                                       )
                    global_event.emit("download-screenshot-finish", self.pkg_name)
                except Exception, e:
                    global_logger.logerror("Download screenshot error: %s" % e)
        except Exception, e:
            global_logger.logerror("fetch_screenshot got error: %s" % e)
Ejemplo n.º 50
0
class SearchUI(DialogBox):
    def __init__(self):
        DialogBox.__init__(
            self, _("Lyrics search"), 460, 300, DIALOG_MASK_MULTIPLE_PAGE, close_callback=self.hide_all, 
            modal=False, window_hint=None, skip_taskbar_hint=False)
        self.artist_entry = InputEntry()
        self.artist_entry.set_size(130, 23)
        self.title_entry = InputEntry()
        self.title_entry.set_size(130, 23)
        artist_label = Label(_("Artist:"))
        title_label = Label(_("Title:"))
        right_align = gtk.Alignment()
        right_align.set(0, 0, 0, 1)
        
        search_button = Button(_("Search"))
        search_button.connect("clicked", self.search_lyric_cb)
        
        info_box = gtk.HBox(spacing=25)
        
        control_box = gtk.HBox(spacing=5)
        title_box = gtk.HBox(spacing=5)        
        title_box.pack_start(title_label, False, False)
        title_box.pack_start(self.title_entry)
        artist_box = gtk.HBox(spacing=5)
        artist_box.pack_start(artist_label, False, False)
        artist_box.pack_start(self.artist_entry)
        control_box.pack_start(title_box, False, False)
        control_box.pack_start(artist_box, False, False)
        
        info_box.pack_start(control_box, False, False)
        info_box.pack_start(search_button, False, False)
        
        scrolled_window = ScrolledWindow(0, 0)
        scrolled_window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
        sort_items = [(lambda item: item.title, cmp), (lambda item: item.artist, cmp)]
        self.result_view = ListView(sort_items)
        self.result_view.connect("double-click-item", self.double_click_cb)
        self.result_view.add_titles([_("Title"), _("Artist")])
        self.result_view.draw_mask = self.get_mask_func(self.result_view)
        scrolled_window.add_child(self.result_view)
        
        self.prompt_label = Label("")
        download_button = Button(_("Download"))
        download_button.connect("clicked", self.download_lyric_cb)
        cancel_button = Button(_("Close"))
        cancel_button.connect("clicked", lambda w: self.hide_all())
        
        info_box_align = gtk.Alignment()
        info_box_align.set_padding(5, 0, 5, 0)
        info_box_align.add(info_box)
        
        self.body_box.set_spacing(5)
        self.body_box.pack_start(info_box_align, False, False)
        self.body_box.pack_start(scrolled_window, True, True)
        self.left_button_box.set_buttons([self.prompt_label])
        self.right_button_box.set_buttons([download_button, cancel_button])
        self.lrc_manager = LrcManager()
        
    def double_click_cb(self, widget, item, colume, x, y):   
        self.download_lyric_cb(widget)
        
    def search_engine(self, artist, title):    
        ttplayer_result = TTPlayer().request(artist, title)
        self.render_lyrics(ttplayer_result)
        
        duomi_result = DUOMI().request(artist, title)
        self.render_lyrics(duomi_result)
        
        soso_result = SOSO().request(artist, title)
        self.render_lyrics(soso_result, True)
        
    def search_lyric_cb(self, widget):
        self.result_view.clear()
        artist = self.artist_entry.entry.get_text()
        title = self.title_entry.entry.get_text()
        self.prompt_label.set_text(_("Now searching"))
        if artist == "" and title == "":
            self.prompt_label.set_text(_("Not found!"))
            return
        utils.ThreadLoad(self.search_engine, artist, title).start()
        
    @post_gui
    def render_lyrics(self, result, last=False):
        '''docs'''
        if result != None:
            try:
                items = [SearchItem(each_info) for each_info in result]
            except:    
                pass
            else:
                self.result_view.add_items(items)

            self.prompt_label.set_text(_("%d lyrics found") % len(self.result_view.items))
        else:    
            if last:
                if len(self.result_view.items) > 0:
                    self.prompt_label.set_text(_("%d lyrics found") % len(self.result_view.items))
                else:
                    self.prompt_label.set_text(_("Not found!"))
        

    def download_lyric_cb(self, widget):
        select_items = self.result_view.select_rows
        save_filepath = self.lrc_manager.get_lrc_filepath(Player.song)
        if len(select_items) > 0:
            self.prompt_label.set_text(_("Downloading lyrics"))
            item = self.result_view.items[select_items[0]]
            url = item.get_url()
            net_encode = item.get_netcode()
            utils.ThreadRun(utils.download, self.render_download, [url, save_filepath, net_encode]).start()
            
    @post_gui        
    def render_download(self, result):
        if result:
            Dispatcher.reload_lrc(Player.song)
            self.prompt_label.set_text(_("File save to %s") % config.get("lyrics", "save_lrc_path"))
        else:    
            self.prompt_label.set_text(_("Fail to download!"))
Ejemplo n.º 51
0
class ShareToWeibo(object):
    '''share picture to weibo'''
    def __init__(self, filename=""):
        '''
        init share
        @param filename: the file to share
        '''
        self.upload_image = filename
        self.thumb_width = 188
        self.thumb_height = 168
        self.MAX_CHAR = 140
        #self.__text_frame_color = (0.76, 0.76, 0.76)
        self.__win_width = 602
        open(COOKIE_FILE,'wb').close()

        self.window = DialogBox(_("Share to social networks"), close_callback=gtk.main_quit)
        self.window.set_keep_above(True)
        self.window.set_size_request(self.__win_width+20, 288)
        self.window.set_resizable(False)
        self.window.titlebar.connect("expose-event", self.__expose_top_and_bottome)
        self.window.button_box.connect("expose-event", self.__expose_top_and_bottome)

        # create slider
        self.slider = HSlider()
        self.slider_list = []

        self.share_box = gtk.VBox(False, 2)     # first page, input context
        self.web_box = gtk.VBox(False, 10)      # second page, login
        self.result_box = gtk.VBox(False, 10)   # third page, share result

        share_align = gtk.Alignment()
        share_align.set(0.5, 0.5, 0, 0)
        share_align.add(self.share_box)
        share_align.connect("expose-event", self.__slider_expose)

        # go back button
        web_left_button = ImageButton(
            app_theme.get_pixbuf("share/back_normal.png"),
            app_theme.get_pixbuf("share/back_hover.png"),
            app_theme.get_pixbuf("share/back_press.png"))
        web_left_button.connect("clicked", lambda w: self.set_slide_index(0))
        web_left_button.set_can_focus(False)
        utils.set_clickable_cursor(web_left_button)
        # show url entry
        self.web_url_entry = InputEntry()
        self.web_url_entry.set_editable(False)
        self.web_url_entry.set_size(555, 20)
        self.web_url_entry.entry.right_menu_visible_flag = False
        # alig url entry
        web_navigate_vbox = gtk.VBox(False)
        web_navigate_vbox.pack_start(self.web_url_entry)
        web_navigate_t_align = gtk.Alignment()
        web_navigate_t_align.set(0.0, 0.5, 0, 0)
        web_navigate_t_align.add(web_navigate_vbox)
        # pack back button and url entry
        web_navigate_box = gtk.HBox(False, 7)
        web_navigate_box.pack_start(web_left_button, False, False)
        web_navigate_box.pack_start(web_navigate_t_align)

        web_navigate_align = gtk.Alignment()
        web_navigate_align.set(0.5, 0.5, 0, 0)
        web_navigate_align.set_padding(4, 0, 11, 13)
        web_navigate_align.add(web_navigate_box)

        # create a webkit
        self.web_view = WebView(COOKIE_FILE)
        self.web_view.connect("notify::load-status", self.web_view_load_status)
        self.web_view.connect("load-error", self.web_view_load_error)
        self.web_scrolled_window = ScrolledWindow()
        self.web_scrolled_window.add(self.web_view)
        self.web_scrolled_window.set_size_request(590, 228)

        self.web_box.pack_start(web_navigate_align, False, False)
        self.web_box.pack_start(self.web_scrolled_window)
        #self.web_box.set_size_request(-1, 258)
        web_align = gtk.Alignment()
        web_align.set(0.5, 0.0, 0, 1)
        web_align.add(self.web_box)
        web_align.connect("expose-event", self.__slider_expose)

        res_align = gtk.Alignment()
        res_align.set(0.5, 0.5, 0, 0)
        res_align.add(self.result_box)
        res_align.connect("expose-event", self.__slider_expose)

        self.slider.set_to_page(share_align)
        self.slider_list.append(share_align)
        self.slider_list.append(web_align)
        self.slider_list.append(res_align)

        self.__weibo_list = []
        self.sina = weibo.Sina(self.web_view)
        self.qq = weibo.Tencent(self.web_view)
        self.twitter = weibo.Twitter(self.web_view)
        self.__weibo_list.append(self.sina)
        self.__weibo_list.append(self.qq)
        self.__weibo_list.append(self.twitter)
        self.__current_weibo = None

        self.window.body_box.pack_start(self.slider, True, True)
        self.init_share_box()

    # webkit load-status, login success, go back
    def web_view_load_status(self, web, status):
        '''web_view notify load-status callback'''
        state = web.get_property("load-status")
        url = web.get_property('uri')
        if url:
            self.web_url_entry.set_editable(True)
            self.web_url_entry.set_text(url)
            self.web_url_entry.entry.move_to_start()
            self.web_url_entry.set_editable(False)
        if state == webkit.LOAD_FAILED:  # load failed
            print "load failed",
            print web.get_property('uri')

        elif state == webkit.LOAD_COMMITTED:
            if self.__current_weibo and self.__current_weibo.is_callback_url(url):
                web.stop_loading()  # if go to  callback url, stop loading
                # access token
                #print "load committed", url
                t = threading.Thread(target=self.weibo_login_thread)
                t.setDaemon(True)
                t.start()

    def web_view_load_error(self, web, fram, url, error, data=None):
        web.load_string(
            "<html><body><p><h1>%s</h1></p>%s</body></html>" % (
            _("Unable to load page"),
            _("Problem occurred while loading the URL '%s'") % (url)),
            "text/html", "UTF-8", "")
        print url
        return True
    
    # login or switch user
    def weibo_login(self, widget, weibo):
        '''weibo button clicked callback'''
        self.web_view.load_uri("about:blank")
        utils.set_cursor(widget)
        self.set_slide_index(1)
        self.__current_weibo = weibo
        t = threading.Thread(target=self.__current_weibo.request_oauth)
        t.setDaemon(True)
        t.start()

    def weibo_login_thread(self):
        '''in webkit login finish, get user info again'''
        self.__current_weibo.access_token()
        self.get_user_info_again()
        gtk.gdk.threads_enter()
        self.set_slide_index(0)
        gtk.gdk.threads_leave()

    def get_user_info_again(self):
        ''' login or switch user, and get user info again'''
        box = self.__current_weibo.get_box()
        #print "cuurent weibo:", self.__current_weibo.t_type
        gtk.gdk.threads_enter()
        children = box.get_children()
        for child in children:
            if child in self.__weibo_check_button_list:
                self.__weibo_check_button_list.remove(child)
            if child in self.__weibo_image_button_list:
                self.__weibo_image_button_list.remove(child)
            child.destroy()
        gtk.gdk.threads_leave()

        self.get_user_info(self.__current_weibo)

        gtk.gdk.threads_enter()
        box.show_all()
        gtk.gdk.threads_leave()

    def set_slide_index(self, index):
        '''
        set slide to index
        @param index: the index of widget in slider, an int num
        '''
        if index >= len(self.slider_list):
            return
        direct = "right"
        if index == 1 and self.window.button_box in self.window.window_frame.get_children():
            #self.slider.set_size_request(-1, 260)
            win = self.window
            if win.left_button_box in win.button_box.get_children():
                win.button_box.remove(win.left_button_box)
            if win.right_button_box in win.button_box.get_children():
                win.button_box.remove(win.right_button_box)
            tmp = gtk.HSeparator()
            tmp.set_size_request(-1, 1)
            tmp.show()
            win.button_box.pack_start(tmp)
            direct = "right"
            #if self.window.button_box in self.window.window_frame.get_children():
                #self.window.window_frame.remove(self.window.button_box)
        elif index == 0:
            #self.slider.set_size_request(-1, 223)
            win = self.window
            for each in win.button_box.get_children():
                each.destroy()
            if win.left_button_box not in win.button_box.get_children():
                win.button_box.pack_start(win.left_button_box)
            if win.right_button_box not in win.button_box.get_children():
                win.button_box.pack_start(win.right_button_box)
            direct = "left"
            #if self.window.button_box not in self.window.window_frame.get_children():
                #self.window.window_frame.pack_start(self.window.button_box, False, False)
        elif index == 2:
            self.window.left_button_box.set_buttons([])
            l = Label("  ")
            l.show()
            self.window.right_button_box.set_buttons([l])
            direct = "right"
            #self.slider.set_size_request(-1, 223)
            
        self.slider.slide_to_page(self.slider_list[index], direct)

    def weibo_check_toggle(self, button, weibo):
        '''weibo check button toggled callback. check the weibo to share'''
        if button.get_active():
            self.to_share_weibo[weibo] = 1
        else:
            self.to_share_weibo[weibo] = 0

    def create_ico_image(self, name):
        ''' create image from file'''
        pix1 = app_theme_get_dynamic_pixbuf('image/share/%s.png' % name).get_pixbuf()
        pix2 = app_theme_get_dynamic_pixbuf('image/share/%s_no.png' % name).get_pixbuf()
        return (pix1, pix2)
    
    def get_user_info(self, weibo):
        '''get weibo user info'''
        info = weibo.get_user_name()
        gtk.gdk.threads_enter()
        #self.get_user_error_text = ""
        weibo_hbox = weibo.get_box()
        hbox = gtk.HBox(False)
        vbox = gtk.VBox(False)
        weibo_hbox.pack_start(vbox, False, False)
        vbox.pack_start(hbox)
        #print weibo.t_type, info
        if info:
            self.is_get_user_info[weibo] = 1
            label = Label(text=info, label_width=70, enable_select=False)
            check = CheckButton()
            #check = gtk.CheckButton()
            check.connect("toggled", self.weibo_check_toggle, weibo)
            check.set_active(True)
            check_vbox = gtk.VBox(False)
            check_align = gtk.Alignment(0.5, 0.5, 0, 0)
            check_align.add(check_vbox)
            check_vbox.pack_start(check, False, False)
            button = ImageButton(
                app_theme.get_pixbuf("share/" + weibo.t_type + ".png"),
                app_theme.get_pixbuf("share/" + weibo.t_type + ".png"),
                app_theme.get_pixbuf("share/" + weibo.t_type + ".png"))
            utils.set_clickable_cursor(button)
            button.connect("enter-notify-event", self.show_tooltip, _("Click to switch user"))
            hbox.pack_start(check_align, False, False)
            hbox.pack_start(button, False, False, 5)
            hbox.pack_start(label, False, False)
        else:
            self.is_get_user_info[weibo] = 0
            check = CheckButton()
            #check = gtk.CheckButton()
            check.set_sensitive(False)
            check_vbox = gtk.VBox(False)
            check_align = gtk.Alignment(0.5, 0.5, 0, 0)
            check_align.add(check_vbox)
            check_vbox.pack_start(check, False, False)
            button = ImageButton(
                app_theme.get_pixbuf("share/" + weibo.t_type + "_no.png"),
                app_theme.get_pixbuf("share/" + weibo.t_type + "_no.png"),
                app_theme.get_pixbuf("share/" + weibo.t_type + "_no.png"))
            utils.set_clickable_cursor(button)
            button.connect("enter-notify-event", self.show_tooltip, _("Click to login"))
            hbox.pack_start(check_align, False, False)
            hbox.pack_start(button, False, False, 5)
            # curl time out
            info_error = weibo.get_curl_error()
            if info_error:
                #self.get_user_error_text += "%s:%s." % (weibo.t_type, _(info_error))
                hbox.pack_start(
                    Label(text="(%s)" % _(info_error), label_width=70,enable_select=False,
                    text_color = app_theme.get_color("left_char_num1")), False, False)
            
        button.connect("clicked", self.weibo_login, weibo)
        self.__weibo_check_button_list.append(check)
        self.__weibo_image_button_list.append(button)
        gtk.gdk.threads_leave()
        return weibo_hbox
    
    def show_tooltip(self, widget, event, text):
        '''Create help tooltip.'''
        Tooltip.text(widget, text)

    def init_user_info_thread(self, button, text_view):
        '''get user name thread'''
        time.sleep(0.1)

        for weibo in self.__weibo_list:
            self.get_user_info(weibo)

        gtk.gdk.threads_enter()
        #self.share_box.set_sensitive(True)
        button.set_sensitive(True)
        text_view.set_editable(True)
        for weibo in self.__weibo_list:
            weibo.get_box().show_all()
            weibo.get_box().queue_draw()
        self.loading_label.destroy()
        gtk.gdk.threads_leave()
    
    # init share box, create share button, input
    def init_share_box(self):
        '''get weibo info, and create button'''
        self.to_share_weibo = {}
        self.to_share_weibo_res = {}
        self.deepin_info = {}
        self.is_get_user_info = {}
        self.__weibo_check_button_list = []
        self.__weibo_image_button_list = []

        # create Thumbnail
        if exists(self.upload_image):
            pixbuf = gtk.gdk.pixbuf_new_from_file(self.upload_image)
            pix_w = pixbuf.get_width()
            pix_h = pixbuf.get_height()
            if pix_w > pix_h:
                pix_s_w = self.thumb_width
                pix_s_h = int(pix_h / (float(pix_w) / self.thumb_width))
            else:
                pix_s_h = self.thumb_height
                pix_s_w = int(pix_w / (float(pix_h) / self.thumb_height))
            pixbuf = pixbuf.scale_simple(pix_s_w, pix_s_h, gtk.gdk.INTERP_TILES)
            thumb = gtk.image_new_from_pixbuf(pixbuf)
        else:
            thumb = gtk.Image()
        thumb.set_size_request(self.thumb_width, self.thumb_height)

        # weibo context input
        text_box = gtk.HBox(False, 2)
        text_vbox = gtk.VBox(False, 2)
        text_bg_vbox = gtk.VBox(False)
        text_bg_align = gtk.Alignment()
        text_bg_align.set(0.5, 0.5, 0, 0)
        text_bg_align.set_padding(5, 5, 16, 5)
        text_bg_align.connect("expose-event", self.text_view_bg_expose)
        text_scrolled_win = ScrolledWindow()
        text_scrolled_win.set_size_request(340, 157)

        text_view = gtk.TextView()
        text_view.set_left_margin(10)
        text_view.set_right_margin(10)
        text_view.set_pixels_above_lines(5)
        text_view.set_pixels_below_lines(5)
        text_view.set_wrap_mode(gtk.WRAP_WORD| gtk.WRAP_CHAR)
        text_view.connect("expose-event", self.text_view_expose)
        buf = text_view.get_buffer()
        text_scrolled_win.add(text_view)
        text_bg_vbox.pack_start(text_scrolled_win)
        text_bg_align.add(text_bg_vbox)

        text_align = gtk.Alignment() 
        text_align.set(0.5, 0.5, 0, 0)
        text_align.set_padding(25, 30, 10, 10)

        text_box.pack_start(thumb, False, False, 10)
        text_box.pack_start(text_bg_align)
        text_vbox.pack_start(text_box, False, False, 10)

        text_align.add(text_vbox)
        #tmp_align = gtk.Alignment()
        #tmp_align.set(0.5, 0, 0, 1)
        #self.share_box.pack_start(tmp_align, False, False)
        self.share_box.pack_start(text_align, False, False)

        # dialog button box
        left_box = self.window.left_button_box
        right_box = self.window.right_button_box

        # input tip label
        self.input_num_label = Label("%d" % self.MAX_CHAR,
            text_size=16, text_x_align=pango.ALIGN_CENTER, label_width=50, enable_select=False)
        self.input_num_label.text_color = app_theme.get_color("left_char_num")

        # login box
        #weibo_box = gtk.HBox(False, 1)
        #weibo_box.set_size_request(-1, 50)
        weibo_box_list = []
        self.loading_label = Label("%s..." % _("Loading"), text_size=12,
            label_width=70, enable_select=False)
        weibo_box_list.append(self.loading_label)

        for weibo in self.__weibo_list:
            box = gtk.HBox(False, 2)
            weibo.set_box(box)
            weibo_box_list.append(box)
        left_box.set_buttons(weibo_box_list)

        # share button
        button = Button(_("Share"))
        #button.set_size_request(75, 25)
        button.connect("clicked", self.share_button_clicked, text_view)
        buf.connect("changed", self.text_view_changed, button)  # check char num

        tmp_vbox = gtk.VBox(False)
        tmp_align = gtk.Alignment()
        tmp_align.set(0.5, 0.5, 0, 0)
        tmp_vbox.pack_start(button, False, False)
        #tmp_vbox.pack_start(tmp_align)
        tmp_align.add(tmp_vbox)
        right_box.set_buttons([self.input_num_label, tmp_align])

        # at first, set widget insensitive
        button.set_sensitive(False)
        text_view.set_editable(False)
        t = threading.Thread(target=self.init_user_info_thread, args=(button, text_view))
        t.setDaemon(True)
        t.start()

    # draw text view background
    def text_view_bg_expose(self, widget, event):
        '''draw text view bg'''
        cr = widget.window.cairo_create()
        rect = widget.allocation
        text_pixbuf = app_theme_get_dynamic_pixbuf('image/share/text_view.png').get_pixbuf()
        draw.draw_pixbuf(cr, text_pixbuf, rect.x, rect.y)

    # if text is empty, show tip info
    def text_view_expose(self, text_view, event):
        '''text_view expose'''
        buf = text_view.get_buffer()
        text = buf.get_text(*buf.get_bounds())

        if text == "" and text_view.get_editable() and not text_view.is_focus():
            win = text_view.get_window(gtk.TEXT_WINDOW_TEXT)
            cr = win.cairo_create()
            cr.move_to(10, 5)
            context = pangocairo.CairoContext(cr)
            layout = context.create_layout()
            layout.set_font_description(pango.FontDescription("Snas 10"))
            layout.set_alignment(pango.ALIGN_LEFT)
            layout.set_text(_("Please input text here"))
            cr.set_source_rgb(0.66, 0.66, 0.66)
            context.update_layout(layout)
            context.show_layout(layout)
    
    # show input char num
    def text_view_changed(self, buf, button):
        '''text_view changed callback'''
        count = buf.get_char_count()
        if count <= self.MAX_CHAR:
            #self.input_tip_label.set_text(_("left"))
            self.input_num_label.set_text("%d" % (self.MAX_CHAR - count))
            self.input_num_label.text_color = app_theme.get_color("left_char_num")
            if not button.is_sensitive():
                button.set_sensitive(True)
        else:
            #self.input_tip_label.set_text(_("exceeds"))
            self.input_num_label.set_text("-%d" % (count - self.MAX_CHAR))
            self.input_num_label.text_color = app_theme.get_color("left_char_num1")
            if button.is_sensitive():
                button.set_sensitive(False)

    def share_button_clicked(self, button, text_view):
        '''share_button_clicked callback'''
        # file is not exist.
        if not exists(self.upload_image):
            d = ConfirmDialog(_("Error"), "%s." % ( _("Picture does not exist.")))
            d.show_all()
            d.set_transient_for(self.window)
            return False
        has_share_web = False
        for weibo in self.to_share_weibo:
            if self.to_share_weibo[weibo]:
                has_share_web = True
                break
        # have no web selected
        if not has_share_web:
            d = ConfirmDialog(_("Error"), _("Please choose at least one platform to share on"))
            d.show_all()
            d.set_transient_for(self.window)
            return False
        # at first, set widget insensitive
        button.set_sensitive(False)
        text_view.set_editable(False)
        #self.window.left_button_box.set_sensitive(False)
        # set weibo checkbutton sensitive
        for check in self.__weibo_check_button_list:
            check.set_sensitive(False)
        # disconnect weibo ico button clicked function
        for img in self.__weibo_image_button_list:
            try:
                img.disconnect_by_func(self.weibo_login)
            except:
                pass
        button.set_label(_("Uploading"))
        t = threading.Thread(target=self.share_to_weibo_thread, args=(text_view, ))
        t.setDaemon(True)
        t.start()
    
    # upload image thread
    def share_to_weibo_thread(self, text_view):
        '''share in thread'''
        buf = text_view.get_buffer()
        text = buf.get_text(*buf.get_bounds())
        if text.strip() == "":
            text = _("from Deepin Screenshot")
        # get deepin official info
        self.deepin_info[self.sina] = self.sina.get_deepin_info()
        self.deepin_info[self.qq] = self.qq.get_deepin_info()
        if default_locale != 'zh_CN':
            self.deepin_info[self.twitter] = self.twitter.get_deepin_info()
        # upload
        for weibo in self.to_share_weibo:
            if self.to_share_weibo[weibo]:
                self.to_share_weibo_res[weibo] = weibo.upload_image(self.upload_image, text)
        self.share_to_weibo_result()
    
    # show upload result
    @post_gui
    def share_to_weibo_result(self):
        '''result of share to weibo'''
        font_color = app_theme.get_color("share_result_text")
        res_hbox = gtk.HBox(False)
        res_hbox.set_size_request(-1, 240)

        res_left_box = DialogLeftButtonBox()
        res_right_box = DialogRightButtonBox()

        res_left_box.button_align.set(0.5, 0.0, 0, 1)
        res_right_box.button_align.set(0.5, 0.0, 0, 1)
        res_left_box.button_align.set_padding(5, 9, 19, 0)
        res_right_box.button_align.set_padding(30, 0, 0, 0)

        res_left_box.set_size_request(405, -1)
        res_right_box.set_size_request(195, -1)
        
        res_hbox.pack_start(res_left_box)
        res_hbox.pack_start(
            VSeparator(app_theme.get_shadow_color("VSeparator").get_color_info(), 0, 0))
        res_hbox.pack_start(res_right_box)

        res_vbox = gtk.VBox(False)
        follow_vbox = gtk.VBox(False)

        tmp_img = gtk.Image()       # only use as a placeholder
        tmp_img.set_size_request(-1, 50) 
        res_vbox.pack_start(tmp_img, False, False)

        follow_tip_hbox = gtk.HBox(False)
        img = gtk.image_new_from_file(app_theme.get_theme_file_path("image/share/deepin_logo.png"))
        follow_tip_hbox.pack_start(img, False, False, 5)
        follow_tip_hbox.pack_start(
            Label("%s %s" % (_("Follow"), "Linux Deepin"), 
                text_color=app_theme_get_dynamic_color("#5f5f5f"),
                text_size=12, enable_select=False), False, False)
        follow_vbox.pack_start(follow_tip_hbox, False, False, 13)
        for weibo in self.to_share_weibo_res:
            vbox = gtk.VBox(False, 1)
            tip_box = gtk.HBox()
            error_box = gtk.HBox()
            vbox.pack_start(tip_box, False, False)
            vbox.pack_start(error_box, False, False)
            if self.to_share_weibo_res[weibo][0]:   # upload succeed
                img = gtk.image_new_from_file(app_theme.get_theme_file_path("image/share/share_succeed.png"))
                #link = LinkButton(_(weibo.t_type), text_size=13, self.to_share_weibo_res[weibo][1])
                link = Label(_(weibo.t_type), text_size=12, 
                    text_color=app_theme.get_color("link_text"))
                #, enable_gaussian=True, gaussian_radious=1, border_radious=0)
                link.add_events(gtk.gdk.BUTTON_PRESS_MASK)
                link.connect("enter-notify-event", lambda w, e: self.__draw_under_line(w))
                link.connect("leave-notify-event", lambda w, e: w.queue_draw())
                link.connect("button-press-event", self.goto_weibo_button_clicked, weibo)
                link_box = gtk.HBox(False)
                link_box.pack_start(link, False, False)
                utils.set_clickable_cursor(link)
                text = _("Share to")
                label = Label(text, text_size=12, 
                    text_color=font_color, enable_select=False)
                text = _("Successful")
                label1 = Label(text, text_size=12, 
                    text_color=font_color, enable_select=False)
                tip_box.pack_start(img, False, False, 15)
                tip_box.pack_start(label, False, False, 3)
                tip_box.pack_start(link_box, False, False, 3)
                tip_box.pack_start(label1, False, False)
                # only use as a placeholder
                img = gtk.Image()
                img.set_size_request(20, 1)
                error_box.pack_start(img, False, False, 16)
                tmp = Label(" ", text_size=9, label_width=200)
                tmp.set_size_request(200, 1)
                error_box.pack_start(tmp, False, False)
                #print text
            else:   # upload failed
                img = gtk.image_new_from_file(app_theme.get_theme_file_path("image/share/share_failed.png"))
                #text = "% %s %s." % (_(weibo.t_type), _("upload failed"))
                text = _("Share to")
                label1 = Label(text, text_size=12, 
                    text_color=font_color, enable_select=False)
                label2 = Label(_(weibo.t_type), text_size=12, 
                    text_color=font_color, enable_select=False)
                text = _("Failed")
                label3 = Label(text, text_size=12, 
                    text_color=font_color, enable_select=False)
                if weibo.curl.error:
                    error = "(%s)" % _(weibo.curl.error)
                elif weibo.get_error_msg():
                    error = "(%s)" % _(weibo.get_error_msg()) 
                else:
                    error = "(%s)" % _("Unknown reason")
                #print "%s: %s" % (weibo.t_type, error)
                #print "%s: %s" % (weibo.t_type, weibo.get_error_msg())
                label = Label(text, text_size=12,
                    text_color=font_color, enable_select=False)
                tip_box.pack_start(img, False, False, 15)
                tip_box.pack_start(label1, False, False, 3)
                tip_box.pack_start(label2, False, False, 3)
                tip_box.pack_start(label3, False, False)
                img = gtk.Image()   # only use as a placeholder
                img.set_size_request(20, 20)
                error_box.pack_start(img, False, False, 16)
                error_box.pack_start(Label(error, text_size=9, label_width=200,
                    text_color=font_color, enable_select=False), False, False)
                #print text
            res_vbox.pack_start(vbox, False, False, 10)

        for weibo in self.deepin_info:
            box = gtk.HBox(False, 15)
            # followed
            img = gtk.image_new_from_pixbuf(app_theme.get_pixbuf("share/"+weibo.t_type+".png").get_pixbuf())
            box.pack_start(img, False, False)
            if self.deepin_info[weibo] is not None and self.deepin_info[weibo][3]:
                if not default_locale.startswith("zh_"):
                    button = gtk.image_new_from_pixbuf(
                        app_theme.get_pixbuf("share/followed_en.png").get_pixbuf())
                else:
                    button = gtk.image_new_from_pixbuf(
                        app_theme.get_pixbuf("share/followed.png").get_pixbuf())
            else:   # to follow
                if not default_locale.startswith("zh_"):
                    button = ImageButton(
                        app_theme.get_pixbuf("share/follow_normal_en.png"),
                        app_theme.get_pixbuf("share/follow_hover_en.png"),
                        app_theme.get_pixbuf("share/follow_press_en.png"))
                else:
                    button = ImageButton(
                        app_theme.get_pixbuf("share/follow_normal.png"),
                        app_theme.get_pixbuf("share/follow_hover.png"),
                        app_theme.get_pixbuf("share/follow_press.png"))
                button.connect("clicked", self.friendships_add_button_clicked, weibo, box)
            box.pack_start(button, False, False)
            align = gtk.Alignment()
            align.set(0.0, 0.5, 0, 0)
            align.set_padding(0, 0, 30, 0)
            align.add(box)
            follow_vbox.pack_start(align, False, False, 8)

        res_left_box.set_buttons([res_vbox])
        res_right_box.set_buttons([follow_vbox])

        self.result_box.pack_start(res_hbox, False, False)
        self.result_box.show_all()
        self.set_slide_index(2)
    
    def goto_weibo_button_clicked(self, widget, event, weibo):
        '''goto my weibo'''
        #print "goto weibo button clicked", weibo.t_type, "xdg-open %s" % self.to_share_weibo_res[weibo][1]
        if weibo in self.to_share_weibo_res:
            if self.to_share_weibo_res[weibo][1]:
                utils.run_command("xdg-open %s" % self.to_share_weibo_res[weibo][1])
        
    def friendships_add_button_clicked(self, widget, weibo, box):
        '''add friendships'''
        #self.result_box.set_sensitive(False)
        if not self.is_get_user_info[weibo]:
            utils.run_command("xdg-open %s" % weibo.index_url)
            return True

        widget.set_sensitive(False)
        t = threading.Thread(target=self.friendships_add_thread, args=(widget, weibo, box))
        t.setDaemon(True)
        t.start()
    
    def friendships_add_thread(self, button, weibo, box):
        '''add friendships'''
        if weibo.friendships_create() is not None:
            gtk.gdk.threads_enter()
            button.destroy()
            if not default_locale.startswith("zh_"):
                button = gtk.image_new_from_pixbuf(
                    app_theme.get_pixbuf("share/followed_en.png").get_pixbuf())
            else:
                button = gtk.image_new_from_pixbuf(
                    app_theme.get_pixbuf("share/followed.png").get_pixbuf())
            button.show()
            box.pack_start(button, False, False)
            #button.set_label("已关注")
            gtk.gdk.threads_leave()
    
    # show window
    def show(self):
        '''show'''
        self.window.show_window()

    # close widnow
    def quit(self, widget):
        ''' close '''
        gtk.main_quit()

    def __slider_expose(self, widget, event):
        ''' slider expose redraw'''
        cr = widget.window.cairo_create()
        rect = widget.allocation
        cr.set_source_rgba(1.0, 1.0, 1.0, 0.8)
        cr.rectangle(rect.x, rect.y, rect.width, rect.height)
        cr.fill()
    
    def __expose_top_and_bottome(self, widget, event):
        '''titlebar or button_box expose'''
        cr = widget.window.cairo_create()
        rect = widget.allocation
        cr.set_source_rgb(0.89, 0.89, 0.89)
        cr.rectangle(rect.x+2, rect.y+2, rect.width-4, rect.height-4)
        cr.fill()

    def __draw_under_line(self, widget):
        '''draw under line'''
        cr = widget.window.cairo_create()
        with utils.cairo_disable_antialias(cr):
            x, y, w, h = widget.allocation
            # #1A70b1
            cr.set_source_rgba(0.1, 0.43, 0.69, 1.0)
            cr.set_line_width(1)
            cr.move_to(x, y+h-3)
            cr.line_to(x+w, y+h-3)
            cr.stroke()
Ejemplo n.º 52
0
class SongPathBar(BaseBar):
    def __init__(self, title_name):
        BaseBar.__init__(self, init_index=-1)
        self.set_spacing(3)
        self.child_box = gtk.VBox()
        self.child_item_height = 22
        self.current_page = 1
        self.page_items_num = 0
        self.items = []

        title_item = StaticLabel(
            app_theme.get_pixbuf("filter/local_normal.png"), title_name, 10,
            25, 15, 10, 25, ALIGN_START)
        self.pack_start(title_item, False, False)
        self.pack_start(self.child_box, True, True)
        self.child_box.connect("size-allocate", self.size_change_cb)

        self.control_box = gtk.HBox()
        self.control_box.set_spacing(15)
        previous_align = self.create_simple_button("previous",
                                                   self.update_current_page,
                                                   "previous")
        next_align = self.create_simple_button("next",
                                               self.update_current_page,
                                               "next")
        self.info_label = Label("0/0",
                                app_theme.get_color("labelText"),
                                text_x_align=ALIGN_MIDDLE)
        self.control_box.pack_start(previous_align, False, False)
        self.control_box.pack_start(self.info_label, False, False)
        self.control_box.pack_start(next_align, False, False)
        self.control_box.set_no_show_all(True)
        control_align = gtk.Alignment()
        control_align.set(1, 1, 0.5, 0.5)
        control_align.add(self.control_box)
        self.pack_start(control_align, False, False)

    def update_current_page(self, widget, name):
        if not self.items or not self.page_items_num:
            return
        total_page = self.adjust_page()
        if name == "previous":
            new_current_page = self.current_page - 1
        else:
            new_current_page = self.current_page + 1

        if new_current_page < 1:
            new_current_page = 1
        elif new_current_page > total_page:
            new_current_page = total_page
        if new_current_page == self.current_page:
            return
        self.current_page = new_current_page
        self.update_items(None)
        self.set_index(-1)

    def get_item_num(self):
        try:
            return self.child_box.allocation.height / self.child_item_height
        except:
            return 0

    def set_label(self, value):
        self.info_label.set_text(value)

    def load_items(self, child_items):
        if child_items:
            container_remove_all(self.child_box)
            for index, item in enumerate(child_items):
                simple_item = SimpleItem(
                    (app_theme.get_pixbuf("filter/folder_normal.png"),
                     app_theme.get_pixbuf("filter/folder_press.png"), item[0],
                     item[1], item[2]), index + 1, 9, self.child_item_height,
                    25, 10, 15, self.set_index, self.get_index, ALIGN_START)
                self.child_box.pack_start(simple_item, False, False)

            if len(child_items) < self.page_items_num:
                block_num = self.page_items_num - len(child_items)
                for i in range(block_num):
                    self.child_box.pack_start(self.create_block_box(), False,
                                              True)
            self.control_box.set_no_show_all(False)
            self.control_box.show_all()
            self.show_all()
            self.queue_draw()
            self.get_toplevel().queue_draw()

    def size_change_cb(self, widget, rect):
        if rect.height > 0:
            new_num = rect.height / self.child_item_height
            if new_num == self.page_items_num:
                return
            else:
                self.page_items_num = new_num

                def fire():
                    self.update_items(None)

                gobject.idle_add(fire)

    def update_items(self, new_items):
        if new_items:
            self.items = new_items

        if not self.items or not self.page_items_num:
            return

        self.items.sort()
        self.update_label()
        total_page = self.adjust_page()
        if total_page == 1:
            page_items = self.items[:]
        elif self.current_page == 1:
            page_items = self.items[:self.page_items_num]
        elif self.current_page == total_page and total_page > 1:
            page_items = self.items[(self.current_page - 1) *
                                    self.page_items_num:]
        else:
            page_items = self.items[(self.current_page - 1) *
                                    self.page_items_num:self.current_page *
                                    self.page_items_num]

        self.load_items(page_items)

    def adjust_page(self):
        if not self.items or not self.page_items_num:
            return

        total_num = len(self.items)
        if total_num <= self.page_items_num:
            self.current_page = 1
            return 1

        mod_num = total_num % self.page_items_num
        if mod_num:
            return total_num / self.page_items_num + 1
        else:
            return total_num / self.page_items_num

    def adjust_current_page(self, total_page):
        if self.current_page > total_page:
            self.current_page = total_page

    def update_label(self):
        total_page = self.adjust_page()
        self.adjust_current_page(total_page)
        self.set_label("%d/%d" % (self.current_page, total_page))

    def create_simple_button(self, name, callback, *args):
        button = ImageButton(
            app_theme.get_pixbuf("filter/%s_normal.png" % name),
            app_theme.get_pixbuf("filter/%s_hover.png" % name),
            app_theme.get_pixbuf("filter/%s_press.png" % name))
        if callback:
            button.connect("clicked", callback, *args)
        align = gtk.Alignment()
        align.set(0.5, 0.5, 0, 0)
        align.add(button)
        return align

    def create_block_box(self):
        box = gtk.EventBox()
        box.set_visible_window(False)
        box.set_size_request(-1, self.child_item_height)
        return box