class HomePage(Gtk.Box): icon_name = 'home-symbolic' disname = _('Home') tooltip = _('Show all of your files on Cloud') first_run = False page_num = 1 path = '/' has_next = True def __init__(self, app): super().__init__(orientation=Gtk.Orientation.VERTICAL) self.app = app # set drop action targets = [['text/plain', Gtk.TargetFlags.OTHER_APP, 0], ['*.*', Gtk.TargetFlags.OTHER_APP, 1]] target_list = [Gtk.TargetEntry.new(*t) for t in targets] self.drag_dest_set(Gtk.DestDefaults.ALL, target_list, Gdk.DragAction.COPY) nav_bar = Gtk.Toolbar() nav_bar.get_style_context().add_class(Gtk.STYLE_CLASS_MENUBAR) nav_bar.props.show_arrow = False nav_bar.props.toolbar_style = Gtk.ToolbarStyle.ICONS nav_bar.props.icon_size = Gtk.IconSize.LARGE_TOOLBAR self.pack_start(nav_bar, False, False, 0) nav_bar.props.valign = Gtk.Align.START path_item = Gtk.ToolItem() nav_bar.insert(path_item, 0) nav_bar.child_set_property(path_item, 'expand', True) path_item.props.valign = Gtk.Align.START path_win = Gtk.ScrolledWindow() path_item.add(path_win) path_win.props.valign = Gtk.Align.START path_win.props.vscrollbar_policy = Gtk.PolicyType.NEVER path_viewport = Gtk.Viewport() path_viewport.props.valign = Gtk.Align.START path_win.add(path_viewport) self.path_box = PathBox(self) self.path_box.props.valign = Gtk.Align.START path_viewport.add(self.path_box) # show loading process loading_button = Gtk.ToolItem() nav_bar.insert(loading_button, 1) loading_button.props.margin_right = 10 self.loading_spin = Gtk.Spinner() loading_button.add(self.loading_spin) self.loading_spin.props.valign = Gtk.Align.CENTER # search button search_button = Gtk.ToggleToolButton() search_button.set_label(_('Search')) search_button.set_icon_name('search-symbolic') search_button.set_tooltip_text( _('Search documents and folders by name')) search_button.connect('toggled', self.on_search_button_toggled) nav_bar.insert(search_button, 2) search_button.props.valign = Gtk.Align.START search_button.props.margin_right = 10 # toggle view mode list_view_button = Gtk.ToolButton() list_view_button.set_label(_('ListView')) list_view_button.set_icon_name('list-view-symbolic') list_view_button.connect('clicked', self.on_list_view_button_clicked) nav_bar.insert(list_view_button, 3) list_view_button.props.valign = Gtk.Align.START grid_view_button = Gtk.ToolButton() grid_view_button.set_label(_('ListView')) grid_view_button.set_icon_name('grid-view-symbolic') grid_view_button.connect('clicked', self.on_grid_view_button_clicked) nav_bar.insert(grid_view_button, 4) grid_view_button.props.valign = Gtk.Align.START # serch entry if Config.GTK_LE_36: self.search_entry = Gtk.Entry() self.search_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.PRIMARY, 'folder-saved-search-symbolic') else: self.search_entry = Gtk.SearchEntry() self.search_entry.props.no_show_all = True self.search_entry.props.visible = False self.search_entry.connect('activate', self.on_search_entry_activated) self.pack_start(self.search_entry, False, False, 0) self.icon_window = IconWindow(self, app) self.pack_end(self.icon_window, True, True, 0) def do_drag_data_received(self, drag_context, x, y, data, info, time): uris = data.get_text() source_paths = util.uris_to_paths(uris) if source_paths and self.app.profile: self.app.upload_page.add_file_tasks(source_paths, self.path) # Open API def load(self, path='/'): self.path = path self.page_num = 1 self.has_next = True self.path_box.set_path(path) self.loading_spin.start() self.loading_spin.show_all() gutil.async_call(pcs.list_dir, self.app.cookie, self.app.tokens, self.path, self.page_num, callback=self.on_load) gutil.async_call(pcs.get_quota, self.app.cookie, self.app.tokens, callback=self.app.update_quota) def on_load(self, info, error=None): self.loading_spin.stop() self.loading_spin.hide() if error or not info or info['errno'] != 0: return self.icon_window.load(info['list']) def load_next(self): '''载入下一页''' def on_load_next(info, error=None): self.loading_spin.stop() self.loading_spin.hide() if error or not info or info['errno'] != 0: return if info['list']: self.icon_window.load_next(info['list']) else: self.has_next = False if not self.has_next: return self.page_num = self.page_num + 1 self.path_box.set_path(self.path) self.loading_spin.start() self.loading_spin.show_all() gutil.async_call(pcs.list_dir, self.app.cookie, self.app.tokens, self.path, self.page_num, callback=on_load_next) def reload(self, *args, **kwds): '''重新载入本页面''' self.load(self.path) def on_search_button_toggled(self, search_button): status = search_button.get_active() self.search_entry.props.visible = status if status: self.search_entry.grab_focus() else: self.reload() def on_list_view_button_clicked(self, button): if not isinstance(self.icon_window, TreeWindow): self.remove(self.icon_window) self.icon_window = TreeWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.reload() def on_grid_view_button_clicked(self, button): if isinstance(self.icon_window, TreeWindow): self.remove(self.icon_window) self.icon_window = IconWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.reload() def on_search_entry_activated(self, search_entry): text = search_entry.get_text() if not text: return self.loading_spin.start() self.loading_spin.show_all() gutil.async_call(pcs.search, self.app.cookie, self.app.tokens, text, self.path, callback=self.on_load)
class CategoryPage(Gtk.Box): page_num = 1 has_next = True first_run = True name = 'CategoryPage' def __init__(self, app): super().__init__(orientation=Gtk.Orientation.VERTICAL) self.app = app if Config.GTK_GE_312: self.headerbar = Gtk.HeaderBar() self.headerbar.props.show_close_button = True self.headerbar.props.has_subtitle = False self.headerbar.set_title(self.disname) # right box right_box = Gtk.Box() right_box_context = right_box.get_style_context() right_box_context.add_class(Gtk.STYLE_CLASS_RAISED) right_box_context.add_class(Gtk.STYLE_CLASS_LINKED) self.headerbar.pack_end(right_box) # toggle view mode list_view_button = Gtk.RadioButton() list_view_button.set_mode(False) list_view_img = Gtk.Image.new_from_icon_name('view-list-symbolic', Gtk.IconSize.SMALL_TOOLBAR) list_view_button.set_image(list_view_img) right_box.pack_start(list_view_button, False, False, 0) grid_view_button = Gtk.RadioButton() grid_view_button.set_mode(False) grid_view_button.join_group(list_view_button) grid_view_button.set_active( self.app.profile['view-mode'][self.name] == const.ICON_VIEW) grid_view_img = Gtk.Image.new_from_icon_name('view-grid-symbolic', Gtk.IconSize.SMALL_TOOLBAR) grid_view_button.set_image(grid_view_img) list_view_button.connect('clicked', self.on_list_view_button_clicked) grid_view_button.connect('clicked', self.on_grid_view_button_clicked) right_box.pack_start(grid_view_button, False, False, 0) # reload button reload_button = Gtk.Button() reload_img = Gtk.Image.new_from_icon_name('view-refresh-symbolic', Gtk.IconSize.SMALL_TOOLBAR) reload_button.set_image(reload_img) reload_button.set_tooltip_text(_('Reload (F5)')) reload_button.connect('clicked', self.reload) self.headerbar.pack_end(reload_button) # show loading process self.loading_spin = Gtk.Spinner() self.loading_spin.props.valign = Gtk.Align.CENTER self.headerbar.pack_end(self.loading_spin) else: nav_bar = Gtk.Box() nav_bar_context = nav_bar.get_style_context() nav_bar_context.add_class(Gtk.STYLE_CLASS_RAISED) nav_bar_context.add_class(Gtk.STYLE_CLASS_LINKED) nav_bar.props.halign = Gtk.Align.END self.pack_start(nav_bar, False, False, 0) # show loading process self.loading_spin = Gtk.Spinner() self.loading_spin.props.valign = Gtk.Align.CENTER nav_bar.pack_start(self.loading_spin, False, False, 0) # toggle view mode list_view_button = Gtk.RadioButton() list_view_button.set_mode(False) list_view_img = Gtk.Image.new_from_icon_name('view-list-symbolic', Gtk.IconSize.SMALL_TOOLBAR) list_view_button.set_image(list_view_img) nav_bar.pack_start(list_view_button, False, False, 0) grid_view_button = Gtk.RadioButton() grid_view_button.props.margin_right = 10 grid_view_button.set_mode(False) grid_view_button.join_group(list_view_button) grid_view_button.set_active( self.app.profile['view-mode'][self.name] == const.ICON_VIEW) grid_view_img = Gtk.Image.new_from_icon_name('view-grid-symbolic', Gtk.IconSize.SMALL_TOOLBAR) grid_view_button.set_image(grid_view_img) list_view_button.connect('clicked', self.on_list_view_button_clicked) grid_view_button.connect('clicked', self.on_grid_view_button_clicked) nav_bar.pack_start(grid_view_button, False, False, 0) def on_page_show(self): if Config.GTK_GE_312: self.app.window.set_titlebar(self.headerbar) self.headerbar.show_all() def check_first(self): if self.first_run: self.first_run = False if self.app.profile['view-mode'][self.name] == const.ICON_VIEW: self.icon_window = IconWindow(self, self.app) else: self.icon_window = TreeWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.load() def load(self): def on_load(info, error=None): self.loading_spin.stop() self.loading_spin.hide() if not info: self.app.toast(_('Network error')) elif info.get('errno', -1) != 0: self.app.toast(info.get('error_msg', _('Network error'))) if error or not info or info.get('errno', -1) != 0: logger.error('%s.on_load: %s, %s' % (self.disname, info, error)) return self.icon_window.load(info['info']) has_next = True self.page_num = 1 self.loading_spin.start() self.loading_spin.show_all() gutil.async_call(pcs.get_category, self.app.cookie, self.app.tokens, self.category, self.page_num, callback=on_load) def load_next(self): def on_load_next(info, error=None): self.loading_spin.stop() self.loading_spin.hide() if not info: self.app.toast(_('Network error')) elif info.get('errno', -1) != 0: self.app.toast(info.get('error_msg', _('Network error'))) if error or not info or info['errno'] != 0: logger.error('%s.on_load_next: %s, %s' % (self.disname, info, error)) return if info['info']: self.icon_window.load_next(info['info']) else: self.has_next = False if not self.has_next: return self.loading_spin.start() self.loading_spin.show_all() self.page_num = self.page_num + 1 gutil.async_call(pcs.get_category, self.app.cookie, self.app.tokens, self.category, self.page_num, callback=on_load_next) def reload(self, *args): self.load() def on_list_view_button_clicked(self, button): if not isinstance(self.icon_window, TreeWindow): self.remove(self.icon_window) self.icon_window = TreeWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.app.profile['view-mode'][self.name] = const.TREE_VIEW gutil.dump_profile(self.app.profile) self.reload() def on_grid_view_button_clicked(self, button): if isinstance(self.icon_window, TreeWindow): self.remove(self.icon_window) self.icon_window = IconWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.app.profile['view-mode'][self.name] = const.ICON_VIEW gutil.dump_profile(self.app.profile) self.reload()
class HomePage(Gtk.Box): icon_name = 'home-symbolic' disname = _('Home') name = 'HomePage' tooltip = _('List all of your files') first_run = False page_num = 1 path = '/' has_next = True def __init__(self, app): super().__init__(orientation=Gtk.Orientation.VERTICAL) self.app = app # set drop action targets = [ ['text/plain', Gtk.TargetFlags.OTHER_APP, 0], ['*.*', Gtk.TargetFlags.OTHER_APP, 1] ] target_list = [Gtk.TargetEntry.new(*t) for t in targets] self.drag_dest_set(Gtk.DestDefaults.ALL, target_list, Gdk.DragAction.COPY) if Config.GTK_GE_312: self.headerbar = Gtk.HeaderBar() self.headerbar.props.show_close_button = True self.headerbar.props.has_subtitle = False path_win = Gtk.ScrolledWindow() self.headerbar.pack_start(path_win) # FIXME: add arrows in both sides path_win.props.hscrollbar_policy = Gtk.PolicyType.NEVER path_win.props.vscrollbar_policy = Gtk.PolicyType.NEVER path_viewport = Gtk.Viewport() path_win.add(path_viewport) self.path_box = PathBox(self) path_viewport.add(self.path_box) # right box right_box = Gtk.Box() right_box_context = right_box.get_style_context() right_box_context.add_class(Gtk.STYLE_CLASS_RAISED) right_box_context.add_class(Gtk.STYLE_CLASS_LINKED) self.headerbar.pack_end(right_box) # toggle view mode list_view_button = Gtk.RadioButton() list_view_button.set_mode(False) list_view_img = Gtk.Image.new_from_icon_name('list-view-symbolic', Gtk.IconSize.SMALL_TOOLBAR) list_view_button.set_image(list_view_img) right_box.pack_start(list_view_button, False, False, 0) grid_view_button = Gtk.RadioButton() grid_view_button.set_mode(False) grid_view_button.join_group(list_view_button) grid_view_button.set_active( self.app.profile['view-mode'][self.name] == const.ICON_VIEW) grid_view_img = Gtk.Image.new_from_icon_name('grid-view-symbolic', Gtk.IconSize.SMALL_TOOLBAR) grid_view_button.set_image(grid_view_img) list_view_button.connect('clicked', self.on_list_view_button_clicked) grid_view_button.connect('clicked', self.on_grid_view_button_clicked) right_box.pack_start(grid_view_button, False, False, 0) # reload button reload_button = Gtk.Button() reload_img = Gtk.Image.new_from_icon_name('view-refresh-symbolic', Gtk.IconSize.SMALL_TOOLBAR) reload_button.set_image(reload_img) reload_button.set_tooltip_text(_('Reload')) reload_button.connect('clicked', self.reload) self.headerbar.pack_end(reload_button) # search button search_button = Gtk.ToggleButton() search_img = Gtk.Image.new_from_icon_name('search-symbolic', Gtk.IconSize.SMALL_TOOLBAR) search_button.set_image(search_img) search_button.set_tooltip_text( _('Search documents and folders by name')) search_button.connect('toggled', self.on_search_button_toggled) self.headerbar.pack_end(search_button) # show loading process self.loading_spin = Gtk.Spinner() self.loading_spin.props.valign = Gtk.Align.CENTER self.headerbar.pack_end(self.loading_spin) self.search_entry = Gtk.SearchEntry() self.search_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.PRIMARY, 'folder-saved-search-symbolic') self.search_entry.props.no_show_all = True self.search_entry.props.visible = False self.search_entry.connect('activate', self.on_search_entry_activated) self.pack_start(self.search_entry, False, False, 0) else: nav_bar = Gtk.Box(spacing=5) self.pack_start(nav_bar, False, False, 0) path_win = Gtk.ScrolledWindow() nav_bar.pack_start(path_win, True, True, 0) path_win.props.hscrollbar_policy = Gtk.PolicyType.NEVER path_win.props.vscrollbar_policy = Gtk.PolicyType.NEVER path_viewport = Gtk.Viewport() path_win.add(path_viewport) self.path_box = PathBox(self) path_viewport.add(self.path_box) # show loading process self.loading_spin = Gtk.Spinner() self.loading_spin.props.valign = Gtk.Align.CENTER nav_bar.pack_start(self.loading_spin, False, False, 0) # search button search_button = Gtk.ToggleButton() search_img = Gtk.Image.new_from_icon_name('search-symbolic', Gtk.IconSize.SMALL_TOOLBAR) search_button.set_image(search_img) search_button.set_tooltip_text( _('Search documents and folders by name')) search_button.connect('toggled', self.on_search_button_toggled) nav_bar.pack_start(search_button, False, False, 0) # right box right_box = Gtk.Box() right_box_context = right_box.get_style_context() right_box_context.add_class(Gtk.STYLE_CLASS_RAISED) right_box_context.add_class(Gtk.STYLE_CLASS_LINKED) nav_bar.pack_start(right_box, False, False, 0) # toggle view mode list_view_button = Gtk.RadioButton() list_view_button.set_mode(False) list_view_img = Gtk.Image.new_from_icon_name('list-view-symbolic', Gtk.IconSize.SMALL_TOOLBAR) list_view_button.set_image(list_view_img) right_box.pack_start(list_view_button, False, False, 0) grid_view_button = Gtk.RadioButton() grid_view_button.set_mode(False) grid_view_button.join_group(list_view_button) grid_view_button.set_active( self.app.profile['view-mode'][self.name] == const.ICON_VIEW) grid_view_img = Gtk.Image.new_from_icon_name('grid-view-symbolic', Gtk.IconSize.SMALL_TOOLBAR) grid_view_button.set_image(grid_view_img) list_view_button.connect('clicked', self.on_list_view_button_clicked) grid_view_button.connect('clicked', self.on_grid_view_button_clicked) right_box.pack_start(grid_view_button, False, False, 0) self.search_entry = Gtk.Entry() self.search_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.PRIMARY, 'folder-saved-search-symbolic') self.search_entry.props.no_show_all = True self.search_entry.props.visible = False self.search_entry.connect('activate', self.on_search_entry_activated) self.pack_start(self.search_entry, False, False, 0) def on_page_show(self): if Config.GTK_GE_312: self.app.window.set_titlebar(self.headerbar) self.headerbar.show_all() def check_first(self): if self.first_run: self.first_run = False if self.app.profile['view-mode'][self.name] == const.ICON_VIEW: self.icon_window = IconWindow(self, self.app) else: self.icon_window = TreeWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.load(is_user=True) # Open API def load(self, path='/', is_user=False): self.path = path self.page_num = 1 self.has_next = True self.path_box.set_path(path, is_user) self.loading_spin.start() self.loading_spin.show_all() gutil.async_call(pcs.list_dir, self.app.cookie, self.app.tokens, self.path, self.page_num, callback=self.on_load) gutil.async_call(pcs.get_quota, self.app.cookie, self.app.tokens, callback=self.app.update_quota) def on_load(self, info, error=None): self.loading_spin.stop() self.loading_spin.hide() if not info: self.app.toast(_('Network error')) elif info.get('errno', -1) != 0: self.app.toast(info.get('error_msg', _('Network error'))) if error or not info or info.get('errno', -1) != 0: logger.error('HomePage.on_load: %s, %s' % (info, error)) return self.icon_window.load(info['list']) def load_next(self): '''载入下一页''' def on_load_next(info, error=None): self.loading_spin.stop() self.loading_spin.hide() if not info: self.app.toast(_('Network error')) elif info.get('errno', -1) != 0: self.app.toast(info.get('error_msg', _('Network error'))) if error or not info or info.get('errno', -1) != 0: logger.error('HomePage.load_next: %s, %s' % (info, error)) return if info['list']: self.icon_window.load_next(info['list']) else: self.has_next = False if not self.has_next: return self.page_num = self.page_num + 1 self.path_box.set_path(self.path) self.loading_spin.start() self.loading_spin.show_all() gutil.async_call(pcs.list_dir, self.app.cookie, self.app.tokens, self.path, self.page_num, callback=on_load_next) def reload(self, *args, **kwds): '''重新载入本页面''' self.load(self.path) def do_drag_data_received(self, drag_context, x, y, data, info, time): '''从其它程序拖放目录/文件, 以便上传''' uris = data.get_text() source_paths = util.uris_to_paths(uris) if source_paths and self.app.profile: self.app.upload_page.add_file_tasks(source_paths, self.path) def on_search_button_toggled(self, search_button): status = search_button.get_active() self.search_entry.props.visible = status if status: self.search_entry.grab_focus() else: self.reload() def on_list_view_button_clicked(self, list_view_button): if not isinstance(self.icon_window, TreeWindow): self.remove(self.icon_window) self.icon_window = TreeWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.app.profile['view-mode'][self.name] = const.TREE_VIEW gutil.dump_profile(self.app.profile) self.reload() def on_grid_view_button_clicked(self, grid_view_button): if isinstance(self.icon_window, TreeWindow): self.remove(self.icon_window) self.icon_window = IconWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.app.profile['view-mode'][self.name] = const.ICON_VIEW gutil.dump_profile(self.app.profile) self.reload() def on_search_entry_activated(self, search_entry): text = search_entry.get_text() if not text: return self.loading_spin.start() self.loading_spin.show_all() gutil.async_call(pcs.search, self.app.cookie, self.app.tokens, text, self.path, callback=self.on_load)
class HomePage(Gtk.Box): icon_name = 'user-home-symbolic' disname = _('Home') name = 'HomePage' tooltip = _('List all of your files') first_run = False page_num = 1 path = '/' has_next = True def __init__(self, app): super().__init__(orientation=Gtk.Orientation.VERTICAL) self.app = app self.drag_dest_set(Gtk.DestDefaults.ALL, DROP_TARGET_LIST, Gdk.DragAction.COPY) if Config.GTK_GE_312: self.headerbar = Gtk.HeaderBar() self.headerbar.props.show_close_button = True self.headerbar.props.has_subtitle = False path_win = Gtk.ScrolledWindow() self.headerbar.pack_start(path_win) # FIXME: add arrows in both sides path_win.props.hscrollbar_policy = Gtk.PolicyType.NEVER path_win.props.vscrollbar_policy = Gtk.PolicyType.NEVER path_viewport = Gtk.Viewport() path_win.add(path_viewport) self.path_box = PathBox(self) path_viewport.add(self.path_box) # right box right_box = Gtk.Box() right_box_context = right_box.get_style_context() right_box_context.add_class(Gtk.STYLE_CLASS_RAISED) right_box_context.add_class(Gtk.STYLE_CLASS_LINKED) self.headerbar.pack_end(right_box) # toggle view mode list_view_button = Gtk.RadioButton() list_view_button.set_mode(False) list_view_img = Gtk.Image.new_from_icon_name( 'view-list-symbolic', Gtk.IconSize.SMALL_TOOLBAR) list_view_button.set_image(list_view_img) right_box.pack_start(list_view_button, False, False, 0) grid_view_button = Gtk.RadioButton() grid_view_button.set_mode(False) grid_view_button.join_group(list_view_button) grid_view_button.set_active( self.app.profile['view-mode'][self.name] == const.ICON_VIEW) grid_view_img = Gtk.Image.new_from_icon_name( 'view-grid-symbolic', Gtk.IconSize.SMALL_TOOLBAR) grid_view_button.set_image(grid_view_img) list_view_button.connect('clicked', self.on_list_view_button_clicked) grid_view_button.connect('clicked', self.on_grid_view_button_clicked) right_box.pack_start(grid_view_button, False, False, 0) # reload button reload_button = Gtk.Button() reload_img = Gtk.Image.new_from_icon_name( 'view-refresh-symbolic', Gtk.IconSize.SMALL_TOOLBAR) reload_button.set_image(reload_img) reload_button.set_tooltip_text(_('Reload (F5)')) reload_button.connect('clicked', self.reload) self.headerbar.pack_end(reload_button) # search button search_button = Gtk.ToggleButton() search_img = Gtk.Image.new_from_icon_name( 'edit-find-symbolic', Gtk.IconSize.SMALL_TOOLBAR) search_button.set_image(search_img) search_button.set_tooltip_text( _('Search documents and folders by name')) search_button.connect('toggled', self.on_search_button_toggled) self.headerbar.pack_end(search_button) # show loading process self.loading_spin = Gtk.Spinner() self.loading_spin.props.valign = Gtk.Align.CENTER self.headerbar.pack_end(self.loading_spin) self.search_entry = Gtk.SearchEntry() self.search_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.PRIMARY, 'edit-find-symbolic') self.search_entry.props.no_show_all = True self.search_entry.props.visible = False self.search_entry.connect('activate', self.on_search_entry_activated) self.pack_start(self.search_entry, False, False, 0) else: nav_bar = Gtk.Box(spacing=5) self.pack_start(nav_bar, False, False, 0) path_win = Gtk.ScrolledWindow() nav_bar.pack_start(path_win, True, True, 0) path_win.props.hscrollbar_policy = Gtk.PolicyType.NEVER path_win.props.vscrollbar_policy = Gtk.PolicyType.NEVER path_viewport = Gtk.Viewport() path_win.add(path_viewport) self.path_box = PathBox(self) path_viewport.add(self.path_box) # show loading process self.loading_spin = Gtk.Spinner() self.loading_spin.props.valign = Gtk.Align.CENTER nav_bar.pack_start(self.loading_spin, False, False, 0) # search button search_button = Gtk.ToggleButton() search_img = Gtk.Image.new_from_icon_name( 'edit-find-symbolic', Gtk.IconSize.SMALL_TOOLBAR) search_button.set_image(search_img) search_button.set_tooltip_text( _('Search documents and folders by name')) search_button.connect('toggled', self.on_search_button_toggled) nav_bar.pack_start(search_button, False, False, 0) # right box right_box = Gtk.Box() right_box_context = right_box.get_style_context() right_box_context.add_class(Gtk.STYLE_CLASS_RAISED) right_box_context.add_class(Gtk.STYLE_CLASS_LINKED) nav_bar.pack_start(right_box, False, False, 0) # toggle view mode list_view_button = Gtk.RadioButton() list_view_button.set_mode(False) list_view_img = Gtk.Image.new_from_icon_name( 'view-list-symbolic', Gtk.IconSize.SMALL_TOOLBAR) list_view_button.set_image(list_view_img) right_box.pack_start(list_view_button, False, False, 0) grid_view_button = Gtk.RadioButton() grid_view_button.set_mode(False) grid_view_button.join_group(list_view_button) grid_view_button.set_active( self.app.profile['view-mode'][self.name] == const.ICON_VIEW) grid_view_img = Gtk.Image.new_from_icon_name( 'view-grid-symbolic', Gtk.IconSize.SMALL_TOOLBAR) grid_view_button.set_image(grid_view_img) list_view_button.connect('clicked', self.on_list_view_button_clicked) grid_view_button.connect('clicked', self.on_grid_view_button_clicked) right_box.pack_start(grid_view_button, False, False, 0) self.search_entry = Gtk.Entry() self.search_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.PRIMARY, 'folder-saved-search-symbolic') self.search_entry.props.no_show_all = True self.search_entry.props.visible = False self.search_entry.connect('activate', self.on_search_entry_activated) self.pack_start(self.search_entry, False, False, 0) def on_page_show(self): if Config.GTK_GE_312: self.app.window.set_titlebar(self.headerbar) self.headerbar.show_all() def check_first(self): if self.first_run: self.first_run = False if self.app.profile['view-mode'][self.name] == const.ICON_VIEW: self.icon_window = IconWindow(self, self.app) else: self.icon_window = TreeWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.load(is_user=True) # Open API def load(self, path='/', is_user=False): self.path = path self.page_num = 1 self.has_next = True self.path_box.set_path(path, is_user) self.loading_spin.start() self.loading_spin.show_all() gutil.async_call(pcs.list_dir, self.app.cookie, self.app.tokens, self.path, self.page_num, callback=self.on_load) gutil.async_call(pcs.get_quota, self.app.cookie, self.app.tokens, callback=self.app.update_quota) def on_load(self, info, error=None): self.loading_spin.stop() self.loading_spin.hide() if not info: self.app.toast(_('Network error')) elif info.get('errno', -1) != 0: self.app.toast(info.get('error_msg', _('Network error'))) if error or not info or info.get('errno', -1) != 0: logger.error('HomePage.on_load: %s, %s' % (info, error)) return self.icon_window.load(info['list']) def load_next(self): '''载入下一页''' def on_load_next(info, error=None): self.loading_spin.stop() self.loading_spin.hide() if not info: self.app.toast(_('Network error')) elif info.get('errno', -1) != 0: self.app.toast(info.get('error_msg', _('Network error'))) if error or not info or info.get('errno', -1) != 0: logger.error('HomePage.load_next: %s, %s' % (info, error)) return if info['list']: self.icon_window.load_next(info['list']) else: self.has_next = False if not self.has_next: return self.page_num = self.page_num + 1 self.path_box.set_path(self.path) self.loading_spin.start() self.loading_spin.show_all() gutil.async_call(pcs.list_dir, self.app.cookie, self.app.tokens, self.path, self.page_num, callback=on_load_next) def reload(self, *args, **kwds): '''重新载入本页面''' self.load(self.path) def do_drag_data_received(self, drag_context, x, y, data, info, time): '''从其它程序拖放目录/文件, 以便上传. 这里, 会直接把文件上传到当前目录(self.path). 拖放事件已经被处理, 所以不会触发self.app.window的拖放动作. ''' if not self.app.profile: return if info == TargetInfo.URI_LIST: uris = data.get_uris() source_paths = util.uris_to_paths(uris) if source_paths: self.app.upload_page.upload_files(source_paths, self.path) def on_search_button_toggled(self, search_button): status = search_button.get_active() self.search_entry.props.visible = status if status: self.search_entry.grab_focus() else: self.reload() def on_list_view_button_clicked(self, list_view_button): if not isinstance(self.icon_window, TreeWindow): self.remove(self.icon_window) self.icon_window = TreeWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.app.profile['view-mode'][self.name] = const.TREE_VIEW gutil.dump_profile(self.app.profile) self.reload() def on_grid_view_button_clicked(self, grid_view_button): if isinstance(self.icon_window, TreeWindow): self.remove(self.icon_window) self.icon_window = IconWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.app.profile['view-mode'][self.name] = const.ICON_VIEW gutil.dump_profile(self.app.profile) self.reload() def on_search_entry_activated(self, search_entry): text = search_entry.get_text() if not text: return self.loading_spin.start() self.loading_spin.show_all() gutil.async_call(pcs.search, self.app.cookie, self.app.tokens, text, self.path, callback=self.on_load)
class CategoryPage(Gtk.Box): page_num = 1 has_next = True first_run = True name = 'CategoryPage' def __init__(self, app): super().__init__(orientation=Gtk.Orientation.VERTICAL) self.app = app if Config.GTK_GE_312: self.headerbar = Gtk.HeaderBar() self.headerbar.props.show_close_button = True self.headerbar.props.has_subtitle = False self.headerbar.set_title(self.disname) # right box right_box = Gtk.Box() right_box_context = right_box.get_style_context() right_box_context.add_class(Gtk.STYLE_CLASS_RAISED) right_box_context.add_class(Gtk.STYLE_CLASS_LINKED) self.headerbar.pack_end(right_box) # toggle view mode list_view_button = Gtk.RadioButton() list_view_button.set_mode(False) list_view_img = Gtk.Image.new_from_icon_name( 'view-list-symbolic', Gtk.IconSize.SMALL_TOOLBAR) list_view_button.set_image(list_view_img) right_box.pack_start(list_view_button, False, False, 0) grid_view_button = Gtk.RadioButton() grid_view_button.set_mode(False) grid_view_button.join_group(list_view_button) grid_view_button.set_active( self.app.profile['view-mode'][self.name] == const.ICON_VIEW) grid_view_img = Gtk.Image.new_from_icon_name( 'view-grid-symbolic', Gtk.IconSize.SMALL_TOOLBAR) grid_view_button.set_image(grid_view_img) list_view_button.connect('clicked', self.on_list_view_button_clicked) grid_view_button.connect('clicked', self.on_grid_view_button_clicked) right_box.pack_start(grid_view_button, False, False, 0) # reload button reload_button = Gtk.Button() reload_img = Gtk.Image.new_from_icon_name( 'view-refresh-symbolic', Gtk.IconSize.SMALL_TOOLBAR) reload_button.set_image(reload_img) reload_button.set_tooltip_text(_('Reload (F5)')) reload_button.connect('clicked', self.reload) self.headerbar.pack_end(reload_button) # show loading process self.loading_spin = Gtk.Spinner() self.loading_spin.props.valign = Gtk.Align.CENTER self.headerbar.pack_end(self.loading_spin) else: nav_bar = Gtk.Box() nav_bar_context = nav_bar.get_style_context() nav_bar_context.add_class(Gtk.STYLE_CLASS_RAISED) nav_bar_context.add_class(Gtk.STYLE_CLASS_LINKED) nav_bar.props.halign = Gtk.Align.END self.pack_start(nav_bar, False, False, 0) # show loading process self.loading_spin = Gtk.Spinner() self.loading_spin.props.valign = Gtk.Align.CENTER nav_bar.pack_start(self.loading_spin, False, False, 0) # toggle view mode list_view_button = Gtk.RadioButton() list_view_button.set_mode(False) list_view_img = Gtk.Image.new_from_icon_name( 'view-list-symbolic', Gtk.IconSize.SMALL_TOOLBAR) list_view_button.set_image(list_view_img) nav_bar.pack_start(list_view_button, False, False, 0) grid_view_button = Gtk.RadioButton() grid_view_button.props.margin_right = 10 grid_view_button.set_mode(False) grid_view_button.join_group(list_view_button) grid_view_button.set_active( self.app.profile['view-mode'][self.name] == const.ICON_VIEW) grid_view_img = Gtk.Image.new_from_icon_name( 'view-grid-symbolic', Gtk.IconSize.SMALL_TOOLBAR) grid_view_button.set_image(grid_view_img) list_view_button.connect('clicked', self.on_list_view_button_clicked) grid_view_button.connect('clicked', self.on_grid_view_button_clicked) nav_bar.pack_start(grid_view_button, False, False, 0) def on_page_show(self): if Config.GTK_GE_312: self.app.window.set_titlebar(self.headerbar) self.headerbar.show_all() def check_first(self): if self.first_run: self.first_run = False if self.app.profile['view-mode'][self.name] == const.ICON_VIEW: self.icon_window = IconWindow(self, self.app) else: self.icon_window = TreeWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.load() def load(self): def on_load(info, error=None): self.loading_spin.stop() self.loading_spin.hide() if not info: self.app.toast(_('Network error')) elif info.get('errno', -1) != 0: self.app.toast(info.get('error_msg', _('Network error'))) if error or not info or info.get('errno', -1) != 0: logger.error('%s.on_load: %s, %s' % (self.disname, info, error)) return self.icon_window.load(info['info']) has_next = True self.page_num = 1 self.loading_spin.start() self.loading_spin.show_all() gutil.async_call(pcs.get_category, self.app.cookie, self.app.tokens, self.category, self.page_num, callback=on_load) def load_next(self): def on_load_next(info, error=None): self.loading_spin.stop() self.loading_spin.hide() if not info: self.app.toast(_('Network error')) elif info.get('errno', -1) != 0: self.app.toast(info.get('error_msg', _('Network error'))) if error or not info or info['errno'] != 0: logger.error('%s.on_load_next: %s, %s' % (self.disname, info, error)) return if info['info']: self.icon_window.load_next(info['info']) else: self.has_next = False if not self.has_next: return self.loading_spin.start() self.loading_spin.show_all() self.page_num = self.page_num + 1 gutil.async_call(pcs.get_category, self.app.cookie, self.app.tokens, self.category, self.page_num, callback=on_load_next) def reload(self, *args): self.load() def on_list_view_button_clicked(self, button): if not isinstance(self.icon_window, TreeWindow): self.remove(self.icon_window) self.icon_window = TreeWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.app.profile['view-mode'][self.name] = const.TREE_VIEW gutil.dump_profile(self.app.profile) self.reload() def on_grid_view_button_clicked(self, button): if isinstance(self.icon_window, TreeWindow): self.remove(self.icon_window) self.icon_window = IconWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.app.profile['view-mode'][self.name] = const.ICON_VIEW gutil.dump_profile(self.app.profile) self.reload()
class CategoryPage(Gtk.Box): page_num = 1 has_next = True first_run = True def __init__(self, app): super().__init__(orientation=Gtk.Orientation.VERTICAL) self.app = app nav_bar = Gtk.Toolbar() nav_bar.get_style_context().add_class(Gtk.STYLE_CLASS_MENUBAR) nav_bar.props.show_arrow = False nav_bar.props.toolbar_style = Gtk.ToolbarStyle.ICONS nav_bar.props.icon_size = Gtk.IconSize.LARGE_TOOLBAR nav_bar.props.halign = Gtk.Align.END self.pack_start(nav_bar, False, False, 0) # show loading process loading_button = Gtk.ToolItem() nav_bar.insert(loading_button, 0) loading_button.props.margin_right = 10 self.loading_spin = Gtk.Spinner() loading_button.add(self.loading_spin) self.loading_spin.props.valign = Gtk.Align.CENTER nav_bar.child_set_property(loading_button, 'expand', True) # toggle view mode list_view_button = Gtk.ToolButton() list_view_button.set_label(_('ListView')) list_view_button.set_icon_name('list-view-symbolic') list_view_button.connect( 'clicked', self.on_list_view_button_clicked) nav_bar.insert(list_view_button, 1) grid_view_button = Gtk.ToolButton() grid_view_button.set_label(_('ListView')) grid_view_button.set_icon_name('grid-view-symbolic') grid_view_button.connect( 'clicked', self.on_grid_view_button_clicked) nav_bar.insert(grid_view_button, 2) self.icon_window = IconWindow(self, app) self.pack_end(self.icon_window, True, True, 0) def load(self): def on_load(info, error=None): self.loading_spin.stop() self.loading_spin.hide() if error or not info or info['errno'] != 0: return self.icon_window.load(info['info']) has_next = True self.page_num = 1 self.loading_spin.start() self.loading_spin.show_all() gutil.async_call( pcs.get_category, self.app.cookie, self.app.tokens, self.category, self.page_num, callback=on_load) def load_next(self): def on_load_next(info, error=None): self.loading_spin.stop() self.loading_spin.hide() if error or not info or info['errno'] != 0: return if info['info']: self.icon_window.load_next(info['info']) else: self.has_next = False if not self.has_next: return self.loading_spin.start() self.loading_spin.show_all() self.page_num = self.page_num + 1 gutil.async_call( pcs.get_category, self.app.cookie, self.app.tokens, self.category, self.page_num, callback=on_load_next) def reload(self, *args): self.load() def on_list_view_button_clicked(self, button): if not isinstance(self.icon_window, TreeWindow): self.remove(self.icon_window) self.icon_window = TreeWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.reload() def on_grid_view_button_clicked(self, button): if isinstance(self.icon_window, TreeWindow): self.remove(self.icon_window) self.icon_window = IconWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.reload()
class HomePage(Gtk.Box): icon_name = 'home-symbolic' disname = _('Home') tooltip = _('Show all of your files on Cloud') first_run = False page_num = 1 path = '/' has_next = True def __init__(self, app): super().__init__(orientation=Gtk.Orientation.VERTICAL) self.app = app # set drop action targets = [ ['text/plain', Gtk.TargetFlags.OTHER_APP, 0], ['*.*', Gtk.TargetFlags.OTHER_APP, 1]] target_list =[Gtk.TargetEntry.new(*t) for t in targets] self.drag_dest_set( Gtk.DestDefaults.ALL, target_list, Gdk.DragAction.COPY) nav_bar = Gtk.Toolbar() nav_bar.get_style_context().add_class(Gtk.STYLE_CLASS_MENUBAR) nav_bar.props.show_arrow = False nav_bar.props.toolbar_style = Gtk.ToolbarStyle.ICONS nav_bar.props.icon_size = Gtk.IconSize.LARGE_TOOLBAR self.pack_start(nav_bar, False, False, 0) nav_bar.props.valign = Gtk.Align.START path_item = Gtk.ToolItem() nav_bar.insert(path_item, 0) nav_bar.child_set_property(path_item, 'expand', True) path_item.props.valign = Gtk.Align.START path_win = Gtk.ScrolledWindow() path_item.add(path_win) path_win.props.valign = Gtk.Align.START path_win.props.vscrollbar_policy = Gtk.PolicyType.NEVER path_viewport = Gtk.Viewport() path_viewport.props.valign = Gtk.Align.START path_win.add(path_viewport) self.path_box = PathBox(self) self.path_box.props.valign = Gtk.Align.START path_viewport.add(self.path_box) # show loading process loading_button = Gtk.ToolItem() nav_bar.insert(loading_button, 1) loading_button.props.margin_right = 10 self.loading_spin = Gtk.Spinner() loading_button.add(self.loading_spin) self.loading_spin.props.valign = Gtk.Align.CENTER # search button search_button = Gtk.ToggleToolButton() search_button.set_label(_('Search')) search_button.set_icon_name('search-symbolic') search_button.set_tooltip_text( _('Search documents and folders by name')) search_button.connect('toggled', self.on_search_button_toggled) nav_bar.insert(search_button, 2) search_button.props.valign = Gtk.Align.START search_button.props.margin_right = 10 # toggle view mode list_view_button = Gtk.ToolButton() list_view_button.set_label(_('ListView')) list_view_button.set_icon_name('list-view-symbolic') list_view_button.connect( 'clicked', self.on_list_view_button_clicked) nav_bar.insert(list_view_button, 3) list_view_button.props.valign = Gtk.Align.START grid_view_button = Gtk.ToolButton() grid_view_button.set_label(_('ListView')) grid_view_button.set_icon_name('grid-view-symbolic') grid_view_button.connect( 'clicked', self.on_grid_view_button_clicked) nav_bar.insert(grid_view_button, 4) grid_view_button.props.valign = Gtk.Align.START # serch entry if Config.GTK_LE_36: self.search_entry = Gtk.Entry() self.search_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.PRIMARY, 'folder-saved-search-symbolic') else: self.search_entry = Gtk.SearchEntry() self.search_entry.props.no_show_all = True self.search_entry.props.visible = False self.search_entry.connect( 'activate', self.on_search_entry_activated) self.pack_start(self.search_entry, False, False, 0) self.icon_window = IconWindow(self, app) self.pack_end(self.icon_window, True, True, 0) def do_drag_data_received(self, drag_context, x, y, data, info, time): uris = data.get_text() source_paths = util.uris_to_paths(uris) if source_paths and self.app.profile: self.app.upload_page.add_file_tasks(source_paths, self.path) # Open API def load(self, path='/'): self.path = path self.page_num = 1 self.has_next = True self.path_box.set_path(path) self.loading_spin.start() self.loading_spin.show_all() gutil.async_call( pcs.list_dir, self.app.cookie, self.app.tokens, self.path, self.page_num, callback=self.on_load) gutil.async_call( pcs.get_quota, self.app.cookie, self.app.tokens, callback=self.app.update_quota) def on_load(self, info, error=None): self.loading_spin.stop() self.loading_spin.hide() if error or not info or info['errno'] != 0: return self.icon_window.load(info['list']) def load_next(self): '''载入下一页''' def on_load_next(info, error=None): self.loading_spin.stop() self.loading_spin.hide() if error or not info or info['errno'] != 0: return if info['list']: self.icon_window.load_next(info['list']) else: self.has_next = False if not self.has_next: return self.page_num = self.page_num + 1 self.path_box.set_path(self.path) self.loading_spin.start() self.loading_spin.show_all() gutil.async_call( pcs.list_dir, self.app.cookie, self.app.tokens, self.path, self.page_num, callback=on_load_next) def reload(self, *args, **kwds): '''重新载入本页面''' self.load(self.path) def on_search_button_toggled(self, search_button): status = search_button.get_active() self.search_entry.props.visible = status if status: self.search_entry.grab_focus() else: self.reload() def on_list_view_button_clicked(self, button): if not isinstance(self.icon_window, TreeWindow): self.remove(self.icon_window) self.icon_window = TreeWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.reload() def on_grid_view_button_clicked(self, button): if isinstance(self.icon_window, TreeWindow): self.remove(self.icon_window) self.icon_window = IconWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.reload() def on_search_entry_activated(self, search_entry): text = search_entry.get_text() if not text: return self.loading_spin.start() self.loading_spin.show_all() gutil.async_call( pcs.search, self.app.cookie, self.app.tokens, text, self.path, callback=self.on_load)
class CategoryPage(Gtk.Box): page_num = 1 has_next = True first_run = True def __init__(self, app): super().__init__(orientation=Gtk.Orientation.VERTICAL) self.app = app nav_bar = Gtk.Toolbar() nav_bar.get_style_context().add_class(Gtk.STYLE_CLASS_MENUBAR) nav_bar.props.show_arrow = False nav_bar.props.toolbar_style = Gtk.ToolbarStyle.ICONS nav_bar.props.icon_size = Gtk.IconSize.LARGE_TOOLBAR nav_bar.props.halign = Gtk.Align.END self.pack_start(nav_bar, False, False, 0) # show loading process loading_button = Gtk.ToolItem() nav_bar.insert(loading_button, 0) loading_button.props.margin_right = 10 self.loading_spin = Gtk.Spinner() loading_button.add(self.loading_spin) self.loading_spin.props.valign = Gtk.Align.CENTER nav_bar.child_set_property(loading_button, 'expand', True) # toggle view mode list_view_button = Gtk.ToolButton() list_view_button.set_label(_('ListView')) list_view_button.set_icon_name('list-view-symbolic') list_view_button.connect('clicked', self.on_list_view_button_clicked) nav_bar.insert(list_view_button, 1) grid_view_button = Gtk.ToolButton() grid_view_button.set_label(_('ListView')) grid_view_button.set_icon_name('grid-view-symbolic') grid_view_button.connect('clicked', self.on_grid_view_button_clicked) nav_bar.insert(grid_view_button, 2) self.icon_window = IconWindow(self, app) self.pack_end(self.icon_window, True, True, 0) def load(self): def on_load(info, error=None): self.loading_spin.stop() self.loading_spin.hide() if error or not info or info['errno'] != 0: return self.icon_window.load(info['info']) has_next = True self.page_num = 1 self.loading_spin.start() self.loading_spin.show_all() gutil.async_call(pcs.get_category, self.app.cookie, self.app.tokens, self.category, self.page_num, callback=on_load) def load_next(self): def on_load_next(info, error=None): self.loading_spin.stop() self.loading_spin.hide() if error or not info or info['errno'] != 0: return if info['info']: self.icon_window.load_next(info['info']) else: self.has_next = False if not self.has_next: return self.loading_spin.start() self.loading_spin.show_all() self.page_num = self.page_num + 1 gutil.async_call(pcs.get_category, self.app.cookie, self.app.tokens, self.category, self.page_num, callback=on_load_next) def reload(self, *args): self.load() def on_list_view_button_clicked(self, button): if not isinstance(self.icon_window, TreeWindow): self.remove(self.icon_window) self.icon_window = TreeWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.reload() def on_grid_view_button_clicked(self, button): if isinstance(self.icon_window, TreeWindow): self.remove(self.icon_window) self.icon_window = IconWindow(self, self.app) self.pack_end(self.icon_window, True, True, 0) self.icon_window.show_all() self.reload()