def __init__(self, gui, get_selected_func): Action_List.__init__(self) self.get_selected = get_selected_func self.community_gui = gui for event in self.community_gui.user_events: self.add_event(event) self.community_gui.register_user_action_list(self)
def initialize_user_action_page(self): vbox = gtk.VBox() add_user_icon = gtk.gdk.pixbuf_new_from_file_at_size(join(get_dir(ICON_DIR), "64px-plus_icon.png"), ACTION_IMAGE_SIZE, ACTION_IMAGE_SIZE) remove_user_icon = gtk.gdk.pixbuf_new_from_file_at_size(join(get_dir(ICON_DIR), "64px-no_icon.png"), ACTION_IMAGE_SIZE, ACTION_IMAGE_SIZE) exchange_keys_icon = gtk.gdk.pixbuf_new_from_file_at_size(join(get_dir(ICON_DIR), "key.png"), ACTION_IMAGE_SIZE, ACTION_IMAGE_SIZE) refetch_icon = gtk.gdk.pixbuf_new_from_file_at_size(join(get_dir(ICON_DIR), "64px-edit_metadata_icon.png"), ACTION_IMAGE_SIZE, ACTION_IMAGE_SIZE) action_buttons = [(add_user_icon, 'Invite to\nCommunity', self.show_invite_dialog_cb), (refetch_icon, 'Refetch\nProfile', self.refetch_profile_cb), ] if self.state_plugin.options.personal_communities: action_buttons.insert(0, (add_user_icon, 'Add to\n Community', self.show_add_dialog_cb)) action_buttons.insert(1, (remove_user_icon, 'Remove from\nCommunity', self.show_remove_dialog_cb)) if self.state_plugin.options.key_exchange: action_buttons.insert(3, (exchange_keys_icon, 'Exchange\nKeys', self.show_exchange_keys_dialog_cb)) self.actions = Action_List() for action in action_buttons: (icon, text, cb) = action self.actions.add_button(icon, text, cb) vbox.pack_start(self.actions.get_widget()) self.announce_checkbox = gtk.CheckButton('Make an alarm when user appears') vbox.pack_start(self.announce_checkbox, False, False) self.announce_checkbox.set_active(self.user.get('friend')) self.announce_checkbox.connect('toggled', self.set_announce) self.notebook.append_page(vbox, gtk.Label('More actions'))
def initialize_action_list(self): search_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-search_content_icon.png")) remove_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-remove_content_icon.png")) action_buttons = [(search_icon, 'Search', self.search_cb), (remove_icon, 'Clear', self.clear_cb) ] self.actions = Action_List() for action in action_buttons: (icon, text, cb) = action self.actions.add_button(icon, text, cb) self.pack_start(self.actions.get_widget(), False, True)
def create_action_list(self): new_message_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), self.NEW_MESSAGE_ICON)) refresh_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), self.REFRESH_ICON)) search_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), self.SEARCH_ICON)) action_buttons = [(new_message_icon, 'Compose', self.create_new_cb), (refresh_icon, 'Refresh / All\nMessages', self.refresh_cb), (new_message_icon, 'My\nMessages', self.my_messages_cb), (search_icon, 'Search', self.search_cb), (search_icon, 'Watches', self.watches_cb), ] self.actions = Action_List() for action in action_buttons: (icon, text, cb) = action self.actions.add_button(icon, text, cb)
def __init__(self, main_gui, getstatecb, modifycb): self.main_gui = main_gui self.modifycb = modifycb self.getstatecb = getstatecb self.guistate = 0 self.page = GUI_Page('Watches') # self.watch_list stores columns: possible picture, keyword, target self.watch_list = gtk.ListStore(gtk.gdk.Pixbuf, str, str) self.update() self.watch_view = gtk.TreeView(self.watch_list) self.pic_cell = gtk.CellRendererPixbuf() self.name_cell = gtk.CellRendererText() self.target_cell = gtk.CellRendererText() self.pic_column = self.watch_view.insert_column_with_attributes( self.COL_ICON, '', self.pic_cell, pixbuf=self.COL_ICON) self.name_column = self.watch_view.insert_column_with_attributes( self.COL_NAME, '', self.name_cell, text=self.COL_NAME) self.target_column = self.watch_view.insert_column_with_attributes( self.COL_TARGET, '', self.target_cell, text=self.COL_TARGET) self.page.pack_start(self.watch_view, True, True) add_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-add_content_icon.png")) remove_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-remove_content_icon.png")) action_buttons = [(add_icon, 'Add', self.add_clicked), (remove_icon, 'Remove', self.remove_clicked) ] self.actions = Action_List() for action in action_buttons: (icon, text, cb) = action self.actions.add_button(icon, text, cb) self.page.pack_start(self.actions.get_widget(), False, True) self.main_gui.add_page(self.page)
def initialize_action_list(self): add_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-add_content_icon.png")) remove_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-remove_content_icon.png")) open_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-publish_content_icon.png")) metadata_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-edit_metadata_icon.png")) action_buttons = [(add_icon, 'Publish\nFile', self.add_file_cb), (add_icon, 'Publish\nDirectory', self.add_dir_cb), (remove_icon, 'Remove', self.remove_cb), (open_icon, 'Open', self.open_cb), (metadata_icon, 'Edit\nMetadata', self.edit_metadata_cb) ] self.actions = Action_List() for action in action_buttons: (icon, text, cb) = action self.actions.add_button(icon, text, cb) self.pack_start(self.actions.get_widget(), False, True)
def initialize_action_list(self): download_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-browse_content_icon.png")) open_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-publish_content_icon.png")) metadata_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-edit_metadata_icon.png")) search_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-search_content_icon.png")) action_buttons = [(download_icon, 'Download', self.download_cb), (open_icon, 'Stream', self.stream_cb), (metadata_icon, 'Show\nMetadata', self.show_metadata_cb), (search_icon, 'Search\nFrom User', self.show_search_cb), (search_icon, 'Refresh', self.refresh_cb) ] self.actions = Action_List() for action in action_buttons: (icon, text, cb) = action self.actions.add_button(icon, text, cb) self.pack_start(self.actions.get_widget(), False, True)
class Messageboard_GUI(GUI_Page): MSGBOARD_ICON = '64px-msgboard_icon.png' MESSAGE_ICON = '64px-messaging_status_icon.png' REFRESH_ICON = '64px-refresh_icon.png' SEARCH_ICON = '64px-search_icon.png' NEW_MESSAGE_ICON = '64px-msgboard_icon.png' def __init__(self, gui): global community, msgboard, chat GUI_Page.__init__(self, 'Messageboard') community = get_plugin_by_type(PLUGIN_TYPE_COMMUNITY) chat = get_plugin_by_type(PLUGIN_TYPE_MESSAGING) msgboard = get_plugin_by_type(PLUGIN_TYPE_MESSAGE_BOARD) self.notify = get_plugin_by_type(PLUGIN_TYPE_NOTIFICATION).notify self.main_gui = gui # Store Message_Page instances, key = sharemeta of the message self.message_pages = {} messageboard_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), self.MSGBOARD_ICON)) community.community_gui.register_user_event(messageboard_icon, 'Msg board', self.start_messageboard_cb) community.community_gui.register_com_event(messageboard_icon, 'Msg board', self.start_messageboard_cb) self.message_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), self.MESSAGE_ICON)) self.in_search_mode = False self.store = None self.search_store = None self.target = None # create widgets here self.create_action_list() self.message_list, self.message_view = self.create_message_list() self.search_hbox = gtk.HBox() self.search_entry = new_entry('Enter search keywords') self.search_entry.connect('activate', self.search_activate_cb) self.search_close = gtk.Button(stock=gtk.STOCK_CLOSE) self.search_close.connect('clicked', self.search_close_cb) self.search_now = gtk.Button(stock=gtk.STOCK_FIND) self.search_now.connect('clicked', self.search_now_cb) self.search_hbox.pack_start(self.search_entry, True, True) self.search_hbox.pack_start(self.search_close, False, True) self.search_hbox.pack_start(self.search_now, False, True) self.vbox = gtk.VBox() self.vbox.pack_start(self.message_list, True, True) self.vbox.pack_start(self.search_hbox, False, True) self.pack_start(self.vbox, True, True) self.pack_start(self.actions.get_widget(), False, True) self.show_all() self.search_hbox.hide() gui.add_page(self) gui.add_key_binding(gtk.gdk.CONTROL_MASK, gtk.keysyms.m, self.key_pressed_ctrl_m) msgboard.register_ui(self) self.watch_dialog = Watches_GUI(self.main_gui, msgboard.get_state, msgboard.modify_state) def append_messages_to_store(self, store, metas): # Display hot messages first hot = [] normal = [] for meta in metas: if msgboard.is_hot(meta): hot.append((True, meta)) else: normal.append((False, meta)) for l in hot, normal: for (ishot, meta) in l: user = None uid = meta.get('src') if uid != None: user = community.get_user(uid) if user == community.get_myself(): sender = 'Myself' elif user != None: sender = pango_escape(user.tag()) else: sender = pango_escape(meta.get('from')) timestamp = msgtime(meta) subject = pango_escape(meta.get('subject')) if ishot: line = '%s <span foreground="gray"><small>%s</small></span>\n<span foreground="red">[HOT] </span><b>%s</b>' % (sender, timestamp, subject) else: line = '%s <span foreground="gray"><small>%s</small></span>\n<b>%s</b>' % (sender, timestamp, subject) icon = self.message_icon if user != None: icon = get_user_profile_picture(user).scale_simple(64, 64, gtk.gdk.INTERP_BILINEAR) store.append([icon, line, meta]) def key_pressed_ctrl_m(self, target, ctx): self.start_messageboard_cb(target) def create_action_list(self): new_message_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), self.NEW_MESSAGE_ICON)) refresh_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), self.REFRESH_ICON)) search_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), self.SEARCH_ICON)) action_buttons = [(new_message_icon, 'Compose', self.create_new_cb), (refresh_icon, 'Refresh / All\nMessages', self.refresh_cb), (new_message_icon, 'My\nMessages', self.my_messages_cb), (search_icon, 'Search', self.search_cb), (search_icon, 'Watches', self.watches_cb), ] self.actions = Action_List() for action in action_buttons: (icon, text, cb) = action self.actions.add_button(icon, text, cb) def watches_cb(self, widget): self.watch_dialog.show() def create_message_list(self): message_list = new_scrollarea() message_view = gtk.TreeView() message_view.set_headers_visible(False) cr1 = gtk.CellRendererPixbuf() cr2 = gtk.CellRendererText() col1 = gtk.TreeViewColumn('Message') col1.pack_start(cr1, False) col1.pack_start(cr2, True) message_view.append_column(col1) col1.add_attribute(cr1, 'pixbuf', 0) col1.add_attribute(cr2, 'markup', 1) message_view.connect('row-activated', self.row_activated_cb) message_list.add(message_view) return message_list, message_view def create_new_cb(self, widget): # HACK: first try Hildon StackableWindow-style try: composer = Message_Composer(self) except: composer = Message_Composer(self.main_gui.get_main_window()) composer.show_all() response = composer.run() if response == 1: sender = community.get_myself().tag() subject = composer.get_subject() text = composer.get_text() cname = None if self.target != None: cname = self.target.get('name') self.publish_message(sender, subject, text, cname) composer.destroy() def refresh_cb(self, widget, showmine=False): if self.in_search_mode: self.search_close_cb(None) msgboard.query_messages(showmine=showmine, target=self.target) def my_messages_cb(self, widget): self.refresh_cb(widget, showmine=True) def search_cb(self, widget): self.in_search_mode = True self.search_hbox.show() self.search_entry.grab_focus() if self.search_store: self.message_view.set_model(self.search_store) def search_close_cb(self, widget): self.in_search_mode = False self.search_hbox.hide() if self.store: self.message_view.set_model(self.store) def search_now_cb(self, widget): self.search_activate_cb(self.search_entry) def search_activate_cb(self, entry): self.search_store = gtk.ListStore(gtk.gdk.Pixbuf, str, object) self.message_view.set_model(self.search_store) text = entry.get_text().strip() keywords = text.split(',') criteria = None if self.target != None: criteria = {'community': self.target.get('name')} msgboard.search(self.got_query_results, criteria=criteria, keywords=keywords) if len(text) > 0: msg = 'Searching for %s' % text else: msg = 'Searching for all messages' self.notify(msg, delay=500) def got_query_results(self, user, metas, ctx): self.append_messages_to_store(self.search_store, metas) def row_activated_cb(self, treeview, path, view_column): store = treeview.get_model() row_iter = store.get_iter(path) meta = store.get(row_iter, 2)[0] self.view_message(meta) def view_message(self, msg): page = self.message_pages.get(msg) if page == None: page = Message_Page(self, msg) self.message_pages[msg] = page self.main_gui.show_page(page) def start_messageboard_cb(self, target): if not isinstance(target, Community): target = None if target == community.get_default_community(): target = None self.target = target msgboard.query_messages(target=self.target) subtitle = None if self.target != None: subtitle = target.get('name') self.set_page_title(subtitle, sub=True) self.main_gui.show_page(self) def update_message_list(self, metas): self.store = gtk.ListStore(gtk.gdk.Pixbuf, str, object) self.append_messages_to_store(self.store, metas) if not self.in_search_mode: self.message_view.set_model(self.store) def message_deleted_cb(self, meta): store = self.store if store == None: return for row in store: if row[2] == meta: store.remove(row.iter) def publish_message(self, sender, subject, msg, cname=None): d = {'from': sender, 'subject': subject, 'msg': msg, 'timestart': int(time()), } if cname != None: d['community'] = cname msgboard.publish(d) self.refresh_cb(None)
class User_Page(GUI_Page): def __init__(self, gui, community_gui, user): """User_Page class is for showing user's profile information defined in the Edit Profile dialog and for showing user's communities. update_user_page() have to be called after user's profile is changed or after user's communities are changed so that new values are loaded into GUI""" GUI_Page.__init__(self, user.get('nick')) self.main_gui = gui self.community_gui = community_gui self.user = user self.community = get_plugin_by_type(PLUGIN_TYPE_COMMUNITY) self.state_plugin = get_plugin_by_type(PLUGIN_TYPE_STATE) self.notebook = gtk.Notebook() self.notebook.set_show_tabs(True) self.notebook.set_show_border(False) self.initialize_profile_page() self.initialize_user_action_page() self.initialize_communities_page() self.pack_start(self.notebook) self.show_all() def get_user(self): return self.user def back_action(self): self.community_gui.user_pages.pop(self.user) self.main_gui.remove_page(self) self.destroy() return True def update_user_page(self): """ Function calls other functions to update user's profile, community, content and plugin pages. """ self.update_profile_widgets() self.set_page_title(self.user.get('nick')) def initialize_user_action_page(self): vbox = gtk.VBox() add_user_icon = gtk.gdk.pixbuf_new_from_file_at_size(join(get_dir(ICON_DIR), "64px-plus_icon.png"), ACTION_IMAGE_SIZE, ACTION_IMAGE_SIZE) remove_user_icon = gtk.gdk.pixbuf_new_from_file_at_size(join(get_dir(ICON_DIR), "64px-no_icon.png"), ACTION_IMAGE_SIZE, ACTION_IMAGE_SIZE) exchange_keys_icon = gtk.gdk.pixbuf_new_from_file_at_size(join(get_dir(ICON_DIR), "key.png"), ACTION_IMAGE_SIZE, ACTION_IMAGE_SIZE) refetch_icon = gtk.gdk.pixbuf_new_from_file_at_size(join(get_dir(ICON_DIR), "64px-edit_metadata_icon.png"), ACTION_IMAGE_SIZE, ACTION_IMAGE_SIZE) action_buttons = [(add_user_icon, 'Invite to\nCommunity', self.show_invite_dialog_cb), (refetch_icon, 'Refetch\nProfile', self.refetch_profile_cb), ] if self.state_plugin.options.personal_communities: action_buttons.insert(0, (add_user_icon, 'Add to\n Community', self.show_add_dialog_cb)) action_buttons.insert(1, (remove_user_icon, 'Remove from\nCommunity', self.show_remove_dialog_cb)) if self.state_plugin.options.key_exchange: action_buttons.insert(3, (exchange_keys_icon, 'Exchange\nKeys', self.show_exchange_keys_dialog_cb)) self.actions = Action_List() for action in action_buttons: (icon, text, cb) = action self.actions.add_button(icon, text, cb) vbox.pack_start(self.actions.get_widget()) self.announce_checkbox = gtk.CheckButton('Make an alarm when user appears') vbox.pack_start(self.announce_checkbox, False, False) self.announce_checkbox.set_active(self.user.get('friend')) self.announce_checkbox.connect('toggled', self.set_announce) self.notebook.append_page(vbox, gtk.Label('More actions')) def initialize_profile_page(self): profile_hbox = gtk.HBox() vbox = gtk.VBox() picture_hbox = gtk.HBox() self.profile_image = gtk.Image() self.profile_image.set_size_request(MAX_FACE_DIMENSION+10, MAX_FACE_DIMENSION+10) picture_hbox.pack_start(self.profile_image, False, True) self.status_label = gtk.Label() self.status_label.set_line_wrap(True) picture_hbox.pack_start(self.status_label) vbox.pack_start(picture_hbox) self.profile_info_label = gtk.Label() self.profile_info_label.set_alignment(0.1, 0.01) # 0.01 on purpose self.profile_info_label.set_line_wrap(True) vbox.pack_start(self.profile_info_label) profile_hbox.pack_start(vbox) self.user_action_list = User_Action_List(self.community_gui, self.get_user) profile_hbox.pack_start(self.user_action_list.action_view) swindow = new_scrollarea() swindow.set_border_width(0) swindow.add_with_viewport(profile_hbox) self.update_profile_widgets() self.notebook.append_page(swindow, gtk.Label('Profile')) def initialize_communities_page(self): vbox = gtk.VBox() self.list = Community_List(self.view_community) for com in self.community.get_user_communities(self.user): self.list.add_community(com) vbox.pack_start(self.list.get_widget()) self.notebook.append_page(vbox, gtk.Label('User communities')) def view_community(self, com): self.community_gui.show_com_page(com) def update_profile_widgets(self): """ Reads new profile information from user and updates profile page's widgets.""" image = get_user_profile_picture(self.user) if not self.user.present: image.saturate_and_pixelate(image, 0.0, True) self.profile_image.set_from_pixbuf(image) value = self.user.get('status') if value == None: value = '' self.status_label.set_text(value) self.profile_info_label.set_markup(self.construct_profile_info_str()) def construct_profile_info_str(self): def heading(s): # Returns a heading string s formatted with pango markup and # a new-line return '<span color="slategray" weight="bold" size="large">%s</span>\n' % pango_escape(s) def field(s): value = self.user.get(s) if value != None: return '<b>%s:</b> %s\n' % (field_descriptions[s], pango_escape(str(value))) else: return '' def join_list(l): out = [] for s in l: value = self.user.get(s) if value != None: out.append(pango_escape(str(value))) if len(out) > 0: return ', '.join(out) + '\n' else: return '' s = heading(self.user.get('nick')) s += field('name') s += join_list(('age', 'gender')) s += field('birth_date') s += join_list(('city', 'state', 'country')) s += field('phone_numbers') s += field('email') s += field('www') s += field('occupation') s += field('languages') s += field('description') s += heading('Last contact') l = [] for (t, location) in self.user.log(): ss = t if len(location) > 0: ss += '\n(at %s)' %(location) l.append(ss) if len(l) == 0: l = ['never'] s += pango_escape('\n'.join(l)) + '\n' if get_debug_mode(): s += heading('Debug information') s += field('uid') s += field('ip') s += field('port') s += field('hops') s += field('status_icon') s += field('v') s += field('faceversion') s += field('myfaceversion') return s def show_add_dialog_cb(self, widget): Add_To_Community_Dialog(self.main_gui, self.user) def show_invite_dialog_cb(self, widget): Invite_To_Community_Dialog(self.main_gui, self.user) def show_remove_dialog_cb(self, widget): Remove_From_Community_Dialog(self.main_gui, self.user) def show_exchange_keys_dialog_cb(self, widget): keymanagement = get_plugin_by_type(PLUGIN_TYPE_KEY_MANAGEMENT) keymanagement.show_exchange_keys_gui(self.user) def refetch_profile_cb(self, widget): self.user.force_profile_update() notification = get_plugin_by_type(PLUGIN_TYPE_NOTIFICATION) notification.notify('Reloading profile for %s' %(self.user.tag())) def set_announce(self, widget): self.user.set('friend', widget.get_active())
class Watches_GUI: # list store columns COL_ICON = 0 COL_NAME = 1 COL_TARGET = 2 def __init__(self, main_gui, getstatecb, modifycb): self.main_gui = main_gui self.modifycb = modifycb self.getstatecb = getstatecb self.guistate = 0 self.page = GUI_Page('Watches') # self.watch_list stores columns: possible picture, keyword, target self.watch_list = gtk.ListStore(gtk.gdk.Pixbuf, str, str) self.update() self.watch_view = gtk.TreeView(self.watch_list) self.pic_cell = gtk.CellRendererPixbuf() self.name_cell = gtk.CellRendererText() self.target_cell = gtk.CellRendererText() self.pic_column = self.watch_view.insert_column_with_attributes( self.COL_ICON, '', self.pic_cell, pixbuf=self.COL_ICON) self.name_column = self.watch_view.insert_column_with_attributes( self.COL_NAME, '', self.name_cell, text=self.COL_NAME) self.target_column = self.watch_view.insert_column_with_attributes( self.COL_TARGET, '', self.target_cell, text=self.COL_TARGET) self.page.pack_start(self.watch_view, True, True) add_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-add_content_icon.png")) remove_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-remove_content_icon.png")) action_buttons = [(add_icon, 'Add', self.add_clicked), (remove_icon, 'Remove', self.remove_clicked) ] self.actions = Action_List() for action in action_buttons: (icon, text, cb) = action self.actions.add_button(icon, text, cb) self.page.pack_start(self.actions.get_widget(), False, True) self.main_gui.add_page(self.page) def show(self): self.page.show_all() self.main_gui.show_page(self.page) def add_clicked(self, widget): if self.guistate != 0: return self.guistate = 1 Input_Dialog(self.main_gui.main_window, 'Add watch', 'Please give a keyword:', self.watch_added) def remove_clicked(self, widget): if self.guistate != 0: return selection = self.watch_view.get_selection() if selection == None: return model, selected = selection.get_selected() if selected != None: keyword = model[selected][1] self.modifycb(False, keyword) self.update() def update(self): self.watch_list.clear() for keyword in self.getstatecb(): self.watch_list.append([None, keyword, '']) def watch_added(self, keyword, ctx=None): self.guistate = 0 if keyword: self.modifycb(True, keyword) self.update()
class File_Sharing_Publish(GUI_Page): """ File_Sharing_Publish includes GUI window for adding shares. """ COL_SHAREMETA = 0 COL_SHAREPATH = 1 COL_TYPE = 2 COL_ICON = 3 COL_GUINAME = 4 COL_SIZE = 5 def __init__(self, fs_gui): GUI_Page.__init__(self, 'Publish content') self.fs_gui = fs_gui self.icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), \ "64px-publish_content_icon.png")) self.vbox = gtk.VBox() self.pack_start(self.vbox) self.folders = {} self.sharelist = gtk.TreeStore(gobject.TYPE_PYOBJECT, str, bool, gtk.gdk.Pixbuf, str, str) self.initialize_share_list() self.initialize_action_list() self.title = gtk.Label("Content Publishing") self.vbox.pack_start(self.title, False, False) scrollwin = new_scrollarea() scrollwin.add_with_viewport(self.sharelist_view) self.vbox.pack_start(scrollwin, True, True) self.show_all() main_gui.add_page(self) def initialize_share_list(self): self.sharelist_view = gtk.TreeView(self.sharelist) self.sharelist_view.set_headers_visible(False) column = gtk.TreeViewColumn('') self.sharelist_view.append_column(column) column.set_expand(True) cr_icon = gtk.CellRendererPixbuf() cr_guiname = gtk.CellRendererText() column.pack_start(cr_icon, False) column.pack_start(cr_guiname) column.add_attribute(cr_icon, 'pixbuf', self.COL_ICON) column.add_attribute(cr_guiname, 'text', self.COL_GUINAME) column = gtk.TreeViewColumn('') self.sharelist_view.append_column(column) cr_size = gtk.CellRendererText() column.pack_start(cr_size) column.add_attribute(cr_size, 'text', self.COL_SIZE) def initialize_action_list(self): add_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-add_content_icon.png")) remove_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-remove_content_icon.png")) open_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-publish_content_icon.png")) metadata_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-edit_metadata_icon.png")) action_buttons = [(add_icon, 'Publish\nFile', self.add_file_cb), (add_icon, 'Publish\nDirectory', self.add_dir_cb), (remove_icon, 'Remove', self.remove_cb), (open_icon, 'Open', self.open_cb), (metadata_icon, 'Edit\nMetadata', self.edit_metadata_cb) ] self.actions = Action_List() for action in action_buttons: (icon, text, cb) = action self.actions.add_button(icon, text, cb) self.pack_start(self.actions.get_widget(), False, True) def show_publish_window(self, target, is_community): if is_community: target_name = target.get('name') else: target_name = target.get('nick') self.sharelist_view.set_model(self.sharelist) self.sharelist_view.show_all() self.title.set_text('Share Content with %s' %(target_name)) self.update_sharelist() main_gui.show_page(self) def add_file_cb(self, widget): File_Chooser(main_gui.get_main_window(), FILE_CHOOSER_TYPE_FILE, True, self.add_file_chooser_cb) def add_file_chooser_cb(self, filenames, ctx): if filenames == None: return for f in filenames: if isfile(f): sharemeta = Share_Meta() sharemeta.set('description', basename(f)) filesharing.add_share(f, sharemeta=sharemeta, stype=SHARE_FILE) else: warning('Invalid filename from file chooser dialog\n') self.update_sharelist() def add_dir_cb(self, widget): File_Chooser(main_gui.get_main_window(), FILE_CHOOSER_TYPE_DIR, False, self.add_dir_chooser_cb) def add_dir_chooser_cb(self, dir_name, ctx): if dir_name == None: return if isdir(dir_name): sharemeta = Share_Meta() sharemeta.set('description', basename(dir_name)) filesharing.add_share(dir_name, sharemeta=sharemeta, stype=SHARE_DIR) else: warning('Invalid dirname from file chooser dialog\n') self.update_sharelist() def open_cb(self, widget): model, selected = self.sharelist_view.get_selection().get_selected_rows() if len(selected) == 0: notification.notify('No file selected!', highpri=True) return row = self.sharelist[selected[0]] meta = row[self.COL_SHAREMETA] sharepath = row[self.COL_SHAREPATH] guiname = row[self.COL_GUINAME] shareid = meta['id'] fullpath = filesharing.native_path(shareid, sharepath) if fullpath == None: warning('FileSharingGUI: Can not open shareid %d sharepath %s\n' %(shareid, sharepath)) return notification.notify('Opening content %s' %(guiname)) if not open_file(fullpath): notification.ok_dialog('Can not open file', 'Can not open file: %s\nUnknown format, or not supported.' %(fullpath)) def remove_cb(self, widget): model, selected = self.sharelist_view.get_selection().get_selected_rows() if len(selected) == 0: notification.notify('No share selected!', highpri=True) return row = self.sharelist[selected[0]] meta = row[self.COL_SHAREMETA] shareid = meta['id'] filesharing.remove_share(filesharing.get_share(shareid)) self.update_sharelist() def edit_metadata_cb(self, widget): model, selected = self.sharelist_view.get_selection().get_selected_rows() if len(selected) == 0: notification.notify('No share selected!', highpri=True) return row = self.sharelist[selected[0]] meta = row[self.COL_SHAREMETA] sharepath = row[self.COL_SHAREPATH] guiname = row[self.COL_GUINAME] shareid = meta['id'] Edit_Metadata_Dialog(main_gui.get_main_window(), shareid, guiname, sharepath, self) def update_sharelist(self): self.sharelist.clear() self.folders = {} for (shareid, share) in filesharing.shares.items(): for (sharepath, ftype) in share.list_recursively().items(): size = '' if ftype == FTYPE_FILE: nativepath = share.native_path(sharepath) size = format_bytes(filesize(nativepath)) self.add_item(share.meta, shareid, sharepath, size, ftype == FTYPE_DIRECTORY) def add_item(self, meta, shareid, sharepath, fsize, directory): key = (shareid, sharepath) riter = self.folders.get(key) if riter != None: return riter if sharepath != '/' and meta.get('type') == SHARE_DIR: parent_path = dirname(sharepath) parent = self.add_item(meta, shareid, parent_path, '', True) else: parent = None guiname = basename(sharepath) if directory: filetype = 'folder' if guiname == '' and meta.get('description'): guiname = meta.get('description') guiname += '/' else: filetype = get_filetype(sharepath) guiname = cut_text(guiname, MAX_GUI_NAME) ft_icon = get_filetype_icon(filetype) riter = self.sharelist.append(parent, [meta, sharepath, directory, ft_icon, guiname, fsize]) if directory: self.folders[key] = riter return riter
class File_Sharing_Browse(GUI_Page): """ File_Sharing_Browse includes GUI window for browsing user's file shares. """ COL_SHAREMETA = 0 COL_SHAREPATH = 1 COL_USER = 2 COL_TYPE = 3 COL_ICON = 4 COL_GUINAME = 5 COL_NICK = 6 COL_SIZE = 7 COL_COLOR = 8 # internal attribute: depends on hop count COL_HOPS = 9 # colors for different hopcounts: 0 = 1 = foreground color, 2 = yellow, 3 or more = red HOP_COLORS = [None, None, "yellow", "red"] def __init__(self, fs_gui, title): GUI_Page.__init__(self, title) self.fs_gui = fs_gui self.target = None self.is_community = False self.items = 0 self.vbox = gtk.VBox() self.pack_start(self.vbox) self.folders = {} self.content_list = gtk.TreeStore(gobject.TYPE_PYOBJECT, str, gobject.TYPE_PYOBJECT, bool, gtk.gdk.Pixbuf, str, str, str, str, int) self.content_list.set_sort_column_id(self.COL_HOPS, gtk.SORT_ASCENDING) self.initialize_browse_list() self.initialize_action_list() self.title = gtk.Label("Content Browsing") self.vbox.pack_start(self.title, False, False) scrollwin = new_scrollarea() scrollwin.add_with_viewport(self.browse_list_view) self.vbox.pack_start(scrollwin, True, True) self.show_all() main_gui.add_page(self) def back_action(self): if self == self.fs_gui.fs_results: return False key = (self.target, self.is_community) self.fs_gui.browse_pages.pop(key) main_gui.remove_page(self) self.destroy() return True def initialize_browse_list(self): self.browse_list_view = gtk.TreeView(self.content_list) # self.browse_list_view.get_selection().set_mode(gtk.SELECTION_MULTIPLE) self.browse_list_view.set_headers_visible(False) column = gtk.TreeViewColumn('') self.browse_list_view.append_column(column) column.set_expand(True) cr_icon = gtk.CellRendererPixbuf() cr_guiname = gtk.CellRendererText() column.pack_start(cr_icon, False) column.pack_start(cr_guiname) column.add_attribute(cr_icon, 'pixbuf', self.COL_ICON) column.add_attribute(cr_guiname, 'text', self.COL_GUINAME) column.add_attribute(cr_guiname, 'foreground', self.COL_COLOR) column = gtk.TreeViewColumn('') self.browse_list_view.append_column(column) cr_nick = gtk.CellRendererText() column.pack_start(cr_nick) column.add_attribute(cr_nick, 'text', self.COL_NICK) column = gtk.TreeViewColumn('') self.browse_list_view.append_column(column) cr_size = gtk.CellRendererText() column.pack_start(cr_size) column.add_attribute(cr_size, 'text', self.COL_SIZE) def initialize_action_list(self): download_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-browse_content_icon.png")) open_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-publish_content_icon.png")) metadata_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-edit_metadata_icon.png")) search_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-search_content_icon.png")) action_buttons = [(download_icon, 'Download', self.download_cb), (open_icon, 'Stream', self.stream_cb), (metadata_icon, 'Show\nMetadata', self.show_metadata_cb), (search_icon, 'Search\nFrom User', self.show_search_cb), (search_icon, 'Refresh', self.refresh_cb) ] self.actions = Action_List() for action in action_buttons: (icon, text, cb) = action self.actions.add_button(icon, text, cb) self.pack_start(self.actions.get_widget(), False, True) def download_cb(self, widget): model, selected = self.browse_list_view.get_selection().get_selected_rows() if len(selected) == 0: notification.notify('No file selected!', highpri=True) return row = self.content_list[selected[0]] meta = row[self.COL_SHAREMETA] user = row[self.COL_USER] sharepath = row[self.COL_SHAREPATH] guiname = row[self.COL_GUINAME] directory = row[self.COL_TYPE] if directory: what = 'directory' else: what = 'file' ctx = (user, meta['id'], sharepath, directory, meta) Download_Dialog(main_gui.get_main_window(), 'Download a %s' % what, 'Downloading a %s from %s: %s' % (what, user.tag(), guiname), self.download_dialog_cb, ctx) def download_dialog_cb(self, accept, open_content, ctx): if not accept: return (user, shareid, sharepath, directory, meta) = ctx name = basename(sharepath) if directory and name == '' and meta.get('description'): name = meta.get('description') destname = filesharing.get_download_path(name) if directory: ctx = (sharepath, destname, name) if not filesharing.query(user, self.download_results, ctx, shareid=shareid, sharepath=sharepath): notification.notify('Unable to list directory contents from %s' % user.tag(), True) return notification.notify('Trying to download from %s' % user.tag()) ctx = (user, destname, sharepath, open_content) if not filesharing.get_files(user, basename(sharepath), [(shareid, sharepath, destname)], download_complete, ctx): notification.ok_dialog('File sharing', 'Unable to download a file from %s: %s' % (user.tag(), name)) def download_results(self, user, allresults, metadict, ctx): (rootpath, destpath, name) = ctx if allresults == None: notification.notify('Unable to list directory contents from %s' % user.tag(), True) return files = [] totallen = 0 for (shareid, sharepath, fsize, ftype) in allresults: # NOTE: The sharepath should begin with rootpath i = len(rootpath) while i < len(sharepath): if sharepath[i] != '/': break i += 1 destname = join(destpath, sharepath[i:]) files.append((shareid, sharepath, destname)) totallen += fsize if not filesharing.get_files(user, name + '/', files, None, totallen=totallen): notification.ok_dialog('File sharing', 'Unable to download a directory from %s: %s' % (user.tag(), name)) def show_metadata_cb(self, widget): model, selected = self.browse_list_view.get_selection().get_selected_rows() if len(selected) == 0: notification.notify('No file selected!', highpri=True) return row = self.content_list[selected[0]] meta = row[self.COL_SHAREMETA] user = row[self.COL_USER] sharepath = row[self.COL_SHAREPATH] guiname = row[self.COL_GUINAME] shareid = meta['id'] ctx = (user, guiname) filesharing.get_metas(user, [(shareid, sharepath)], self.got_metadata_for_file, ctx) filesharing.progress_update('Getting metadata for content...') def got_metadata_for_file(self, metas, ctx): (user, guiname) = ctx filesharing.progress_update(None) if len(metas) == 0: msg = 'No metadata for file: %s' %(guiname) notification.ok_dialog('Filesharing', msg) return if len(metas) != 1: debug('FileSharing: Found too many metadatas for file\n') return (shareid, fname, meta) = metas[0] Show_Metadata_Dialog(main_gui.get_main_window(), guiname, meta) def show_browse_window(self, target, is_community, criteria=None, keywords=None): if is_community: target_name = target.get('name') else: target_name = target.get('nick') self.is_community = is_community self.target = target self.criteria = criteria self.keywords = keywords self.set_page_title(target_name, sub=True) main_gui.show_page(self) self.update_content_list() def show_search_cb(self, widget): model, selected = self.browse_list_view.get_selection().get_selected_rows() if len(selected) == 0: notification.notify('No file selected!', highpri=True) return row = self.content_list[selected[0]] user = row[self.COL_USER] self.fs_gui.fs_search.show_file_sharing_search(user, False) def stream_cb(self, widget): model, selected = self.browse_list_view.get_selection().get_selected_rows() if len(selected) == 0: notification.notify('No file selected!', highpri=True) return row = self.content_list[selected[0]] meta = row[self.COL_SHAREMETA] user = row[self.COL_USER] sharepath = row[self.COL_SHAREPATH] filesharing.stream(user, meta['id'], sharepath) notification.notify('Trying to stream from %s' % user.tag()) def update_content_list(self): self.content_list.clear() self.folders = {} self.items = 0 self.title.set_text('No content found') if not self.is_community: if self.target == community.get_myself(): # do not fetch own shares return if not filesharing.query(self.target, self.query_results, criteria=self.criteria, keywords=self.keywords): notification.notify('Unable to query shares from %s' % self.target.tag(), True) else: # Community filesharing.query_community(self.target, self.query_results, criteria=self.criteria, keywords=self.keywords) def refresh_cb(self, widget): self.update_content_list() def query_results(self, user, allresults, metadict, ctx): if allresults == None: notification.notify('Unable to query shares from %s' % user.tag(), True) return for (shareid, sharepath, fsize, ftype) in allresults: meta = metadict[shareid] size = '' if ftype == FTYPE_FILE: size = format_bytes(fsize) self.add_item(meta, user, shareid, sharepath, size, ftype == FTYPE_DIRECTORY) self.items += 1 self.title.set_text('Showing %d items' % self.items) def add_item(self, meta, user, shareid, sharepath, fsize, directory): key = (user, shareid, sharepath) riter = self.folders.get(key) if riter != None: return riter if sharepath != '/' and meta.get('type') == SHARE_DIR: parent_path = dirname(sharepath) parent = self.add_item(meta, user, shareid, parent_path, '', True) else: parent = None guiname = basename(sharepath) if directory: filetype = 'folder' if guiname == '' and meta.get('description'): guiname = meta.get('description') guiname += '/' else: filetype = get_filetype(sharepath) guiname = cut_text(guiname, MAX_GUI_NAME) ft_icon = get_filetype_icon(filetype) nick = user.get('nick') hops = user.get('hops') if hops == None: hops = 0 if hops < 4: color = self.HOP_COLORS[hops] else: color = self.HOP_COLORS[3] riter = self.content_list.append(parent, [meta, sharepath, user, directory, ft_icon, guiname, nick, fsize, color, hops]) if directory: self.folders[key] = riter return riter
class File_Sharing_Search(GUI_Page): """ File_Sharing_Search includes GUI window for searching user's files. The window is in two parts, first the search window is shown and after search is clicked the gui moves to the next window which shows the search results. Currently one limitation: multiple search windows can not be open at the same time. If a new window is opened the old one is replaced with the new one.""" def __init__(self, fs_gui): GUI_Page.__init__(self, 'Search content') self.fs_gui = fs_gui self.target = None self.is_community = False self.vbox = gtk.VBox() self.pack_start(self.vbox) self.entries = {} self.initialize_search_window() self.initialize_action_list() self.title = gtk.Label('Search Content') self.vbox.pack_start(self.title, False, False) self.vbox.pack_start(gtk.HSeparator(), False, False) self.vbox.pack_start(self.search_fwindow, True, True) self.show_all() main_gui.add_page(self) def initialize_search_window(self): self.search_fwindow = new_scrollarea() self.search_vbox = gtk.VBox() self.search_fwindow.add_with_viewport(self.search_vbox) entrylist = [('keywords', 'Keywords:'), \ ('fname', 'Filename:'), \ ('title', 'Title:'), \ ('author', 'Author:'), \ ('description', 'Description:')] for (key, header) in entrylist: hbox = gtk.HBox() label = gtk.Label(header) label.set_size_request(130, -1) label.set_alignment(0, 0) hbox.pack_start(label, False, False) entry = gtk.Entry() self.entries[key] = entry entry.connect("activate", self.search_cb) hbox.pack_start(entry, True, True) self.search_vbox.pack_start(hbox, False, False) def initialize_action_list(self): search_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-search_content_icon.png")) remove_icon = gtk.gdk.pixbuf_new_from_file(join(get_dir(ICON_DIR), "64px-remove_content_icon.png")) action_buttons = [(search_icon, 'Search', self.search_cb), (remove_icon, 'Clear', self.clear_cb) ] self.actions = Action_List() for action in action_buttons: (icon, text, cb) = action self.actions.add_button(icon, text, cb) self.pack_start(self.actions.get_widget(), False, True) def clear_cb(self, widget): for (key, entry) in self.entries.items(): entry.set_text('') self.entries['keywords'].grab_focus() def search_cb(self, widget): query = {} for (key, entry) in self.entries.items(): query[key] = entry.get_text() keywords = None criteria = [] text = self.entries['keywords'].get_text().strip() if text != '': keywords = split_keywords(text) if len(keywords) == 0: keywords = None for field in ['fname', 'title', 'author', 'description']: text = self.entries[field].get_text().strip() if text != '': criteria.append((field, text)) if len(criteria) == 0: criteria = None self.fs_gui.fs_results.show_browse_window(self.target, self.is_community, criteria=criteria, keywords=keywords) def show_file_sharing_search(self, target, is_community): """ Opens the whole file sharing window.""" if is_community: target_name = target.get('name') else: target_name = target.get('nick') self.is_community = is_community self.target = target self.title.set_text('Search content from: %s' % target_name) self.entries['keywords'].set_property("can-focus", True) self.set_page_title(target_name, sub=True) main_gui.show_page(self) self.entries['keywords'].grab_focus()