def __init__(self): QObject.__init__(self) self.window = kate.mainInterfaceWindow().window() kate.configuration.root.clear() self.act = KAction(KIcon("reload"), i18n("Auto Reload"), self) self.act.setObjectName("auto reload") self.window.actionCollection().addAction(self.act.objectName(), self.act) self.window.findChild(QMenu, 'view').addAction(self.act) if not self.act.objectName() in kate.configuration: kate.configuration[self.act.objectName()] = "alt+r" self.act.setShortcut(kate.configuration[self.act.objectName()]) self.act.setCheckable(True) self.act.setChecked(False) self.act.changed.connect(self.onActionChange) self.act.toggled.connect(self.toggle) kate.mainInterfaceWindow().viewChanged.connect(self.onViewChanged)
def create_actions(self): """Create actions for the main window.""" self.connect_action = KAction(KIcon("document-open-remote"), i18n("Connect"), self) self.fetch_action = KAction(KIcon("download"), i18n("Download"), self) self.clean_action = KAction(KIcon("trash-empty"), i18n("Clear thumbnail cache"), self) self.batch_download_action = KAction(KIcon("download"), i18n("Batch download"), self) self.pool_toggle_action = KToggleAction(KIcon("image-x-generic"), i18n("Pools"), self) self.tag_display_action = KDualAction(i18n("Show tags"), i18n("Hide tags"), self) self.tag_display_action.setIconForStates(KIcon("image-x-generic")) self.tag_display_action.setEnabled(False) # Shortcuts connect_default = KAction.ShortcutTypes(KAction.DefaultShortcut) connect_active = KAction.ShortcutTypes(KAction.ActiveShortcut) self.connect_action.setShortcut(KStandardShortcut.open()) self.fetch_action.setShortcut(KStandardShortcut.find()) self.fetch_action.setEnabled(False) self.batch_download_action.setEnabled(False) self.pool_toggle_action.setEnabled(False)
def addAction(self, objectName, icon, text, shortcut = "", slot = None, menuName = None): act = KAction(KIcon(icon), text, self) act.setObjectName(objectName) # Set shortcut if not act.objectName() in kate.configuration: kate.configuration[act.objectName()] = shortcut act.setShortcut(kate.configuration[act.objectName()]) # Set slots if slot != None: act.triggered.connect( slot ) kate.mainInterfaceWindow().window().actionCollection().addAction(act.objectName(), act) # Add to menu if menuName != None: menu = kate.mainInterfaceWindow().window().findChild(QMenu, menuName.lower()) if menu == None: menu = kate.mainInterfaceWindow().window().menuBar().addMenu(menuName) menu.addAction(act) # Save changes to shortcut act.changed.connect( self.onActionChange ) return act
def toolbar(name, group=None, callable=None): """ Returns the action with the given name for toolbar use. Toolbar use means that there is an icon without text. Needed configuration keys: icon, action Ignored keys: text Parameters: name -- The name of the action. group -- The QActionGroup to add this action to. callable -- The callable to call when the action is triggered. Can be used to override the action in the definition or provide one. """ global toolbar_actions action = toolbar_actions.get(name, None) if action is None: # Create the toolbar action and insert it into the toolbar_actions dict global parent global action_definitions config = action_definitions.get(name, None) if config is None: return None #Without the config no action can be created if group is None: action = KAction(parent) else: action = KAction(group) # Will result in a KeyError when the icon is not set in the config. # This is slightly wanted behaviour, as the icon is needed for a # toolbar action. action.setIcon(KIcon(config["icon"])) if "checkable" in config: action.setCheckable(True) # Same exception is wanted here. As an alternative one can specify a callable as a parameter. if callable is not None: action.triggered.connect(callable) else: action.triggered.connect(config["action"]) if "text" in config: action.setText(config["text"]) toolbar_actions["name"] = action return action
def setupActions (self): clearAction = KAction(KIcon("edit-clear"), i18n("Clear"), self) dfltShortcut = KAction.ShortcutTypes (KAction.DefaultShortcut) activeShortcut = KAction.ShortcutTypes (KAction.ActiveShortcut) clearAction.setShortcut(Qt.CTRL+Qt.Key_W, dfltShortcut | activeShortcut) self.actionCollection().addAction("clear", clearAction) self.connect (clearAction, SIGNAL ("triggered(bool)"), self.textArea.clear) KStandardAction.quit (app.quit, self.actionCollection()) self.setupGUI(QSize (600, 400), KXmlGuiWindow.Default, os.path.join (sys.path [0], "kactionui.rc"))
def addHotKey(self, name, key): if not KGlobalAccel.isGlobalShortcutAvailable(key): actions = KGlobalAccel.getGlobalShortcutsByKey(key) if KGlobalAccel.promptStealShortcutSystemwide(None, actions, key): KGlobalAccel.stealShortcutSystemwide(key) action = KAction(None) action.setObjectName(name) action.setText(name) action.setGlobalShortcut(KShortcut(key), \ KAction.ShortcutType(KAction.ActiveShortcut | KAction.DefaultShortcut), KAction.NoAutoloading) action.triggered.connect(self.catchGlobalKey) self.actions[self.nextId] = action self.nextId += 1 return self.nextId - 1
def setupActions(self): clearAction = KAction(KIcon("edit-clear"), i18n("Clear"), self) self.actionCollection().addAction("clear", clearAction) self.connect(clearAction, SIGNAL("triggered(bool)"), self.textArea.clear) KStandardAction.quit(app.quit, self.actionCollection()) self.setupGUI(QSize(600, 400), KXmlGuiWindow.Default, os.path.join(sys.path[0], "kactionui.rc"))
def __init__(self): app_name = "magneto" catalog = "" prog_name = ki18n("Magneto") version = "1.0" description = ki18n("System Update Status") lic = KAboutData.License_GPL cright = ki18n("(c) 2013 Fabio Erculiani") text = ki18n("none") home_page = "www.sabayon.org" bug_mail = "*****@*****.**" self._kabout = KAboutData(app_name, catalog, prog_name, version, description, lic, cright, text, home_page, bug_mail) argv = [sys.argv[0]] KCmdLineArgs.init(argv, self._kabout) self._app = KApplication() from dbus.mainloop.qt import DBusQtMainLoop super(Magneto, self).__init__(main_loop_class=DBusQtMainLoop) self._window = KStatusNotifierItem() # do not show "Quit" and use quitSelected() signal self._window.setStandardActionsEnabled(False) icon_name = self.icons.get("okay") self._window.setIconByName(icon_name) self._window.setStatus(KStatusNotifierItem.Passive) self._window.connect(self._window, SIGNAL("activateRequested(bool,QPoint)"), self.applet_activated) self._menu = KMenu(_("Magneto Entropy Updates Applet")) self._window.setContextMenu(self._menu) self._menu_items = {} for item in self._menu_item_list: if item is None: self._menu.addSeparator() continue myid, _unused, mytxt, myslot_func = item name = self.get_menu_image(myid) action_icon = KIcon(name) w = KAction(action_icon, mytxt, self._menu) self._menu_items[myid] = w self._window.connect(w, SIGNAL("triggered()"), myslot_func) self._menu.addAction(w) self._menu.hide()
def setupActions(self): # update dictionaries self._updateAction = KAction(KIcon('system-software-update'), i18n("&Update..."), self) self.actionCollection.addAction("updatedictionaries", self._updateAction) self._updateAction.setWhatsThis( i18n("Download and update dictionaries.")) self.connect(self._updateAction, SIGNAL("triggered(bool)"), self.exec_) # optimise database self._optimiseAction = KAction(KIcon('system-run'), i18n("&Optimise database"), self) self.actionCollection.addAction("optimisedatabase", self._optimiseAction) self._optimiseAction.setWhatsThis( i18n("Rearranges and optimises the database.")) self._optimiseAction.setEnabled(True) # TODO self.connect(self._optimiseAction, SIGNAL("triggered(bool)"), self.slotOptimiseDatabase)
def menu(name): """ Returns the action with the given name for menu use. Menu use that the action has a text and might have an icon. Needed configuration keys: text, action Optional keys: icon Parameters: name -- The name of the action, """ global menu_actions action = menu_actions.get(name, None) if action is None: # Create the toolbar action and insert it into the toolbar_actions dict global parent global action_definitions config = action_definitions.get(name, None) if config is None: return None #Without the config no action can be created action = KAction(parent) if "icon" in config: action.setIcon(KIcon(config["icon"])) if "checkable" in config: action.setCheckable(True) # Will result in a KeyError when the text is not set in the config. # This is slightly wanted behaviour, as the text is needed for a # menu action. action.setText(config["text"]) # Same exception is wanted here. action.triggered.connect(config["action"]) menu_actions["name"] = action return action
def create (parent, ac): """here be common actions for satyr skins""" actions= ( ('queue', Qt.CTRL+Qt.Key_Q, False, "Queue songs"), ('rename', Qt.CTRL+Qt.Key_R, False, "Arrange songs"), ('toggleVA', Qt.CTRL+Qt.Key_V, False, "Toggle 'Various Artists' flag"), ('delete', Qt.CTRL+Qt.Key_D, False, "Delete songs"), # globals ('player.prev', KShortcut (Qt.Key_MediaPrevious), True, "Previous song"), ('player.stop', KShortcut (Qt.Key_MediaStop), True, "Stop"), ('player.play', KShortcut (Qt.Key_MediaPlay), True, "Play"), ('player.pause', KShortcut (Qt.Key_Pause), True, "Toggle Pause"), ('player.play_pause', KShortcut (Qt.Key_MediaPlay), True, "Switch between Play and Pause"), ('player.next', KShortcut (Qt.Key_MediaNext), True, "Next song"), ('player.toggleStopAfter', KShortcut (Qt.Key_Eject), True, "Stop after playing current song"), # TODO: S-Play/Pause -> cycle random # TODO: S-|<</>>| -> beginning/prev album, next album ) for fqn, shortcut, globalSC, text in actions: try: obj, name= traverseObjects (parent, fqn) except AttributeError, e: logger.warning ("actions.create(): %s, shortcut for %s not set", e.args[0], fqn) else: fqn= "satyr."+fqn action= KAction (text, parent) action.setObjectName (fqn) if globalSC: action.setGlobalShortcut (shortcut) else: action.setShortcut (shortcut) ac.addAction (fqn, action) # the skin can decide to not implement an action! method= getattr (obj, name, None) if method is not None: action.triggered.connect (method) else: logger.warning ("actions.create(): no method %s, shortcut for %s not set", name, fqn)
def setupActions(self): clearAction = KAction(KIcon("edit-clear"), i18n("Clear"), self) dfltShortcut = KAction.ShortcutTypes(KAction.DefaultShortcut) activeShortcut = KAction.ShortcutTypes(KAction.ActiveShortcut) clearAction.setShortcut(Qt.CTRL + Qt.Key_W, dfltShortcut | activeShortcut) self.actionCollection().addAction("clear", clearAction) self.connect(clearAction, SIGNAL("triggered(bool)"), self.textArea.clear) KStandardAction.quit(app.quit, self.actionCollection()) self.setupGUI(QSize(600, 400), KXmlGuiWindow.Default, os.path.join(sys.path[0], "kactionui.rc"))
def __init__(self, tool, part): super(Player, self).__init__(tool.mainwin) self.player = part self._currentFile = None self._currentFileList = None self._tempo = 60.0 layout = QGridLayout() self.setLayout(layout) layout.setSpacing(0) fl = self.fileList = QComboBox() fl.activated.connect(self.slotItemActivated) fl.setEnabled(False) layout.addWidget(fl, 0, 0, 1, 2) pb = self.pauseButton = QToolButton() pb.setIcon(KIcon('media-playback-pause')) pb.clicked.connect(self.pause) pb.setToolTip(i18n("Pause")) layout.addWidget(pb, 1, 0) lcd = self.lcd = QLCDNumber() lcd.setMaximumHeight(60) lcd.setSegmentStyle(QLCDNumber.Flat) lcd.setStyleSheet("""QLCDNumber { border-width: 5 3 2 4; border-image: url('css:lcd-borders.png') repeat; background-image: url('css:lcd-background.png') repeat; color: #151B19; }""") layout.addWidget(lcd, 2, 0, 1, 2) vs = self.volumeSlider = QSlider(Qt.Vertical) vs.setRange(0, 20) vs.setValue(int(self.readProperty('volumeFactor') * 10)) vs.setToolTip(i18n("Volume")) layout.addWidget(vs, 0, 2, 3, 1) # KMid Part widget widget = self.widget = part.widget() layout.addWidget(widget, 1, 1) # make smaller widget.layout().setSpacing(0) widget.layout().setContentsMargins(0, 0, 0, 0) # set auto start off self.writeProperty('autoStart', False) # connect stuff part.connect(part, SIGNAL("stateChanged(int)"), self.slotStateChanged, Qt.QueuedConnection) part.connect(part, SIGNAL("beat(int,int,int)"), self.slotBeat) part.connect(part, SIGNAL("tempoEvent(double)"), self.slotTempoEvent) vs.valueChanged.connect(self.setVolumeFactor) tool.mainwin.aboutToClose.connect(self.quit) tool.mainwin.currentDocumentChanged.connect(self.setCurrentDocument) tool.mainwin.jobManager().jobFinished.connect(self.jobFinished) self.slotBeat(0, 0, 0) self.setCurrentDocument(tool.mainwin.currentDocument()) # keyboard action to pause playback, works when the MIDI tool is visible # (hardcoded to Pause and MediaPlay) a = KAction(self) a.setShortcut(KShortcut( QKeySequence(Qt.Key_Pause), QKeySequence(Qt.Key_MediaPlay))) a.triggered.connect(self.slotPlayPause) self.addAction(a) # keyboard action to stop playback, ESC and MediaStop a = KAction(self) a.setShortcut(KShortcut( QKeySequence(Qt.Key_Escape), QKeySequence(Qt.Key_MediaStop))) a.triggered.connect(self.stop) self.addAction(a)
def __init__(self, menu, macro, callback): KAction.__init__(self, macro.TITLE.toString(), menu) self.macro = macro self.callback = callback self.connect(self, SIGNAL("triggered()"), self.on_triggered)
def addMenuAction(self, menu_name_id, act_name_id, act_name_string, is_check=False): i = self.get_menu_index(menu_name_id) if i < 0: return menu_widget = self.menu_indexes[i][iMenuWidget] if TrayEngine == "KDE": act_widget = KAction(act_name_string, menu_widget) act_widget.setCheckable(is_check) menu_widget.addAction(act_widget) elif TrayEngine == "AppIndicator": menu_widget = menu_widget.get_submenu() if is_check: act_widget = Gtk.CheckMenuItem(act_name_string) else: act_widget = Gtk.ImageMenuItem(act_name_string) act_widget.set_image(None) act_widget.show() menu_widget.append(act_widget) elif TrayEngine == "Qt": act_widget = QAction(act_name_string, menu_widget) act_widget.setCheckable(is_check) menu_widget.addAction(act_widget) else: act_widget = None act_obj = [None, None, None, None] act_obj[iActNameId] = act_name_id act_obj[iActWidget] = act_widget act_obj[iActParentMenuId] = menu_name_id self.act_indexes.append(act_obj)
def addAction(self, act_name_id, act_name_string, is_check=False): if TrayEngine == "KDE": act_widget = KAction(act_name_string, self.menu) act_widget.setCheckable(is_check) self.menu.addAction(act_widget) elif TrayEngine == "AppIndicator": if is_check: act_widget = Gtk.CheckMenuItem(act_name_string) else: act_widget = Gtk.ImageMenuItem(act_name_string) act_widget.set_image(None) act_widget.show() self.menu.append(act_widget) elif TrayEngine == "Qt": act_widget = QAction(act_name_string, self.menu) act_widget.setCheckable(is_check) self.menu.addAction(act_widget) else: act_widget = None act_obj = [None, None, None, None] act_obj[iActNameId] = act_name_id act_obj[iActWidget] = act_widget self.act_indexes.append(act_obj)
class MainWindow(KXmlGuiWindow): "Class which displays the main Danbooru Client window." def __init__(self, *args): "Initialize a new main window." super(MainWindow, self).__init__(*args) self.cache = KPixmapCache("danbooru") self.preferences = preferences.Preferences() self.api = None self.__ratings = None self.__step = 0 self.url_list = self.preferences.boards_list self.max_retrieve = self.preferences.thumbnail_no self.statusbar = self.statusBar() self.progress = QProgressBar() self.thumbnailarea = None self.tag_dock = None self.pool_dock = None self.first_fetch_widget = None self.progress.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) # FIXME: Hackish, but how to make it small otherwise? self.progress.setMinimumSize(100, 1) self.statusbar.addPermanentWidget(self.progress) self.progress.hide() self.setup_welcome_widget() self.setup_actions() def reload_config(self): """Reload configuration after a change""" urls = self.preferences.boards_list if self.first_fetch_widget is not None: self.first_fetch_widget.setup_urls(urls) if self.thumbnailarea is not None: max_thumbnail = self.preferences.thumbnail_no max_rating = self.preferences.max_allowed_rating self.thumbnailarea.fetchwidget.limit = max_thumbnail self.thumbnailarea.fetchwidget.rating = max_rating self.thumbnailarea.fetchwidget.update_values() self.thumbnailarea.connectwidget.setup_urls(urls) self.url_list = self.preferences.boards_list self.max_retrieve = self.preferences.thumbnail_no def setup_welcome_widget(self): """Load the welcome widget at startup.""" widget = QWidget() layout = QVBoxLayout() welcome = QLabel(parent=self) pix = QPixmap(KStandardDirs.locate("appdata","logo.png")) welcome.setPixmap(pix) welcome.setAlignment(Qt.AlignCenter) self.first_fetch_widget = connectwidget.ConnectWidget( self.preferences.boards_list, self) self.statusbar.addPermanentWidget(self.first_fetch_widget, 300) self.first_fetch_widget.connectionEstablished.connect( self.handle_connection) self.first_fetch_widget.rejected.connect( self.first_fetch_widget.hide) self.first_fetch_widget.hide() self.first_fetch_widget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) layout.addWidget(self.first_fetch_widget) layout.addWidget(welcome) widget.setLayout(layout) self.setCentralWidget(widget) def setup_tooltips(self): """Set tooltips for the actions.""" self.connect_action.setToolTip(i18n("Connect to a Danbooru board")) self.fetch_action.setToolTip( i18n("Fetch thumbnails from a Danbooru board") ) self.batch_download_action.setToolTip(i18n("Batch download images")) def create_actions(self): """Create actions for the main window.""" self.connect_action = KAction(KIcon("document-open-remote"), i18n("Connect"), self) self.fetch_action = KAction(KIcon("download"), i18n("Download"), self) self.clean_action = KAction(KIcon("trash-empty"), i18n("Clear thumbnail cache"), self) self.batch_download_action = KAction(KIcon("download"), i18n("Batch download"), self) self.pool_toggle_action = KToggleAction(KIcon("image-x-generic"), i18n("Pools"), self) self.tag_display_action = KDualAction(i18n("Show tags"), i18n("Hide tags"), self) self.tag_display_action.setIconForStates(KIcon("image-x-generic")) self.tag_display_action.setEnabled(False) # Shortcuts connect_default = KAction.ShortcutTypes(KAction.DefaultShortcut) connect_active = KAction.ShortcutTypes(KAction.ActiveShortcut) self.connect_action.setShortcut(KStandardShortcut.open()) self.fetch_action.setShortcut(KStandardShortcut.find()) self.fetch_action.setEnabled(False) self.batch_download_action.setEnabled(False) self.pool_toggle_action.setEnabled(False) def setup_action_collection(self): """Set up the action collection by adding the actions.""" action_collection = self.actionCollection() # Addition to the action collection action_collection.addAction("connect", self.connect_action) action_collection.addAction("fetch", self.fetch_action) action_collection.addAction("clean", self.clean_action) action_collection.addAction("batchDownload", self.batch_download_action) action_collection.addAction("poolDownload", self.pool_toggle_action) action_collection.addAction("tagDisplay", self.tag_display_action) KStandardAction.quit (self.close, action_collection) KStandardAction.preferences(self.show_preferences, action_collection) action_collection.removeAction( action_collection.action("help_contents")) action_collection.actionHovered.connect(self.setup_action_tooltip) def setup_actions(self): """Set up the relevant actions, tooltips, and load the RC file.""" self.create_actions() self.setup_tooltips() self.setup_action_collection() # Connect signals self.connect_action.triggered.connect(self.connect) self.fetch_action.triggered.connect(self.get_posts) self.clean_action.triggered.connect(self.clean_cache) self.batch_download_action.triggered.connect(self.batch_download) self.pool_toggle_action.toggled.connect(self.pool_toggle) self.tag_display_action.activeChanged.connect(self.tag_display) window_options = self.StandardWindowOption(self.ToolBar| self.Keys | self.Create | self.Save | self.StatusBar) setupGUI_args = [ QSize(500, 400), self.StandardWindowOption(window_options) ] #Check first in standard locations for danbooruui.rc rc_file = KStandardDirs.locate("appdata", "danbooruui.rc") if rc_file.isEmpty(): setupGUI_args.append(os.path.join(sys.path [0], "danbooruui.rc")) else: setupGUI_args.append(rc_file) self.setupGUI(*setupGUI_args) def setup_action_tooltip(self, action): "Show statusbar help when actions are hovered." if action.isEnabled(): self.statusBar().showMessage(action.toolTip(), 2000) def setup_connections(self): """Set up connections for post and tag retrieval.""" if self.api is None: return self.api.postRetrieved.connect(self.update_progress) self.api.postDownloadFinished.connect(self.download_finished) self.api.tagRetrieved.connect(self.tag_dock.widget().add_tags) self.tag_dock.widget().itemDoubleClicked.connect( self.fetch_tagged_items) def show_preferences(self): "Show the preferences dialog." if KConfigDialog.showDialog("Preferences dialog"): return else: dialog = preferences.PreferencesDialog(self, "Preferences dialog", self.preferences) dialog.show() dialog.settingsChanged.connect(self.reload_config) def connect(self, ok): "Connect to a Danbooru board." if self.thumbnailarea is None: self.first_fetch_widget.show() else: self.thumbnailarea.connectwidget.show() def restore(self): self.statusbar.removeWidget(self.connect_widget) def handle_connection(self, connection): self.api = None self.api = connection self.api.cache = self.cache if self.pool_dock is not None: self.pool_dock.hide() self.pool_dock.widget().clear() self.pool_toggle_action.setChecked(False) if self.thumbnailarea is not None: #TODO: Investigate usability self.clear(clear_pool=True) self.thumbnailarea.clear() self.thumbnailarea.api_data = self.api self.setup_connections() else: self.first_fetch_widget.connectionEstablished.disconnect() self.first_fetch_widget.rejected.disconnect() self.statusbar.removeWidget(self.first_fetch_widget) self.setup_area() self.api.cache = self.cache self.statusBar().showMessage(i18n("Connected to %s" % self.api.url), 3000) self.fetch_action.setEnabled(True) # Set up pool widget pool_widget = poolwidget.DanbooruPoolWidget(self.api) self.pool_dock = QDockWidget("Pools", self) self.pool_dock.setObjectName("PoolDock") self.pool_dock.setAllowedAreas(Qt.BottomDockWidgetArea) self.pool_dock.setWidget(pool_widget) #self.pool_dock.setFeatures(QDockWidget.NoDockWidgetFeatures) self.addDockWidget(Qt.BottomDockWidgetArea, self.pool_dock) self.pool_dock.widget().poolDownloadRequested.connect( self.pool_prepare) self.pool_dock.hide() self.pool_toggle_action.setEnabled(True) self.clear() # Needed to show properly the stuff after connecting self.api.get_post_list(tags="", limit=self.thumbnailarea.post_limit, rating=self.preferences.max_allowed_rating, blacklist=list(self.preferences.tag_blacklist)) self.api.get_tag_list(name="",blacklist=list(self.preferences.tag_blacklist), limit=20) def get_posts(self, ok): "Get posts from the connected Danbooru board." if not self.api: return self.thumbnailarea.fetchwidget.show() def handle_fetching(self, tags, max_rating, limit): """Slot connected to the dataSent signal of the fetch widget. The widgets are set up if they don't exist, and the API is queried to do the actual downloading of tags and """ self.clear() self.thumbnailarea.fetchwidget.hide() if self.tag_dock is not None: self.tag_dock.widget().clear() self.thumbnailarea.post_limit = limit blacklist= list(self.preferences.tag_blacklist) self.api.get_post_list(tags=tags, limit=limit, rating=max_rating, blacklist=blacklist) tags = [item for item in tags if item] if not tags: # No related tags, fetch the most recent 20 tags = "" self.api.get_tag_list(name=tags,blacklist=blacklist, limit=20) else: self.api.get_related_tags(tags=tags, blacklist=blacklist) def fetch_tagged_items(self, item): """Fetch items found in the tag list widget.""" tag_name = unicode(item.text()) self.clear() blacklist = self.preferences.tag_blacklist limit = self.preferences.thumbnail_no rating = self.preferences.max_allowed_rating self.api.get_post_list(page=1, tags=[tag_name], blacklist=blacklist, limit=limit, rating=rating) self.api.get_related_tags(tags=[tag_name], blacklist=blacklist) def pool_toggle(self, checked): "Toggle the presence/absence of the pool dock." if not self.api: return if not checked: self.pool_dock.hide() else: self.pool_dock.show() def pool_prepare(self, pool_id): """Prepare the central area for pool image loading.""" if self.thumbnailarea is None: self.setup_area() else: self.clear(clear_pool=False) self.api.get_pool(pool_id, blacklist=self.preferences.tag_blacklist, rating=self.preferences.max_allowed_rating) def batch_download(self, ok): "Download images in batch." selected_items = self.thumbnailarea.selected_images() if not selected_items: return start_url = KUrl("kfiledialog:///danbooru") caption = i18n("Select a directory to save the images to") directory = KFileDialog.getExistingDirectoryUrl(start_url, self, caption) if directory.isEmpty(): return for item in selected_items: file_url = item.url_label.url() tags = item.data.tags # Make a local copy to append paths as addPath works in-place destination = KUrl(directory) file_name = KUrl(file_url).fileName() destination.addPath(file_name) job = KIO.file_copy(KUrl(file_url), destination, -1) job.setProperty("tags", QVariant(tags)) job.result.connect(self.batch_download_slot) def setup_area(self): "Set up the central widget to display thumbnails." self.thumbnailarea = thumbnailarea.DanbooruTabWidget(self.api, self.preferences, self.preferences.thumbnail_no, self) self.setCentralWidget(self.thumbnailarea) self.thumbnailarea.connectwidget.connectionEstablished.connect( self.handle_connection, type=Qt.UniqueConnection) self.thumbnailarea.connectwidget.rejected.connect( self.thumbnailarea.connectwidget.hide, type=Qt.UniqueConnection) self.thumbnailarea.fetchwidget.dataSent.connect( self.handle_fetching, type=Qt.UniqueConnection) self.thumbnailarea.fetchwidget.rejected.connect( self.thumbnailarea.fetchwidget.hide, type=Qt.UniqueConnection) # Set up tag widget blacklist = self.preferences.tag_blacklist tag_widget = tagwidget.DanbooruTagWidget(blacklist, self) self.tag_display_action.setActive(True) self.tag_display_action.setEnabled(True) self.tag_dock = QDockWidget("Similar tags", self) self.tag_dock.setObjectName("TagDock") self.tag_dock.setAllowedAreas(Qt.RightDockWidgetArea) self.tag_dock.setWidget(tag_widget) #self.tag_dock.setFeatures(QDockWidget.NoDockWidgetFeatures) self.addDockWidget(Qt.RightDockWidgetArea, self.tag_dock) self.tag_dock.hide() # Container signal-slot connections self.setup_connections() def download_finished(self): """Slot called when all the data has been completed. Clears the progress bar and resets it to 0.""" if not self.batch_download_action.isEnabled(): self.batch_download_action.setEnabled(True) self.__step = 0 self.progress.hide() def update_progress(self): "Update the progress bar." if not self.progress.isVisible(): self.progress.show() self.__step += 1 self.progress.setValue(self.__step) def clear(self, clear_pool=True): "Clear the central widget." if self.thumbnailarea is None: return self.thumbnailarea.clear() self.tag_dock.widget().clear() if clear_pool: self.pool_dock.widget().clear() self.batch_download_action.setEnabled(False) def clean_cache(self): "Purge the thumbnail cache." self.cache.discard() self.statusBar().showMessage(i18n("Thumbnail cache cleared.")) def batch_download_slot(self, job): """Slot called when doing batch download, for each file retrieved. If Nepomuk tagging is enabled, each file is tagged using the item's respective tags. """ if job.error(): job.ui().showErrorMessage() else: if self.preferences.nepomuk_enabled: tags = job.property("tags").toPyObject() #danbooru2nepomuk.tag_danbooru_item(job.destUrl().path(), # tags) def tag_display(self, state): """Display or hide the tag dock.""" if self.tag_dock is None: self.tag_display_action.setActive(False) return if state: self.tag_dock.show() else: self.tag_dock.hide()
class KateReload(QObject): def __init__(self): QObject.__init__(self) self.window = kate.mainInterfaceWindow().window() kate.configuration.root.clear() self.act = KAction(KIcon("reload"), i18n("Auto Reload"), self) self.act.setObjectName("auto reload") self.window.actionCollection().addAction(self.act.objectName(), self.act) self.window.findChild(QMenu, 'view').addAction(self.act) if not self.act.objectName() in kate.configuration: kate.configuration[self.act.objectName()] = "alt+r" self.act.setShortcut(kate.configuration[self.act.objectName()]) self.act.setCheckable(True) self.act.setChecked(False) self.act.changed.connect(self.onActionChange) self.act.toggled.connect(self.toggle) kate.mainInterfaceWindow().viewChanged.connect(self.onViewChanged) def onViewChanged(self): try: doc = sip.cast(kate.activeDocument(), KateDocument) except kate.api.NoActiveView: return self.act.blockSignals(True) if doc.property('AutoReload'): self.act.setChecked(True) else: self.act.setChecked(False) self.act.blockSignals(False) def onActionChange(self): kate.configuration[self.sender().objectName()] = self.sender().shortcut().toString() kate.configuration.save() def toggle(self, state): doc = sip.cast(kate.activeDocument(), KateDocument) if state == True: self.enable(doc) else: self.disable(doc) def enable(self, doc): if doc.url() == '': self.act.blockSignals(True) showError(i18n('Can\'t auto-reload unsaved file')) self.act.setChecked(False) self.act.blockSignals(False) return doc.setModifiedOnDiskWarning(False) doc.modifiedOnDisk.connect(doc.documentReload) doc.setProperty('AutoReload', True) showOk(i18n('Auto-Reload enabled')) def disable(self, doc): if doc.property('AutoReload'): doc.setModifiedOnDiskWarning(True) doc.modifiedOnDisk.disconnect(doc.documentReload) doc.setProperty('AutoReload', False) showOk(i18n('Auto-Reload disabled')) else: print('Error disabled called on something with no auto-reload')
def setupActions(self): """Sets up all actions (signal/slot combinations).""" # standard action KStandardAction.quit(g_app.quit, self.actionCollection()) # dictionary actions self.dictionaryPage.registerGlobalActions(self.actionCollection()) # update dictionaries if self.updateDialog: self.updateAction = self.updateDialog.updateAction( self.actionCollection()) # optimise database self.updateDialog.optimiseAction(self.actionCollection()) else: self.updateAction = None # search bar self.characterCombo = KHistoryComboBox() self.characterCombo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) font = QFont() font.setPointSize(13) self.characterCombo.setFont(font) self.characterCombo.setObjectName("characterCombo") self.connect(self.characterCombo, SIGNAL("activated(const QString &)"), self.slotCharacterComboActivated) comboAction = KAction(self) comboAction.setText(i18n("Search bar")) comboAction.setShortcut(Qt.Key_F6) self.connect(comboAction, SIGNAL("triggered()"), self.slotSearchComboActivated) comboAction.setDefaultWidget(self.characterCombo) comboAction.setWhatsThis( i18n("<html>Search bar<br/><br/>Enter character of search string</html>")) self.actionCollection().addAction("searchbar", comboAction) goUrl = self.actionCollection().addAction("go_search") goUrl.setIcon(KIcon("go-jump-locationbar")) goUrl.setText(i18n("Go")) self.connect(goUrl, SIGNAL("triggered()"), lambda: self.slotCharacterComboActivated( self.characterCombo.currentText())) goUrl.setWhatsThis( i18n("<html>Go<br /><br />Searches for the string given in the search bar.</html>")) # clear search bar action clearLocationAction = KAction(KIcon("edit-clear-locationbar-ltr"), i18n("Clear &Location Bar"), self) clearLocationAction.setShortcut(Qt.CTRL + Qt.Key_L) clearLocationAction.setWhatsThis( i18n("Clears the location bar and places the cursor inside")) self.actionCollection().addAction("clearlocationbar", clearLocationAction) self.connect(clearLocationAction, SIGNAL("triggered(bool)"), self.characterCombo.clearEditText) self.connect(clearLocationAction, SIGNAL("triggered(bool)"), self.characterCombo.setFocus) # show/hide character page self.toggleToolboxAction = KToggleAction(KIcon("view-sidetree"), i18n("Show Character Toolbox"), self) self.toggleToolboxAction.setShortcut(Qt.Key_F9) self.toggleToolboxAction.setWhatsThis( i18n("Shows and Hides the character choosing toolbox")) self.actionCollection().addAction("showtoolbox", self.toggleToolboxAction) self.connect(self.toggleToolboxAction, SIGNAL("triggered(bool)"), self.slotToggleToolbox) # auto-lookup clipboard self.autoLookupAction = KToggleAction(i18n("&Auto-Lookup"), self) self.autoLookupAction.setToolTip( i18n("Automatically look up text selected by the mouse cursor.")) self.autoLookupAction.setWhatsThis( i18n("Automatically look up text selected by the mouse cursor.")) self.actionCollection().addAction("autolookup", self.autoLookupAction) self.connect(self.autoLookupAction, SIGNAL("triggered(bool)"), self.setAutoLookup) self.autoLookupAction.setIcon( QIcon(util.getIcon('auto-lookup-selection.png'))) self.connect(QApplication.clipboard(), SIGNAL("selectionChanged()"), self.slotSelectionChanged)
class UpdateDialog(KDialog): def __init__(self, mainWindow, renderThread, pluginConfig=None): KDialog.__init__(self, mainWindow) self.renderThread = renderThread self.databaseUrl = None if pluginConfig: self.databaseUrl = util.readConfigString(self.pluginConfig, "Update database url", None) if not self.databaseUrl: self.databaseUrl = unicode('sqlite:///' + util.getLocalData('dictionaries.db')) self.renderThread.setObject(DictionaryInfo, databaseUrl=self.databaseUrl) self.setCaption(i18n("Install/Update Dictionaries")) self.setButtons(KDialog.ButtonCode(KDialog.Close)) self.enableButton(KDialog.Cancel, False) # TODO can we defer the creation of the update widget until the dialog is shown? self.updateWidget = UpdateWidget(mainWindow, renderThread, pluginConfig) self.connect(self.updateWidget, SIGNAL("working(bool)"), self.slotUpdateWorking) self.setMainWidget(self.updateWidget) self.connect(self, SIGNAL("finished()"), self.slotFinish) self.initialised = False self.connect(self.renderThread, SIGNAL("jobFinished"), self.contentRendered) self.connect(self.renderThread, SIGNAL("jobErrorneous"), self.renderingFailed) self.actionCollection = KActionCollection(self) self.setupActions() def showEvent(self, event): if not self.initialised: self.initialised = True self.loadDatabaseBuilder() self.updateWidget.setup() def setupActions(self): # update dictionaries self._updateAction = KAction(KIcon('system-software-update'), i18n("&Update..."), self) self.actionCollection.addAction("updatedictionaries", self._updateAction) self._updateAction.setWhatsThis( i18n("Download and update dictionaries.")) self.connect(self._updateAction, SIGNAL("triggered(bool)"), self.exec_) # optimise database self._optimiseAction = KAction(KIcon('system-run'), i18n("&Optimise database"), self) self.actionCollection.addAction("optimisedatabase", self._optimiseAction) self._optimiseAction.setWhatsThis( i18n("Rearranges and optimises the database.")) self._optimiseAction.setEnabled(True) # TODO self.connect(self._optimiseAction, SIGNAL("triggered(bool)"), self.slotOptimiseDatabase) def updateAction(self, actionCollection): actionCollection.addAction(self._updateAction.objectName(), self._updateAction) return self._updateAction def optimiseAction(self, actionCollection): actionCollection.addAction(self._optimiseAction.objectName(), self._optimiseAction) return self._optimiseAction def slotUpdateWorking(self, working): if working: self.setButtons(KDialog.ButtonCode(KDialog.Cancel)) else: self.setButtons(KDialog.ButtonCode(KDialog.Close)) def slotFinish(self): if self.updateWidget.isWorking(): self.updateWidget.cancel() def slotOptimiseDatabase(self): self.loadDatabaseBuilder() dbBuild = self.renderThread.getObjectInstance(build.DatabaseBuilder) if dbBuild.isOptimizable(): if KMessageBox.warningContinueCancel(self, i18n("This operation might take some time."), i18n("Optimise Database"), KStandardGuiItem.cont(), KStandardGuiItem.cancel(), 'database_optimise') \ == KMessageBox.Continue: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.currentJob = self.renderThread.enqueue( build.DatabaseBuilder, 'optimize') def loadDatabaseBuilder(self): if not self.renderThread.hasObject(build.DatabaseBuilder): options = EclectusCommandLineBuilder.getDefaultOptions() db = getDBConnector(getDatabaseConfiguration(self.databaseUrl)) self.renderThread.setObject(build.DatabaseBuilder, dbConnectInst=db, **options) def contentRendered(self, id, classObject, method, args, param, content): if classObject == build.DatabaseBuilder and method == 'optimize': QApplication.restoreOverrideCursor() def renderingFailed(self, id, classObject, method, args, param, e, stacktrace): if classObject == build.DatabaseBuilder and method == 'optimize': print >>sys.stderr, stacktrace QApplication.restoreOverrideCursor()
class KateReload(QObject): def __init__(self): QObject.__init__(self) self.window = kate.mainInterfaceWindow().window() kate.configuration.root.clear() self.act = KAction(KIcon("reload"), i18n("Auto Reload"), self) self.act.setObjectName("auto reload") self.window.actionCollection().addAction(self.act.objectName(), self.act) self.window.findChild(QMenu, 'view').addAction(self.act) if not self.act.objectName() in kate.configuration: kate.configuration[self.act.objectName()] = "alt+r" self.act.setShortcut(kate.configuration[self.act.objectName()]) self.act.setCheckable(True) self.act.setChecked(False) self.act.changed.connect(self.onActionChange) self.act.toggled.connect(self.toggle) kate.mainInterfaceWindow().viewChanged.connect(self.onViewChanged) def onViewChanged(self): try: doc = sip.cast(kate.activeDocument(), KateDocument) except kate.api.NoActiveView: return self.act.blockSignals(True) if doc.property('AutoReload'): self.act.setChecked(True) else: self.act.setChecked(False) self.act.blockSignals(False) def onActionChange(self): kate.configuration[ self.sender().objectName()] = self.sender().shortcut().toString() kate.configuration.save() def toggle(self, state): doc = sip.cast(kate.activeDocument(), KateDocument) if state == True: self.enable(doc) else: self.disable(doc) def enable(self, doc): if doc.url() == '': self.act.blockSignals(True) showError(i18n('Can\'t auto-reload unsaved file')) self.act.setChecked(False) self.act.blockSignals(False) return doc.setModifiedOnDiskWarning(False) doc.modifiedOnDisk.connect(doc.documentReload) doc.setProperty('AutoReload', True) showOk(i18n('Auto-Reload enabled')) def disable(self, doc): if doc.property('AutoReload'): doc.setModifiedOnDiskWarning(True) doc.modifiedOnDisk.disconnect(doc.documentReload) doc.setProperty('AutoReload', False) showOk(i18n('Auto-Reload disabled')) else: print('Error disabled called on something with no auto-reload')
def kaction(name, actionCollection=None, callable=None): # Create the toolbar action and insert it into the toolbar_actions dict global parent global action_definitions global action_groups config = action_definitions.get(name, None) if config is None: print "ERR: No config for action:", name return None #Without the config no action can be created action = KAction(parent) if "group" in config: group_name = config["group"] if group_name in action_groups: group = action_groups[group_name] else: group = QtGui.QActionGroup(parent) action_groups[group_name] = group action.setActionGroup(group) if "icon" in config: action.setIcon(KIcon(config["icon"])) if "checkable" in config: action.setCheckable(True) # Same exception is wanted here. As an alternative one can specify a callable as a parameter. if callable is not None: action.triggered.connect(callable) else: action.triggered.connect(config["action"]) if "text" in config: action.setText(config["text"]) if "tooltip" in config: action.setToolTip(config["tooltip"]) if "whatsthis" in config: action.setWhatsThis(config["whatsthis"]) if actionCollection is not None: actionCollection.addAction(name, action) return action
def create_toolbar(self): self.toolbar = KToolBar(self, True, True) self.toolbar.setIconDimensions(16) self.toolbar.setAllowedAreas(QtCore.Qt.BottomToolBarArea) self.toolbar.setMovable(False) self.toolbar.setFloatable(False) self.toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) self.addToolBar(QtCore.Qt.BottomToolBarArea, self.toolbar) self.toolbar.show() self.action_collection = KActionCollection(self) self.action_collection.addAssociatedWidget(self.toolbar) self.clear_live_action = self.action_collection.addAction( "clear_live_action") icon = QtGui.QIcon(":texter/images/edit-clear.png") self.clear_live_action.setIcon(icon) self.clear_live_action.setIconText("clear live") self.clear_live_action.setShortcut( KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_Q)), KAction.ShortcutTypes(KAction.ActiveShortcut | KAction.DefaultShortcut)) self.save_live_action = self.action_collection.addAction( "save_live_action") icon = QtGui.QIcon(":texter/images/document-new.png") self.save_live_action.setIcon(icon) self.save_live_action.setIconText("save live") self.save_live_action.setShortcut( KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_W)), KAction.ShortcutTypes(KAction.ActiveShortcut | KAction.DefaultShortcut)) self.clear_preview_action = self.action_collection.addAction( "clear_preview_action") icon = QtGui.QIcon(":texter/images/edit-clear.png") self.clear_preview_action.setIcon(icon) self.clear_preview_action.setIconText("clear preview") self.clear_preview_action.setShortcut( KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_A)), KAction.ShortcutTypes(KAction.ActiveShortcut | KAction.DefaultShortcut)) self.save_preview_action = self.action_collection.addAction( "save_preview_action") icon = QtGui.QIcon(":texter/images/document-new.png") self.save_preview_action.setIcon(icon) self.save_preview_action.setIconText("save preview") self.save_preview_action.setShortcut( KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_S)), KAction.ShortcutTypes(KAction.ActiveShortcut | KAction.DefaultShortcut)) self.publish_action = self.action_collection.addAction( "publish_action") icon = QtGui.QIcon(":texter/images/edit-copy.png") self.publish_action.setIcon(icon) self.publish_action.setIconText("publish") self.publish_action.setShortcutConfigurable(True) self.publish_action.setShortcut( KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_Return)), KAction.ShortcutTypes(KAction.ActiveShortcut | KAction.DefaultShortcut)) self.toolbar.insertSeparator(self.publish_action) self.auto_publish_action = KToggleAction(self.action_collection) self.action_collection.addAction("auto publish", self.auto_publish_action) icon = QtGui.QIcon(":texter/images/view-refresh.png") self.auto_publish_action.setIcon(icon) self.auto_publish_action.setObjectName("auto_publish_action") self.auto_publish_action.setIconText("auto publish") self.auto_publish_action.setShortcut( KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_P)), KAction.ShortcutTypes(KAction.ActiveShortcut | KAction.DefaultShortcut)) self.typer_animation_action = KToggleAction(self.action_collection) icon = QtGui.QIcon(":texter/images/media-playback-stop.png") self.typer_animation_action.setIcon(icon) self.typer_animation_action.setIconText("animate") self.typer_animation_action.setObjectName("typer_animation_action") self.typer_animation_action.setShortcut( KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_M)), KAction.ShortcutTypes(KAction.ActiveShortcut | KAction.DefaultShortcut)) self.action_collection.addAction("typer_animation_action", self.typer_animation_action) self.text_editor_action = self.action_collection.addAction( "text_editor_action") icon = QtGui.QIcon(":texter/images/document-open-data.png") self.text_editor_action.setIcon(icon) self.text_editor_action.setIconText("edit") self.text_editor_action.setShortcut( KShortcut(QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_O)), KAction.ShortcutTypes(KAction.ActiveShortcut | KAction.DefaultShortcut)) self.toolbar.insertSeparator(self.text_editor_action) self.save_action = self.action_collection.addAction("save_action") icon = QtGui.QIcon(":texter/images/document-save.png") self.save_action.setIcon(icon) self.save_action.setIconText("save") self.save_action.setShortcut( KShortcut(QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_S)), KAction.ShortcutTypes(KAction.ActiveShortcut | KAction.DefaultShortcut)) self.streaming_action = KToggleAction(self.action_collection) icon = QtGui.QIcon(":texter/images/media-record.png") self.streaming_action.setIcon(icon) self.streaming_action.setIconText("stream") self.streaming_action.setObjectName("stream") self.streaming_action.setShortcut( KShortcut(QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_1)), KAction.ShortcutTypes(KAction.ActiveShortcut | KAction.DefaultShortcut)) self.action_collection.addAction("stream", self.streaming_action) spacer = KToolBarSpacerAction(self.action_collection) self.action_collection.addAction("1_spacer", spacer) self.previous_action = self.action_collection.addAction( "previous_action") icon = QtGui.QIcon(":texter/images/go-previous-view-page.png") self.previous_action.setIcon(icon) self.previous_action.setIconText("previous") self.previous_action.setShortcut( KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_Left)), KAction.ShortcutTypes(KAction.ActiveShortcut | KAction.DefaultShortcut)) self.text_combo = KSelectAction(self.action_collection) self.text_combo.setEditable(False) icon = QtGui.QIcon(":texter/images/document-open-recent.png") self.text_combo.setIcon(icon) self.text_combo.setIconText("saved texts") self.text_combo.setObjectName("text_combo") self.action_collection.addAction("saved texts", self.text_combo) self.next_action = self.action_collection.addAction("next_action") icon = QtGui.QIcon(":texter/images/go-next-view-page.png") self.next_action.setIcon(icon) self.next_action.setIconText("next") self.next_action.setShortcut( KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_Right)), KAction.ShortcutTypes(KAction.ActiveShortcut | KAction.DefaultShortcut)) self.toolbar.addSeparator() self.save_action.triggered.connect(self.slot_save) self.publish_action.triggered.connect(self.slot_publish) self.clear_live_action.triggered.connect(self.slot_clear_live) self.clear_preview_action.triggered.connect(self.slot_clear_preview) self.text_combo.triggered[int].connect(self.slot_load_preview_text) self.text_editor_action.triggered.connect(self.slot_open_dialog) self.save_live_action.triggered.connect(self.slot_save_live_text) self.save_preview_action.triggered.connect(self.slot_save_preview_text) self.streaming_action.triggered.connect(self.slot_toggle_streaming) self.auto_publish_action.toggled.connect(self.slot_auto_publish) self.typer_animation_action.toggled.connect(self.slot_toggle_animation) self.preview_size_action.triggered[QtGui.QAction].connect( self.slot_preview_font_size) self.live_size_action.triggered[QtGui.QAction].connect( self.slot_live_font_size) self.next_action.triggered.connect(self.slot_next_item) self.previous_action.triggered.connect(self.slot_previous_item) self.streaming_action.setChecked(True)
def __init__(self, parent, description, item, target): KAction.__init__(self, description, parent) self.item = item self.connect(self, SIGNAL("triggered()"), self.on_triggered) self.connect(self, SIGNAL("actionSig"), target)
def __init__(self, menu, macro, callback): KAction.__init__(self, macro.TITLE.toString(), menu) self.macro = macro self.callback = callback self.connect(self, SIGNAL("triggered()"), self.on_triggered ) # TODO: SIGNAL deprecated and removed in PyQt5
class MainWindow(KXmlGuiWindow): "Class which displays the main Danbooru Client window." def __init__(self, *args): "Initialize a new main window." super(MainWindow, self).__init__(*args) self.cache = KPixmapCache("danbooru") self.preferences = preferences.Preferences() self.api = None self.__ratings = None self.__step = 0 self.url_list = self.preferences.boards_list self.max_retrieve = self.preferences.thumbnail_no self.statusbar = self.statusBar() self.progress = QProgressBar() self.thumbnailarea = None self.tag_dock = None self.pool_dock = None self.first_fetch_widget = None self.progress.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) # FIXME: Hackish, but how to make it small otherwise? self.progress.setMinimumSize(100, 1) self.statusbar.addPermanentWidget(self.progress) self.progress.hide() self.setup_welcome_widget() self.setup_actions() def reload_config(self): """Reload configuration after a change""" urls = self.preferences.boards_list if self.first_fetch_widget is not None: self.first_fetch_widget.setup_urls(urls) if self.thumbnailarea is not None: max_thumbnail = self.preferences.thumbnail_no max_rating = self.preferences.max_allowed_rating self.thumbnailarea.fetchwidget.limit = max_thumbnail self.thumbnailarea.fetchwidget.rating = max_rating self.thumbnailarea.fetchwidget.update_values() self.thumbnailarea.connectwidget.setup_urls(urls) self.url_list = self.preferences.boards_list self.max_retrieve = self.preferences.thumbnail_no def setup_welcome_widget(self): """Load the welcome widget at startup.""" widget = QWidget() layout = QVBoxLayout() welcome = QLabel(parent=self) pix = QPixmap(KStandardDirs.locate("appdata", "logo.png")) welcome.setPixmap(pix) welcome.setAlignment(Qt.AlignCenter) self.first_fetch_widget = connectwidget.ConnectWidget( self.preferences.boards_list, self) self.statusbar.addPermanentWidget(self.first_fetch_widget, 300) self.first_fetch_widget.connectionEstablished.connect( self.handle_connection) self.first_fetch_widget.rejected.connect(self.first_fetch_widget.hide) self.first_fetch_widget.hide() self.first_fetch_widget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) layout.addWidget(self.first_fetch_widget) layout.addWidget(welcome) widget.setLayout(layout) self.setCentralWidget(widget) def setup_tooltips(self): """Set tooltips for the actions.""" self.connect_action.setToolTip(i18n("Connect to a Danbooru board")) self.fetch_action.setToolTip( i18n("Fetch thumbnails from a Danbooru board")) self.batch_download_action.setToolTip(i18n("Batch download images")) def create_actions(self): """Create actions for the main window.""" self.connect_action = KAction(KIcon("document-open-remote"), i18n("Connect"), self) self.fetch_action = KAction(KIcon("download"), i18n("Download"), self) self.clean_action = KAction(KIcon("trash-empty"), i18n("Clear thumbnail cache"), self) self.batch_download_action = KAction(KIcon("download"), i18n("Batch download"), self) self.pool_toggle_action = KToggleAction(KIcon("image-x-generic"), i18n("Pools"), self) self.tag_display_action = KDualAction(i18n("Show tags"), i18n("Hide tags"), self) self.tag_display_action.setIconForStates(KIcon("image-x-generic")) self.tag_display_action.setEnabled(False) # Shortcuts connect_default = KAction.ShortcutTypes(KAction.DefaultShortcut) connect_active = KAction.ShortcutTypes(KAction.ActiveShortcut) self.connect_action.setShortcut(KStandardShortcut.open()) self.fetch_action.setShortcut(KStandardShortcut.find()) self.fetch_action.setEnabled(False) self.batch_download_action.setEnabled(False) self.pool_toggle_action.setEnabled(False) def setup_action_collection(self): """Set up the action collection by adding the actions.""" action_collection = self.actionCollection() # Addition to the action collection action_collection.addAction("connect", self.connect_action) action_collection.addAction("fetch", self.fetch_action) action_collection.addAction("clean", self.clean_action) action_collection.addAction("batchDownload", self.batch_download_action) action_collection.addAction("poolDownload", self.pool_toggle_action) action_collection.addAction("tagDisplay", self.tag_display_action) KStandardAction.quit(self.close, action_collection) KStandardAction.preferences(self.show_preferences, action_collection) action_collection.removeAction( action_collection.action("help_contents")) action_collection.actionHovered.connect(self.setup_action_tooltip) def setup_actions(self): """Set up the relevant actions, tooltips, and load the RC file.""" self.create_actions() self.setup_tooltips() self.setup_action_collection() # Connect signals self.connect_action.triggered.connect(self.connect) self.fetch_action.triggered.connect(self.get_posts) self.clean_action.triggered.connect(self.clean_cache) self.batch_download_action.triggered.connect(self.batch_download) self.pool_toggle_action.toggled.connect(self.pool_toggle) self.tag_display_action.activeChanged.connect(self.tag_display) window_options = self.StandardWindowOption(self.ToolBar | self.Keys | self.Create | self.Save | self.StatusBar) setupGUI_args = [ QSize(500, 400), self.StandardWindowOption(window_options) ] #Check first in standard locations for danbooruui.rc rc_file = KStandardDirs.locate("appdata", "danbooruui.rc") if rc_file.isEmpty(): setupGUI_args.append(os.path.join(sys.path[0], "danbooruui.rc")) else: setupGUI_args.append(rc_file) self.setupGUI(*setupGUI_args) def setup_action_tooltip(self, action): "Show statusbar help when actions are hovered." if action.isEnabled(): self.statusBar().showMessage(action.toolTip(), 2000) def setup_connections(self): """Set up connections for post and tag retrieval.""" if self.api is None: return self.api.postRetrieved.connect(self.update_progress) self.api.postDownloadFinished.connect(self.download_finished) self.api.tagRetrieved.connect(self.tag_dock.widget().add_tags) self.tag_dock.widget().itemDoubleClicked.connect( self.fetch_tagged_items) def show_preferences(self): "Show the preferences dialog." if KConfigDialog.showDialog("Preferences dialog"): return else: dialog = preferences.PreferencesDialog(self, "Preferences dialog", self.preferences) dialog.show() dialog.settingsChanged.connect(self.reload_config) def connect(self, ok): "Connect to a Danbooru board." if self.thumbnailarea is None: self.first_fetch_widget.show() else: self.thumbnailarea.connectwidget.show() def restore(self): self.statusbar.removeWidget(self.connect_widget) def handle_connection(self, connection): self.api = None self.api = connection self.api.cache = self.cache if self.pool_dock is not None: self.pool_dock.hide() self.pool_dock.widget().clear() self.pool_toggle_action.setChecked(False) if self.thumbnailarea is not None: #TODO: Investigate usability self.clear(clear_pool=True) self.thumbnailarea.clear() self.thumbnailarea.api_data = self.api self.setup_connections() else: self.first_fetch_widget.connectionEstablished.disconnect() self.first_fetch_widget.rejected.disconnect() self.statusbar.removeWidget(self.first_fetch_widget) self.setup_area() self.api.cache = self.cache self.statusBar().showMessage(i18n("Connected to %s" % self.api.url), 3000) self.fetch_action.setEnabled(True) # Set up pool widget pool_widget = poolwidget.DanbooruPoolWidget(self.api) self.pool_dock = QDockWidget("Pools", self) self.pool_dock.setObjectName("PoolDock") self.pool_dock.setAllowedAreas(Qt.BottomDockWidgetArea) self.pool_dock.setWidget(pool_widget) #self.pool_dock.setFeatures(QDockWidget.NoDockWidgetFeatures) self.addDockWidget(Qt.BottomDockWidgetArea, self.pool_dock) self.pool_dock.widget().poolDownloadRequested.connect( self.pool_prepare) self.pool_dock.hide() self.pool_toggle_action.setEnabled(True) self.clear() # Needed to show properly the stuff after connecting self.api.get_post_list(tags="", limit=self.thumbnailarea.post_limit, rating=self.preferences.max_allowed_rating, blacklist=list(self.preferences.tag_blacklist)) self.api.get_tag_list(name="", blacklist=list(self.preferences.tag_blacklist), limit=20) def get_posts(self, ok): "Get posts from the connected Danbooru board." if not self.api: return self.thumbnailarea.fetchwidget.show() def handle_fetching(self, tags, max_rating, limit): """Slot connected to the dataSent signal of the fetch widget. The widgets are set up if they don't exist, and the API is queried to do the actual downloading of tags and """ self.clear() self.thumbnailarea.fetchwidget.hide() if self.tag_dock is not None: self.tag_dock.widget().clear() self.thumbnailarea.post_limit = limit blacklist = list(self.preferences.tag_blacklist) self.api.get_post_list(tags=tags, limit=limit, rating=max_rating, blacklist=blacklist) tags = [item for item in tags if item] if not tags: # No related tags, fetch the most recent 20 tags = "" self.api.get_tag_list(name=tags, blacklist=blacklist, limit=20) else: self.api.get_related_tags(tags=tags, blacklist=blacklist) def fetch_tagged_items(self, item): """Fetch items found in the tag list widget.""" tag_name = unicode(item.text()) self.clear() blacklist = self.preferences.tag_blacklist limit = self.preferences.thumbnail_no rating = self.preferences.max_allowed_rating self.api.get_post_list(page=1, tags=[tag_name], blacklist=blacklist, limit=limit, rating=rating) self.api.get_related_tags(tags=[tag_name], blacklist=blacklist) def pool_toggle(self, checked): "Toggle the presence/absence of the pool dock." if not self.api: return if not checked: self.pool_dock.hide() else: self.pool_dock.show() def pool_prepare(self, pool_id): """Prepare the central area for pool image loading.""" if self.thumbnailarea is None: self.setup_area() else: self.clear(clear_pool=False) self.api.get_pool(pool_id, blacklist=self.preferences.tag_blacklist, rating=self.preferences.max_allowed_rating) def batch_download(self, ok): "Download images in batch." selected_items = self.thumbnailarea.selected_images() if not selected_items: return start_url = KUrl("kfiledialog:///danbooru") caption = i18n("Select a directory to save the images to") directory = KFileDialog.getExistingDirectoryUrl( start_url, self, caption) if directory.isEmpty(): return for item in selected_items: file_url = item.url_label.url() tags = item.data.tags # Make a local copy to append paths as addPath works in-place destination = KUrl(directory) file_name = KUrl(file_url).fileName() destination.addPath(file_name) job = KIO.file_copy(KUrl(file_url), destination, -1) job.setProperty("tags", QVariant(tags)) job.result.connect(self.batch_download_slot) def setup_area(self): "Set up the central widget to display thumbnails." self.thumbnailarea = thumbnailarea.DanbooruTabWidget( self.api, self.preferences, self.preferences.thumbnail_no, self) self.setCentralWidget(self.thumbnailarea) self.thumbnailarea.connectwidget.connectionEstablished.connect( self.handle_connection, type=Qt.UniqueConnection) self.thumbnailarea.connectwidget.rejected.connect( self.thumbnailarea.connectwidget.hide, type=Qt.UniqueConnection) self.thumbnailarea.fetchwidget.dataSent.connect( self.handle_fetching, type=Qt.UniqueConnection) self.thumbnailarea.fetchwidget.rejected.connect( self.thumbnailarea.fetchwidget.hide, type=Qt.UniqueConnection) # Set up tag widget blacklist = self.preferences.tag_blacklist tag_widget = tagwidget.DanbooruTagWidget(blacklist, self) self.tag_display_action.setActive(True) self.tag_display_action.setEnabled(True) self.tag_dock = QDockWidget("Similar tags", self) self.tag_dock.setObjectName("TagDock") self.tag_dock.setAllowedAreas(Qt.RightDockWidgetArea) self.tag_dock.setWidget(tag_widget) #self.tag_dock.setFeatures(QDockWidget.NoDockWidgetFeatures) self.addDockWidget(Qt.RightDockWidgetArea, self.tag_dock) self.tag_dock.hide() # Container signal-slot connections self.setup_connections() def download_finished(self): """Slot called when all the data has been completed. Clears the progress bar and resets it to 0.""" if not self.batch_download_action.isEnabled(): self.batch_download_action.setEnabled(True) self.__step = 0 self.progress.hide() def update_progress(self): "Update the progress bar." if not self.progress.isVisible(): self.progress.show() self.__step += 1 self.progress.setValue(self.__step) def clear(self, clear_pool=True): "Clear the central widget." if self.thumbnailarea is None: return self.thumbnailarea.clear() self.tag_dock.widget().clear() if clear_pool: self.pool_dock.widget().clear() self.batch_download_action.setEnabled(False) def clean_cache(self): "Purge the thumbnail cache." self.cache.discard() self.statusBar().showMessage(i18n("Thumbnail cache cleared.")) def batch_download_slot(self, job): """Slot called when doing batch download, for each file retrieved. If Nepomuk tagging is enabled, each file is tagged using the item's respective tags. """ if job.error(): job.ui().showErrorMessage() else: if self.preferences.nepomuk_enabled: tags = job.property("tags").toPyObject() #danbooru2nepomuk.tag_danbooru_item(job.destUrl().path(), # tags) def tag_display(self, state): """Display or hide the tag dock.""" if self.tag_dock is None: self.tag_display_action.setActive(False) return if state: self.tag_dock.show() else: self.tag_dock.hide()