def main(): setStyle() app = QApplication(sys.argv) settings = SettingsWindow() image_output = TestImageOutput(settings) ir_board = ir.IrBoard(image_output) print u"Версия библиотеки инфракрасная ручка ",ir_board.getVersion() win = MainWindow(settings) win.show() tray_menu = QMenu() tray_menu.addAction(QIcon(':/main/restore.png'), u"Восстановить", win.show) tray_menu.addAction(QIcon(':/main/calibrate.png'), u"Калибровка", win.calibrate) tray_menu.addAction(QIcon(':/main/cogwheel.png'), u"Настройка", win.settings_window.show) tray_menu.addSeparator() tray_menu.addAction(QIcon(':/main/close.png'), u"Выход", app.quit) tray = QSystemTrayIcon() tray.setIcon(QIcon(':/main/webcam.png')) tray.setContextMenu(tray_menu) tray.show() return app.exec_()
def create(self, window: QtGui.QMainWindow, parent_menu: QtGui.QMenu): if self.disabled: return if callable(self.method_name): method = self.method_name else: method = getattr(window, self.method_name) if self.sep: parent_menu.addSeparator() if self.submenu: menu = QtGui.QMenu(self.verbose_name, p(parent_menu)) if self.icon: action = parent_menu.addMenu(get_icon(self.icon), menu) else: action = parent_menu.addMenu(menu) action.hovered.connect(functools.partial(self.fill_submenu, window, menu, method)) else: if self.icon: action = QtGui.QAction(get_icon(self.icon), self.verbose_name, p(parent_menu)) else: action = QtGui.QAction(self.verbose_name, p(parent_menu)) # noinspection PyUnresolvedReferences action.triggered.connect(method) parent_menu.addAction(action) if self.shortcut: action.setShortcut(self.shortcut) if self.help_text: action.setStatusTip(self.help_text)
def _create_theme_menu(self): theme_menu = QMenu(self) theme_menu.setTitle('Buttons Theme') theme_menu.setTearOffEnabled(True) theme_menu.setWindowTitle(TAG) theme_actions = QActionGroup(self) theme_actions.setExclusive(True) # create ordered theme list custom_order_theme = sorted(THEMES.iterkeys()) custom_order_theme.remove('Maya Theme') custom_order_theme.insert(0, 'Maya Theme') default_item = True for theme in custom_order_theme: current_theme_action = QAction(theme, theme_actions) current_theme_action.setCheckable(True) current_theme_action.setChecked( MTTSettings.value('theme', 'Maya Theme') == theme) current_theme_action.triggered.connect(self.on_change_theme) theme_menu.addAction(current_theme_action) if default_item: theme_menu.addSeparator() default_item = False return theme_menu
def _handle_context_menu(self, pos): index = self.ui.tree_view.indexAt(pos) if index.isValid(): pos = self.ui.tree_view.viewport().mapToGlobal(pos) menu = QMenu() menu.addAction(self.ui.action_mark_watched) menu.addAction(self.ui.action_mark_unwatched) menu.addSeparator() menu.addAction(self.ui.action_remove) menu.exec_(pos)
def contextMenuEvent(self, event): """ Handles the ``contextMenuEvent`` event for :class:`CmdPromptInput`. :param `event`: a `QContextMenuEvent` event to be processed. """ menu = QMenu(self) menu.addSeparator() # TODO: Extra stuff menu.addAction(QAction("TODO: Add Extra stuff", self)) menu.exec_(event.globalPos())
def __setup_stream_menu(self): """ Setup the actions in the context menu. """ m = QMenu(self.parent) watch_action = QAction("Watch", self, triggered=self.watch) videos_action = QAction("Videos", self, triggered=self.videos) web_action = QAction("View on Twitch", self, triggered=self.www_view) remove_action = QAction("Remove", self, triggered=self.remove) m.addAction(watch_action) m.addAction(videos_action) m.addSeparator() m.addAction(web_action) m.addAction(remove_action) return m
def __init__(self, parent=None): icon = self.loadIcon() QSystemTrayIcon.__init__(self, icon, parent) menu = QMenu(parent) VBoxMenu.build(menu) menu.addSeparator() menu.addAction("Exit", lambda: sys.exit(0)) self.connect(menu, SIGNAL("aboutToShow()"), VBoxMenu.check_state) self.setContextMenu(menu) self.setToolTip("VBoxTrayIco") traySignal = "activated(QSystemTrayIcon::ActivationReason)" QObject.connect(self, SIGNAL(traySignal), self.showMenu)
def contextMenuEvent(self, event): """ Handles the ``contextMenuEvent`` event for :class:`MDISubWindow_TextEdit`. :param `event`: a `QContextMenuEvent` event to be processed. """ menu = QMenu(self) menu.addAction(self.action_Edit_Undo) menu.addAction(self.action_Edit_Redo) menu.addSeparator() menu.addAction(self.action_Edit_Cut) menu.addAction(self.action_Edit_Copy) menu.addAction(self.action_Edit_Paste) menu.addAction(self.action_Edit_Delete) menu.addSeparator() menu.addAction(self.action_Edit_SelectAll) menu.popup(self.mapToGlobal(event.pos())) # menu.exec_(self.mapToGlobal(event.pos())) event.accept() print("MDISubWindow_TextEdit contextMenuEvent")
class WebUI(BaseWebUI): def __init__(self, app, hub, debug=False): BaseWebUI.__init__(self, "index.html", app, hub, debug) self.html = index.html self.agent = '%s v%s' % (USER_AGENT, '.'.join(str(v) for v in VERSION)) log("Starting [%s]..." % self.agent, LEVEL_INFO) # Setup the system tray icon if sys.platform == 'darwin': tray_icon = 'sumominer_16x16_mac.png' elif sys.platform == "win32": tray_icon = 'sumominer_16x16.png' else: tray_icon = 'sumominer_32x32_ubuntu.png' self.trayIcon = QSystemTrayIcon(self._getQIcon(tray_icon)) self.trayIcon.setToolTip(tray_icon_tooltip) # Setup the tray icon context menu self.trayMenu = QMenu() self.showAppAction = QAction('&Show %s' % APP_NAME, self) f = self.showAppAction.font() f.setBold(True) self.showAppAction.setFont(f) self.trayMenu.addAction(self.showAppAction) self.aboutAction = QAction('&About...', self) self.trayMenu.addAction(self.aboutAction) self.trayMenu.addSeparator() self.exitAction = QAction('&Exit', self) self.trayMenu.addAction(self.exitAction) # Add menu to tray icon self.trayIcon.setContextMenu(self.trayMenu) # connect signals self.trayIcon.activated.connect(self._handleTrayIconActivate) self.exitAction.triggered.connect(self.handleExitAction) self.aboutAction.triggered.connect(self.handleAboutAction) self.showAppAction.triggered.connect(self._handleShowAppAction) self.app.aboutToQuit.connect(self._handleAboutToQuit) # Setup notification support self.system_tray_running_notified = False self.notifier = Notify(APP_NAME) self.trayIcon.show() def run(self): # load user's pool list # load_pools(self.app.property("AppPath")) self.view.loadFinished.connect(self._load_finished) # self.view.load(qt_core.QUrl(self.url)) self.view.setHtml(index.html, qt_core.QUrl(self.url)) self.resetWindowSize() self.center() self.timer = QTimer(self) self.timer.timeout.connect(self._updateHashRate) self.timer.start(2000) self.wait(1) self.timer2 = QTimer(self) self.timer2.timeout.connect(self._reportError) self.timer2.start(2000) self.trayIcon.show() self.show() def closeEvent(self, event): """ Override QT close event """ event.ignore() self.hide() if not self.system_tray_running_notified: self.notify("%s is still running at system tray." % APP_NAME, "Running Status") self.system_tray_running_notified = True def resetWindowSize(self): ws = qt_core.QSize( WINDOW_WIDTH, HEAD_ROW_HEIGHT + POOL_ROW_HEIGHT*(len([p for p in self.hub.pools.all_pools if not p['is_hidden']])) + BOTTOM_MARGIN) self.setFixedSize(ws) def _getQIcon(self, icon_file): _icon_path = os.path.join(self.app.property("ResPath"), 'icons', icon_file) return QIcon(_icon_path) def _handleTrayIconActivate(self, reason): if reason == QSystemTrayIcon.DoubleClick: self.showNormal() self.activateWindow() def handleExitAction(self, show_confirmation=False): reply = QMessageBox.No if show_confirmation: reply=QMessageBox.question(self,'Exit %s?' % APP_NAME, "Are you sure to exit %s?" % APP_NAME, QMessageBox.Yes,QMessageBox.No) if not show_confirmation or reply==QMessageBox.Yes: self.trayIcon.hide() QTimer.singleShot(250, self.app.quit) def _handleShowAppAction(self): self.showNormal() self.activateWindow() def handleAboutAction(self): self.showNormal() self.about() def _reportError(self): for pool_info in self.hub.pools.all_pools: if 'error' in pool_info: if pool_info['error'] is not None: self.hub.report_error(pool_info['id'], pool_info['error']) else: self.hub.report_error(pool_info['id'], 'ERROR_END') pool_info.pop("error", None) def _updateHashRate(self): _sum_hashrates = 0. for pool_info in self.hub.pools.all_pools: _json = {'pool_id': pool_info['id']} hash_rates = pool_info['hash_report'] if 'hash_report' in pool_info else {} if len(hash_rates) > 0: _hash_rates = dict(hash_rates) _total_hash_rate = reduce(lambda x, y: x+y, [_hash_rates[k] for k in _hash_rates]) _json['hash_rate'] = _total_hash_rate _sum_hashrates += _total_hash_rate pool_info['total_hashrate'] = _total_hash_rate else: _json['hash_rate'] = 0.0 # reset hashrate if 'hash_report' in pool_info and 'thr_list' in pool_info: if pool_info['thr_list'] is not None: for thr in pool_info['thr_list']: pool_info['hash_report'].update({'%d' % thr._thr_id: 0.0}) work_report = pool_info['work_report'] if 'work_report' in pool_info else {} if 'work_submited' in work_report and work_report['work_submited'] > 0: _json['shares_good'] = work_report['work_accepted'] if 'work_accepted' in work_report else 0 _json['shares_total'] = work_report['work_submited'] _json['shares_pct'] = "%.2f%%" % (_json['shares_good']*100.0/_json['shares_total'], ) else: _json['shares_good'] = 0 _json['shares_total'] = 0 _json['shares_pct'] = "0.00%" if 'difficulty' in work_report: _json['difficulty'] = "%.f" % work_report['difficulty'] else: _json['difficulty'] = "0" self.hub.update_hashrate(json.dumps(_json)) self.trayIcon.setToolTip("%s\nHashrate: %s" % (tray_icon_tooltip, human_readable_hashrate(_sum_hashrates))) def _load_finished(self): #This is the actual context/frame a webpage is running in. # Other frames could include iframes or such. main_page = self.view.page() main_frame = main_page.mainFrame() # ATTENTION here's the magic that sets a bridge between Python to HTML main_frame.addToJavaScriptWindowObject("app_hub", self.hub) if self.is_first_load: ## Avoid re-settings on page reload (if happened) change_setting = main_page.settings().setAttribute settings = web_core.QWebSettings change_setting(settings.DeveloperExtrasEnabled, self.debug) change_setting(settings.LocalStorageEnabled, True) change_setting(settings.OfflineStorageDatabaseEnabled, True) change_setting(settings.OfflineWebApplicationCacheEnabled, True) change_setting(settings.JavascriptCanOpenWindows, True) change_setting(settings.PluginsEnabled, False) # Show web inspector if debug on if self.debug: self.inspector = web_core.QWebInspector() self.inspector.setPage(self.view.page()) self.inspector.show() #Tell the HTML side, we are open for business main_frame.evaluateJavaScript("app_ready()") # send pool list to HTML for rendering self.hub.create_pool_list() # Resize main window to fit web content (avoid scroll bars showed) main_page.setViewportSize(main_frame.contentsSize()) #self.setFixedSize(860, 360) # resume mining jobs for p in self.hub.pools.all_pools: if 'is_mining' in p and p['is_mining']: self.hub.start_stop_mining(p['id']) self.is_first_load = False def _handleAboutToQuit(self): log("%s is about to quit..." % APP_NAME, LEVEL_INFO) for pool_info in self.hub.pools.all_pools: if not 'thr_list' in pool_info or pool_info['thr_list'] is None: pool_info['is_mining'] = False else: # shut down threads for thr in pool_info['thr_list']: thr.shutdown() thr.join() # shut down RPC client pool_info['rpc'].shutdown() pool_info['rpc'].join() pool_info['is_mining'] = True # save mining status to resume on next start if manager: manager.shutdown() # save pool list self.hub.pools.save_all() def notify(self, message, title="", icon=None, msg_type=None): if self.notifier.notifier is not None: self.notifier.notify(title, message, icon) else: self.showMessage(message, title, msg_type) def showMessage(self, message, title="", msg_type=None, timeout=2000): """Displays 'message' through the tray icon's showMessage function, with title 'title'. 'type' is one of the enumerations of 'common.MessageTypes'. """ if msg_type is None or msg_type == MSG_TYPE_INFO: icon = QSystemTrayIcon.Information elif msg_type == MSG_TYPE_WARNING: icon = QSystemTrayIcon.Warning elif msg_type == MSG_TYPE_CRITICAL: icon = QSystemTrayIcon.Critical title = "%s - %s" % (APP_NAME, title) if title else APP_NAME self.trayIcon.showMessage(title, message, icon, timeout) def about(self): QMessageBox.about(self, "About", \ u"%s <br><br>Copyright© 2017 - Sumokoin Projects<br><br>\ <b>www.sumokoin.org</b>" % self.agent) def wait(self, timeout=1): for _ in range(timeout*10): sleep(0.1) self.app.processEvents()
class MenuNode(object): _currentMenuContext = None """docstring for MenuNode""" def __init__(self, option, parent, menubar = None): if isinstance(option ,(str,unicode)): blobs = option.split('|') _option={ 'label':blobs[0] } l = len(blobs) if l>1: _option['shortcut'] = blobs[1] if l>2: _option['help'] = blobs[2] option = _option self.qtmenubar = menubar self.qtaction = None self.qtmenu = None # self.qtaction = None self.owner = None self.parent = parent signal = option.get( 'signal', None ) self.setSignal(signal) self.mgr = parent and parent.mgr self.owner = parent and parent.owner self.children = [] self.label = option.get('label', 'UNNAMED') self.name = option.get('name',self.label.replace('&','').replace(' ','_')) self.name = self.name.lower() self.shortcut = option.get( 'shortcut', False ) self.help = option.get( 'help', '' ) self.priority = option.get( 'priority', 0 ) self.itemType = option.get( 'type', False ) self.onClick = option.get( 'on_click', None ) self.cmd = option.get( 'command', None ) self.cmdArgs = option.get( 'command_args', None ) self.link = None self.menuType = self.qtmenubar and 'menubar' or 'item' children = option.get( 'children', None ) link = option.get( 'link', None ) if children or self.itemType == 'menu': if self.menuType != 'menubar': self.menuType = 'menu' self.itemType = False elif link: self.link = link if self.menuType != 'menubar': self.menuType = 'link' elif parent and parent.menuType == 'menubar': self.menuType = 'menu' if self.menuType == 'menu' : self.qtmenu = QMenu(self.label) if not parent or parent.menuType == 'root': return parent.addChildControl(self) if self.itemType == 'check': checked = option.get('checked',False) self.setValue(checked or False) if children: for data in children: self.addChild(data) # self.mgr.addNodeIndex(self) def getFullName(self): if parent: return parent.getFullName()+'/'+self.name return self.name def addChild( self, option, owner = None ): if option=='----': if self.qtmenu: self.qtmenu.addSeparator() elif isinstance(option, list): output=[] for data in option: n = self.addChild(data) if n : output.append(n) if owner: n.owner = owner return output else: node = MenuNode(option, self) if owner: node.owner = owner self.children.append(node) return node def addChildControl(self, child): childType = child.menuType selfType = self.menuType if selfType=='menu': if childType=='menu': child.qtaction = self.qtmenu.addMenu(child.qtmenu) elif child.link: qtmenu = child.link.qtmenu child.qtaction = self.qtmenu.addMenu(qtmenu) else: action = QtGui.QAction(child.label, None, shortcut = child.shortcut, statusTip = child.help, checkable = child.itemType=='check', triggered = child.handleEvent ) self.qtmenu.addAction(action) child.qtaction = action elif selfType=='menubar': if childType=='menu': self.qtmenubar.addMenu(child.qtmenu) child.qtaction = child.qtmenu.menuAction() else: logging.warning('attempt to add menuitem/link to a menubar') return else: logging.warning('menuitem has no child') def setEnabled(self, enabled): #todo: set state of linked item selfType = self.menuType if selfType == 'menubar': self.qtmenubar.setEnable(enabled) return if self.qtmenu: self.qtmenu.setEnabled(enabled) else: self.qtaction.setEnabled(enabled) def remove(self): self.clear() self.parent.children.remove(self) selfType = self.menuType if not self.parent: return if selfType=='menubar': return parentType = self.parent.menuType if parentType == 'menu': self.parent.qtmenu.removeAction( self.qtaction ) elif parentType == 'menubar': self.parent.qtmenubar.removeAction( self.qtaction ) logging.info('remove menunode:' + self.name ) def clear( self ): if self.menuType in [ 'menu', 'menubar' ]: for node in self.children[:]: node.remove() def findChild(self,name): name = name.lower() for c in self.children: if c.name==name: return c return None def getValue(self): if self.itemType in ('check','radio'): return self.qtaction.isChecked() return True def setValue(self, v): if self.itemType in ('check','radio'): self.qtaction.setChecked(v and True or False) def setSignal(self, signal): if isinstance(signal, (str, unicode)): signal = signals.get(signal) self.signal = signal def popUp( self, **option ): if self.qtmenu: context = option.get( 'context', None ) MenuNode._currentMenuContext = context self.qtmenu.exec_(QtGui.QCursor.pos()) def getContext( self ): return MenuNode._currentMenuContext def setOnClick(self, onClick): self.onClick = onClick def handleEvent(self): itemtype = self.itemType value = self.getValue() logging.debug( 'menu event:' + self.name ) if self.owner: if hasattr( self.owner, 'onMenu' ): self.owner.onMenu( self ) if self.signal: self.signal(value) if self.onClick != None: self.onClick(value) if self.cmd: args = self.cmdArgs or {} app.doCommand( self.cmd, **args ) MenuNode._currentMenuContext = None
class Indicator(QSystemTrayIcon): """Indicator applet class""" notes_get = Signal(list) def __init__(self, app, *args, **kwargs): """Init indicator Keyword Arguments: app -- QApplication Returns: None """ QSystemTrayIcon.__init__(self, *args, **kwargs) self._action_threads = [] self._cached_notes = {} self.menu = QMenu() self.setContextMenu(self.menu) self.app = app app.indicator = self self.menu.aboutToShow.connect(self.update) self.auth_dialog = AuthDialog(self.app) self._notes = [] self.notes_get.connect(self.notes_getted) self.get_notes() @Slot(list) def notes_getted(self, notes): self._notes = notes def get_notes(self): self.app.sync_thread.action_receive.emit(( self.app.provider.get_notes, ('', 10), {}, self.notes_get, )) @Slot() def update(self): """Set notes to menu""" self.menu.clear() self._open_slots = [] if self.app.authenticated: for note in self._notes: slot = Slot()(partial(self.show_note, note[1])) self._open_slots.append(slot) self.menu.addAction( note[2][:40], slot, ) self.menu.addSeparator() self.menu.addAction( self.tr('New note'), self.new_note, ) self.menu.addAction( self.tr('Auth settings'), self.auth_settings, ) else: self.menu.addAction( self.tr('Please authorise'), self.auth_settings, ) self.menu.addAction(self.tr('Exit'), self.app.end) self.get_notes() @Slot() def new_note(self): """Create new note""" self.show_note(None, True) @Slot() def auth_settings(self): """Show auth settings dialog""" self.auth_dialog.show() def show_note(self, id, create=False): """Show note""" if create: note = None else: note = self.app.provider.get_note(id) prev = self.app.opened.get(id, None) if not prev or getattr(prev, 'closed', False): self.app.opened[id] = NoteWindow(self.app, note, create) self.app.opened[id].show()
def handleEvents(self, event, signals): att = self.axisOrder[self.findAxisIndex(event.x)] # context menu if event.contextRequested: contextMenu = QMenu(self) contextMenu.addAction(u'Select all') contextMenu.addAction(u'Select none') contextMenu.addSeparator() act = QAction(u'Hide Axis', self) contextMenu.addAction(act) if len(self.axisOrder) <= 1: act.setEnabled(False) axesMenu = QMenu(u'Show/Hide Axes', self) axesActions = QActionGroup(self) for a in self.axisOrder: act = QAction(a,self,checkable=True) if self.axes[a].visible: act.toggle() if len(self.axisOrder) <= 1: act.setEnabled(False) axesActions.addAction(act) for act in axesActions.actions(): axesMenu.addAction(act) contextMenu.addMenu(axesMenu) contextMenu.addSeparator() contextMenu.addAction(u'Use as X axis') contextMenu.addAction(u'Use as Y axis') resultAction = contextMenu.exec_(QCursor.pos()) if resultAction != None and resultAction != 0: # Select all if resultAction.text() == u'Select all': self.app.intMan.newOperation(operation.ALL,att=att.dataAxis) # Select none if resultAction.text() == u'Select none': self.app.intMan.newOperation(operation.NONE,att=att.dataAxis) # Hide axis if resultAction.text() == u'Hide Axis': self.toggleVisible(att) # Toggle axis if resultAction.actionGroup() == axesActions: self.toggleVisible(resultAction.text()) # X axis if resultAction.text() == u'Use as X axis': if self.app.currentYattribute != self.app.currentXattribute: self.axes[self.app.currentXattribute].visAxis.handle.background.setAttribute('fill',self.normalHandleColor) self.axes[self.app.currentXattribute].visAxis.handle.originalBackgroundColor = self.normalHandleColor self.axes[att].visAxis.handle.background.setAttribute('fill',self.activeHandleColor) self.axes[att].visAxis.handle.originalBackgroundColor = self.activeHandleColor self.app.notifyAxisChange(att,xAxis=True) # Y axis if resultAction.text() == u'Use as Y axis': if self.app.currentXattribute != self.app.currentYattribute: self.axes[self.app.currentYattribute].visAxis.handle.background.setAttribute('fill',self.normalHandleColor) self.axes[self.app.currentYattribute].visAxis.handle.originalBackgroundColor = self.normalHandleColor self.axes[att].visAxis.handle.background.setAttribute('fill',self.activeHandleColor) self.axes[att].visAxis.handle.originalBackgroundColor = self.activeHandleColor self.app.notifyAxisChange(att,xAxis=False) #if linesMoved: # self.highlightedLayer.refreshLines(self.app.highlightedRsNumbers) return signals
class Indicator(QSystemTrayIcon): def __init__(self, app, *args, **kwargs): QSystemTrayIcon.__init__(self, *args, **kwargs) self.app = app self.menu = QMenu() self.setContextMenu(self.menu) self.menu.aboutToShow.connect(self.update) self.opened_notes = {} self.management = None @Slot() def update(self): self.menu.clear() if get_auth_token(): for note_struct in self.app.provider.find_notes( "", dbus.Array([], signature="i"), dbus.Array([], signature="i"), 0, 20, Note.ORDER_UPDATED_DESC ): note = Note.from_tuple(note_struct) self.menu.addAction(note.title[:40], Slot()(partial(self.open, note=note))) self.menu.addSeparator() self.menu.addAction(self.tr("Create Note"), self.create) if self.app.provider.get_status() == STATUS_SYNC: action = self.menu.addAction(self.tr("Sync in progress")) action.setEnabled(False) else: self.menu.addAction( self.tr("Last sync: %s") % self.app.provider.get_last_sync(), Slot()(self.app.provider.sync) ) self.menu.addAction(self.tr("Settings and Management"), self.show_management) self.menu.addSeparator() self.menu.addAction(self.tr("Exit"), self.exit) def open(self, note): old_note_window = self.opened_notes.get(note.id, None) if old_note_window and not getattr(old_note_window, "closed", True): editor = self.opened_notes[note.id] editor.activateWindow() else: editor = Editor(self.app, note) editor.show() self.opened_notes[note.id] = editor return editor @Slot() def create(self, attach=None): note_struct = Note( # maybe replace NONE's to somthing better id=NONE_ID, title=self.tr("New note"), content=self.tr("New note content"), tags=dbus.Array([], signature="i"), notebook=NONE_ID, created=NONE_VAL, updated=NONE_VAL, place="", ).struct note = Note.from_tuple(self.app.provider.create_note(note_struct)) editor = self.open(note) if attach: editor.resource_edit.add_attach(attach) @Slot() def show_management(self): if not self.management or getattr(self.management, "closed", True): self.management = Management(self.app) self.management.show() else: self.management.activateWindow() @Slot() def exit(self): sys.exit(0)
class menuBar(QMenuBar): def __init__(self,prozor): QMenuBar.__init__(self) self.prozor=prozor menuBarActions.menuBarActions.mBarActions(self) #File self.fileMenu = QMenu() self.fileMenu.setTitle("File") self.fileMenu.addAction(self.newFileAction) self.fileMenu.addSeparator() self.fileMenu.addAction(self.openFileAction) self.fileMenu.addSeparator() self.fileMenu.addAction(self.saveAction) self.fileMenu.addSeparator() self.fileMenu.addAction(self.saveAsAction) self.fileMenu.addSeparator() self.fileMenu.addAction(self.exitProgramAction) self.addMenu(self.fileMenu) #Edit self.editMenu=QMenu() self.editMenu.setTitle("Edit") self.editMenu.addAction(self.undoAction) self.fileMenu.addSeparator() self.editMenu.addAction(self.redoAction) self.fileMenu.addSeparator() self.editMenu.addAction(self.cutAction) self.fileMenu.addSeparator() self.editMenu.addAction(self.copyAction) self.fileMenu.addSeparator() self.editMenu.addAction(self.pasteAction) self.fileMenu.addSeparator() self.addMenu(self.editMenu) self.addAction(self.optionsAction)
def __init__(self, parent=None): super(Truss, self).__init__(parent) self.resize(800, 600) self.filename = None self.filetuple = None self.dirty = False # Refers to Data Page only. centralwidget = QWidget(self) gridLayout = QGridLayout(centralwidget) self.tabWidget = QTabWidget(centralwidget) self.tab = QWidget() font = QFont() font.setFamily("Courier 10 Pitch") font.setPointSize(12) self.tab.setFont(font) gridLayout_3 = QGridLayout(self.tab) self.plainTextEdit = QPlainTextEdit(self.tab) gridLayout_3.addWidget(self.plainTextEdit, 0, 0, 1, 1) self.tabWidget.addTab(self.tab, "") self.tab_2 = QWidget() self.tab_2.setFont(font) gridLayout_2 = QGridLayout(self.tab_2) self.plainTextEdit_2 = QPlainTextEdit(self.tab_2) gridLayout_2.addWidget(self.plainTextEdit_2, 0, 0, 1, 1) self.tabWidget.addTab(self.tab_2, "") gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) self.setCentralWidget(centralwidget) menubar = QMenuBar(self) menubar.setGeometry(QRect(0, 0, 800, 29)) menu_File = QMenu(menubar) self.menu_Solve = QMenu(menubar) self.menu_Help = QMenu(menubar) self.setMenuBar(menubar) self.statusbar = QStatusBar(self) self.setStatusBar(self.statusbar) self.action_New = QAction(self) self.actionSave_As = QAction(self) self.action_Save = QAction(self) self.action_Open = QAction(self) self.action_Quit = QAction(self) self.action_About = QAction(self) self.actionShow_CCPL = QAction(self) self.action_Solve = QAction(self) self.action_CCPL = QAction(self) self.action_Help = QAction(self) menu_File.addAction(self.action_New) menu_File.addAction(self.action_Open) menu_File.addAction(self.actionSave_As) menu_File.addAction(self.action_Save) menu_File.addSeparator() menu_File.addAction(self.action_Quit) self.menu_Solve.addAction(self.action_Solve) self.menu_Help.addAction(self.action_About) self.menu_Help.addAction(self.action_CCPL) self.menu_Help.addAction(self.action_Help) menubar.addAction(menu_File.menuAction()) menubar.addAction(self.menu_Solve.menuAction()) menubar.addAction(self.menu_Help.menuAction()) self.setWindowTitle("Main Window") self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab),\ "Data Page") self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2),\ "Solution Page") menu_File.setTitle("&File") self.menu_Solve.setTitle("&Solve") self.menu_Help.setTitle("&Help") self.tabWidget.setCurrentIndex(0) self.action_New.setText("&New") self.action_Open.setText("&Open") self.actionSave_As.setText("Save &As") self.action_Save.setText("&Save") self.action_Quit.setText("&Quit") self.action_Solve.setText("&Solve") self.action_About.setText("&About") self.action_CCPL.setText("&CCPL") self.action_Help.setText("&Help") self.action_Quit.triggered.connect(self.close) allToolBar = self.addToolBar("AllToolBar") allToolBar.setObjectName("AllToolBar") self.addActions(allToolBar, (self.action_Open, self.actionSave_As,\ self.action_Save, self.action_Solve,\ self.action_Quit )) self.action_New.triggered.connect(self.fileNew) self.action_Open.triggered.connect(self.fileOpen) self.actionSave_As.triggered.connect(self.fileSaveAs) self.action_Save.triggered.connect(self.fileSave) self.action_Solve.triggered.connect(self.trussSolve) self.action_About.triggered.connect(self.aboutBox) self.action_CCPL.triggered.connect(self.displayCCPL) self.action_Help.triggered.connect(self.help) self.plainTextEdit.textChanged.connect(self.setDirty) self.action_New = self.editAction(self.action_New, None,\ 'ctrl+N', 'filenew', 'New File.') self.action_Open = self.editAction(self.action_Open, None, 'ctrl+O', 'fileopen', 'Open File.') self.actionSave_As = self.editAction(self.actionSave_As,\ None, 'ctrl+A', 'filesaveas',\ 'Save and Name File.') self.action_Save = self.editAction(self.action_Save, None, 'ctrl+S', 'filesave', 'Save File.') self.action_Solve = self.editAction(self.action_Solve, None, 'ctrl+L', 'solve', 'Solve Structure.') self.action_About = self.editAction(self.action_About, None, 'ctrl+B', 'about','Pop About Box.') self.action_CCPL = self.editAction(self.action_CCPL, None, 'ctrl+G', 'licence', 'Show Licence') self.action_Help = self.editAction(self.action_Help, None, 'ctrl+H', 'help', 'Show Help Page.') self.action_Quit = self.editAction(self.action_Quit, None, 'ctrl+Q', 'quit', 'Quit the program.') self.plainTextEdit_2.setReadOnly(True)
def notifyOntologyAdded(self, ontology): """ Notify that an ontology was added to the index. Parameter : - ontology : The added ontology. """ if ontology is None: return self.addRecentOntology(ontology) i = len(self.menuOntology.actions()) - 3 ontologyMenu = None for x in range(i, len(self.menuOntology.actions())): a = self.menuOntology.actions()[x] if a.text() == ontology.name: # Don't need to add menu. ontologyMenu = a.menu() break if ontologyMenu is None: ontologyMenu = QMenu(self) ontologyMenu.setTitle(ontology.name) ontologyMenu.clear() # Update action icon = QIcon() icon.addPixmap(QPixmap(":/actions/gfx/actions/update-product.png"), QIcon.Normal, QIcon.Off) actionUpdate = ontologyMenu.addAction("Update") actionUpdate.setData(ontology) actionUpdate.setIcon(icon) actionUpdate.setIconVisibleInMenu(True) actionUpdate.triggered.connect(partial(self._updateOntology_, ontology)) icon = QIcon() icon.addPixmap(QPixmap(":/actions/gfx/actions/document-revert.png"), QIcon.Normal, QIcon.Off) actionRevert = ontologyMenu.addAction("Revert") actionRevert.setData(ontology) actionRevert.setIcon(icon) actionRevert.setIconVisibleInMenu(True) actionRevert.triggered.connect( partial(self._revertOntology_, ontology, ontologyMenu)) icon = QIcon() icon.addPixmap( QPixmap(":/actions/gfx/actions/document-properties.png"), QIcon.Normal, QIcon.Off) actionProperties = ontologyMenu.addAction("Properties") actionProperties.setData(ontology) actionProperties.setIconVisibleInMenu(True) actionProperties.setIcon(icon) actionProperties.triggered.connect( partial(self._showOntologyProperties_, ontology)) ontologyMenu.addSeparator() # Close action icon = QIcon() icon.addPixmap(QPixmap(":/actions/gfx/actions/document-close.png"), QIcon.Normal, QIcon.Off) actionClose = ontologyMenu.addAction("Close") actionClose.setIcon(icon) actionClose.setIconVisibleInMenu(True) actionClose.setData(ontology) actionClose.triggered.connect( partial(self._closeOntology_, ontology, ontologyMenu)) ontologyMenu.addSeparator() # Add ontology menu to menu bar self.menuOntology.addMenu(ontologyMenu)
class Indicator(QSystemTrayIcon): def __init__(self, *args, **kwargs): QSystemTrayIcon.__init__(self, *args, **kwargs) self.app = QApplication.instance() self.menu = QMenu() self.setContextMenu(self.menu) self.menu.aboutToShow.connect(self.update) self.opened_notes = {} self.activated.connect(self._activated) self.settings = QSettings('everpad', 'everpad-pad') def _activated(self, reason): if reason == QSystemTrayIcon.Trigger: self.menu.popup(QCursor().pos()) def _add_note(self, struct): note = Note.from_tuple(struct) title = note.title[:40].replace('&', '&&') self.menu.addAction(title, Slot()(partial(self.open, note=note))) @Slot() def update(self): self.menu.clear() try: version = self.app.provider.get_api_version() except ( # dbus raise some magic dbus.exceptions.UnknownMethodException, dbus.exceptions.DBusException, ): version = -1 if version != API_VERSION: action = self.menu.addAction( self.tr('API version missmatch, please restart'), ) action.setEnabled(False) if version < API_VERSION: handler = self.app.provider.kill else: handler = partial(os.execlp, 'everpad', '--replace') self.menu.addAction( self.tr('Restart everpad'), handler, ) return if self.app.provider.is_authenticated(): pin_notes = self.app.provider.find_notes( '', dbus.Array([], signature='i'), dbus.Array([], signature='i'), 0, 20, Note.ORDER_UPDATED_DESC, 1, ) notes = self.app.provider.find_notes( '', dbus.Array([], signature='i'), dbus.Array([], signature='i'), 0, 20 - len(pin_notes), Note.ORDER_UPDATED_DESC, 0, ) first_sync = not (len(notes) + len(pin_notes) or self.app.provider.is_first_synced()) status_syncing = self.app.provider.get_status() == STATUS_SYNC if status_syncing and first_sync: sync_label = self.tr('Wait, first sync in progress') elif status_syncing and not first_sync: sync_label = self.tr('Sync in progress') elif not status_syncing and first_sync: sync_label = self.tr('Please perform first sync') else: last_sync = self.app.provider.get_last_sync() delta_sync = (datetime.now() - datetime.strptime( last_sync, '%H:%M')).seconds // 60 if delta_sync == 0: sync_label = self.tr('Last Sync: Just now') elif delta_sync == 1: sync_label = self.tr('Last Sync: %s min ago') % delta_sync else: sync_label = self.tr('Last Sync: %s mins ago') % delta_sync menu_items = { 'create_note': [self.tr('Create Note'), self.create], 'all_notes': [self.tr('All Notes'), self.show_all_notes], 'sync': [sync_label, Slot()(self.app.provider.sync)], 'pin_notes': pin_notes, 'notes': notes, } for item in self.app.settings.value('menu-order', DEFAULT_INDICATOR_LAYOUT): if item == 'pin_notes' or item == 'notes': if not first_sync: if len(menu_items[item]): self.menu.addSeparator() for struct in menu_items[item]: self._add_note(struct) self.menu.addSeparator() else: action = self.menu.addAction(menu_items[item][0], menu_items[item][1]) if status_syncing and item == 'sync': action.setEnabled(False) self.menu.addSeparator() self.menu.addAction(self.tr('Settings and Management'), self.show_management) self.menu.addAction(self.tr('Exit'), self.exit) def open(self, note, search_term=''): old_note_window = self.opened_notes.get(note.id, None) if old_note_window and not getattr(old_note_window, 'closed', True): editor = self.opened_notes[note.id] # hide and show for bringing to front editor.hide() editor.show() else: editor = Editor(note) editor.show() self.opened_notes[note.id] = editor if search_term: editor.findbar.set_search_term(search_term) editor.findbar.show() editor.raise_() editor.activateWindow() return editor @Slot() def create(self, attach=None, notebook_id=NONE_ID): note_struct = Note( # maybe replace NONE's to somthing better id=NONE_ID, title=self.tr('New note'), content=self.tr("New note content"), tags=dbus.Array([], signature='i'), notebook=notebook_id, created=NONE_VAL, updated=NONE_VAL, conflict_parent=NONE_VAL, conflict_items=dbus.Array([], signature='i'), place='', share_date=NONE_VAL, share_url='', ).struct note = Note.from_tuple(self.app.provider.create_note(note_struct), ) editor = self.open(note) if attach: editor.resource_edit.add_all_attach(attach) @Slot() def show_all_notes(self): if not hasattr(self, 'list') or getattr(self.list, 'closed', True): self.list = List() self.list.show() else: self.list.activateWindow() @Slot() def show_management(self): if not hasattr(self, 'management') or getattr(self.management, 'closed', True): self.management = Management() self.management.show() else: self.management.activateWindow() @Slot() def exit(self): self.app.quit()
class Indicator(QSystemTrayIcon): def __init__(self, *args, **kwargs): QSystemTrayIcon.__init__(self, *args, **kwargs) self.app = QApplication.instance() self.menu = QMenu() self.setContextMenu(self.menu) self.menu.aboutToShow.connect(self.update) self.opened_notes = {} self.activated.connect(self._activated) def _activated(self, reason): if reason == QSystemTrayIcon.Trigger: self.menu.popup(QCursor().pos()) def _add_note(self, struct): note = Note.from_tuple(struct) title = note.title[:40].replace("&", "&&") self.menu.addAction(title, Slot()(partial(self.open, note=note))) @Slot() def update(self): self.menu.clear() try: version = self.app.provider.get_api_version() except (dbus.exceptions.UnknownMethodException, dbus.exceptions.DBusException): # dbus raise some magic version = -1 if version != API_VERSION: action = self.menu.addAction(self.tr("API version missmatch, please restart")) action.setEnabled(False) if version < API_VERSION: handler = self.app.provider.kill else: handler = partial(os.execlp, "everpad", "--replace") self.menu.addAction(self.tr("Restart everpad"), handler) return if get_auth_token(): pin_notes = self.app.provider.find_notes( "", dbus.Array([], signature="i"), dbus.Array([], signature="i"), 0, 20, Note.ORDER_UPDATED_DESC, 1 ) notes = self.app.provider.find_notes( "", dbus.Array([], signature="i"), dbus.Array([], signature="i"), 0, 20 - len(pin_notes), Note.ORDER_UPDATED_DESC, 0, ) if len(notes) + len(pin_notes) or self.app.provider.is_first_synced(): self.menu.addAction(self.tr("All Notes"), self.show_all_notes) self.menu.addSeparator() if len(pin_notes): for struct in pin_notes: self._add_note(struct) self.menu.addSeparator() for struct in notes: self._add_note(struct) self.menu.addSeparator() self.menu.addAction(self.tr("Create Note"), self.create) first_sync = False else: first_sync = True if self.app.provider.get_status() == STATUS_SYNC: action = self.menu.addAction( self.tr("Wait, first sync in progress") if first_sync else self.tr("Sync in progress") ) action.setEnabled(False) else: if first_sync: label = self.tr("Please perform first sync") else: last_sync = self.app.provider.get_last_sync() delta_sync = (datetime.now() - datetime.strptime(last_sync, "%H:%M")).seconds // 60 if delta_sync == 0: label = self.tr("Last Sync: Just now") elif delta_sync == 1: label = self.tr("Last Sync: %s min ago") % delta_sync else: label = self.tr("Last Sync: %s mins ago") % delta_sync self.menu.addAction(label, Slot()(self.app.provider.sync)) self.menu.addAction(self.tr("Settings and Management"), self.show_management) self.menu.addSeparator() self.menu.addAction(self.tr("Exit"), self.exit) def open(self, note, search_term=""): old_note_window = self.opened_notes.get(note.id, None) if old_note_window and not getattr(old_note_window, "closed", True): editor = self.opened_notes[note.id] editor.activateWindow() else: editor = Editor(note) editor.show() self.opened_notes[note.id] = editor if search_term: editor.findbar.set_search_term(search_term) editor.findbar.show() return editor @Slot() def create(self, attach=None, notebook_id=NONE_ID): note_struct = Note( # maybe replace NONE's to somthing better id=NONE_ID, title=self.tr("New note"), content=self.tr("New note content"), tags=dbus.Array([], signature="i"), notebook=notebook_id, created=NONE_VAL, updated=NONE_VAL, conflict_parent=NONE_VAL, conflict_items=dbus.Array([], signature="i"), place="", ).struct note = Note.from_tuple(self.app.provider.create_note(note_struct)) editor = self.open(note) if attach: editor.resource_edit.add_attach(attach) @Slot() def show_all_notes(self): if not hasattr(self, "list") or getattr(self.list, "closed", True): self.list = List() self.list.show() else: self.list.activateWindow() @Slot() def show_management(self): if not hasattr(self, "management") or getattr(self.management, "closed", True): self.management = Management() self.management.show() else: self.management.activateWindow() @Slot() def exit(self): self.app.quit()
class Ui_MainWindow(object): def setupUi(self, MainWindow): lbMinWidth = 65 # leMinWidth = 200 MainWindow.setObjectName("MainWindow") MainWindow.resize(400, 310) # self.centralwidget = QWidget(MainWindow) self.mainSplitter = QSplitter(Qt.Horizontal, MainWindow) self.mainSplitter.setObjectName("centralwidget") self.mainSplitter.setProperty("childrenCollapsible", False) MainWindow.setCentralWidget(self.mainSplitter) self.leftSplitter = QSplitter(Qt.Vertical, self.mainSplitter) self.leftSplitter.setProperty("childrenCollapsible", False) ##### login_gbox self.login_gbox = QGroupBox(self.leftSplitter) self.login_gbox.setFlat(True) self.login_gbox.setObjectName("login_gbox") login_gbox_layout = QVBoxLayout(self.login_gbox) login_gbox_csf_layout = QHBoxLayout() login_gbox_account_layout = QHBoxLayout() login_gbox_connect_layout = QHBoxLayout() login_gbox_layout.addLayout(login_gbox_csf_layout) login_gbox_layout.addLayout(login_gbox_account_layout) login_gbox_layout.addLayout(login_gbox_connect_layout) self.lb_client_secrets_file_path = QLabel(self.login_gbox) self.lb_client_secrets_file_path.setObjectName("lb_client_secrets_file_path") self.lb_client_secrets_file_path.setMinimumWidth(lbMinWidth) self.client_secrets_file_path_le = QLineEdit(self.login_gbox) self.client_secrets_file_path_le.setObjectName("client_secrets_file_path_le") self.client_secret_file_path_tBtn = QToolButton(self.login_gbox) self.client_secret_file_path_tBtn.setObjectName("client_secret_file_path_tBtn") login_gbox_csf_layout.addWidget(self.lb_client_secrets_file_path) login_gbox_csf_layout.addWidget(self.client_secrets_file_path_le) login_gbox_csf_layout.addWidget(self.client_secret_file_path_tBtn) self.lb_account = QLabel(self.login_gbox) self.lb_account.setMaximumWidth(lbMinWidth) self.lb_account.setObjectName("lb_account") self.remove_account_btn = QToolButton(self.login_gbox) self.remove_account_btn.setObjectName("remove_account_btn") self.remove_account_btn.setMinimumWidth(20) self.remove_account_btn.setEnabled(False) self.add_account_btn = QToolButton(self.login_gbox) self.add_account_btn.setObjectName("add_account_btn") self.add_account_btn.setMinimumWidth(20) self.accounts_cb = QComboBox(self.login_gbox) self.accounts_cb.setObjectName("accounts_cb") login_gbox_account_layout.addWidget(self.lb_account) login_gbox_account_layout.addWidget(self.remove_account_btn) login_gbox_account_layout.addWidget(self.add_account_btn) login_gbox_account_layout.addWidget(self.accounts_cb) self.lb_decryption_key = QLabel(self.login_gbox) self.lb_decryption_key.setObjectName("lb_decryption_key") self.lb_decryption_key.setMinimumWidth(lbMinWidth) self.lb_decryption_key.hide() self.decryption_key_le = QLineEdit(self.login_gbox) self.decryption_key_le.setEchoMode(QLineEdit.Password) self.decryption_key_le.setObjectName("decryption_key_le") self.decryption_key_le.hide() self.connect_btn = QPushButton(self.login_gbox) self.connect_btn.setEnabled(False) self.connect_btn.setObjectName("connect_btn") login_gbox_connect_layout.addWidget(self.lb_decryption_key) login_gbox_connect_layout.addWidget(self.decryption_key_le) login_gbox_connect_layout.addWidget(self.connect_btn) #### search_gbox self.search_gbox = QGroupBox(self.leftSplitter) self.search_gbox.setFlat(True) self.search_gbox.setObjectName("search_gbox") self.search_gbox.hide() search_gbox_layout = QVBoxLayout(self.search_gbox) search_gbox_mailbox_layout = QVBoxLayout() search_gbox_date_layout = QHBoxLayout() search_gbox_from_layout = QHBoxLayout() search_gbox_to_layout = QHBoxLayout() search_gbox_subject_layout = QHBoxLayout() search_gbox_threads_layout = QHBoxLayout() search_gbox_paramaters_layout = QHBoxLayout() search_gbox_layout.addLayout(search_gbox_mailbox_layout) search_gbox_layout.addLayout(search_gbox_date_layout) search_gbox_layout.addLayout(search_gbox_from_layout) search_gbox_layout.addLayout(search_gbox_to_layout) search_gbox_layout.addLayout(search_gbox_subject_layout) search_gbox_layout.addLayout(search_gbox_threads_layout) search_gbox_layout.addLayout(search_gbox_paramaters_layout) self.lb_select_mailbox = QLabel(self.search_gbox) self.lb_select_mailbox.setObjectName("lb_select_mailbox") self.mailboxes_lw = QListWidget(self.search_gbox) self.mailboxes_lw.setEditTriggers(QAbstractItemView.NoEditTriggers) self.mailboxes_lw.setSelectionMode(QAbstractItemView.ExtendedSelection) self.mailboxes_lw.setObjectName("mailboxes_lw") search_gbox_mailbox_layout.addWidget(self.lb_select_mailbox) search_gbox_mailbox_layout.addWidget(self.mailboxes_lw) self.after_date_cb = QCheckBox(self.search_gbox) self.after_date_cb.setObjectName("after_date_cb") self.after_date_cb.setMinimumWidth(lbMinWidth) self.after_date_cb.setMaximumWidth(lbMinWidth) self.after_date_edit = QDateEdit(self.search_gbox) self.after_date_edit.setCalendarPopup(True) self.after_date_edit.setObjectName("after_date_edit") self.after_date_edit.setDate(QDate.currentDate().addDays(-365)) self.after_date_edit.setMaximumDate(QDate.currentDate()) self.after_date_edit.setEnabled(False) self.before_date_cb = QCheckBox(self.search_gbox) self.before_date_cb.setObjectName("before_date_cb") self.before_date_cb.setMinimumWidth(70) self.before_date_cb.setMaximumWidth(70) self.before_date_edit = QDateEdit(self.search_gbox) self.before_date_edit.setCalendarPopup(True) self.before_date_edit.setObjectName("before_date_edit") self.before_date_edit.setDate(QDate.currentDate()) self.before_date_edit.setMaximumDate(QDate.currentDate()) self.before_date_edit.setEnabled(False) search_gbox_date_layout.addWidget(self.after_date_cb) search_gbox_date_layout.addWidget(self.after_date_edit) search_gbox_date_layout.addWidget(self.before_date_cb) search_gbox_date_layout.addWidget(self.before_date_edit) self.lb_from = QLabel(self.search_gbox) self.lb_from.setObjectName("lb_from") self.lb_from.setMinimumWidth(lbMinWidth) self.from_le = QLineEdit(self.search_gbox) self.from_le.setObjectName("from_le") search_gbox_from_layout.addWidget(self.lb_from) search_gbox_from_layout.addWidget(self.from_le) self.lb_to = QLabel(self.search_gbox) self.lb_to.setObjectName("lb_to") self.lb_to.setMinimumWidth(lbMinWidth) self.to_le = QLineEdit(self.search_gbox) self.to_le.setObjectName("to_le") search_gbox_to_layout.addWidget(self.lb_to) search_gbox_to_layout.addWidget(self.to_le) self.lb_subject = QLabel(self.search_gbox) self.lb_subject.setObjectName("lb_subject") self.lb_subject.setMinimumWidth(lbMinWidth) self.subject_le = QLineEdit(self.search_gbox) self.subject_le.setObjectName("subject_le") search_gbox_subject_layout.addWidget(self.lb_subject) search_gbox_subject_layout.addWidget(self.subject_le) self.lb_threads = QLabel(self.search_gbox) self.lb_threads.setObjectName("lb_threads") self.lb_threads.setMaximumWidth(lbMinWidth) self.thread_count_sb = QSpinBox(self.search_gbox) self.thread_count_sb.setMinimum(1) self.thread_count_sb.setMaximum(10) self.thread_count_sb.setObjectName("thread_count_sb") self.html_radio = QRadioButton(self.search_gbox) self.html_radio.setObjectName("html_radio") self.text_radio = QRadioButton(self.search_gbox) self.text_radio.setObjectName("text_radio") self.extactTypeButtonGroup = QButtonGroup(self) self.extactTypeButtonGroup.addButton(self.html_radio) self.extactTypeButtonGroup.addButton(self.text_radio) self.html_radio.setChecked(True) self.search_btn = QPushButton(self.search_gbox) self.search_btn.setObjectName("search_btn") search_gbox_threads_layout.addWidget(self.lb_threads) search_gbox_threads_layout.addWidget(self.thread_count_sb) search_gbox_threads_layout.addWidget(self.html_radio) search_gbox_threads_layout.addWidget(self.text_radio) search_gbox_threads_layout.addWidget(self.search_btn) self.parameters_cb = QCheckBox(self.search_gbox) self.parameters_cb.setText("") self.parameters_cb.setObjectName("parameters_cb") self.parameters_le = QLineEdit(self.search_gbox) self.parameters_le.setEnabled(False) self.parameters_le.setObjectName("parameters_le") search_gbox_paramaters_layout.addWidget(self.parameters_cb) search_gbox_paramaters_layout.addWidget(self.parameters_le) #### log_gbox self.log_gbox = QGroupBox(self.leftSplitter) self.log_gbox.setFlat(True) self.log_gbox.setObjectName("log_gbox") log_layout = QVBoxLayout(self.log_gbox) self.log_te = QTextEdit(self.log_gbox) self.log_te.setLineWrapMode(QTextEdit.NoWrap) self.log_te.setReadOnly(True) self.log_te.setTextInteractionFlags(Qt.TextSelectableByKeyboard | Qt.TextSelectableByMouse) self.log_te.setObjectName("log_te") self.disconnect_btn = QPushButton(self.log_gbox) self.disconnect_btn.setObjectName("disconnect_btn") self.disconnect_btn.hide() log_layout.addWidget(self.log_te) log_layout_btn = QHBoxLayout() log_layout.addLayout(log_layout_btn) log_layout_btn.addWidget(self.disconnect_btn) log_layout_btn.addStretch() #### links_gbox self.links_gbox = QGroupBox(self.mainSplitter) self.links_gbox.setFlat(True) self.links_gbox.setObjectName("links_gbox") self.links_gbox.hide() links_gbox_layout = QVBoxLayout(self.links_gbox) links_gbox_links_layout = QVBoxLayout() links_gbox_buttons_layout = QHBoxLayout() links_gbox_layout.addLayout(links_gbox_links_layout) links_gbox_layout.addLayout(links_gbox_buttons_layout) self.links_text_edit = QTextEdit(self.links_gbox) self.links_text_edit.setObjectName("links_text_edit") links_gbox_links_layout.addWidget(self.links_text_edit) self.export_txt_btn = QPushButton(self.links_gbox) self.export_txt_btn.setObjectName("export_txt_btn") self.export_txt_btn.setEnabled(False) self.export_html_btn = QPushButton(self.links_gbox) self.export_html_btn.setObjectName("export_html_btn") self.export_html_btn.setEnabled(False) links_gbox_buttons_layout.addWidget(self.export_txt_btn) links_gbox_buttons_layout.addWidget(self.export_html_btn) ### menubar self.menubar = QMenuBar(MainWindow) # self.menubar.setGeometry(QRect(0, 0, 860, 21)) self.menubar.setObjectName("menubar") self.menu_file = QMenu(self.menubar) self.menu_file.setObjectName("menu_file") self.menu_help = QMenu(self.menubar) self.menu_help.setObjectName("menu_help") MainWindow.setMenuBar(self.menubar) self.action_about = QAction(MainWindow) self.action_about.setObjectName("action_about") self.action_About_Qt = QAction(MainWindow) self.action_About_Qt.setObjectName("action_About_Qt") self.action_exit = QAction(MainWindow) self.action_exit.setObjectName("action_exit") self.actionSave = QAction(MainWindow) self.actionSave.setObjectName("actionSave") self.action_Gmail_Advanced_Search_Syntax = QAction(MainWindow) self.action_Gmail_Advanced_Search_Syntax.setObjectName("action_Gmail_Advanced_Search_Syntax") self.menu_file.addAction(self.action_exit) self.menu_help.addAction(self.action_Gmail_Advanced_Search_Syntax) self.menu_help.addSeparator() self.menu_help.addAction(self.action_about) self.menu_help.addAction(self.action_About_Qt) self.menubar.addAction(self.menu_file.menuAction()) self.menubar.addAction(self.menu_help.menuAction()) self.retranslateUi(MainWindow) QMetaObject.connectSlotsByName(MainWindow) MainWindow.setTabOrder(self.client_secrets_file_path_le, self.client_secret_file_path_tBtn) MainWindow.setTabOrder(self.client_secret_file_path_tBtn, self.remove_account_btn) MainWindow.setTabOrder(self.remove_account_btn, self.add_account_btn) MainWindow.setTabOrder(self.add_account_btn, self.accounts_cb) MainWindow.setTabOrder(self.decryption_key_le, self.connect_btn) MainWindow.setTabOrder(self.connect_btn, self.log_te) MainWindow.setTabOrder(self.log_te, self.mailboxes_lw) MainWindow.setTabOrder(self.mailboxes_lw, self.after_date_cb) MainWindow.setTabOrder(self.after_date_cb, self.after_date_edit) MainWindow.setTabOrder(self.after_date_edit, self.before_date_cb) MainWindow.setTabOrder(self.before_date_cb, self.before_date_edit) MainWindow.setTabOrder(self.before_date_edit, self.from_le) MainWindow.setTabOrder(self.from_le, self.to_le) MainWindow.setTabOrder(self.to_le, self.subject_le) MainWindow.setTabOrder(self.subject_le, self.thread_count_sb) MainWindow.setTabOrder(self.thread_count_sb, self.html_radio) MainWindow.setTabOrder(self.html_radio, self.text_radio) MainWindow.setTabOrder(self.text_radio, self.search_btn) MainWindow.setTabOrder(self.search_btn, self.parameters_cb) MainWindow.setTabOrder(self.parameters_cb, self.parameters_le) MainWindow.setTabOrder(self.parameters_le, self.disconnect_btn) MainWindow.setTabOrder(self.disconnect_btn, self.links_text_edit) MainWindow.setTabOrder(self.links_text_edit, self.export_txt_btn) MainWindow.setTabOrder(self.export_txt_btn, self.export_html_btn) MainWindow.setTabOrder(self.export_html_btn, self.mailboxes_lw) def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(QApplication.translate("MainWindow", "Gmail URL Parser", None, QApplication.UnicodeUTF8)) self.login_gbox.setTitle(QApplication.translate("MainWindow", " Client secrets file path ", None, QApplication.UnicodeUTF8)) self.client_secrets_file_path_le.setPlaceholderText(QApplication.translate("MainWindow", "Please select your client secrets file", None, QApplication.UnicodeUTF8)) self.lb_client_secrets_file_path.setText(QApplication.translate("MainWindow", "Path", None, QApplication.UnicodeUTF8)) self.connect_btn.setText(QApplication.translate("MainWindow", "Connect", None, QApplication.UnicodeUTF8)) self.client_secret_file_path_tBtn.setText(QApplication.translate("MainWindow", "...", None, QApplication.UnicodeUTF8)) self.lb_account.setText(QApplication.translate("MainWindow", "Account", None, QApplication.UnicodeUTF8)) self.add_account_btn.setText(QApplication.translate("MainWindow", "+", None, QApplication.UnicodeUTF8)) self.remove_account_btn.setText(QApplication.translate("MainWindow", "-", None, QApplication.UnicodeUTF8)) self.decryption_key_le.setPlaceholderText(QApplication.translate("MainWindow", "Decryption key", None, QApplication.UnicodeUTF8)) self.lb_decryption_key.setText(QApplication.translate("MainWindow", "Key", None, QApplication.UnicodeUTF8)) self.log_gbox.setTitle(QApplication.translate("MainWindow", " Log ", None, QApplication.UnicodeUTF8)) self.search_gbox.setTitle(QApplication.translate("MainWindow", " Search Parameters ", None, QApplication.UnicodeUTF8)) self.lb_to.setText(QApplication.translate("MainWindow", "To", None, QApplication.UnicodeUTF8)) self.lb_from.setText(QApplication.translate("MainWindow", "From", None, QApplication.UnicodeUTF8)) self.lb_subject.setText(QApplication.translate("MainWindow", "Subject", None, QApplication.UnicodeUTF8)) self.search_btn.setText(QApplication.translate("MainWindow", "Search", None, QApplication.UnicodeUTF8)) self.after_date_edit.setDisplayFormat(QApplication.translate("MainWindow", "yyyy-MM-dd", None, QApplication.UnicodeUTF8)) self.before_date_edit.setDisplayFormat(QApplication.translate("MainWindow", "yyyy-MM-dd", None, QApplication.UnicodeUTF8)) self.lb_select_mailbox.setToolTip(QApplication.translate("MainWindow", "<html><head/><body><p>Select multiple items to select labels</p></body></html>", None, QApplication.UnicodeUTF8)) self.lb_select_mailbox.setText(QApplication.translate("MainWindow", "Select Mailbox or Labels", None, QApplication.UnicodeUTF8)) self.after_date_cb.setText(QApplication.translate("MainWindow", "After", None, QApplication.UnicodeUTF8)) self.before_date_cb.setText(QApplication.translate("MainWindow", "Before", None, QApplication.UnicodeUTF8)) self.html_radio.setText(QApplication.translate("MainWindow", "html", None, QApplication.UnicodeUTF8)) self.text_radio.setText(QApplication.translate("MainWindow", "text", None, QApplication.UnicodeUTF8)) self.lb_threads.setText(QApplication.translate("MainWindow", "Threads", None, QApplication.UnicodeUTF8)) self.links_gbox.setTitle(QApplication.translate("MainWindow", " Links ", None, QApplication.UnicodeUTF8)) self.disconnect_btn.setText(QApplication.translate("MainWindow", "Disconnect", None, QApplication.UnicodeUTF8)) self.export_txt_btn.setText(QApplication.translate("MainWindow", "Export as txt", None, QApplication.UnicodeUTF8)) self.export_html_btn.setText(QApplication.translate("MainWindow", "Export as HTML", None, QApplication.UnicodeUTF8)) self.menu_file.setTitle(QApplication.translate("MainWindow", "File", None, QApplication.UnicodeUTF8)) self.menu_help.setTitle(QApplication.translate("MainWindow", "Help", None, QApplication.UnicodeUTF8)) self.action_about.setText(QApplication.translate("MainWindow", "About", None, QApplication.UnicodeUTF8)) self.action_About_Qt.setText(QApplication.translate("MainWindow", "About Qt", None, QApplication.UnicodeUTF8)) self.action_exit.setText(QApplication.translate("MainWindow", "Exit", None, QApplication.UnicodeUTF8)) self.action_exit.setShortcut(QApplication.translate("MainWindow", "Ctrl+Q", None, QApplication.UnicodeUTF8)) self.actionSave.setText(QApplication.translate("MainWindow", "Save", None, QApplication.UnicodeUTF8)) self.action_Gmail_Advanced_Search_Syntax.setText(QApplication.translate("MainWindow", "Gmail Advanced Search Syntax", None, QApplication.UnicodeUTF8))
class Indicator(QSystemTrayIcon): def __init__(self, app, *args, **kwargs): QSystemTrayIcon.__init__(self, *args, **kwargs) self.app = app self.menu = QMenu() self.setContextMenu(self.menu) self.menu.aboutToShow.connect(self.update) self.opened_notes = {} self.activated.connect(self._activated) def _activated(self, reason): if reason == QSystemTrayIcon.Trigger: self.menu.popup(QCursor().pos()) def _add_note(self, struct): note = Note.from_tuple(struct) title = note.title[:40].replace('&', '&&') self.menu.addAction(title, Slot()(partial(self.open, note=note))) @Slot() def kill_all(self): try: self.app.provider.kill() except dbus.exceptions.DBusException: pass os.system('everpad --replace') @Slot() def update(self): self.menu.clear() try: version = self.app.provider.get_api_version() except ( # dbus raise some magic dbus.exceptions.UnknownMethodException, dbus.exceptions.DBusException, ): version = -1 if version != API_VERSION: action = self.menu.addAction( self.tr('API version missmatch, please restart'), ) action.setEnabled(False) self.menu.addAction( self.tr('Restart everpad'), self.kill_all, ) return if get_auth_token(): pin_notes = self.app.provider.find_notes( '', dbus.Array([], signature='i'), dbus.Array([], signature='i'), 0, 20, Note.ORDER_UPDATED_DESC, 1, ) notes = self.app.provider.find_notes( '', dbus.Array([], signature='i'), dbus.Array([], signature='i'), 0, 20 - len(pin_notes), Note.ORDER_UPDATED_DESC, 0, ) if len(notes) + len( pin_notes) or self.app.provider.is_first_synced(): self.menu.addAction(self.tr('All Notes'), self.show_all_notes) self.menu.addSeparator() if len(pin_notes): for struct in pin_notes: self._add_note(struct) self.menu.addSeparator() for struct in notes: self._add_note(struct) self.menu.addSeparator() self.menu.addAction(self.tr('Create Note'), self.create) first_sync = False else: first_sync = True if self.app.provider.get_status() == STATUS_SYNC: action = self.menu.addAction( self.tr('Wait, first sync in progress' ) if first_sync else self.tr('Sync in progress')) action.setEnabled(False) else: if first_sync: label = self.tr('Please perform first sync') else: label = self.tr( 'Last sync: %s') % self.app.provider.get_last_sync() self.menu.addAction(label, Slot()(self.app.provider.sync)) self.menu.addAction(self.tr('Settings and Management'), self.show_management) self.menu.addSeparator() self.menu.addAction(self.tr('Exit'), self.exit) def open(self, note, search_term=''): old_note_window = self.opened_notes.get(note.id, None) if old_note_window and not getattr(old_note_window, 'closed', True): editor = self.opened_notes[note.id] editor.activateWindow() else: editor = Editor(self.app, note) editor.show() self.opened_notes[note.id] = editor if search_term: editor.findbar.set_search_term(search_term) editor.findbar.show() return editor @Slot() def create(self, attach=None, notebook_id=NONE_ID): note_struct = Note( # maybe replace NONE's to somthing better id=NONE_ID, title=self.tr('New note'), content=self.tr("New note content"), tags=dbus.Array([], signature='i'), notebook=notebook_id, created=NONE_VAL, updated=NONE_VAL, place='', ).struct note = Note.from_tuple(self.app.provider.create_note(note_struct), ) editor = self.open(note) if attach: editor.resource_edit.add_attach(attach) @Slot() def show_all_notes(self): if not hasattr(self, 'list') or getattr(self.list, 'closed', True): self.list = List(self.app) self.list.show() else: self.list.activateWindow() @Slot() def show_management(self): if not hasattr(self, 'management') or getattr(self.management, 'closed', True): self.management = Management(self.app) self.management.show() else: self.management.activateWindow() @Slot() def exit(self): sys.exit(0)
def showIndividualContextMenu(self, person): actionLookup = {} m = QMenu() actionLookup['Show Details'] = m.addAction('Show Details') # TODO: Add to / remove from path targets m.addSeparator() a = m.addMenu('Set A as') b = m.addMenu('Set B as') for label1 in AppState.ADDITION_ITERATOR_ORDER: a2 = a.addMenu(label1) b2 = b.addMenu(label1) for label2 in AppState.LEVEL_OPTION_ORDER: actionLookup[('Set A as', self.additionIterators[label1], AppState.LEVEL_OPTIONS[label2])] = a2.addAction(label2) actionLookup[('Set B as', self.additionIterators[label1], AppState.LEVEL_OPTIONS[label2])] = b2.addAction(label2) m.addSeparator() actionLookup['Trim Parents'] = m.addAction('Trim Parents') actionLookup['Trim Spouses'] = m.addAction('Trim Spouses') actionLookup['Trim Children'] = m.addAction('Trim Children') if not person in self.aSet and not person in self.bSet: actionLookup['Trim Parents'].setDisabled(True) actionLookup['Trim Spouses'].setDisabled(True) actionLookup['Trim Children'].setDisabled(True) m.addSeparator() for label1 in AppState.ADDITION_ITERATOR_ORDER: temp = m.addMenu('Expand '+label1) for label2 in AppState.LEVEL_OPTION_ORDER: actionLookup[('Expand', self.additionIterators[label1], AppState.LEVEL_OPTIONS[label2])] = temp.addAction(label2) choice = m.exec_(QCursor.pos()) if choice != None: for menus,action in actionLookup.iteritems(): if action == choice: if menus == 'Show Details': self.showIndividualDetails(person) elif menus == 'Trim Parents': self.snip(person, [self.ped.CHILD_TO_PARENT]) elif menus == 'Trim Spouses': self.snip(person, [self.ped.HUSBAND_TO_WIFE, self.ped.WIFE_TO_HUSBAND]) elif menus == 'Trim Children': self.snip(person, [self.ped.PARENT_TO_CHILD]) else: assert isinstance(menus,tuple) newSet = set(menus[1](person,level=menus[2])) if menus[0] == 'Set A as': historyID = self.addPedigree(newSet) self.changePedigreeA(historyID) elif menus[0] == 'Set B as': historyID = self.addPedigree(newSet) self.changePedigreeB(historyID) elif menus[0] == 'Expand': self.expand(person, newSet) break
class MTTSettingsMenu(QMenu): def __init__(self, parent=None): super(MTTSettingsMenu, self).__init__(parent) self.view = parent self.is_master_cmd = False # power user state self.power_user = MTTSettings.value('powerUser') self.__create_actions() self.__populate_menu() def keyPressEvent(self, event): if event.modifiers() == Qt.ControlModifier: self.is_master_cmd = True super(MTTSettingsMenu, self).keyPressEvent(event) def keyReleaseEvent(self, event): self.is_master_cmd = False super(MTTSettingsMenu, self).keyReleaseEvent(event) def __create_actions(self): def add_action(lbl, tip, cmd, checkable=False, checked=False): a = QAction(lbl, self) a.setStatusTip(tip) a.triggered.connect(cmd) if checkable: a.setCheckable(True) a.setChecked(checked) return a self.help_a = add_action('Help', 'Opens the online Help page', self.on_settings_help) self.switch_edit_a = add_action( 'Switch Edit/Source', 'Replace "Edit" button by "Source" button', self.on_switch_source_edit_menu, True, MTTSettings.value('switchEdit')) self.heads_up_a = add_action('HeadsUp Message', 'Show HeadsUp Message in viewport', self.on_toggle_headsup, True, MTTSettings.value('showHeadsUp')) self.focus_filter_a = add_action('Focus Filter Field at Startup', 'Focus filter field at startup', self.on_toggle_focus, True, MTTSettings.value('filterFocus')) self.force_relative_path_a = add_action( 'Force Relative Path', 'Set a relative path when selecting a new file', self.on_force_relative_path, True, MTTSettings.value('forceRelativePath')) self.show_real_attr_value_a = add_action( 'Show Real Attribute Value', 'Show fullpath instead of filtering path as Attribute Editor', self.on_show_real_attribute_value, True, MTTSettings.value('showRealAttributeValue')) self.manage_quick_filter_a = add_action( 'Manage Quick Filters', 'Manage filters that popup with right clic in filter field', self.on_filter_manage_quick_filter) self.clear_completion_cache_a = add_action( 'Clear Completion Cache', 'Erase auto completion cache of filter field', self.on_filter_clear_completion_cache) self.override_panels_a = add_action( 'Add CreateNode Button to Editors', ('Add "Create Node" to HyperShade and ' 'Node Editor for the current session'), self.on_override_panels) self.export_to_csv = add_action( 'Export Texture List as CSV', 'Export current textures into a csv file', self.view.model.export_as_csv) self.about = add_action('About', 'About', self.on_settings_about) def __populate_menu(self): self.addAction(self.help_a) self.addSeparator() self.addAction(self._get_menu_header('SETTINGS')) self.addAction(self.switch_edit_a) self.addAction(self.heads_up_a) self.addAction(self.focus_filter_a) self.addAction(self.force_relative_path_a) self.addAction(self.show_real_attr_value_a) self.addMenu(self._create_instance_menu()) self.addMenu(self._create_theme_menu()) self.addSeparator() self.addAction(self._get_menu_header('FILTER OPTIONS')) self.addAction(self.manage_quick_filter_a) self.addAction(self.clear_completion_cache_a) self.addSeparator() self.addAction(self._get_menu_header('MISC')) self.addAction(self.override_panels_a) self.addAction(self.export_to_csv) self.addSeparator() self.addAction(self._get_menu_header('DEBUG')) self.addMenu(self._create_debug_menu()) self.addSeparator() self.addAction(self.about) def _get_menu_header(self, title): header = QAction(title, self) header.setEnabled(False) return header def _create_instance_menu(self): self.instance_menu = QMenu(self) self.instance_menu.setTitle('Prompt Instance Delay') self.instance_menu.aboutToShow.connect( self.on_show_prompt_instance_delay_menu) return self.instance_menu def _create_theme_menu(self): theme_menu = QMenu(self) theme_menu.setTitle('Buttons Theme') theme_menu.setTearOffEnabled(True) theme_menu.setWindowTitle(TAG) theme_actions = QActionGroup(self) theme_actions.setExclusive(True) # create ordered theme list custom_order_theme = sorted(THEMES.iterkeys()) custom_order_theme.remove('Maya Theme') custom_order_theme.insert(0, 'Maya Theme') default_item = True for theme in custom_order_theme: current_theme_action = QAction(theme, theme_actions) current_theme_action.setCheckable(True) current_theme_action.setChecked( MTTSettings.value('theme', 'Maya Theme') == theme) current_theme_action.triggered.connect(self.on_change_theme) theme_menu.addAction(current_theme_action) if default_item: theme_menu.addSeparator() default_item = False return theme_menu def _create_debug_menu(self): self.debug_menu = QMenu(self) self.debug_menu.setTitle('Debug Menu') self.debug_menu.aboutToShow.connect(self.on_show_debug_menu) return self.debug_menu def on_change_theme(self): self.view.on_choose_theme(self.sender().text()) def on_show_debug_menu(self): self.debug_menu.clear() if self.is_master_cmd or self.power_user: power_user_mode = QAction('Power User Mode', self) power_user_mode.setCheckable(True) power_user_mode.setChecked(MTTSettings.value('powerUser')) power_user_mode.triggered.connect(self.__on_toggle_power_user) self.debug_menu.addAction(power_user_mode) self.is_master_cmd = False self.debug_menu.addSeparator() open_pref_folder_action = QAction('Open Preferences Folder', self) open_pref_folder_action.setStatusTip('Open MTT preference folder') open_pref_folder_action.triggered.connect( self.on_open_preference_folder) self.debug_menu.addAction(open_pref_folder_action) self.debug_menu.addSeparator() database_dump_csv = QAction('Dump Database as CSV', self) database_dump_csv.triggered.connect(self.view.model.database_dump_csv) self.debug_menu.addAction(database_dump_csv) database_dump_sql = QAction('Dump Database as SQL', self) database_dump_sql.triggered.connect(self.view.model.database_dump_sql) self.debug_menu.addAction(database_dump_sql) self.debug_menu.addSeparator() support_info = QMenu(self) support_info.setTitle('Supported Node Type') support_info.aboutToShow.connect(self.on_show_supported_type) self.debug_menu.addMenu(support_info) def on_filter_clear_completion_cache(self): """ Clear filter auto completion cache """ self.view.on_filter_set_text('') MTTSettings.remove('filterCompletionWildcard') MTTSettings.remove('filterCompletionRegExp') self.view.completion_model.setStringList([]) def on_switch_source_edit_menu(self): state = MTTSettings.value('switchEdit') MTTSettings.set_value('switchEdit', not state) self.view.on_set_source_edit_menu(not state) def on_show_real_attribute_value(self): self.view.model.layoutAboutToBeChanged.emit() show_real_attribute_state = MTTSettings.value('showRealAttributeValue') MTTSettings.set_value('showRealAttributeValue', not show_real_attribute_state) self.view._layout_changed() def on_filter_manage_quick_filter(self): """ Open Quick Filter words manager and save its content """ manager = MTTQuickFilterManager(self) if manager.exec_(): lists = manager.get_lists() # save list in settings MTTSettings.set_value('filterQuickWordsWildcard', ';;'.join(lists[0])) MTTSettings.set_value('filterQuickWordsRegExp', ';;'.join(lists[1])) # set current list self.view.quick_filter_words = lists[MTTSettings.value('filterRE')] manager.deleteLater() @staticmethod def on_toggle_headsup(): state = MTTSettings.value('showHeadsUp') MTTSettings.set_value('showHeadsUp', not state) @staticmethod def on_toggle_focus(): state = MTTSettings.value('filterFocus') MTTSettings.set_value('filterFocus', not state) @staticmethod def on_force_relative_path(): state = MTTSettings.value('forceRelativePath') MTTSettings.set_value('forceRelativePath', not state) def on_show_supported_type(self): node_types = sorted( [n_type for (n_type, nice, attr) in MTTSettings.SUPPORTED_TYPE] + MTTSettings.UNSUPPORTED_TYPE) support_info = self.sender() support_info.clear() for node_type in node_types: current = QAction(node_type, self) current.setEnabled(False) current.setCheckable(True) current.setChecked(node_type not in MTTSettings.UNSUPPORTED_TYPE) support_info.addAction(current) def __on_toggle_power_user(self): state = MTTSettings.value('powerUser') MTTSettings.set_value('powerUser', not state) self.power_user = not state @staticmethod def on_open_preference_folder(): """ Open preference folder """ folder_path = os.path.dirname(MTTSettings.filename()) cmds.launchImageEditor(viewImageFile=folder_path) @staticmethod def on_override_panels(): """ Override HyperShade and NodeEditor creation callback""" override_info_box = QMessageBox() override_info_box.setWindowTitle(WINDOW_TITLE) override_info_box.setIcon(QMessageBox.Information) override_info_box.setText( 'Buttons will be added to HyperShade toolbar and Node Editor toolbar.<br/>' 'Changes will exists during this session.') override_info_box.setInformativeText( '<i>Read Help to set this settings permanent</i>') override_info_box.setStandardButtons(QMessageBox.Ok) override_info_box.setDefaultButton(QMessageBox.Ok) override_info_box.exec_() mttOverridePanels.override_panels() def on_settings_about(self): special_list = map( lambda x: x.replace(' ', ' '), sorted([ u'Beno\xeet Stordeur', u'Fran\xe7ois Jumel', 'Jonathan Lorber', 'Norbert Cretinon', 'Gilles Hoff' ])) QMessageBox.about( self.parent(), WINDOW_TITLE, '<b>Maya Texture Toolkit v{:.02f}</b>' u'<p>{} - \xa9 2014 - 2016' '</p>' '<p>Special thanks to :<br/>' '<i>{}</i>' '</p>'.format(__version__, __author__, ', '.join(special_list))) @staticmethod def on_settings_help(): help_wiki = 'https://github.com/Bioeden/dbMayaTextureToolkit/wiki' webbrowser.open(help_wiki) def on_show_prompt_instance_delay_menu(self): prompt_instance_state = cmds.optionVar( query='MTT_prompt_instance_state') if prompt_instance_state == PROMPT_INSTANCE_WAIT: elapsed_time = time() - cmds.optionVar( query='MTT_prompt_instance_suspend') if elapsed_time > PROMPT_INSTANCE_WAIT_DURATION: prompt_instance_state = PROMPT_INSTANCE_ASK cmds.optionVar( iv=['MTT_prompt_instance_state', prompt_instance_state]) else: mtt_log('Remaining %.2fs' % (PROMPT_INSTANCE_WAIT_DURATION - elapsed_time)) elif prompt_instance_state == PROMPT_INSTANCE_SESSION: if 'mtt_prompt_session' not in __main__.__dict__: prompt_instance_state = PROMPT_INSTANCE_ASK cmds.optionVar( iv=['MTT_prompt_instance_state', prompt_instance_state]) self.instance_menu.clear() prompt_delay = QActionGroup(self) prompt_delay.setExclusive(True) for i in range(len(PROMPT_INSTANCE_STATE.keys())): current_delay_action = QAction(PROMPT_INSTANCE_STATE[i], prompt_delay) current_delay_action.setCheckable(True) current_delay_action.setChecked(prompt_instance_state == i) current_delay_action.triggered.connect( partial(self.view.on_choose_instance_delay, i, prompt=i != 0)) self.instance_menu.addAction(current_delay_action)
def __init__(self, parent=None): super(Truss, self).__init__(parent) self.resize(800, 600) self.filename = None self.filetuple = None self.dirty = False # Refers to Data Page only. centralwidget = QWidget(self) gridLayout = QGridLayout(centralwidget) self.tabWidget = QTabWidget(centralwidget) self.tab = QWidget() font = QFont() font.setFamily("Courier 10 Pitch") font.setPointSize(12) self.tab.setFont(font) gridLayout_3 = QGridLayout(self.tab) self.plainTextEdit = QPlainTextEdit(self.tab) gridLayout_3.addWidget(self.plainTextEdit, 0, 0, 1, 1) self.tabWidget.addTab(self.tab, "") self.tab_2 = QWidget() self.tab_2.setFont(font) gridLayout_2 = QGridLayout(self.tab_2) self.plainTextEdit_2 = QPlainTextEdit(self.tab_2) gridLayout_2.addWidget(self.plainTextEdit_2, 0, 0, 1, 1) self.tabWidget.addTab(self.tab_2, "") gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) self.setCentralWidget(centralwidget) menubar = QMenuBar(self) menubar.setGeometry(QRect(0, 0, 800, 29)) menu_File = QMenu(menubar) self.menu_Solve = QMenu(menubar) self.menu_Help = QMenu(menubar) self.setMenuBar(menubar) self.statusbar = QStatusBar(self) self.setStatusBar(self.statusbar) self.action_New = QAction(self) self.actionSave_As = QAction(self) self.action_Save = QAction(self) self.action_Open = QAction(self) self.action_Quit = QAction(self) self.action_About = QAction(self) self.actionShow_CCPL = QAction(self) self.action_Solve = QAction(self) self.action_CCPL = QAction(self) self.action_Help = QAction(self) menu_File.addAction(self.action_New) menu_File.addAction(self.action_Open) menu_File.addAction(self.actionSave_As) menu_File.addAction(self.action_Save) menu_File.addSeparator() menu_File.addAction(self.action_Quit) self.menu_Solve.addAction(self.action_Solve) self.menu_Help.addAction(self.action_About) self.menu_Help.addAction(self.action_CCPL) self.menu_Help.addAction(self.action_Help) menubar.addAction(menu_File.menuAction()) menubar.addAction(self.menu_Solve.menuAction()) menubar.addAction(self.menu_Help.menuAction()) self.setWindowTitle("Main Window") self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab),\ "Data Page") self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2),\ "Solution Page") menu_File.setTitle("&File") self.menu_Solve.setTitle("&Solve") self.menu_Help.setTitle("&Help") self.tabWidget.setCurrentIndex(0) self.action_New.setText("&New") self.action_Open.setText("&Open") self.actionSave_As.setText("Save &As") self.action_Save.setText("&Save") self.action_Quit.setText("&Quit") self.action_Solve.setText("&Solve") self.action_About.setText("&About") self.action_CCPL.setText("&CCPL") self.action_Help.setText("&Help") self.action_Quit.triggered.connect(self.close) allToolBar = self.addToolBar("AllToolBar") allToolBar.setObjectName("AllToolBar") self.addActions(allToolBar, (self.action_Open, self.actionSave_As,\ self.action_Save, self.action_Solve,\ self.action_Quit )) self.action_New.triggered.connect(self.fileNew) self.action_Open.triggered.connect(self.fileOpen) self.actionSave_As.triggered.connect(self.fileSaveAs) self.action_Save.triggered.connect(self.fileSave) self.action_Solve.triggered.connect(self.trussSolve) self.action_About.triggered.connect(self.aboutBox) self.action_CCPL.triggered.connect(self.displayCCPL) self.action_Help.triggered.connect(self.help) self.plainTextEdit.textChanged.connect(self.setDirty) self.action_New = self.editAction(self.action_New, None,\ 'ctrl+N', 'filenew', 'New File.') self.action_Open = self.editAction(self.action_Open, None, 'ctrl+O', 'fileopen', 'Open File.') self.actionSave_As = self.editAction(self.actionSave_As,\ None, 'ctrl+A', 'filesaveas',\ 'Save and Name File.') self.action_Save = self.editAction(self.action_Save, None, 'ctrl+S', 'filesave', 'Save File.') self.action_Solve = self.editAction(self.action_Solve, None, 'ctrl+L', 'solve', 'Solve Structure.') self.action_About = self.editAction(self.action_About, None, 'ctrl+B', 'about', 'Pop About Box.') self.action_CCPL = self.editAction(self.action_CCPL, None, 'ctrl+G', 'licence', 'Show Licence') self.action_Help = self.editAction(self.action_Help, None, 'ctrl+H', 'help', 'Show Help Page.') self.action_Quit = self.editAction(self.action_Quit, None, 'ctrl+Q', 'quit', 'Quit the program.') self.plainTextEdit_2.setReadOnly(True)
class SysTray(QWidget): # instdir = '/'.join(realpath(__file__).split('/')[:-1]) def __init__(self, display, parent=None): super(SysTray, self).__init__(parent) self.m = managerui.uiManager() self.s = searchui.uiSearch(display) self.menuActions() self.trayIconAndMenu() self.trayIcon.show() # def mycloseEvent(self): # if self.manProc: # self.manProc.kill() # if self.seaProc: # self.seaProc.kill() def trayIconAndMenu(self): self.trayMenu = QMenu(self) self.trayMenu.addAction(self.openSearch) self.trayMenu.addAction(self.openManager) self.trayMenu.addSeparator() self.trayMenu.addAction(self.quitAction) self.trayIcon = QSystemTrayIcon(self) self.icon = QIcon(":/res/ooo-base.png") self.trayIcon.setIcon(self.icon) self.trayIcon.setToolTip("Tag Manager Menu") self.trayIcon.setContextMenu(self.trayMenu) def iconActivated(self, reason): pass def menuActions(self): self.openSearch = QAction("S&earch", self, triggered=self.initSearch) self.openManager = QAction("M&anage Files", self, triggered=self.initManager) self.quitAction = QAction("&Quit", self, triggered=qApp.quit) # These halt the system tray icons execution # will have to thread these calls @Slot() def initSearch(self): self.s.show() # self.seaProc = Popen(["python", # self.instdir + "/searchui.py"]) def initManager(self): self.m.show()
class Indicator(QSystemTrayIcon): def __init__(self, *args, **kwargs): QSystemTrayIcon.__init__(self, *args, **kwargs) self.app = QApplication.instance() self.menu = QMenu() self.setContextMenu(self.menu) self.menu.aboutToShow.connect(self.update) self.opened_notes = {} self.activated.connect(self._activated) self.settings = QSettings('everpad', 'everpad-pad') def _activated(self, reason): if reason == QSystemTrayIcon.Trigger: self.menu.popup(QCursor().pos()) def _add_note(self, menu, struct): note = Note.from_tuple(struct) title = note.title[:40].replace('&', '&&') menu.addAction(title, Slot()( partial(self.open, note=note) )) @Slot() def update(self): self.menu.clear() try: version = self.app.provider.get_api_version() except ( # dbus raise some magic dbus.exceptions.UnknownMethodException, dbus.exceptions.DBusException, ): version = -1 if version != API_VERSION: action = self.menu.addAction( self.tr('API version missmatch, please restart'), ) action.setEnabled(False) if version < API_VERSION: handler = self.app.provider.kill else: handler = partial(os.execlp, 'everpad', '--replace') self.menu.addAction( self.tr('Restart everpad'), handler, ) return if self.app.provider.is_authenticated(): pin_notes = self.app.provider.find_notes( '', dbus.Array([], signature='i'), dbus.Array([], signature='i'), 0, 20, Note.ORDER_UPDATED_DESC, 1, ) sort_by_notebook = bool(int( self.app.provider.get_settings_value('sort-by-notebook') or 0)) has_notes = False if not sort_by_notebook: notes = self.app.provider.find_notes( '', dbus.Array([], signature='i'), dbus.Array([], signature='i'), 0, 20 - len(pin_notes), Note.ORDER_UPDATED_DESC, 0, ) has_notes = bool(notes) else: notebooks = self.app.provider.list_notebooks() notes = {} for notebook_struct in notebooks: notebook = Notebook.from_tuple(notebook_struct) _notes = self.app.provider.find_notes('', [notebook.id], dbus.Array([], signature='i'), 0, 20 - len(pin_notes), Note.ORDER_UPDATED_DESC, 0, ) notes[notebook] = _notes if _notes: has_notes = True first_sync = not ( has_notes or len(pin_notes) or self.app.provider.is_first_synced() ) status_syncing = self.app.provider.get_status() == STATUS_SYNC if status_syncing and first_sync: sync_label = self.tr('Wait, first sync in progress') elif status_syncing and not first_sync: sync_label = self.tr('Sync in progress') elif not status_syncing and first_sync: sync_label = self.tr('Please perform first sync') else: last_sync = self.app.provider.get_last_sync() delta_sync = ( datetime.now() - datetime.strptime(last_sync, '%H:%M') ).seconds // 60 if delta_sync == 0: sync_label = self.tr('Last Sync: Just now') elif delta_sync == 1: sync_label = self.tr('Last Sync: %s min ago') % delta_sync else: sync_label = self.tr('Last Sync: %s mins ago') % delta_sync menu_items = { 'create_note': [self.tr('Create Note'), self.create], 'all_notes': [self.tr('All Notes'), self.show_all_notes], 'sync': [sync_label, Slot()(self.app.provider.sync)], 'pin_notes': pin_notes, 'notes': notes, } for item in self.app.settings.value('menu-order', DEFAULT_INDICATOR_LAYOUT): if item == 'pin_notes' or item == 'notes': if not first_sync and len(menu_items[item]): self.menu.addSeparator() if item == 'notes' and sort_by_notebook: for notebook in menu_items[item]: sub_menu = self.menu.addMenu(notebook.name) _notes = menu_items[item][notebook] for struct in _notes: self._add_note(sub_menu, struct) else: for struct in menu_items[item]: self._add_note(self.menu, struct) self.menu.addSeparator() else: action = self.menu.addAction(menu_items[item][0], menu_items[item][1]) if status_syncing and item == 'sync': action.setEnabled(False) self.menu.addSeparator() self.menu.addAction(self.tr('Settings and Management'), self.show_management) self.menu.addAction(self.tr('Exit'), self.exit) def open(self, note, search_term=''): old_note_window = self.opened_notes.get(note.id, None) if old_note_window and not getattr(old_note_window, 'closed', True): editor = self.opened_notes[note.id] # hide and show for bringing to front editor.hide() editor.show() else: editor = Editor(note) editor.show() self.opened_notes[note.id] = editor if search_term: editor.findbar.set_search_term(search_term) editor.findbar.show() editor.raise_() editor.activateWindow() return editor @Slot() def create(self, attach=None, notebook_id=NONE_ID): note_struct = Note( # maybe replace NONE's to somthing better id=NONE_ID, title=self.tr('New note'), content=self.tr("New note content"), tags=dbus.Array([], signature='i'), notebook=notebook_id, created=NONE_VAL, updated=NONE_VAL, conflict_parent=NONE_VAL, conflict_items=dbus.Array([], signature='i'), place='', share_date=NONE_VAL, share_url='', ).struct note = Note.from_tuple( self.app.provider.create_note(note_struct), ) editor = self.open(note) if attach: editor.resource_edit.add_all_attach(attach) @Slot() def show_all_notes(self): if not hasattr(self, 'list') or getattr(self.list, 'closed', True): self.list = List() self.list.show() else: self.list.activateWindow() @Slot() def show_management(self): if not hasattr(self, 'management') or getattr(self.management, 'closed', True): self.management = Management() self.management.show() else: self.management.activateWindow() @Slot() def exit(self): self.app.quit()
class ActivityStatus(QMainWindow): """ Main application window, responsible for application lifecycle """ def __init__(self): QMainWindow.__init__(self, None, Qt.FramelessWindowHint) self.__settings = Settings() self.__activityManager = ActivityManager(self.__settings) self.__trayIcon = QSystemTrayIcon(self) self.__managerController = ActivityManagerControl(self, self.__activityManager) self.__appMenu = QMenu(self) self.__closeAction = QAction(self.tr('Close'), self) self.__appIcon = resources.getIcon('pomidor.png') self._configureActions() self._configureMenu() self._setupTrayIcon() self._configureMainWindow() self._setupEventHooks() logging.debug('Application started') def _setupTrayIcon(self): """ Set initial image on tray icon """ self.__trayIcon.setIcon(self.__appIcon) self.__trayIcon.show() self.__trayIcon.activated.connect(self._trayIconClicked) self.__trayIcon.setContextMenu(self.__appMenu) def _configureMainWindow(self): """Configure main window contents""" self.setCentralWidget(self.__managerController) self.setWindowIcon(self.__appIcon) def _setupEventHooks(self): """Connect to event hooks provided by the activity manager""" self.__activityManager.activityStarted += self._hideMainWindow self.__activityManager.workActivityEnded += self._notifyActivityEnding self.__activityManager.breakActivityEnded += self._notifyActivityEnding self.__activityManager.activityTimeChanged += self._showRemainingTime def _configureMenu(self): """Configure application menu, add all actions and separators""" self.__appMenu.addActions(self.__managerController.actionList) self.__appMenu.addSeparator() self.__appMenu.addAction(self.__closeAction) def _configureActions(self): """Configure actions of the main controller""" self.__closeAction.triggered.connect(_closeApplication) def _trayIconClicked(self, reason): """ Process the click on the tray icon @param reason: how the icon was clicked """ logging.debug('Tray icon clicked') if reason == QSystemTrayIcon.Trigger: if self.isVisible(): self._hideMainWindow() else: self._showMainWindw() def closeEvent(self, event): """ Prevent main window from closing by clicking on close button @param event: the event, which controls the operation @type event: QCloseEvent """ event.ignore() self._hideMainWindow() def _hideMainWindow(self, _=''): """Hide main window from the screen""" logging.debug('Main window is hidden') self.setVisible(False) def _showMainWindw(self): """Show main window near-by to the system tray icon""" logging.debug('Main window is shown') self.setVisible(True) trayIconGeometry = self.__trayIcon.geometry() screenGeometry = QApplication.desktop().screenGeometry(trayIconGeometry.topLeft()) self.move(_calculateWindowPosition(screenGeometry, trayIconGeometry, self.width(), self.height())) def _notifyActivityEnding(self): """Invoke activity ending action""" logging.debug('Notifying user about action ending') process = Process(target=_executeAction, args=(self.__settings.endActivityAction,)) process.start() self.__trayIcon.setIcon(self.__appIcon) def _showRemainingTime(self, seconds): """ Show remaining time to the user @param seconds: remaining time @type seconds: int """ if seconds > 60: time = int(seconds / 60) else: time = seconds text = "{0:02d}".format(time) basePixelMap = resources.getPixelMap('pomidor.png') painter = QPainter(basePixelMap) painter.setFont(QFont("PT Sans", 64, QFont.Bold)) painter.setPen(QPen(QColor(0, 0, 0))) painter.drawText(basePixelMap.rect(), Qt.AlignCenter, text) painter.setFont(QFont("PT Sans", 58, QFont.Bold)) painter.setPen(QPen(QColor(240, 240, 240))) painter.drawText(basePixelMap.rect(), Qt.AlignCenter, text) painter.end() self.__trayIcon.setIcon(QIcon(basePixelMap))
def __init__(self, window): self.window = window self.state = self.window.state self.keepCheckFormsAlive = set() self.doingAllChecks = False self.checkCount = 0 self.undoAction = Lib.createAction(window, ":/edit-undo.svg", "&Undo", self.state.undo, QKeySequence(Qt.Key_F9), tooltip="""\ <p><b>Index→Undo</b></p> <p>Undo the last entry or index action if possible.</p>""".format( QKeySequence(Qt.Key_F9))) self.redoAction = Lib.createAction( window, ":/edit-redo.svg", "&Redo", self.state.redo, QKeySequence(Qt.CTRL + Qt.Key_F9), tooltip="""\ <p><b>Index→Redo</b></p> <p>Redo the last entry or index action that was undone if possible.</p>""". format(QKeySequence(Qt.CTRL + Qt.Key_F9))) self.combinePagesAction = Lib.createAction( window, ":/combinepages.svg", "&Combine Overlapping Pages...", self.combinePages, tooltip="""\ <p><b>Index→Combine Overlapping Pages</b></p> <p>Combine overlapping pages where possible.</p>""") self.renumberPagesAction = Lib.createAction(window, ":/renumberpages.svg", "Renumber &Pages...", self.renumberPages, tooltip="""\ <p><b>Index→Renumber Pages</b></p> <p>Renumber all or a selected range of pages.</p>""") self.ignoredFirstsAction = Lib.createAction( window, ":/format-justify-right.svg", "Ignored &Subentry Function Words...", self.editSubentryIgnoreFirsts, tooltip="""\ <p><b>Index→Ignored Subentry Function Words</b></p> <p>Edit the function words to be ignored when sorting subentries if the <b>Index→Options</b>, <b>Rules</b>, <b>Ignore Subentries Function Words</b> checkbox is checked.</p>""") self.optionsAction = Lib.createAction( window, ":/preferences-system.svg", "&Options...", self.options, tooltip="""\ <p><b>Index→Options</b></p> <p>Set options for {} and for the current index.""".format( QApplication.applicationName())) self.outputOptionsAction = Lib.createAction( window, ":/preferences-system.svg", "Ou&tput Options...", self.outputOptions, tooltip="""\ <p><b>Index→Output Options</b></p> <p>Set {}'s output and print options.</p>""".format( QApplication.applicationName())) self.checkActions = Lib.createAction(window, ":/check.svg", "Chec&k", tooltip="""\ <p><b>Index→Check</b></p> <p>Check various aspects of the index.</p>""") menu = QMenu(window) action = Lib.createAction(window, ":/check.svg", "&All the Checks", self.allChecks, tooltip="""\ <p><b>Index→Check→All the Checks</b></p> <p>Perform all the checks.</p>""") menu.addAction(action) menu.addSeparator() action = Lib.createAction( window, ":/check.svg", "&Same Term Texts", lambda: self.check(FilterKind.SAME_TERM_TEXTS), tooltip="""\ <p><b>Index→Check→Same Term Texts</b></p> <p>Check to see if any entries at the same level have the same term texts irrespective of formatting or case and regardless of their Sort As texts.</p>""") menu.addAction(action) action = Lib.createAction( window, ":/check.svg", "&Overlapping Pages", lambda: self.check(FilterKind.HAS_OVERLAPPING_PAGES), tooltip="""\ <p><b>Index→Check→Overlapping Pages</b></p> <p>Check to see if any entries have overlapping pages.</p>""") menu.addAction(action) action = Lib.createAction(window, ":/check.svg", "Too &High Page Number", lambda: self.check(FilterKind.TOO_HIGH_PAGE), tooltip="""\ <p><b>Index→Check→Too High Page Number</b></p> <p>Check to see if any entries have page numbers exceeding the limit set in the Index→Options General tab's Publisher's Limits.</p>""") menu.addAction(action) action = Lib.createAction( window, ":/check.svg", "Too &Large Page Range", lambda: self.check(FilterKind.TOO_LARGE_PAGE_RANGE), tooltip="""\ <p><b>Index→Check→Too Large Page Range</b></p> <p>Check to see if any entries have page ranges spanning more page number than the the limit set in the Index→Options General tab's Publisher's Limits.</p>""") menu.addAction(action) action = Lib.createAction( window, ":/check.svg", "Too &Many Pages", lambda: self.check(FilterKind.TOO_MANY_PAGES), tooltip="""\ <p><b>Index→Check→Too Many Pages</b></p> <p>Check to see if any entries have more pages than the the limit set in the Index→Options General tab's Publisher's Limits.</p>""") menu.addAction(action) action = Lib.createAction(window, ":/check.svg", "&Unindexed Pages", self.unindexedPages, tooltip="""\ <p><b>Index→Check→Unindexed Pages</b></p> <p>Check to see if there are any (decimal) pages that have no index entries. (This checks pages between 1 and the highest page limit set in the Index→Options General tab's Publisher's Limits.)</p>""") menu.addAction(action) self.checkActions.setMenu(menu) self.customMarkupAction = Lib.createAction(window, ":/markup.svg", "Custom &Markup...", self.customMarkup, tooltip="""\ <p><b>Index→Custom Markup</b></p> <p>Create, edit, or delete custom plain-text markup.</p>""") self.infoAction = Lib.createAction(window, ":/about.svg", "&Information...", self.info, tooltip="""\ <p><b>Index→Information</b></p> <p>Show some basic information about the current index.</p>""") self.showSuggestionsAction = Lib.createAction( window, ":/showpanel.svg", "Show Suggestions and &Groups", self.state.window.showSuggestions, tooltip=""" <p><b>Index→Show Suggestions and Groups</b></p> <p>Show the Suggestions and Groups panels if they aren't visible.</p>""") self.showToobarsAction = Lib.createAction(window, ":/preferences-desktop.svg", "Sho&w Toolbars", self.showToobars, tooltip="""\ <p><b>Index→Show Toolbars</b></p> <p>Show all {}'s toolbars; useful if they have all been hidden.</p> """.format(QApplication.applicationName()))
class MTTSettingsMenu(QMenu): def __init__(self, parent=None): super(MTTSettingsMenu, self).__init__(parent) self.view = parent self.is_master_cmd = False # power user state self.power_user = MTTSettings.value('powerUser') self.__create_actions() self.__populate_menu() def keyPressEvent(self, event): if event.modifiers() == Qt.ControlModifier: self.is_master_cmd = True super(MTTSettingsMenu, self).keyPressEvent(event) def keyReleaseEvent(self, event): self.is_master_cmd = False super(MTTSettingsMenu, self).keyReleaseEvent(event) def __create_actions(self): def add_action(lbl, tip, cmd, checkable=False, checked=False): a = QAction(lbl, self) a.setStatusTip(tip) a.triggered.connect(cmd) if checkable: a.setCheckable(True) a.setChecked(checked) return a self.help_a = add_action( 'Help', 'Opens the online Help page', self.on_settings_help) self.switch_edit_a = add_action( 'Switch Edit/Source', 'Replace "Edit" button by "Source" button', self.on_switch_source_edit_menu, True, MTTSettings.value('switchEdit')) self.heads_up_a = add_action( 'HeadsUp Message', 'Show HeadsUp Message in viewport', self.on_toggle_headsup, True, MTTSettings.value('showHeadsUp')) self.focus_filter_a = add_action( 'Focus Filter Field at Startup', 'Focus filter field at startup', self.on_toggle_focus, True, MTTSettings.value('filterFocus')) self.force_relative_path_a = add_action( 'Force Relative Path', 'Set a relative path when selecting a new file', self.on_force_relative_path, True, MTTSettings.value('forceRelativePath')) self.show_real_attr_value_a = add_action( 'Show Real Attribute Value', 'Show fullpath instead of filtering path as Attribute Editor', self.on_show_real_attribute_value, True, MTTSettings.value('showRealAttributeValue')) self.manage_quick_filter_a = add_action( 'Manage Quick Filters', 'Manage filters that popup with right clic in filter field', self.on_filter_manage_quick_filter) self.clear_completion_cache_a = add_action( 'Clear Completion Cache', 'Erase auto completion cache of filter field', self.on_filter_clear_completion_cache) self.override_panels_a = add_action( 'Add CreateNode Button to Editors', ('Add "Create Node" to HyperShade and ' 'Node Editor for the current session'), self.on_override_panels) self.export_to_csv = add_action( 'Export Texture List as CSV', 'Export current textures into a csv file', self.view.model.export_as_csv) self.about = add_action( 'About', 'About', self.on_settings_about) def __populate_menu(self): self.addAction(self.help_a) self.addSeparator() self.addAction(self._get_menu_header('SETTINGS')) self.addAction(self.switch_edit_a) self.addAction(self.heads_up_a) self.addAction(self.focus_filter_a) self.addAction(self.force_relative_path_a) self.addAction(self.show_real_attr_value_a) self.addMenu(self._create_instance_menu()) self.addMenu(self._create_theme_menu()) self.addSeparator() self.addAction(self._get_menu_header('FILTER OPTIONS')) self.addAction(self.manage_quick_filter_a) self.addAction(self.clear_completion_cache_a) self.addSeparator() self.addAction(self._get_menu_header('MISC')) self.addAction(self.override_panels_a) self.addAction(self.export_to_csv) self.addSeparator() self.addAction(self._get_menu_header('DEBUG')) self.addMenu(self._create_debug_menu()) self.addSeparator() self.addAction(self.about) def _get_menu_header(self, title): header = QAction(title, self) header.setEnabled(False) return header def _create_instance_menu(self): self.instance_menu = QMenu(self) self.instance_menu.setTitle('Prompt Instance Delay') self.instance_menu.aboutToShow.connect( self.on_show_prompt_instance_delay_menu) return self.instance_menu def _create_theme_menu(self): theme_menu = QMenu(self) theme_menu.setTitle('Buttons Theme') theme_menu.setTearOffEnabled(True) theme_menu.setWindowTitle(TAG) theme_actions = QActionGroup(self) theme_actions.setExclusive(True) # create ordered theme list custom_order_theme = sorted(THEMES.iterkeys()) custom_order_theme.remove('Maya Theme') custom_order_theme.insert(0, 'Maya Theme') default_item = True for theme in custom_order_theme: current_theme_action = QAction(theme, theme_actions) current_theme_action.setCheckable(True) current_theme_action.setChecked( MTTSettings.value('theme', 'Maya Theme') == theme) current_theme_action.triggered.connect(self.on_change_theme) theme_menu.addAction(current_theme_action) if default_item: theme_menu.addSeparator() default_item = False return theme_menu def _create_debug_menu(self): self.debug_menu = QMenu(self) self.debug_menu.setTitle('Debug Menu') self.debug_menu.aboutToShow.connect(self.on_show_debug_menu) return self.debug_menu def on_change_theme(self): self.view.on_choose_theme(self.sender().text()) def on_show_debug_menu(self): self.debug_menu.clear() if self.is_master_cmd or self.power_user: power_user_mode = QAction('Power User Mode', self) power_user_mode.setCheckable(True) power_user_mode.setChecked(MTTSettings.value('powerUser')) power_user_mode.triggered.connect(self.__on_toggle_power_user) self.debug_menu.addAction(power_user_mode) self.is_master_cmd = False self.debug_menu.addSeparator() open_pref_folder_action = QAction('Open Preferences Folder', self) open_pref_folder_action.setStatusTip('Open MTT preference folder') open_pref_folder_action.triggered.connect(self.on_open_preference_folder) self.debug_menu.addAction(open_pref_folder_action) self.debug_menu.addSeparator() database_dump_csv = QAction('Dump Database as CSV', self) database_dump_csv.triggered.connect(self.view.model.database_dump_csv) self.debug_menu.addAction(database_dump_csv) database_dump_sql = QAction('Dump Database as SQL', self) database_dump_sql.triggered.connect(self.view.model.database_dump_sql) self.debug_menu.addAction(database_dump_sql) self.debug_menu.addSeparator() support_info = QMenu(self) support_info.setTitle('Supported Node Type') support_info.aboutToShow.connect(self.on_show_supported_type) self.debug_menu.addMenu(support_info) def on_filter_clear_completion_cache(self): """ Clear filter auto completion cache """ self.view.on_filter_set_text('') MTTSettings.remove('filterCompletionWildcard') MTTSettings.remove('filterCompletionRegExp') self.view.completion_model.setStringList([]) def on_switch_source_edit_menu(self): state = MTTSettings.value('switchEdit') MTTSettings.set_value('switchEdit', not state) self.view.on_set_source_edit_menu(not state) def on_show_real_attribute_value(self): self.view.model.layoutAboutToBeChanged.emit() show_real_attribute_state = MTTSettings.value('showRealAttributeValue') MTTSettings.set_value( 'showRealAttributeValue', not show_real_attribute_state) self.view._layout_changed() def on_filter_manage_quick_filter(self): """ Open Quick Filter words manager and save its content """ manager = MTTQuickFilterManager(self) if manager.exec_(): lists = manager.get_lists() # save list in settings MTTSettings.set_value('filterQuickWordsWildcard', ';;'.join(lists[0])) MTTSettings.set_value('filterQuickWordsRegExp', ';;'.join(lists[1])) # set current list self.view.quick_filter_words = lists[MTTSettings.value('filterRE')] manager.deleteLater() @staticmethod def on_toggle_headsup(): state = MTTSettings.value('showHeadsUp') MTTSettings.set_value('showHeadsUp', not state) @staticmethod def on_toggle_focus(): state = MTTSettings.value('filterFocus') MTTSettings.set_value('filterFocus', not state) @staticmethod def on_force_relative_path(): state = MTTSettings.value('forceRelativePath') MTTSettings.set_value('forceRelativePath', not state) def on_show_supported_type(self): node_types = sorted( [n_type for (n_type, nice, attr) in MTTSettings.SUPPORTED_TYPE] + MTTSettings.UNSUPPORTED_TYPE) support_info = self.sender() support_info.clear() for node_type in node_types: current = QAction(node_type, self) current.setEnabled(False) current.setCheckable(True) current.setChecked(node_type not in MTTSettings.UNSUPPORTED_TYPE) support_info.addAction(current) def __on_toggle_power_user(self): state = MTTSettings.value('powerUser') MTTSettings.set_value('powerUser', not state) self.power_user = not state @staticmethod def on_open_preference_folder(): """ Open preference folder """ folder_path = os.path.dirname(MTTSettings.filename()) cmds.launchImageEditor(viewImageFile=folder_path) @staticmethod def on_override_panels(): """ Override HyperShade and NodeEditor creation callback""" override_info_box = QMessageBox() override_info_box.setWindowTitle(WINDOW_TITLE) override_info_box.setIcon(QMessageBox.Information) override_info_box.setText( 'Buttons will be added to HyperShade toolbar and Node Editor toolbar.<br/>' 'Changes will exists during this session.' ) override_info_box.setInformativeText('<i>Read Help to set this settings permanent</i>') override_info_box.setStandardButtons(QMessageBox.Ok) override_info_box.setDefaultButton(QMessageBox.Ok) override_info_box.exec_() mttOverridePanels.override_panels() def on_settings_about(self): special_list = map(lambda x: x.replace(' ', ' '), sorted([ u'Beno\xeet Stordeur', u'Fran\xe7ois Jumel', 'Jonathan Lorber', 'Norbert Cretinon', 'Gilles Hoff' ])) QMessageBox.about( self.parent(), WINDOW_TITLE, '<b>Maya Texture Toolkit v{:.02f}</b>' u'<p>{} - \xa9 2014 - 2016' '</p>' '<p>Special thanks to :<br/>' '<i>{}</i>' '</p>'.format(__version__, __author__, ', '.join(special_list)) ) @staticmethod def on_settings_help(): help_wiki = 'https://github.com/Bioeden/dbMayaTextureToolkit/wiki' webbrowser.open(help_wiki) def on_show_prompt_instance_delay_menu(self): prompt_instance_state = cmds.optionVar(query='MTT_prompt_instance_state') if prompt_instance_state == PROMPT_INSTANCE_WAIT: elapsed_time = time() - cmds.optionVar(query='MTT_prompt_instance_suspend') if elapsed_time > PROMPT_INSTANCE_WAIT_DURATION: prompt_instance_state = PROMPT_INSTANCE_ASK cmds.optionVar(iv=['MTT_prompt_instance_state', prompt_instance_state]) else: mtt_log('Remaining %.2fs' % (PROMPT_INSTANCE_WAIT_DURATION - elapsed_time)) elif prompt_instance_state == PROMPT_INSTANCE_SESSION: if 'mtt_prompt_session' not in __main__.__dict__: prompt_instance_state = PROMPT_INSTANCE_ASK cmds.optionVar(iv=['MTT_prompt_instance_state', prompt_instance_state]) self.instance_menu.clear() prompt_delay = QActionGroup(self) prompt_delay.setExclusive(True) for i in range(len(PROMPT_INSTANCE_STATE.keys())): current_delay_action = QAction(PROMPT_INSTANCE_STATE[i], prompt_delay) current_delay_action.setCheckable(True) current_delay_action.setChecked(prompt_instance_state == i) current_delay_action.triggered.connect( partial(self.view.on_choose_instance_delay, i, prompt=i != 0)) self.instance_menu.addAction(current_delay_action)
class Indicator(QSystemTrayIcon): def __init__(self, app, *args, **kwargs): QSystemTrayIcon.__init__(self, *args, **kwargs) self.app = app self.menu = QMenu() self.setContextMenu(self.menu) self.menu.aboutToShow.connect(self.update) self.opened_notes = {} self.activated.connect(self._activated) def _activated(self, reason): if reason == QSystemTrayIcon.Trigger: self.menu.popup(QCursor().pos()) def _add_note(self, struct): note = Note.from_tuple(struct) title = note.title[:40].replace('&', '&&') self.menu.addAction(title, Slot()( partial(self.open, note=note) )) @Slot() def kill_all(self): try: self.app.provider.kill() except dbus.exceptions.DBusException: pass os.system('everpad --replace') @Slot() def update(self): self.menu.clear() try: version = self.app.provider.get_api_version() except ( # dbus raise some magic dbus.exceptions.UnknownMethodException, dbus.exceptions.DBusException, ): version = -1 if version != API_VERSION: action = self.menu.addAction( self.tr('API version missmatch, please restart'), ) action.setEnabled(False) self.menu.addAction( self.tr('Restart everpad'), self.kill_all, ) return if get_auth_token(): pin_notes = self.app.provider.find_notes( '', dbus.Array([], signature='i'), dbus.Array([], signature='i'), 0, 20, Note.ORDER_UPDATED_DESC, 1, ) notes = self.app.provider.find_notes( '', dbus.Array([], signature='i'), dbus.Array([], signature='i'), 0, 20 - len(pin_notes), Note.ORDER_UPDATED_DESC, 0, ) if len(notes) + len(pin_notes) or self.app.provider.is_first_synced(): self.menu.addAction(self.tr('All Notes'), self.show_all_notes) self.menu.addSeparator() if len(pin_notes): for struct in pin_notes: self._add_note(struct) self.menu.addSeparator() for struct in notes: self._add_note(struct) self.menu.addSeparator() self.menu.addAction(self.tr('Create Note'), self.create) first_sync = False else: first_sync = True if self.app.provider.get_status() == STATUS_SYNC: action = self.menu.addAction( self.tr('Wait, first sync in progress') if first_sync else self.tr('Sync in progress') ) action.setEnabled(False) else: if first_sync: label = self.tr('Please perform first sync') else: label = self.tr('Last sync: %s') % self.app.provider.get_last_sync() self.menu.addAction(label, Slot()(self.app.provider.sync)) self.menu.addAction(self.tr('Settings and Management'), self.show_management) self.menu.addSeparator() self.menu.addAction(self.tr('Exit'), self.exit) def open(self, note, search_term=''): old_note_window = self.opened_notes.get(note.id, None) if old_note_window and not getattr(old_note_window, 'closed', True): editor = self.opened_notes[note.id] editor.activateWindow() else: editor = Editor(self.app, note) editor.show() self.opened_notes[note.id] = editor if search_term: editor.findbar.set_search_term(search_term) editor.findbar.show() return editor @Slot() def create(self, attach=None, notebook_id=NONE_ID): note_struct = Note( # maybe replace NONE's to somthing better id=NONE_ID, title=self.tr('New note'), content=self.tr("New note content"), tags=dbus.Array([], signature='i'), notebook=notebook_id, created=NONE_VAL, updated=NONE_VAL, place='', ).struct note = Note.from_tuple( self.app.provider.create_note(note_struct), ) editor = self.open(note) if attach: editor.resource_edit.add_attach(attach) @Slot() def show_all_notes(self): if not hasattr(self, 'list') or getattr(self.list, 'closed', True): self.list = List(self.app) self.list.show() else: self.list.activateWindow() @Slot() def show_management(self): if not hasattr(self, 'management') or getattr(self.management, 'closed', True): self.management = Management(self.app) self.management.show() else: self.management.activateWindow() @Slot() def exit(self): sys.exit(0)
class CodeEdit(QPlainTextEdit, StyledObject): """ The code editor text edit. This is a specialized QPlainTextEdit made to expose additional signals, styling and methods. It also provides a custom context menu and methods to add actions, separators and sub-menus. Most of the code editor functionnalities are provided by installing modes on the PCEF instance. Additional signals: - dirtyChanged(bool) - focusedIn(QFocusEvent) - keyPressed(QKeyEvent) - keyReleased(QKeyEvent) - mousePressed(QMouseEvent) - mouseReleased(QMouseEvent) - newTextSet() - prePainting(QPaintEvent) - postPainting(QPaintEvent) - visibleBlocksChanged() """ QSS = """QPlainTextEdit { background-color: %(b)s; color: %(t)s; selection-background-color: %(bs)s; selection-color: %(ts)s; border: none; border-radius: 0px; } """ #--------------------------------------------------------------------------- # Signals #--------------------------------------------------------------------------- #: Signal emitted when the dirty state of the document changed dirtyChanged = Signal(bool) #: Signal emitted when a key is pressed keyPressed = Signal(QKeyEvent) #: Signal emitted when a key is released keyReleased = Signal(QKeyEvent) #: Signal emitted when a mouse button is pressed mousePressed = Signal(QMouseEvent) #: Signal emitted when a mouse button is released mouseReleased = Signal(QMouseEvent) #: Signal emitted on a wheel event mouseWheelActivated = Signal(QWheelEvent) #: Signal emitted before painting the core widget prePainting = Signal(QPaintEvent) #: Signal emitted after painting the core widget postPainting = Signal(QPaintEvent) #: Signal emitted at the end of the keyPressed event postKeyPressed = Signal(QKeyEvent) #: Signal emitted when the list of visible blocks changed visibleBlocksChanged = Signal() #: Signal emitted when setPlainText is invoked newTextSet = Signal() #: Signal emitted when focusInEvent is is called focusedIn = Signal(QFocusEvent) #: Signal emitted when the text is saved with pcef.saveFileFromEditor. # The signal is emitted with the complete file path textSaved = Signal(str) #--------------------------------------------------------------------------- # Properties #--------------------------------------------------------------------------- def __get_dirty(self): return self.__dirty def __set_dirty(self, dirty): if dirty != self.__dirty: self.__dirty = dirty self.dirtyChanged.emit(dirty) @property def contextMenu(self): return self.__context_menu #: Tells whether the editor is dirty(changes have been made to the document) dirty = property(__get_dirty, __set_dirty) #--------------------------------------------------------------------------- # Methods #--------------------------------------------------------------------------- def __init__(self, parent=None): """ Creates the widget. :param parent: Optional parent widget """ QPlainTextEdit.__init__(self, parent) StyledObject.__init__(self) #: Tag member used to remeber the filename of the edited text if any self.tagFilename = None #: Tag member used to remeber the filename of the edited text if any self.tagEncoding = 'utf8' #: Weakref to the editor self.editor = None self.__originalText = "" #: dirty flag self.__dirty = False #: our custom context menu self.__context_menu = QMenu() #: The list of active extra-selections (TextDecoration) self.__selections = [] self.__numBlocks = -1 self.visible_blocks = [] #: Shortcut to the fontMetrics self.fm = self.fontMetrics() self.textChanged.connect(self.__onTextChanged) self.blockCountChanged.connect(self.__onBlocksChanged) self.verticalScrollBar().valueChanged.connect(self.__onBlocksChanged) self.newTextSet.connect(self.__onBlocksChanged) self.cursorPositionChanged.connect(self.__onBlocksChanged) self.setLineWrapMode(QPlainTextEdit.NoWrap) self.setMouseTracking(True) self._onStyleChanged() def addAction(self, action): """ Adds an action to the text edit context menu :param action: QAction """ QTextEdit.addAction(self, action) self.__context_menu.addAction(action) def addSeparator(self): """ Adds a separator to the context menu """ self.__context_menu.addSeparator() def addDecoration(self, decoration): """ Add a text decoration :param decoration: Text decoration :type decoration: pcef.core.TextDecoration """ self.__selections.append(decoration) self.__selections = sorted(self.__selections, key=lambda sel: sel.draw_order) self.setExtraSelections(self.__selections) def removeDecoration(self, decoration): """ Remove text decoration. :param decoration: The decoration to remove :type decoration: pcef.core.TextDecoration """ try: self.__selections.remove(decoration) self.setExtraSelections(self.__selections) except ValueError: pass def setShowWhitespaces(self, show): """ Shows/Hides whitespaces. :param show: True to show whitespaces, False to hide them :type show: bool """ doc = self.document() options = doc.defaultTextOption() if show: options.setFlags(options.flags() | QTextOption.ShowTabsAndSpaces) else: options.setFlags(options.flags() & ~QTextOption.ShowTabsAndSpaces) doc.setDefaultTextOption(options) def indent(self, size): """ Indent current line or selection :param size: indent size in spaces :type size: int """ cursor = self.textCursor() cursor.beginEditBlock() sel_start = cursor.selectionStart() sel_end = cursor.selectionEnd() has_selection = True if not cursor.hasSelection(): cursor.select(QTextCursor.LineUnderCursor) has_selection = False nb_lines = len(cursor.selection().toPlainText().splitlines()) cursor.setPosition(cursor.selectionStart()) for i in range(nb_lines): cursor.movePosition(QTextCursor.StartOfLine) cursor.insertText(" " * size) cursor.movePosition(QTextCursor.EndOfLine) cursor.setPosition(cursor.position() + 1) cursor.setPosition(sel_start + size) if has_selection: cursor.setPosition(sel_end + (nb_lines * size), QTextCursor.KeepAnchor) cursor.endEditBlock() self.setTextCursor(cursor) def unIndent(self, size): """ Un-indent current line or selection by tab_size """ cursor = self.textCursor() assert isinstance(cursor, QTextCursor) cursor.beginEditBlock() pos = cursor.position() sel_start = cursor.selectionStart() sel_end = cursor.selectionEnd() has_selection = True if not cursor.hasSelection(): cursor.select(QTextCursor.LineUnderCursor) has_selection = False nb_lines = len(cursor.selection().toPlainText().splitlines()) cursor.setPosition(cursor.selectionStart()) cpt = 0 for i in range(nb_lines): cursor.select(QTextCursor.LineUnderCursor) if cursor.selectedText().startswith(" " * size): cursor.movePosition(QTextCursor.StartOfLine) [cursor.deleteChar() for _ in range(size)] pos = pos - size cpt += 1 else: cursor.clearSelection() # next line cursor.movePosition(QTextCursor.EndOfLine) cursor.setPosition(cursor.position() + 1) if cpt: cursor.setPosition(sel_start - size) else: cursor.setPosition(sel_start) if has_selection: cursor.setPosition(sel_end - (cpt * size), QTextCursor.KeepAnchor) cursor.endEditBlock() self.setTextCursor(cursor) def updateOriginalText(self): self.__originalText = self.toPlainText() def _onStyleChanged(self): """ Updates widget style when style changed. """ self.setFont(QFont(self.currentStyle.fontName, self.currentStyle.fontSize)) self.fm = self.fontMetrics() qss = self.QSS % { 'b': self.currentStyle.backgroundColor, 't': self.currentStyle.tokenColor(Token), "bs": self.currentStyle.selectionBackgroundColor, "ts": self.currentStyle.selectionTextColor} self.setShowWhitespaces(self.currentStyle.showWhitespaces) self.setStyleSheet(qss) def paintEvent(self, event): """ Emits prePainting and postPainting signals :param event: QPaintEvent """ self.prePainting.emit(event) QPlainTextEdit.paintEvent(self, event) self.postPainting.emit(event) def keyPressEvent(self, event): """ Performs indentation if tab key presed, else emits the keyPressed signal :param event: QKeyEvent """ # assert isinstance(event, QKeyEvent) event.stop = False # replace tabs by space if event.key() == Qt.Key_Tab: cursor = self.textCursor() assert isinstance(cursor, QTextCursor) if not cursor.hasSelection(): # insert tab at cursor pos cursor.insertText(" " * self.editor().TAB_SIZE) else: # indent whole selection self.indent(self.editor().TAB_SIZE) event.stop = True self.keyPressed.emit(event) if not event.stop: QPlainTextEdit.keyPressEvent(self, event) self.postKeyPressed.emit(event) def keyReleaseEvent(self, event): """ Performs indentation if tab key pressed, else emits the keyPressed signal :param event: QKeyEvent """ assert isinstance(event, QKeyEvent) event.stop = False self.keyReleased.emit(event) if not event.stop: QPlainTextEdit.keyReleaseEvent(self, event) def focusInEvent(self, event): """ Emits the focusedIn signal :param event: :return: """ self.focusedIn.emit(event) QPlainTextEdit.focusInEvent(self, event) def mousePressEvent(self, event): """ Emits mousePressed signal :param event: QMouseEvent """ event.stop = False self.mousePressed.emit(event) if not event.stop: QPlainTextEdit.mousePressEvent(self, event) def mouseReleaseEvent(self, event): """ Emits mouseReleased signal. :param event: QMouseEvent """ event.stop = False self.mouseReleased.emit(event) if not event.stop: QPlainTextEdit.mouseReleaseEvent(self, event) def wheelEvent(self, event): """ Emits the mouseWheelActivated signal. :param event: QMouseEvent """ event.stop = False self.mouseWheelActivated.emit(event) if not event.stop: QPlainTextEdit.wheelEvent(self, event) def mouseMoveEvent(self, event): assert isinstance(event, QMouseEvent) c = self.cursorForPosition(event.pos()) for sel in self.__selections: if sel.containsCursor(c) and sel.tooltip: QToolTip.showText(self.mapToGlobal(event.pos()), sel.tooltip, self) break QPlainTextEdit.mouseMoveEvent(self, event) def contextMenuEvent(self, event): """ Shows our own context menu """ self.__context_menu.exec_(event.globalPos()) def resizeEvent(self, event): """ Updates visible blocks on resize """ self.__onBlocksChanged() QPlainTextEdit.resizeEvent(self, event) def __onTextChanged(self): """ Sets dirty to true """ if self.toPlainText() != self.__originalText: # self.__originalText = self.toPlainText() self.dirty = True else: self.dirty = False def setPlainText(self, txt): """ Sets the text edit content and emits newTextSet signal. :param txt: New text to display """ self.__originalText = txt QPlainTextEdit.setPlainText(self, txt) self.newTextSet.emit() def __onBlocksChanged(self): """ Updates the list of visible blocks and emits visibleBlocksChanged signal. """ visible_blocks = [] block = self.firstVisibleBlock() row = block.blockNumber() + 1 width = self.width() w = width - 2 h = self.fm.height() bbox = self.blockBoundingGeometry(block) top = bbox.translated(self.contentOffset()).top() bottom = top + bbox.height() zoneTop = 0 # event.rect().top() zoneBottom = self.height() # event.rect().bottom() visible_blocks_append = visible_blocks.append while block.isValid() and top <= zoneBottom: if block.isVisible() and bottom >= zoneTop: visible_blocks_append( VisibleBlock(row, block, (0, top, w, h)) ) block = block.next() row += 1 top = bottom bottom = top + self.blockBoundingRect(block).height() self.visible_blocks = visible_blocks self.visibleBlocksChanged.emit() def fold(self, start, end, fold=True): """ Fold/Unfold a block of text delimitted by start/end line numbers :param start: Start folding line (this line is not fold, only the next ones) :param end: End folding line. :param fold: True to fold, False to unfold """ doc = self.document() assert isinstance(doc, QTextDocument) for i in range(start + 1, end): block = self.document().findBlockByNumber(i) assert isinstance(block, QTextBlock) block.setVisible(not fold) doc.markContentsDirty(block.position(), block.length()) self.update() self.viewport().repaint() self.__onBlocksChanged()
class LogFilter(QFrame): def __init__(self, parent=None): super(LogFilter, self).__init__(parent=parent) setup_ui(self) self.filter_model = FilterModel(parent=self) self._viewer = None self.revs_menu = QMenu(parent=self) self.revs_separator = None self.rev_actions = QActionGroup(self) self.rev_actions.addAction(self.action_all_refs) self.select_revs_button.setMenu(self.revs_menu) self.action_all_refs.revs = None self.action_all_refs.triggered.connect(self.show_all_refs) self.action_select_branches.triggered.connect(self.pick_branches) self.filter_text.textEdited.connect(self.filter_text_edited) @property def source_model(self): return self.filter_model.sourceModel() @source_model.setter def source_model(self, model): self.filter_model.setSourceModel(model) self.revs_menu.clear() for action in self.rev_actions.actions(): if action is not self.action_all_refs: self.rev_actions.removeAction(action) self.revs_menu.addAction(self.action_all_refs) if not model.repo.head_ref: self.revs_menu.addAction(self.create_rev_action(model.repo, 'HEAD')) for branch in model.repo.branches: self.revs_menu.addAction(self.create_rev_action(model.repo, branch)) if model.all: self._select_action(self.action_all_refs) else: selected_revs = model.revs if not selected_revs: if model.repo.head_ref: selected_revs = (model.repo.head_ref,) else: selected_revs = ('HEAD',) action = self._find_rev_action(selected_revs) if not action: action = self.create_rev_action(model.repo, model.revs) self.revs_menu.addAction(action) self._select_action(action) self.revs_separator = self.revs_menu.addSeparator() self.revs_menu.addAction(self.action_select_branches) @property def viewer(self): return self._viewer @viewer.setter def viewer(self, new_viewer): self._viewer = new_viewer self._viewer.setModel(self.filter_model) def create_rev_action(self, repo, *revs): action = QAction(self.revs_menu) action.revs = revs action.setText(', '.join(str(rev) for rev in revs)) action.setCheckable(True) action.setActionGroup(self.rev_actions) action.triggered.connect(self._revs_action_triggered) return action def show_all_refs(self): self._select_action(self.action_all_refs) with busy_cursor(): self.source_model.revs = () self.source_model.all = True self.source_model.refresh() def pick_branches(self): dialog = PickBranchesDialog(repo=self.source_model.repo, parent=self) if dialog.exec_() == dialog.Accepted: self.show_revs(*dialog.selected_branches) def _select_action(self, action): action.setChecked(True) self.select_revs_button.setText(action.text()) def _revs_action_triggered(self): self._select_action(self.sender()) with busy_cursor(): self.source_model.revs = self.sender().revs self.source_model.all = False self.source_model.refresh() def _find_rev_action(self, revs): return next((action for action in self.rev_actions.actions() if action.revs == revs), None) def show_revs(self, *revs): action = self._find_rev_action(revs) if not action: action = self.create_rev_action(self.source_model.repo, *revs) self.revs_menu.insertAction(self.revs_separator, action) self._select_action(action) with busy_cursor(): self.source_model.revs = revs self.source_model.all = False self.source_model.refresh() def filter_text_edited(self, text): if text: self.viewer.hideColumn(0) self.filter_model.filters += self.filter_graph_row else: self.filter_model.filters -= self.filter_graph_row self.viewer.showColumn(0) def filter_graph_row(self, graph_row): return commit_matches_text(graph_row.log_entry, self.filter_text.text())