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)
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)
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)
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
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!"))
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()
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)
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 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 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
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 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()
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)
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()
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 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)
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)
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("&", "&").replace("<", "<").replace( ">", ">"), 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)
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 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()
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
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)
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)
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 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
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
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()
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 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 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
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()
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)
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("&", "&").replace("<", "<").replace(">", ">"), 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)
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!"))
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()
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