def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.chat_widget = ChatWidget(self) self.setCentralWidget(self.chat_widget) # set up all actions self.chat_widget.message.connect(self.statusBar().showMessage) app_menu = self.menuBar().addMenu('&Application') self.connect_action = QAction('&Connect', self) self.connect_action.triggered.connect(self._connect) self.connect_action.setShortcut('Ctrl+C') app_menu.addAction(self.connect_action) app_menu.addSeparator() self.quit_server_action = QAction('Quit &server', self) self.quit_server_action.triggered.connect(self._quit_server) self.quit_server_action.setEnabled(False) self.quit_server_action.setShortcut('Ctrl+D') app_menu.addAction(self.quit_server_action) quit_action = QAction( self.style().standardIcon(QStyle.SP_DialogCloseButton), '&Quit', self) quit_action.triggered.connect(QApplication.instance().quit) quit_action.setShortcut('Ctrl+Q') app_menu.addAction(quit_action) # attempt to connect self._connect()
def setup_ui(self): """ Setup the UI for the window. """ central_widget = QWidget() layout = QVBoxLayout() layout.addWidget(self.clock_view) layout.addWidget(self.message_view) central_widget.setLayout(layout) self.setCentralWidget(central_widget) menubar = self.menuBar() file_menu = QMenu('File') preferences_action = QAction('Preferences', file_menu) preferences_action.triggered.connect(self.on_preferences_triggered) quit_action = QAction('Quit', file_menu) quit_action.triggered.connect(self.on_quit_triggered) file_menu.addAction(preferences_action) file_menu.addAction(quit_action) menubar.addMenu(file_menu) view_menu = QMenu('View') fullscreen_action = QAction('Fullscreen', view_menu) fullscreen_action.setCheckable(True) fullscreen_action.setChecked(Config.get('FULLSCREEN', True)) fullscreen_action.setShortcut('Ctrl+Meta+F') fullscreen_action.toggled.connect(self.on_fullscreen_changed) view_menu.addAction(fullscreen_action) menubar.addMenu(view_menu)
def __init__(self, args, continuous): self.continuous = continuous gobject.GObject.__init__(self) #start by making our app self.app = QApplication(args) #make a window self.window = QMainWindow() #give the window a name self.window.setWindowTitle("BlatherQt") self.window.setMaximumSize(400, 200) center = QWidget() self.window.setCentralWidget(center) layout = QVBoxLayout() center.setLayout(layout) #make a listen/stop button self.lsbutton = QPushButton("Listen") layout.addWidget(self.lsbutton) #make a continuous button self.ccheckbox = QCheckBox("Continuous Listen") layout.addWidget(self.ccheckbox) #connect the buttons self.lsbutton.clicked.connect(self.lsbutton_clicked) self.ccheckbox.clicked.connect(self.ccheckbox_clicked) #add a label to the UI to display the last command self.label = QLabel() layout.addWidget(self.label) #add the actions for quiting quit_action = QAction(self.window) quit_action.setShortcut('Ctrl+Q') quit_action.triggered.connect(self.accel_quit) self.window.addAction(quit_action)
def updateFileMenu(self): """ Updates the file menu dynamically, so that recent files can be shown. """ self.menuFile.clear() # self.menuFile.addAction(self.actionNew) # disable for now self.menuFile.addAction(self.actionOpen) self.menuFile.addAction(self.actionSave) self.menuFile.addAction(self.actionSave_as) self.menuFile.addAction(self.actionClose_Model) recentFiles = [] for filename in self.recentFiles: if QFile.exists(filename): recentFiles.append(filename) if len(self.recentFiles) > 0: self.menuFile.addSeparator() for i, filename in enumerate(recentFiles): action = QAction("&%d %s" % (i + 1, QFileInfo(filename).fileName()), self) action.setData(filename) action.setStatusTip("Opens recent file %s" % QFileInfo(filename).fileName()) action.setShortcut(QKeySequence(Qt.CTRL | (Qt.Key_1+i))) action.triggered.connect(self.load_model) #self.connect(action, SIGNAL("triggered()"), self.load_model) self.menuFile.addAction(action) self.menuFile.addSeparator() self.menuFile.addAction(self.actionQuit)
def __setupMenu(self): """Defines basic top menu""" quit_action = QAction("&Exit", self) quit_action.setShortcut('Ctrl+Q') quit_action.triggered.connect(self.close) sign_out_action = QAction("Sign out", self) sign_out_action.setShortcut('Ctrl+L') sign_out_action.triggered.connect(lambda: (self.app.logOut(), self.hide(), self.requestCredentials())) change_password_action = QAction("Change password", self) change_password_action.triggered.connect(self.requestPasswordChange) about_action = QAction("About", self) about_action.triggered.connect(lambda: QMessageBox.about(self, "About", u'© ' + __author__ + ' 2013')) self.file_menu = self.menuBar().addMenu("&File") self.file_menu.addAction(quit_action) self.account_menu = self.menuBar().addMenu("&Account") self.account_menu.addAction(sign_out_action) self.account_menu.addAction(change_password_action) self.help_menu = self.menuBar().addMenu("&Help") self.help_menu.addAction(about_action)
def __init__(self,args,continuous): self.continuous = continuous gobject.GObject.__init__(self) #start by making our app self.app = QApplication(args) #make a window self.window = QMainWindow() #give the window a name self.window.setWindowTitle("BlatherQt") self.window.setMaximumSize(400,200) center = QWidget() self.window.setCentralWidget(center) layout = QVBoxLayout() center.setLayout(layout) #make a listen/stop button self.lsbutton = QPushButton("Listen") layout.addWidget(self.lsbutton) #make a continuous button self.ccheckbox = QCheckBox("Continuous Listen") layout.addWidget(self.ccheckbox) #connect the buttons self.lsbutton.clicked.connect(self.lsbutton_clicked) self.ccheckbox.clicked.connect(self.ccheckbox_clicked) #add a label to the UI to display the last command self.label = QLabel() layout.addWidget(self.label) #add the actions for quiting quit_action = QAction(self.window) quit_action.setShortcut('Ctrl+Q') quit_action.triggered.connect(self.accel_quit) self.window.addAction(quit_action)
def updateFileMenu(self): """ Updates the file menu dynamically, so that recent files can be shown. """ self.menuFile.clear() # self.menuFile.addAction(self.actionNew) # disable for now self.menuFile.addAction(self.actionOpen) self.menuFile.addAction(self.actionSave) self.menuFile.addAction(self.actionSave_as) self.menuFile.addAction(self.actionClose_Model) recentFiles = [] for filename in self.recentFiles: if QFile.exists(filename): recentFiles.append(filename) if len(self.recentFiles) > 0: self.menuFile.addSeparator() for i, filename in enumerate(recentFiles): action = QAction("&%d %s" % (i + 1, QFileInfo(filename).fileName()), self) action.setData(filename) action.setStatusTip("Opens recent file %s" % QFileInfo(filename).fileName()) action.setShortcut(QKeySequence(Qt.CTRL | (Qt.Key_1 + i))) action.triggered.connect(self.load_model) self.menuFile.addAction(action) self.menuFile.addSeparator() self.menuFile.addAction(self.actionQuit)
def testPythonStringAsQKeySequence(self): '''Passes a Python string to an argument expecting a QKeySequence.''' keyseq = py3k.unicode_('Ctrl+A') action = QAction(None) action.setShortcut(keyseq) shortcut = action.shortcut() self.assert_(isinstance(shortcut, QKeySequence)) self.assertEqual(shortcut.toString(), keyseq)
def addExitButton(self): """ Adds the Exit Button to the ToolBar """ exitAction = QAction(self.getQIcon('exit.png'), 'Exit the Application', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip("Exit the Application.") exitAction.triggered.connect(QtCore.QCoreApplication.instance().quit) self.addAction(exitAction)
def testSetShortcut(self): # Somehow an exception was leaking from the constructor # and appearing in setShortcut. o = QWidget() action = QAction('aaaa', o) shortcut = 'Ctrl+N' action.setShortcut(shortcut) s2 = action.shortcut() self.assertEqual(s2, shortcut)
def addNewTransactionButton(self): """ Adds the New Transaction Button to the ToolBar """ newIcon = self.getQIcon('money.png') newTransactionAction = QAction(newIcon, 'New Transaction', self) newTransactionAction.setShortcut('Ctrl+N') newTransactionAction.setStatusTip("Create a New Transaction.") newTransactionAction.triggered.connect(self.newTransaction) self.addAction(newTransactionAction)
def createAction(widget, icon, text, slot=None, shortcut=None, tooltip=None): action = QAction(QIcon(icon), text, widget) if slot is not None: action.triggered.connect(slot) if shortcut is not None: action.setShortcut(shortcut) if tooltip is not None: action.setToolTip(tooltip) return action
class ChatWindow(QMainWindow): """ The chat application window. """ def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.chat_widget = ChatWidget(self) self.setCentralWidget(self.chat_widget) # set up all actions self.chat_widget.message.connect(self.statusBar().showMessage) app_menu = self.menuBar().addMenu('&Application') self.connect_action = QAction('&Connect', self) self.connect_action.triggered.connect(self._connect) self.connect_action.setShortcut('Ctrl+C') app_menu.addAction(self.connect_action) app_menu.addSeparator() self.quit_server_action = QAction('Quit &server', self) self.quit_server_action.triggered.connect(self._quit_server) self.quit_server_action.setEnabled(False) self.quit_server_action.setShortcut('Ctrl+D') app_menu.addAction(self.quit_server_action) quit_action = QAction( self.style().standardIcon(QStyle.SP_DialogCloseButton), '&Quit', self) quit_action.triggered.connect(QApplication.instance().quit) quit_action.setShortcut('Ctrl+Q') app_menu.addAction(quit_action) # attempt to connect self._connect() def _quit_server(self): if self.chat_widget.connected: self.chat_widget.send_text('quit') def _connect(self): # connect to a server if not self.chat_widget.connected: self.chat_widget.connection = QTcpSocket() # upon connection, disable the connect action, and enable the # quit server action self.chat_widget.connection.connected.connect( partial(self.quit_server_action.setEnabled, True)) self.chat_widget.connection.connected.connect( partial(self.connect_action.setDisabled, True)) # to the reverse thing upon disconnection self.chat_widget.connection.disconnected.connect( partial(self.connect_action.setEnabled, True)) self.chat_widget.connection.disconnected.connect( partial(self.quit_server_action.setDisabled, True)) # connect to the chat server self.chat_widget.connection.connectToHost(HOST_ADDRESS, PORT)
class ChatWindow(QMainWindow): """ The chat application window. """ def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.chat_widget = ChatWidget(self) self.setCentralWidget(self.chat_widget) # set up all actions self.chat_widget.message.connect(self.statusBar().showMessage) app_menu = self.menuBar().addMenu('&Application') self.connect_action = QAction('&Connect', self) self.connect_action.triggered.connect(self._connect) self.connect_action.setShortcut('Ctrl+C') app_menu.addAction(self.connect_action) app_menu.addSeparator() self.quit_server_action = QAction('Quit &server', self) self.quit_server_action.triggered.connect(self._quit_server) self.quit_server_action.setEnabled(False) self.quit_server_action.setShortcut('Ctrl+D') app_menu.addAction(self.quit_server_action) quit_action = QAction(self.style().standardIcon( QStyle.SP_DialogCloseButton), '&Quit', self) quit_action.triggered.connect(QApplication.instance().quit) quit_action.setShortcut('Ctrl+Q') app_menu.addAction(quit_action) # attempt to connect self._connect() def _quit_server(self): if self.chat_widget.connected: self.chat_widget.send_text('quit') def _connect(self): # connect to a server if not self.chat_widget.connected: self.chat_widget.connection = QTcpSocket() # upon connection, disable the connect action, and enable the # quit server action self.chat_widget.connection.connected.connect( partial(self.quit_server_action.setEnabled, True)) self.chat_widget.connection.connected.connect( partial(self.connect_action.setDisabled, True)) # to the reverse thing upon disconnection self.chat_widget.connection.disconnected.connect( partial(self.connect_action.setEnabled, True)) self.chat_widget.connection.disconnected.connect( partial(self.quit_server_action.setDisabled, True)) # connect to the chat server self.chat_widget.connection.connectToHost(HOST_ADDRESS, PORT)
def _createAction(self, text, slot=None, shortcut=None, icon=None, tip=None, checkable=False, signal="triggered"): action = QAction(text, self) if icon is not None: action.setIcon(QIcon(":/{0}.png".format(icon))) if shortcut is not None: action.setShortcut(shortcut) if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) if slot is not None: getattr(action, signal).connect(slot) if checkable: action.setCheckable(True) return action
def createactions(self, text, slot=None, shortcut="None", icon=None, tip=None, checkable=False, signal="triggered()"): action = QAction(text, self) if icon is not None: action.setIcon(QIcon(icon)) if shortcut is not None: action.setShortcut(shortcut) if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) if slot is not None: self.connect(action, SIGNAL(signal), slot) if checkable: action.setCheckable(True) return action
def _createAction(self, name, slot, shortcut=None, statusTip=None): action = QAction(name, self) action.triggered.connect(slot) if shortcut is not None: action.setShortcut(shortcut) if statusTip is not None: action.setStatusTip(statusTip) key = _stripEllipsis(name) self._actions[key] = action return action
def __init__(self, parent=None): """Create Qt widgets, connect event handlers.""" super(App, self).__init__(parent) self.windowTitle = 'DMD | ' self.fileName = '' self.setWindowTitle(self.windowTitle + 'Unsaved File') exitAction = QAction('Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(self.close) openAction = QAction('Open', self) openAction.setShortcut('Ctrl+O') openAction.setStatusTip('Open Markdown File') openAction.triggered.connect(self.openFile) newAction = QAction('New', self) newAction.setShortcut('Ctrl+N') newAction.setStatusTip('New Markdown File') newAction.triggered.connect(self.newFile) saveAction = QAction('Save', self) saveAction.setShortcut('Ctrl+S') saveAction.setStatusTip('Save File') saveAction.triggered.connect(self.saveFile) self.statusBar() menubar = self.menuBar() fileMenu = menubar.addMenu('&File') fileMenu.addAction(newAction) fileMenu.addAction(openAction) fileMenu.addAction(saveAction) fileMenu.addAction(exitAction) self.setGeometry(300, 300, 1024, 768) self.show() self.txtInput = QTextEdit() self.txtInput.setTabStopWidth(20) self.webPreview = QWebView() self.webPreview.setHtml('Start typing...', baseUrl=QUrl('preview')) self.txtInput.textChanged.connect(self.loadPreview) splitter = QSplitter() splitter.addWidget(self.txtInput) splitter.addWidget(self.webPreview) self.setCentralWidget(splitter)
def __init__(self,fileName=None): """ Constructor Function """ # QWidget.__init__(self) # self.setWindowTitle("Icon Sample") # self.setGeometry(300, 300, 200, 150) QMainWindow.__init__(self) self.setWindowTitle("Icon Sample") self.setGeometry(300, 300, 200, 150) QToolTip.setFont(QFont("Decorative", 8, QFont.Bold)) self.setToolTip('Our Main Window') self.icon='C:\Users\Hamed\Documents\soheil sites image\imageedit__9411602959.gif' self.textEdit = QTextEdit() self.setCentralWidget(self.textEdit) self.fileName = None self.filters = "Text files (*.txt)" openFile = QAction(QIcon('open.png'), 'Open', self) openFile.setShortcut('Ctrl+O') openFile.setStatusTip('Open new File') openFile.triggered.connect(self.showDialog) menubar = self.menuBar() # fileMenu = menubar.addMenu('&File') # fileMenu.addAction(openFile) self.setGeometry(300, 300, 350, 300) self.setWindowTitle('Example - File Dialog') # self.myNameLE = QLineEdit(self) # self.myAgeLE = QLineEdit(self) # self.myChoiceLE = QLineEdit(self) self.statusLabel = QLabel('Showing Progress') self.progressBar = QProgressBar() self.progressBar.setMinimum(0) self.progressBar.setMaximum(100) ##################@@@@@@@@@@@@@@2 self.threads = [] self.addWorker(MyWorkerThread(1)) self.addWorker(MyWorkerThread(2)) #######################@@@@@@@@@@@@@ self.show()
def populate_menu( menu, action_target, list_actions, context=Qt.WindowShortcut): """ action_target is a QWidget where the menu's action can be added so that they are callable from there """ global configuration global user_session for t in list_actions: # t = (Text, Slot to call, KeySequence shortcut, roles which can use the action) # t = (QAction, roles which can use the action) # if QAction then slot, KeySequence will be ignored roles = a = None if isinstance( t[0], QAction): a = t[0] roles = t[1] if a.parent() is None: action_target.addAction(a) elif isinstance( t[0], QMenu): a = t[0] roles = t[1] else: a = QAction(t[0],action_target) # text, parent if t[1]: a.triggered.connect(t[1]) if t[2]: a.setShortcut(t[2]) a.setShortcutContext(context) roles = t[3] action_target.addAction(a) if roles is not None: a.setEnabled(user_session.has_any_roles(roles)) if isinstance( a, QMenu): menu.addMenu(a) else: menu.addAction(a)
def OnCreate(self, form): if HAS_PYSIDE: self.parent = self.FormToPySideWidget(form) else: self.parent = self.FormToPyQtWidget(form) self._idp_hooks = AutoReIDPHooks(self) if not self._idp_hooks.hook(): print 'IDP_Hooks.hook() failed' self.tv = QTreeView() self.tv.setExpandsOnDoubleClick(False) root_layout = QVBoxLayout(self.parent) # self.le_filter = QLineEdit(self.parent) # root_layout.addWidget(self.le_filter) root_layout.addWidget(self.tv) self.parent.setLayout(root_layout) self._model = QtGui.QStandardItemModel() self._init_model() self.tv.setModel(self._model) self.tv.setColumnWidth(0, 200) self.tv.setColumnWidth(1, 300) self.tv.header().setStretchLastSection(True) self.tv.expandAll() self.tv.doubleClicked.connect(self.on_navigate_to_method_requested) # self.le_filter.textChanged.connect(self.on_filter_text_changed) self.tv.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.tv.customContextMenuRequested.connect(self._tree_customContextMenuRequesssted) rename_action = QAction('Rename...', self.tv) rename_action.setShortcut('n') rename_action.triggered.connect(self._tv_rename_action_triggered) self.tv.addAction(rename_action)
def _setupMenuBar(self): menu_bar = self.menuBar() # setup the file menu file_menu = menu_bar.addMenu(self.tr("&File")) action_export = QAction(self.tr("&Export all ..."), self) action_export.triggered.connect(self._showExportDialog) file_menu.addAction(action_export) action_exit = QAction(self.tr("&Quit"), self) action_exit.setShortcut(QKeySequence.Quit) action_exit.triggered.connect(self.close) file_menu.addAction(action_exit) # setup the edit menu edit_menu = menu_bar.addMenu(self.tr("&Edit")) action_find_replace = QAction(self.tr("Find/Replace"), self) action_find_replace.setShortcut(QKeySequence.Find) action_find_replace.triggered.connect(self._showFindReplaceDialog) edit_menu.addAction(action_find_replace) # setup the help menu menu_help = menu_bar.addMenu(self.tr("&Help")) action_about = QAction(self.tr("About"), self) action_about.triggered.connect(self._showAboutDialog) menu_help.addAction(action_about)
def _parseactions(self, actions): actionlist = [] for act in actions: atts = actions[act] if act == "Separator": newaction = "Separator" else: try: newaction = QAction(QtGui.QIcon(atts["icon"]), atts["text"], self) except: newaction = QAction(atts["text"], self) try: newaction.setShortcut(atts["shortcut"]) except: pass try: newaction.setStatusTip(atts["statustip"]) except: pass actionlist.append((atts["pos"], newaction, act)) actionlist = self._sortbyposition(actionlist) return actionlist
def initUI(self): textEdit1 = QkLineView(sample=10) textEdit2 = QkLineView(sample=100) textEdit3 = QkLineView(sample=200) tabs = QTabWidget() tabs.addTab(textEdit1, "TAB1") tabs.addTab(textEdit2, "TAB2") tabs.addTab(textEdit3, "TAB3") tabs.setMovable(True) self.setCentralWidget(tabs) exitAct = QAction(QIcon(":pics/exit.PNG"), self.tr("Exit"), self) exitAct.setShortcut('Ctrl+Q') exitAct.setStatusTip(self.tr('Exit application')) exitAct.triggered.connect(self.close) self.statusBar() menubar = self.menuBar() fileMenu = menubar.addMenu(self.tr('&File')) fileMenu.addAction(exitAct) toolbar = self.addToolBar(self.tr('Exit')) toolbar.addAction(exitAct) toolbar.addAction(exitAct) self.setGeometry(300, 300, 350, 250) self.setWindowTitle(self.tr('binkeul main window')) self.show()
def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.chat_widget = ChatWidget(self) self.setCentralWidget(self.chat_widget) # set up all actions self.chat_widget.message.connect(self.statusBar().showMessage) app_menu = self.menuBar().addMenu('&Application') self.connect_action = QAction('&Connect', self) self.connect_action.triggered.connect(self._connect) self.connect_action.setShortcut('Ctrl+C') app_menu.addAction(self.connect_action) app_menu.addSeparator() self.quit_server_action = QAction('Quit &server', self) self.quit_server_action.triggered.connect(self._quit_server) self.quit_server_action.setEnabled(False) self.quit_server_action.setShortcut('Ctrl+D') app_menu.addAction(self.quit_server_action) quit_action = QAction(self.style().standardIcon( QStyle.SP_DialogCloseButton), '&Quit', self) quit_action.triggered.connect(QApplication.instance().quit) quit_action.setShortcut('Ctrl+Q') app_menu.addAction(quit_action) # attempt to connect self._connect()
def _initUI(self,parent): "Adds the menu items into the menu bar" #File Menu #add action _addAction = QAction("Add Snippet", parent) _addAction.setShortcut("Ctrl+N") _addAction.setStatusTip('Add new Snippet') _addAction.triggered.connect(self._addSnippet) #edit action _editAction = QAction("Edit Snippet", parent) _editAction.setShortcut("Ctrl+O") _editAction.setStatusTip('Edit Snippet') _editAction.triggered.connect(self._editSnippet) #exit action _exitAction = QAction("&Exit", parent) _exitAction.setShortcut("Ctrl+Q") _exitAction.setStatusTip('Exit application') _exitAction.triggered.connect(parent.closeApp) # Adding to file menu _fileMenu = self.addMenu('&File') _fileMenu.addAction(_addAction) _fileMenu.addAction(_editAction) _fileMenu.addSeparator() _fileMenu.addAction(_exitAction) #Edit Menu #copy action _copyAction = QAction("&Copy", parent) _copyAction.setShortcut("Ctrl+C") _copyAction.setStatusTip('Copy text') _editMenu = self.addMenu('&Edit') _editMenu.addAction(_copyAction) #Tools _toolsMenu = self.addMenu('&Tools')
def Menu(self): #this creates an action exit, a shortcut and status tip exitAction = QAction(QIcon('icons/exit.png'), '&Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(self.close) openFile = QAction(QIcon('icons/open.png'), '&Open', self) openFile.setShortcut('Ctrl+O') openFile.setStatusTip('Open new File') openFile.triggered.connect(self.browse) runAction = QAction(QIcon('icons/run.png'), '&Run', self) runAction.setShortcut('Ctrl+R') runAction.setStatusTip('Run Mars') runAction.triggered.connect(self.run_event)
class OperationsOverviewWidget(QWidget): def __init__(self,parent=None): super(OperationsOverviewWidget,self).__init__(parent) self.operation_prototype = [] self.operation_prototype.append( OperationDefinitionPrototype('operation_definition_id',_('Op.'),operation_definition_cache.all_on_order_part(), editable=False)) self.operation_prototype.append( TextAreaPrototype('description',_('Description'),nullable=True,editable=False)) self.operation_prototype.append( FloatNumberPrototype('value',_('Value'),nullable=True,editable=False)) self.operation_prototype.append( DurationPrototype('planned_hours',_('Planned time'),nullable=True,editable=False)) # operation_prototype.append( DurationPrototype('t_reel',_('Used time'),nullable=False,editable=False)) self.operation_prototype.append( DurationPrototype('done_hours',_('Imputations'),editable=False)) # operation_prototype.append( TextLinePrototype('note',_('Note'),editable=True,nullable=True,hidden=True)) self.model = PrototypedModelView(self.operation_prototype,self) self.view = PrototypedQuickView(self.operation_prototype,self) self.view.setModel(self.model) self.view.verticalHeader().hide() self.view.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents) # Description column wide enough self.view.horizontalHeader().setResizeMode(1,QHeaderView.Stretch) self.view.setWordWrap(True) self.view.setSelectionBehavior(QAbstractItemView.SelectRows) self.view.setSelectionMode(QAbstractItemView.ExtendedSelection) # self.controller_operation = PrototypeController(self, # self.operation_prototype, # ProxyTableView(None,self.operation_prototype)) # self.controller_operation.view.verticalHeader().hide() # # self.controller_operation.setModel(TrackingProxyModel(None,operation_prototype)) # self.controller_operation.setModel(TrackingProxyModel(self,self.operation_prototype)) # self.controller_operation.view.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents) # Description column wide enough # self.controller_operation.view.horizontalHeader().setResizeMode(1,QHeaderView.Stretch) # self.controller_operation.view.setSelectionBehavior(QAbstractItemView.SelectRows) layout = QHBoxLayout() layout.setContentsMargins(0,0,0,0) layout.addWidget(self.view) self.setLayout(layout) self.copy_operations_action = QAction(_("Copy operations"),self.view) self.copy_operations_action.triggered.connect( self.copy_operations_slot) self.copy_operations_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_C)) self.copy_operations_action.setShortcutContext(Qt.WidgetWithChildrenShortcut) self.view.addAction(self.copy_operations_action) def fill_order_part(self, order_part_id): """ Fill with order part's data. Doesn't keep any reference to the order part. """ if order_part_id: mainlog.debug("fill_order_part : triggered !") operations = dao.operation_dao.find_by_order_part_id_frozen(order_part_id) mainlog.debug("fill_order_part : build model !") self.model.buildModelFromObjects(operations) mainlog.debug("fill_order_part : build model complete !") self.view.verticalHeader().setResizeMode(QHeaderView.ResizeToContents) else: self.model.clear() ndx = self.model.index(0,0) mainlog.debug("fill_order_part : setCurrentIndex !") self.view.setCurrentIndex(ndx) mainlog.debug("fill_order_part : setCurrentIndex done!") @Slot() def copy_operations_slot(self): mainlog.debug("copy_operations_slot") view = self.view model = self.model # Collect the rows indices rows = set() for ndx in view.selectedIndexes(): if ndx.row() >= 0: rows.add(ndx.row()) # There are no guarantee on the selectedIndexes order rows = sorted(list(rows)) # Copy for elsewhere in Horse if len(rows): operations = [] for row_ndx in rows: operation = model.object_at(row_ndx) mainlog.debug(operation) operations.append(operation) copy_paste_manager.copy_operations(operations) else: # If nothing to copy then we leave the copy/paste clipboard # as it is. So one could paste again what he copied before. pass
def createAction(self, icon, toolTip, statusTip, scripted=False): """ TOWRITE :param `icon`: TOWRITE :type `icon`: QString :param `toolTip`: TOWRITE :type `toolTip`: QString :param `statusTip`: TOWRITE :type `statusTip`: QString :param `scripted`: TOWRITE :type `scripted`: bool :rtype: `QAction`_ .. TODO:: send the global Icon, Image, Commands Dirs in to be used. """ connect = self.connect # NOT local optimization, but for ease of the code looking similar to the C++ whash mdiArea = self.mdiArea # ditto ACTION = QAction( QIcon(self.gIconDir + os.sep + self.getSettingsGeneralIconTheme() + "/" + icon + ".png"), toolTip, self ) # QAction * # TODO: Qt4.7 wont load icons without an extension... ACTION.setStatusTip(statusTip) ACTION.setObjectName(icon) # TODO: Set What's This Context Help to statusTip for now so there is some infos there. # Make custom whats this context help popup with more descriptive help than just # the status bar/tip one liner(short but not real long) with a hyperlink in the custom popup # at the bottom to open full help file description. Ex: like wxPython AGW's SuperToolTip. ACTION.setWhatsThis(statusTip) # TODO: Finish All Commands ... <.< if icon == "donothing": connect(ACTION, SIGNAL("triggered()"), self, SLOT("doNothing()")) elif icon == "new": ACTION.setShortcut(QKeySequence.New) connect(ACTION, SIGNAL("triggered()"), self, SLOT("newFile()")) elif icon == "open": ACTION.setShortcut(QKeySequence.Open) connect(ACTION, SIGNAL("triggered()"), self, SLOT("openFile()")) elif icon == "save": ACTION.setShortcut(QKeySequence.Save) connect(ACTION, SIGNAL("triggered()"), self, SLOT("savefile()")) elif icon == "saveas": ACTION.setShortcut(QKeySequence.SaveAs) connect(ACTION, SIGNAL("triggered()"), self, SLOT("saveasfile()")) elif icon == "print": ACTION.setShortcut(QKeySequence.Print) connect(ACTION, SIGNAL("triggered()"), self, SLOT("print_()")) elif icon == "designdetails": ACTION.setShortcut(QKeySequence("Ctrl+D")) connect(ACTION, SIGNAL("triggered()"), self, SLOT("designDetails()")) elif icon == "exit": ACTION.setShortcut(QKeySequence("Ctrl+Q")) connect(ACTION, SIGNAL("triggered()"), self, SLOT("exit()")) elif icon == "cut": ACTION.setShortcut(QKeySequence.Cut) connect(ACTION, SIGNAL("triggered()"), self, SLOT("cut()")) elif icon == "copy": ACTION.setShortcut(QKeySequence.Copy) connect(ACTION, SIGNAL("triggered()"), self, SLOT("copy()")) elif icon == "paste": ACTION.setShortcut(QKeySequence.Paste) connect(ACTION, SIGNAL("triggered()"), self, SLOT("paste()")) elif icon == "windowcascade": connect(ACTION, SIGNAL("triggered()"), mdiArea, SLOT("cascade()")) elif icon == "windowtile": connect(ACTION, SIGNAL("triggered()"), mdiArea, SLOT("tile()")) elif icon == "windowclose": ACTION.setShortcut(QKeySequence.Close) connect(ACTION, SIGNAL("triggered()"), self, SLOT("onCloseWindow()")) elif icon == "windowcloseall": connect(ACTION, SIGNAL("triggered()"), mdiArea, SLOT("closeAllSubWindows()")) elif icon == "windownext": ACTION.setShortcut(QKeySequence.NextChild) connect(ACTION, SIGNAL("triggered()"), mdiArea, SLOT("activateNextSubWindow()")) elif icon == "windowprevious": ACTION.setShortcut(QKeySequence.PreviousChild) connect(ACTION, SIGNAL("triggered()"), mdiArea, SLOT("activatePreviousSubWindow()")) elif icon == "help": connect(ACTION, SIGNAL("triggered()"), self, SLOT("help()")) elif icon == "changelog": connect(ACTION, SIGNAL("triggered()"), self, SLOT("changelog()")) elif icon == "tipoftheday": connect(ACTION, SIGNAL("triggered()"), self, SLOT("tipOfTheDay()")) elif icon == "about": connect(ACTION, SIGNAL("triggered()"), self, SLOT("about()")) elif icon == "whatsthis": connect(ACTION, SIGNAL("triggered()"), self, SLOT("whatsThisContextHelp()")) elif icon == "icon16": connect(ACTION, SIGNAL("triggered()"), self, SLOT("icon16()")) elif icon == "icon24": connect(ACTION, SIGNAL("triggered()"), self, SLOT("icon24()")) elif icon == "icon32": connect(ACTION, SIGNAL("triggered()"), self, SLOT("icon32()")) elif icon == "icon48": connect(ACTION, SIGNAL("triggered()"), self, SLOT("icon48()")) elif icon == "icon64": connect(ACTION, SIGNAL("triggered()"), self, SLOT("icon64()")) elif icon == "icon128": connect(ACTION, SIGNAL("triggered()"), self, SLOT("icon128()")) elif icon == "settingsdialog": connect(ACTION, SIGNAL("triggered()"), self, SLOT("settingsDialog()")) elif icon == "undo": connect(ACTION, SIGNAL("triggered()"), self, SLOT("undo()")) elif icon == "redo": connect(ACTION, SIGNAL("triggered()"), self, SLOT("redo()")) elif icon == "makelayercurrent": connect(ACTION, SIGNAL("triggered()"), self, SLOT("makeLayerActive()")) elif icon == "layers": connect(ACTION, SIGNAL("triggered()"), self, SLOT("layerManager()")) elif icon == "layerprevious": connect(ACTION, SIGNAL("triggered()"), self, SLOT("layerPrevious()")) elif icon == "textbold": ACTION.setCheckable(True) connect(ACTION, SIGNAL("toggled(bool)"), self, SLOT("setTextBold(bool)")) elif icon == "textitalic": ACTION.setCheckable(True) connect(ACTION, SIGNAL("toggled(bool)"), self, SLOT("setTextItalic(bool)")) elif icon == "textunderline": ACTION.setCheckable(True) connect(ACTION, SIGNAL("toggled(bool)"), self, SLOT("setTextUnderline(bool)")) elif icon == "textstrikeout": ACTION.setCheckable(True) connect(ACTION, SIGNAL("toggled(bool)"), self, SLOT("setTextStrikeOut(bool)")) elif icon == "textoverline": ACTION.setCheckable(True) connect(ACTION, SIGNAL("toggled(bool)"), self, SLOT("setTextOverline(bool)")) elif icon == "zoomrealtime": connect(ACTION, SIGNAL("triggered()"), self, SLOT("zoomRealtime()")) elif icon == "zoomprevious": connect(ACTION, SIGNAL("triggered()"), self, SLOT("zoomPrevious()")) elif icon == "zoomwindow": connect(ACTION, SIGNAL("triggered()"), self, SLOT("zoomWindow()")) elif icon == "zoomdynamic": connect(ACTION, SIGNAL("triggered()"), self, SLOT("zoomDynamic()")) elif icon == "zoomscale": connect(ACTION, SIGNAL("triggered()"), self, SLOT("zoomScale()")) elif icon == "zoomcenter": connect(ACTION, SIGNAL("triggered()"), self, SLOT("zoomCenter()")) elif icon == "zoomin": connect(ACTION, SIGNAL("triggered()"), self, SLOT("zoomIn()")) elif icon == "zoomout": connect(ACTION, SIGNAL("triggered()"), self, SLOT("zoomOut()")) elif icon == "zoomselected": connect(ACTION, SIGNAL("triggered()"), self, SLOT("zoomSelected()")) elif icon == "zoomall": connect(ACTION, SIGNAL("triggered()"), self, SLOT("zoomAll()")) elif icon == "zoomextents": connect(ACTION, SIGNAL("triggered()"), self, SLOT("zoomExtents()")) elif icon == "panrealtime": connect(ACTION, SIGNAL("triggered()"), self, SLOT("panrealtime()")) elif icon == "panpoint": connect(ACTION, SIGNAL("triggered()"), self, SLOT("panpoint()")) elif icon == "panleft": connect(ACTION, SIGNAL("triggered()"), self, SLOT("panLeft()")) elif icon == "panright": connect(ACTION, SIGNAL("triggered()"), self, SLOT("panRight()")) elif icon == "panup": connect(ACTION, SIGNAL("triggered()"), self, SLOT("panUp()")) elif icon == "pandown": connect(ACTION, SIGNAL("triggered()"), self, SLOT("panDown()")) elif icon == "day": connect(ACTION, SIGNAL("triggered()"), self, SLOT("dayVision()")) elif icon == "night": connect(ACTION, SIGNAL("triggered()"), self, SLOT("nightVision()")) elif scripted: ACTION.setIcon( QIcon(self.gAppDir + os.sep + "commands/" + icon + "/" + icon + ".png")) connect(ACTION, SIGNAL("triggered()"), self, SLOT("runCommand()")) else: ACTION.setEnabled(False) connect(ACTION, SIGNAL("triggered()"), self, SLOT("stub_implement()")) return ACTION
def create_actions(self): # File menu self.open_action = QAction("&Open...", self, shortcut=QtGui.QKeySequence.Open, triggered=self.open_file, icon=self.style().standardIcon( QtGui.QStyle.SP_DialogOpenButton)) self.save_action = QAction("&Save", self, shortcut=QtGui.QKeySequence.Save, triggered=self.save_document, icon=self.style().standardIcon( QtGui.QStyle.SP_DialogSaveButton)) self.save_crops_action = QAction("&Save crops", self, triggered=self.save_crops) self.export_csv_action = QAction("&Export CSV", self, triggered=self.export_csv) self.close_action = QAction("&Close", self, shortcut=QtGui.QKeySequence.Close, triggered=self.close_document) self.exit_action = QAction("E&xit", self, shortcut=QtGui.QKeySequence.Quit, triggered=self.close) # Edit menu self.select_all_action = QAction("Select &All", self, shortcut=QtGui.QKeySequence.SelectAll, triggered=self.select_all) # QT does not provide a 'select none' key sequence self.select_none_action = QAction("Select &None", self, shortcut="ctrl+D", triggered=self.select_none) self.next_box_action = QAction("Next box", self, shortcut="N", triggered=partial(self.select_next_prev, next=True)) self.previous_box_action = QAction("Previous box", self, shortcut="P", triggered=partial( self.select_next_prev, next=False)) # TODO LH Does CMD + Backspace work on a mac? self.delete_action = QAction("&Delete selected", self, shortcut=QtGui.QKeySequence.Delete, triggered=self.delete_selected) self.rotate_clockwise_action = QAction("Rotate clockwise", self, shortcut="R", triggered=partial( self.rotate90, clockwise=True)) self.rotate_counter_clockwise_action = QAction( "Rotate counter-clockwise", self, shortcut="L", triggered=partial(self.rotate90, clockwise=False)) # Plugins # Plugin shortcuts start at F5 shortcut_offset = 5 for index, plugin in enumerate(self.plugins): action = QAction(plugin.name(), self, triggered=partial(self.run_plugin, index)) shortcut_fkey = index + shortcut_offset if shortcut_fkey < 13: # Keyboards typically have 12 function keys action.setShortcut('f{0}'.format(shortcut_fkey)) icon = plugin.icon() if icon: action.setIcon(icon) self.plugin_actions[index] = action # View menu # The obvious approach is to set the trigger to # partial(self.tabs.setCurrentIndex, 0) but this causes a segfault when # the application exits on linux. self.boxes_view_action = QAction("&Boxes", self, checkable=True, triggered=partial(self.show_tab, 0)) self.metadata_view_action = QAction("&Specimens", self, checkable=True, triggered=partial( self.show_tab, 1)) # FullScreen added in Qt 5.something # https://qt.gitorious.org/qt/qtbase-miniak/commit/1ef8a6d if not hasattr(QtGui.QKeySequence, 'FullScreen'): if 'darwin' == sys.platform: KeySequenceFullScreen = 'shift+ctrl+f' else: KeySequenceFullScreen = 'f11' else: KeySequenceFullScreen = QtGui.QKeySequence.FullScreen self.full_screen_action = QAction("&Full screen", self, shortcut=KeySequenceFullScreen, triggered=self.toggle_full_screen) self.zoom_in_action = QAction("Zoom &In", self, shortcut=QtGui.QKeySequence.ZoomIn, triggered=self.zoom_in, icon=self.style().standardIcon( QtGui.QStyle.SP_ArrowUp)) self.zoom_out_action = QAction("Zoom &Out", self, shortcut=QtGui.QKeySequence.ZoomOut, triggered=self.zoom_out, icon=self.style().standardIcon( QtGui.QStyle.SP_ArrowDown)) self.toogle_zoom_action = QAction("&Toogle Zoom", self, shortcut='Z', triggered=self.toggle_zoom) self.zoom_home_action = QAction( "Fit To Window", self, shortcut=QtGui.QKeySequence.MoveToStartOfDocument, triggered=self.zoom_home) # TODO LH Is F3 (normally meaning 'find next') really the right # shortcut for the 'toggle plugin image' action? self.toggle_plugin_image_action = QAction( "&Display plugin image", self, shortcut="f3", triggered=self.toggle_plugin_image, statusTip="Display plugin image", checkable=True) self.show_specimen_grid_action = QAction('Show grid', self, shortcut='g', triggered=self.show_grid) self.show_specimen_expanded_action = QAction( 'Show expanded', self, shortcut='e', triggered=self.show_expanded) # Help menu self.about_action = QAction("&About", self, triggered=self.about) self.help_action = QAction("&Help", self, shortcut=QtGui.QKeySequence.HelpContents, triggered=self.help)
class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(810, 492) lbMinWidth = 65 lbMinWidthLogin = 110 # leMinWidth = 200 # 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_presets_layout = QHBoxLayout() login_gbox_server_layout = QHBoxLayout() login_gbox_ssl_layout = QHBoxLayout() login_gbox_address_layout = QHBoxLayout() login_gbox_pass_layout = QHBoxLayout() login_gbox_connect_layout = QHBoxLayout() login_gbox_layout.addLayout(login_gbox_presets_layout) login_gbox_layout.addLayout(login_gbox_server_layout) login_gbox_layout.addLayout(login_gbox_ssl_layout) login_gbox_layout.addLayout(login_gbox_address_layout) login_gbox_layout.addLayout(login_gbox_pass_layout) login_gbox_layout.addLayout(login_gbox_connect_layout) self.lb_presets = QLabel(self.login_gbox) self.lb_presets.setObjectName("lb_presets") self.lb_presets.setMinimumWidth(lbMinWidthLogin) self.lb_presets.setMaximumWidth(lbMinWidthLogin) self.presets_cbox = QComboBox(self.login_gbox) self.presets_cbox.setObjectName("presets_cbox") self.add_preset_btn = QPushButton(self.login_gbox) self.add_preset_btn.setObjectName("add_preset_btn") self.add_preset_btn.setMaximumWidth(30) self.remove_preset_btn = QPushButton(self.login_gbox) self.remove_preset_btn.setObjectName("remove_preset_btn") self.remove_preset_btn.setMaximumWidth(20) login_gbox_presets_layout.addWidget(self.lb_presets) login_gbox_presets_layout.addWidget(self.presets_cbox) login_gbox_presets_layout.addWidget(self.add_preset_btn) login_gbox_presets_layout.addWidget(self.remove_preset_btn) self.lb_imap_server = QLabel(self.login_gbox) self.lb_imap_server.setObjectName("lb_imap_server") self.lb_imap_server.setMinimumWidth(lbMinWidthLogin) self.imap_server_le = QLineEdit(self.login_gbox) self.imap_server_le.setObjectName("imap_server_le") login_gbox_server_layout.addWidget(self.lb_imap_server) login_gbox_server_layout.addWidget(self.imap_server_le) self.lb_ssl = QLabel(self.login_gbox) self.lb_ssl.setObjectName("lb_ssl") self.lb_ssl.setMinimumWidth(lbMinWidthLogin) self.lb_ssl.setMaximumWidth(lbMinWidthLogin) self.ssl_cb = QCheckBox(self.login_gbox) self.ssl_cb.setEnabled(False) self.ssl_cb.setCheckable(True) self.ssl_cb.setChecked(True) self.ssl_cb.setObjectName("ssl_cb") login_gbox_ssl_layout.addWidget(self.lb_ssl) login_gbox_ssl_layout.addWidget(self.ssl_cb) self.lb_adress = QLabel(self.login_gbox) self.lb_adress.setObjectName("lb_adress") self.lb_adress.setMinimumWidth(lbMinWidthLogin) self.adress_le = QLineEdit(self.login_gbox) self.adress_le.setInputMethodHints(Qt.ImhNone) self.adress_le.setObjectName("adress_le") login_gbox_address_layout.addWidget(self.lb_adress) login_gbox_address_layout.addWidget(self.adress_le) self.lb_pass = QLabel(self.login_gbox) self.lb_pass.setObjectName("lb_pass") self.lb_pass.setMinimumWidth(lbMinWidthLogin) self.pass_le = QLineEdit(self.login_gbox) self.pass_le.setText("") self.pass_le.setEchoMode(QLineEdit.Password) self.pass_le.setObjectName("pass_le") login_gbox_pass_layout.addWidget(self.lb_pass) login_gbox_pass_layout.addWidget(self.pass_le) self.connect_btn = QPushButton(self.login_gbox) self.connect_btn.setObjectName("connect_btn") login_gbox_connect_layout.addStretch() login_gbox_connect_layout.addWidget(self.connect_btn) # search_gbox self.search_gbox = QGroupBox(self.leftSplitter) self.search_gbox.hide() self.search_gbox.setObjectName("search_gbox") 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.since_date_cb = QCheckBox(self.search_gbox) self.since_date_cb.setObjectName("since_date_cb") self.since_date_cb.setMinimumWidth(lbMinWidth) self.since_date_cb.setMaximumWidth(lbMinWidth) self.since_date_edit = QDateEdit(self.search_gbox) self.since_date_edit.setCalendarPopup(True) self.since_date_edit.setObjectName("since_date_edit") self.since_date_edit.setDate(QDate.currentDate().addDays(-365)) self.since_date_edit.setMaximumDate(QDate.currentDate()) self.since_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.since_date_cb) search_gbox_date_layout.addWidget(self.since_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.addStretch() search_gbox_threads_layout.addWidget(self.html_radio) search_gbox_threads_layout.addWidget(self.text_radio) # search_gbox_threads_layout.addStretch() 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") 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.setObjectName("menubar") self.menu_file = QMenu(self.menubar) self.menu_file.setObjectName("menu_file") self.menu_about = QMenu(self.menubar) self.menu_about.setObjectName("menu_about") 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.menu_file.addAction(self.action_exit) self.menu_about.addAction(self.action_about) self.menu_about.addAction(self.action_About_Qt) self.menubar.addAction(self.menu_file.menuAction()) self.menubar.addAction(self.menu_about.menuAction()) self.retranslateUi(MainWindow) QMetaObject.connectSlotsByName(MainWindow) MainWindow.setTabOrder(self.presets_cbox, self.imap_server_le) MainWindow.setTabOrder(self.imap_server_le, self.adress_le) MainWindow.setTabOrder(self.adress_le, self.pass_le) MainWindow.setTabOrder(self.pass_le, self.connect_btn) MainWindow.setTabOrder(self.connect_btn, self.log_te) MainWindow.setTabOrder(self.log_te, self.since_date_cb) MainWindow.setTabOrder(self.since_date_cb, self.since_date_edit) MainWindow.setTabOrder(self.since_date_edit, self.before_date_cb) MainWindow.setTabOrder(self.before_date_cb, self.before_date_edit) MainWindow.setTabOrder(self.before_date_edit, self.mailboxes_lw) MainWindow.setTabOrder(self.mailboxes_lw, 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.search_btn) MainWindow.setTabOrder(self.search_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.disconnect_btn) MainWindow.setTabOrder(self.disconnect_btn, self.add_preset_btn) MainWindow.setTabOrder(self.add_preset_btn, self.remove_preset_btn) MainWindow.setTabOrder(self.remove_preset_btn, self.ssl_cb) def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(QApplication.translate("MainWindow", "Email Link Extractor", None, QApplication.UnicodeUTF8)) self.login_gbox.setTitle(QApplication.translate("MainWindow", " Login", None, QApplication.UnicodeUTF8)) self.lb_presets.setText(QApplication.translate("MainWindow", "Server Presets", None, QApplication.UnicodeUTF8)) self.add_preset_btn.setText(QApplication.translate("MainWindow", "+", None, QApplication.UnicodeUTF8)) self.remove_preset_btn.setText(QApplication.translate("MainWindow", "-", None, QApplication.UnicodeUTF8)) self.lb_imap_server.setText(QApplication.translate("MainWindow", "IMAP Server", None, QApplication.UnicodeUTF8)) self.lb_ssl.setText(QApplication.translate("MainWindow", "SSL", None, QApplication.UnicodeUTF8)) self.ssl_cb.setText(QApplication.translate("MainWindow", "Port : 993", None, QApplication.UnicodeUTF8)) self.lb_adress.setText(QApplication.translate("MainWindow", "Adress", None, QApplication.UnicodeUTF8)) self.lb_pass.setText(QApplication.translate("MainWindow", "Password", None, QApplication.UnicodeUTF8)) self.connect_btn.setText(QApplication.translate("MainWindow", "Connect", None, QApplication.UnicodeUTF8)) self.lb_select_mailbox.setText(QApplication.translate("MainWindow", "Select Mailbox", None, QApplication.UnicodeUTF8)) self.search_gbox.setTitle(QApplication.translate("MainWindow", " Search Parameters", None, QApplication.UnicodeUTF8)) self.since_date_cb.setText(QApplication.translate("MainWindow", "Since", None, QApplication.UnicodeUTF8)) self.since_date_edit.setDisplayFormat(QApplication.translate("MainWindow", "dd-MMM-yyyy", None, QApplication.UnicodeUTF8)) self.before_date_cb.setText(QApplication.translate("MainWindow", "Before", None, QApplication.UnicodeUTF8)) self.before_date_edit.setDisplayFormat(QApplication.translate("MainWindow", "dd-MMM-yyyy", 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.lb_from.setText(QApplication.translate("MainWindow", "From", None, QApplication.UnicodeUTF8)) self.lb_to.setText(QApplication.translate("MainWindow", "To", 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.links_gbox.setTitle(QApplication.translate("MainWindow", " Links", None, QApplication.UnicodeUTF8)) self.export_html_btn.setText(QApplication.translate("MainWindow", "Export as HTML", None, QApplication.UnicodeUTF8)) self.export_txt_btn.setText(QApplication.translate("MainWindow", "Export as txt", None, QApplication.UnicodeUTF8)) self.log_gbox.setTitle(QApplication.translate("MainWindow", " Log", None, QApplication.UnicodeUTF8)) self.disconnect_btn.setText(QApplication.translate("MainWindow", "Disconnect", None, QApplication.UnicodeUTF8)) self.menu_file.setTitle(QApplication.translate("MainWindow", "File", None, QApplication.UnicodeUTF8)) self.menu_about.setTitle(QApplication.translate("MainWindow", "About", 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))
def setupMenubar(self): commentAction = QAction('Comment', self) commentAction.setShortcut('Ctrl+K') commentAction.setStatusTip('Comment Block') commentAction.triggered.connect(self.fireComment) uncommentAction = QAction('Uncomment', self) uncommentAction.setShortcut('Ctrl+Shift+K') uncommentAction.setStatusTip('Comment Block') uncommentAction.triggered.connect(self.fireUnComment) searchAction = QAction('search', self) searchAction.setShortcut('Ctrl+F') searchAction.setStatusTip('search') searchAction.triggered.connect(self.fireSearchView) newAction = QAction('New', self) newAction.setShortcut('Ctrl+N') newAction.setStatusTip('creats empty cpacs-file') newAction.triggered.connect(self.fireNewAction) self.updateAction = QAction('Update', self) self.updateAction.setShortcut('Ctrl+U') self.updateAction.setStatusTip('Update CPACS') self.updateAction.triggered.connect(self.fireUpdate) revertAction = QAction('Revert', self) revertAction.setShortcut('Ctrl+R') revertAction.triggered.connect(self.fireRevert) clearAction = QAction('Clear', self) clearAction.setStatusTip('Clear Editor') clearAction.triggered.connect(self.editor.clear) numbarAction = QAction('Line Number', self) numbarAction.triggered.connect(self.fireSwitchLayout) self.xpathAction = QAction('Current XPath', self) self.xpathAction.triggered.connect(self.getCursorXPath) link_to_node_YesAction = QAction('yes', self) link_to_node_YesAction.triggered.connect(self.dummyFuction) link_to_node_NoAction = QAction('no', self) link_to_node_NoAction.triggered.connect(self.dummyFuction) toolXAction = QAction('Tool X',self) toolXAction.triggered.connect(self.fireToolX) menubar = self.menuBar() filemenu = menubar.addMenu("File") filemenu.addAction(newAction) filemenu.addAction(self.updateAction) filemenu.addAction(revertAction) sourcemenu = menubar.addMenu("Source") sourcemenu.addAction(commentAction) sourcemenu.addAction(uncommentAction) sourcemenu.addAction(searchAction) editormenu = menubar.addMenu("Editor") editormenu.addAction(clearAction) editormenu.addSeparator() editormenu.addAction(numbarAction) editormenu.addAction(self.xpathAction) editormenu_child1 = editormenu.addMenu('Link to node') editormenu_child1.addAction(link_to_node_YesAction) editormenu_child1.addAction(link_to_node_NoAction) toolmenu = menubar.addMenu("Tools") toolmenu.addAction(toolXAction) self.editor.setContextMenuPolicy(Qt.CustomContextMenu) self.editor.customContextMenuRequested.connect(self.showMenu)
class EditorWindow(QMainWindow): """initialize editor""" def __init__(self, tixi, xmlFilename, cpacs_scheme=Config.path_cpacs_21_schema): super(EditorWindow, self).__init__() self.cur_file_path = "" self.cur_schema_path = "" self.setupEditor() self.setupButtonMenu() self.setupSearchBox() self.setupStatusbar() self.setupMenubar() self.setupNumbar() self.popUpWidget = None self.flag_layout = False self.hbox = QHBoxLayout() self.hbox.setSpacing(0) self.hbox.setContentsMargins(0,0,0,0) self.hbox.addWidget(self.number_bar) self.hbox.addWidget(self.editor) self.layout = QGridLayout() self.layout.addWidget(self.searchbox, 0, 0, 1, 4) self.layout.addWidget(self.button1, 0, 4, 1, 1) self.layout.addWidget(self.button2, 0, 5, 1, 1) self.layout.addLayout(self.hbox, 2, 0, 1, 8) self.layout.addWidget(self.fontsizeSpinBox, 0, 6, 1, 1) self.layout.addWidget(self.label1, 0, 7, 1, 1) self.window = QWidget() self.window.setLayout(self.layout) self.setWindowTitle('Simple XML editor') self.setCentralWidget(self.window) self.resize(800, 800) self.show() self.tixi = tixi self.loadFile(xmlFilename, cpacs_scheme) ''' loads cpacs file and validates it against the cpacs_schema @param xmlFilename: input file @param cpacs_scheme: validation scheme ''' def loadFile(self, xmlFilename=None, cpacs_scheme=Config.path_cpacs_21_schema): if xmlFilename and cpacs_scheme : try: self.tixi.open(xmlFilename) #self.tixi.openDocument(xmlFilename) #self.tixi.schemaValidateFromFile(cpacs_scheme) self.editor.setPlainText(self.tixi.exportDocumentAsString()) self.cur_file_path = xmlFilename self.cur_schema_path = cpacs_scheme except TixiException as e: self.statusBar().showMessage('CPACS ERROR: ' + e.error) ''' update the dictionary by the cpacs scheme @param path_dict: path to directory @param path_scheme: path to cpacs_scheme ''' def updatedictionary(self, path_dict=Config.path_code_completion_dict, path_scheme=Config.path_cpacs_21_schema): found = False olddict = open(path_dict) scheme_file = open(path_scheme, 'r') with open(path_dict, "a") as newdict : for line in scheme_file : word = re.search("(?<=\<xsd:complexType name=\").*(?=\"\>)", line) if word != None : for tmp in olddict : if tmp == word.group(0) +"\n" : found = True break if(not found) : newdict.write(word.group(0)+"\n") olddict.seek(0) found = False olddict.close() newdict.close() scheme_file.close() ''' validate xml file and write result to statusBar ''' def validate(self): try: etree.fromstring(str(self.editor.toPlainText())) self.statusBar().showMessage("Valid XML") except etree.XMLSyntaxError as e: if e.error_log.last_error is not None: msg = e.error_log.last_error.message line = e.error_log.last_error.line col = e.error_log.last_error.column self.statusBar().showMessage("Invalid XML: Line %s, Col %s: %s"%(line,col,msg)) except: self.statusBar().showMessage("Invalid XML: Unknown error") ''' close and cleanup tixi ''' def __del__(self): pass #self.tixi.close() #self.tixi.cleanup() ''' set and connect the search buttons ''' def setupButtonMenu(self): self.button1 = QPushButton("previous" ) self.button2 = QPushButton("next" ) self.label1 = QLabel("font") self.fontsizeSpinBox = QSpinBox() self.button1.hide() self.button2.hide() self.label1.hide() self.fontsizeSpinBox.hide() self.button1.clicked.connect(self.fire_search_backward) self.button2.clicked.connect(self.fire_search_foreward) self.fontsizeSpinBox.setRange(4, 30) self.fontsizeSpinBox.setSingleStep(1) self.fontsizeSpinBox.setSuffix('pt') self.fontsizeSpinBox.setValue(10) self.fontsizeSpinBox.valueChanged.connect(self.setfontsize) def setfontsize(self, value): self.font.setPointSize(value) self.editor.setFont(self.font) def setupEditor(self): self.font = QFont() self.font.setFamily('Courier') self.font.setFixedPitch(True) self.font.setPointSize(10) self.editor = EditorCodeCompletion(Config().path_code_completion_dict) self.editor.setFont(self.font) self.editor.setTabStopWidth(20) self.editor.setAcceptRichText(False) self.editor.setLineWrapMode(QTextEdit.NoWrap) self.editor.textChanged.connect(self.validate) self.highlighter = Highlighter(self.editor.document()) def setupNumbar(self): self.number_bar = NumberBar() self.number_bar.setTextEdit(self.getStates()) self.editor.cursorPositionChanged.connect(self.fireUpdateNumbar) self.connect(self.editor.verticalScrollBar(), SIGNAL("valueChanged(int)"), self.fireUpdateNumbar) #self.editor.verticalScrollBar.valueChanged.connect(self.fireUpdateNumbar) def setupStatusbar(self): self.lineNumber = -1 self.colNumber = -1 self.m_statusRight = QLabel("row: " + str(self.lineNumber) + ", col:" + str(self.colNumber), self) self.statusBar().addPermanentWidget(self.m_statusRight, 0) def setupSearchBox(self): self.searchbox = SearchField() self.searchbox.hide() def setupMenubar(self): commentAction = QAction('Comment', self) commentAction.setShortcut('Ctrl+K') commentAction.setStatusTip('Comment Block') commentAction.triggered.connect(self.fireComment) uncommentAction = QAction('Uncomment', self) uncommentAction.setShortcut('Ctrl+Shift+K') uncommentAction.setStatusTip('Comment Block') uncommentAction.triggered.connect(self.fireUnComment) searchAction = QAction('search', self) searchAction.setShortcut('Ctrl+F') searchAction.setStatusTip('search') searchAction.triggered.connect(self.fireSearchView) newAction = QAction('New', self) newAction.setShortcut('Ctrl+N') newAction.setStatusTip('creats empty cpacs-file') newAction.triggered.connect(self.fireNewAction) self.updateAction = QAction('Update', self) self.updateAction.setShortcut('Ctrl+U') self.updateAction.setStatusTip('Update CPACS') self.updateAction.triggered.connect(self.fireUpdate) revertAction = QAction('Revert', self) revertAction.setShortcut('Ctrl+R') revertAction.triggered.connect(self.fireRevert) clearAction = QAction('Clear', self) clearAction.setStatusTip('Clear Editor') clearAction.triggered.connect(self.editor.clear) numbarAction = QAction('Line Number', self) numbarAction.triggered.connect(self.fireSwitchLayout) self.xpathAction = QAction('Current XPath', self) self.xpathAction.triggered.connect(self.getCursorXPath) link_to_node_YesAction = QAction('yes', self) link_to_node_YesAction.triggered.connect(self.dummyFuction) link_to_node_NoAction = QAction('no', self) link_to_node_NoAction.triggered.connect(self.dummyFuction) toolXAction = QAction('Tool X',self) toolXAction.triggered.connect(self.fireToolX) menubar = self.menuBar() filemenu = menubar.addMenu("File") filemenu.addAction(newAction) filemenu.addAction(self.updateAction) filemenu.addAction(revertAction) sourcemenu = menubar.addMenu("Source") sourcemenu.addAction(commentAction) sourcemenu.addAction(uncommentAction) sourcemenu.addAction(searchAction) editormenu = menubar.addMenu("Editor") editormenu.addAction(clearAction) editormenu.addSeparator() editormenu.addAction(numbarAction) editormenu.addAction(self.xpathAction) editormenu_child1 = editormenu.addMenu('Link to node') editormenu_child1.addAction(link_to_node_YesAction) editormenu_child1.addAction(link_to_node_NoAction) toolmenu = menubar.addMenu("Tools") toolmenu.addAction(toolXAction) self.editor.setContextMenuPolicy(Qt.CustomContextMenu) self.editor.customContextMenuRequested.connect(self.showMenu) #self.editor.connect(self.editor, SIGNAL( "customContextMenuRequested(QPoint)" ), self.showMenu ) def showMenu( self, pos ): """ Show a context menu for the active layer in the legend """ menu = self.editor.createStandardContextMenu() menu.addAction(self.xpathAction) menu.exec_(QtCore.QPoint( self.mapToGlobal( pos ).x() + 5, self.mapToGlobal( pos ).y() )) def fireUpdateNumbar(self): self.updateLineNumber() self.number_bar.update() def dummyFuction(self): print ("not implemented yet") def getStates(self): self.stats = { "searchbox":self.searchbox, "editor":self.editor} return self.stats ''' find previous button ''' def fire_search_backward(self): self.editor.find(self.searchbox.text(), QTextDocument.FindBackward) self.searchbox.setFocus() ''' find next button ''' def fire_search_foreward(self): #print self.tixi.getNumberOfChilds('/cpacs/vehicles/aircraft/model[@uID="Aircraft1"]/wings/wing[@uID="Aircraft1_Wing1"]/transformation[@uID="Aircraft1_Wing1_Transf"]/scaling[@uID="Aircraft1_Wing1_Transf_Sca"]/z') searchList = list(filter(lambda a : a!='', self.searchbox.text().split('/'))) if len(searchList) == 1 : if self.editor.find(searchList[0]) : pass elif not self.editor.find(searchList[0], QTextDocument.FindBackward): QMessageBox.about(self, "error", "String %s not found" % (searchList[0])) else : self.editor.moveCursor(QTextCursor.Start) self.editor.find(searchList[0]) else : self.searchXPath(self.searchbox.text(), searchList) self.searchbox.setFocus() # test # /cpacs/vehicles/aircraft/model/wings/wing/sections/section def searchXPath(self, path, searchList): try: if self.tixi.xPathEvaluateNodeNumber(path) > 1 : QMessageBox.about(self, "error", "XPath %s not unique" % path) return self.editor.moveCursor(QTextCursor.Start) found = True # search index snd loop j = 0 # search backwards for uid for i in range(len(searchList)-1, -1, -1) : if '[' in searchList[i] : # get value in brackets : [x] --> x uid = re.search(r'\[(.*)\]', searchList[i]).group(1) uid = self.__transToSearchUid(searchList[:i+1], uid) found = self.editor.find(uid) j = i+1 break # search forward for all nodes after last uid while found and j < len(searchList) : found = self.editor.find('<'+searchList[j]) j += 1 if not found : QMessageBox.about(self, "error", "XPath %s not found" % path) except TixiException : QMessageBox.about(self, "error", "XPath %s not found" % path) def __transToSearchUid(self, path_list, uid): try: int(uid) path = "" for p in path_list : path = path + '/' + p return self.tixi.getTextAttribute(path , 'uID') except ValueError: return uid.replace('@', '') def getCursorXPath(self): start_pos = self.editor.textCursor().position() tag , tag_pos , isCursorInTag = self.getTagNameAtCursor() _,xpath_idx, xpath_uid = self.__findXPath_rec('/cpacs', '/cpacs' , tag, tag_pos) if not isCursorInTag: xpath_idx = self.__strRemoveReverseToChar(xpath_idx, '/') xpath_uid = self.__strRemoveReverseToChar(xpath_uid, '/') self.__setCursorToPostion(start_pos) self.__startXPathPopUp(xpath_idx, xpath_uid) def getTagNameAtCursor(self): ''' @return: name of tag , position of tag , cursor is btw open and closing tag ''' self.editor.find('<', QTextDocument.FindBackward) isClosingTag , fst_tag = self.__getTagName() pos = self.editor.textCursor().position() if isClosingTag : # find open tag of this closing tag self.editor.find('<'+fst_tag, QTextDocument.FindBackward) pos = self.editor.textCursor().position() return fst_tag , pos , False else: return fst_tag , pos , True def __getTagName(self): tc = self.editor.textCursor() tc.select(QTextCursor.WordUnderCursor) tx = tc.selectedText() isClosingTag = False if "</" in tx : # select next word tc.select(QTextCursor.WordUnderCursor) tx = tc.selectedText() isClosingTag = True return isClosingTag , "" if "<" in tx else tx def __findXPath_rec(self, xpath_idx, xpath_uid, search, pos): nodes = self.__getChildNodesIdxTuple(xpath_idx) for (node, idx) in nodes: if node != '#text' : new_xpath_idx, new_xpath_uid = self.__createNewXPath(xpath_idx, xpath_uid, node, idx) if search == node and self.isNodeAtSearchedTagPosition(new_xpath_uid, pos) : print ("gefunden" , new_xpath_idx) return True, new_xpath_idx , new_xpath_uid else: flag , res_idx, res_uid = self.__findXPath_rec(new_xpath_idx, new_xpath_uid, search, pos) if flag : return True, res_idx, res_uid return False , xpath_idx , xpath_uid def __getChildNodesIdxTuple(self, xpath): n = self.tixi.getNumberOfChilds(xpath) + 1 node_list = list(map(lambda i : self.tixi.getChildNodeName(xpath, i), range(1,n))) res = [] for j in range(len(node_list)) : cnt = 1 for k in range(j): if node_list[k] == node_list[j] : cnt = cnt + 1 res.append((node_list[j],cnt)) return res def __createNewXPath(self, xpath_idx, xpath_uid, node, idx): path_idx = xpath_idx + '/' + node path_uid = xpath_uid + '/' + node try : uID = self.tixi.getTextAttribute(path_idx + '[' + str(idx) + ']', 'uID') path_idx = path_idx + '[' + str(idx) + ']' path_uid = path_uid+'[@uID="' + uID + '"]' except TixiException: pass # e.error == 'ATTRIBUTE_NOT_FOUND return path_idx , path_uid def isNodeAtSearchedTagPosition(self, xpath, pos): ''' @param xpath: xpath with uids (doesn't work with indices) @param param: ''' self.editor.moveCursor(QTextCursor.Start) # split string at / and remove all empty strings l = list(filter(lambda x : x != '' , xpath.split('/'))) # search index snd loop j = 0 # search backwards for uid for i in range(len(l)-1, -1, -1) : if '[' in l[i] : # get value in brackets : [x] --> x uid = re.search(r'\[@(.*)\]', l[i]).group(1) self.editor.find(uid) j = i+1 break # search forward for all nodes after last uid while j < len(l) : self.editor.find('<'+l[j]) j += 1 return pos <= self.editor.textCursor().position() def __setCursorToPostion(self, pos): tc = self.editor.textCursor() tc.setPosition(pos) self.editor.setTextCursor(tc) def __startXPathPopUp(self, xpath_idx, xpath_uid): self.popUpWidget = XPathDialog(xpath_idx, xpath_uid) self.setEnabled(False) self.popUpWidget.closeAct.triggered.connect(self.__resetPopUpWidget) self.popUpWidget.show() def updateLineNumber(self): ''' sets the line and column number ''' self.lineNumber = self.editor.textCursor().blockNumber() + 1 self.colNumber = self.editor.textCursor().columnNumber() + 1 self.m_statusRight.setText("row: " + str(self.lineNumber) + ", col:" + str(self.colNumber)) def highlightCurrentLine(self) : ''' highlight line under cursor ''' extraSelections = [] selection = QTextEdit.ExtraSelection() lineColor = QColor(255, 250, 205) selection.format.setBackground(lineColor) selection.format.setProperty(QTextFormat.FullWidthSelection, True) selection.cursor = self.editor.textCursor() selection.cursor.clearSelection() extraSelections.append(selection) self.editor.setExtraSelections(extraSelections) self.editor.setFocus() #TODO: implemnt def fireUpdate(self): print ('dummy function - update the model') text_file = open(Config.path_cpacs_tmp_file, "w") text_file.write(self.editor.toPlainText()) text_file.close() #self.tixi.saveDocument(Config.path_cpacs_tmp_file) # '../cpacs_files/temp.xml' def fireRevert(self): ''' reloads cpacs file if not updated yet ''' if(self.cur_file_path and self.cur_schema_path) : self.loadFile(self.cur_file_path, self.cur_schema_path) else : QMessageBox.about(self, "error", "CPACS-File or Validation-Schema not available") def fireSwitchLayout(self): ''' function to show or hide line numbers ''' if(self.flag_layout) : self.number_bar.flag_show_numbers = True self.update() else : self.number_bar.flag_show_numbers = False self.update() self.flag_layout = not self.flag_layout def fireNewAction(self): ''' opens new file input form ''' self.setEnabled(False) self.popUpWidget = NewFileDialog() self.popUpWidget.buttonBox.accepted.connect(self.__createNewCpacsFile) self.popUpWidget.buttonBox.rejected.connect(self.__resetPopUpWidget) self.popUpWidget.closeAct.triggered.connect(self.__resetPopUpWidget) self.popUpWidget.show() def fireToolX(self): self.popUpWidget = ToolX("X-Tool", self.tixi) self.setEnabled(False) self.popUpWidget.buttonBox.accepted.connect(self.__resetPopUpWidget) self.popUpWidget.buttonBox.rejected.connect(self.__resetPopUpWidget) # closeAct for pressing X to close window self.popUpWidget.closeAct.triggered.connect(self.__resetPopUpWidget) self.popUpWidget.show() def __createNewCpacsFile(self): ''' closes all documents and creates new empty cpacs temporary file ''' idict = self.popUpWidget.fire_submitInput() self.tixi.closeAllDocuments() self.tixi.create('cpacs') self.tixi.addCpacsHeader(idict['name'], idict['creator'], idict['version'], idict['description'], idict['cpacsVersion']) self.tixi.saveDocument(Config.path_cpacs_tmp_file) self.loadFile(Config.path_cpacs_tmp_file) self.__resetPopUpWidget() def __resetPopUpWidget(self): self.popUpWidget.close() self.popUpWidget = None self.setEnabled(True) def fireComment(self): ''' inserts open respective closing tag before and after a selected text. ''' tc = self.editor.textCursor() tc.beginEditBlock() tc.setPosition(self.editor.textCursor().selectionStart()) tc.insertText("<!--") tc.setPosition(self.editor.textCursor().selectionEnd()) tc.insertText("-->") tc.endEditBlock() def fireUnComment(self): ''' removes open respective closing tag before and after a selected text. ''' tc = self.editor.textCursor() selectTxt = tc.selectedText() if selectTxt.find('<!--') != -1 : if selectTxt.rfind('-->') != -1 : selectTxt = selectTxt.replace('<!--', '', 1) selectTxt = self.__rreplace(selectTxt, '-->' , '', 1) tc.insertText(selectTxt) else: QMessageBox.about(self, "error", "no open tag (%s) in selection" % ('-->')) else: QMessageBox.about(self, "error", "no close tag (%s) in selection" % ('<!--')) def fireSearchView(self): ''' show and hide searchbox and buttons ''' if self.searchbox.isFocused() : self.searchbox.hide() self.button1.hide() self.button2.hide() self.label1.hide() self.fontsizeSpinBox.hide() else : self.searchbox.show() self.button1.show() self.button2.show() self.label1.show() self.fontsizeSpinBox.show() self.searchbox.setFocus() def keyPressEvent(self,event): ''' handle for searching strings by pressing enter key ''' if self.searchbox.isFocused() and event.key() == Qt.Key_Return : self.fire_search_foreward() # ====================================================================================================================== # utilities # ====================================================================================================================== def __strRemoveReverseToChar(self, s, c): return self.__rm_rec(s, c) def __rm_rec(self, s, c): if s == "" : return "" elif s[-1] == c : return s[:-1] else : return self.__rm_rec(s[:-1], c) def __rreplace(self, s, old, new, occurrence): ''' reverse string replace function @param s: source string @param old: char to be replaced @param new: new char @param occurrence: only the given count occurrences are replaced. ''' li = s.rsplit(old, occurrence) return new.join(li)
def __init__(self): QMainWindow.__init__(self) self.resize(800,600) self.setWindowTitle('PDF Merger') about = QAction('About', self) self.connect(about, SIGNAL('triggered()'), self.show_about) exit = QAction('Exit', self) exit.setShortcut('Ctrl+Q') self.connect(exit, SIGNAL('triggered()'), SLOT('close()')) self.statusBar() menubar = self.menuBar() file = menubar.addMenu('File') file.addAction(about) file.addAction(exit) self.main_widget = QWidget(self) self.setCentralWidget(self.main_widget) self.up_down_widget = QWidget(self) self.options_widget = QWidget(self) input_files_label = QLabel("Input PDFs\nThis is the order in which the files will be merged too") self.files_list = QListWidget() self.files_list.setSelectionMode(QAbstractItemView.ExtendedSelection) add_button = QPushButton("Add PDF(s) to merge...") add_button.clicked.connect(self.clicked_add) up_button = QPushButton("Up") up_button.clicked.connect(self.move_file_up) down_button = QPushButton("Down") down_button.clicked.connect(self.move_file_down) remove_button = QPushButton("Remove PDF") remove_button.clicked.connect(self.remove_file) select_path_label = QLabel("Output PDF") self.dest_path_edit = QLineEdit() self.dest_path_edit.setReadOnly(True) select_path = QPushButton("Select...") select_path.clicked.connect(self.select_save_path) start = QPushButton("Start") start.clicked.connect(self.merge_pdf) up_down_vbox = QVBoxLayout(self.up_down_widget) up_down_vbox.addWidget(up_button) up_down_vbox.addWidget(down_button) up_down_vbox.addWidget(remove_button) self.up_down_widget.setLayout(up_down_vbox) group_input = QGroupBox() grid_input = QGridLayout() grid_input.addWidget(add_button, 0, 0) grid_input.addWidget(input_files_label, 1, 0) grid_input.addWidget(self.files_list, 2, 0) grid_input.addWidget(self.up_down_widget, 2, 1) group_input.setLayout(grid_input) group_output = QGroupBox() grid_output = QGridLayout() grid_output.addWidget(select_path_label, 0, 0) grid_output.addWidget(self.dest_path_edit, 1, 0) grid_output.addWidget(select_path, 1, 1) group_output.setLayout(grid_output) vbox_options = QVBoxLayout(self.options_widget) vbox_options.addWidget(group_input) vbox_options.addWidget(group_output) vbox_options.addWidget(start) self.options_widget.setLayout(vbox_options) splitter_filelist = QSplitter() splitter_filelist.setOrientation(Qt.Vertical) splitter_filelist.addWidget(self.options_widget) vbox_main = QVBoxLayout(self.main_widget) vbox_main.addWidget(splitter_filelist) vbox_main.setContentsMargins(0,0,0,0)
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))
def __init__(self): QMainWindow.__init__(self) self.resize(800, 600) self.setWindowTitle('PDF Merger') about = QAction('About', self) self.connect(about, SIGNAL('triggered()'), self.show_about) exit = QAction('Exit', self) exit.setShortcut('Ctrl+Q') self.connect(exit, SIGNAL('triggered()'), SLOT('close()')) self.statusBar() menubar = self.menuBar() file = menubar.addMenu('File') file.addAction(about) file.addAction(exit) self.main_widget = QWidget(self) self.setCentralWidget(self.main_widget) self.up_down_widget = QWidget(self) self.options_widget = QWidget(self) input_files_label = QLabel( "Input PDFs\nThis is the order in which the files will be merged too" ) self.files_list = QListWidget() self.files_list.setSelectionMode(QAbstractItemView.ExtendedSelection) add_button = QPushButton("Add PDF(s) to merge...") add_button.clicked.connect(self.clicked_add) up_button = QPushButton("Up") up_button.clicked.connect(self.move_file_up) down_button = QPushButton("Down") down_button.clicked.connect(self.move_file_down) remove_button = QPushButton("Remove PDF") remove_button.clicked.connect(self.remove_file) select_path_label = QLabel("Output PDF") self.dest_path_edit = QLineEdit() self.dest_path_edit.setReadOnly(True) select_path = QPushButton("Select...") select_path.clicked.connect(self.select_save_path) start = QPushButton("Start") start.clicked.connect(self.merge_pdf) up_down_vbox = QVBoxLayout(self.up_down_widget) up_down_vbox.addWidget(up_button) up_down_vbox.addWidget(down_button) up_down_vbox.addWidget(remove_button) self.up_down_widget.setLayout(up_down_vbox) group_input = QGroupBox() grid_input = QGridLayout() grid_input.addWidget(add_button, 0, 0) grid_input.addWidget(input_files_label, 1, 0) grid_input.addWidget(self.files_list, 2, 0) grid_input.addWidget(self.up_down_widget, 2, 1) group_input.setLayout(grid_input) group_output = QGroupBox() grid_output = QGridLayout() grid_output.addWidget(select_path_label, 0, 0) grid_output.addWidget(self.dest_path_edit, 1, 0) grid_output.addWidget(select_path, 1, 1) group_output.setLayout(grid_output) vbox_options = QVBoxLayout(self.options_widget) vbox_options.addWidget(group_input) vbox_options.addWidget(group_output) vbox_options.addWidget(start) self.options_widget.setLayout(vbox_options) splitter_filelist = QSplitter() splitter_filelist.setOrientation(Qt.Vertical) splitter_filelist.addWidget(self.options_widget) vbox_main = QVBoxLayout(self.main_widget) vbox_main.addWidget(splitter_filelist) vbox_main.setContentsMargins(0, 0, 0, 0)
class MainWindow(QMainWindow): ''' MainWindow Class This is the main window for the pyDiveLog application. It contains the core GUI including the tool bar, menu bar, status bar, navigation tree, and individual model views. ''' def __init__(self): super(MainWindow, self).__init__() self._logbook = None self._logbookName = 'None' self._logbookPath = None self._createActions() self._createMenus() self._createLayout() self._createStatusBar() self.setWindowTitle(self.tr('pyDiveLog - %s') % self._logbookName) self._readSettings() def _createActions(self): 'Create main window actions' self._actNewLogbook = QAction(self.tr('&New Logbook...'), self) self._actNewLogbook.setShortcut(QKeySequence.New) self._actNewLogbook.setStatusTip(self.tr('Create a new Logbook file')) self._actNewLogbook.triggered.connect(self._actNewLogbookTriggered) self._actOpenLogbook = QAction(self.tr('&Open Logbook...'), self) self._actOpenLogbook.setShortcut(QKeySequence.Open) self._actOpenLogbook.setStatusTip(self.tr('Open an existing Logbook file')) self._actOpenLogbook.triggered.connect(self._actOpenLogbookTriggered) self._actCloseLogbook = QAction(self.tr('&Close Logbook'), self) self._actCloseLogbook.setStatusTip(self.tr('Close the current Logbook file')) self._actCloseLogbook.triggered.connect(self._actCloseLogbookTriggered) self._actExit = QAction(self.tr('E&xit'), self) self._actExit.setShortcut(QKeySequence.Quit) self._actExit.setStatusTip(self.tr('Exit the pyDiveLog application')) self._actExit.triggered.connect(self.close) def _createLayout(self): 'Create main window controls and layout' pass def _createMenus(self): 'Create main window menus' self._fileMenu = self.menuBar().addMenu(self.tr("&File")) self._fileMenu.addAction(self._actNewLogbook) self._fileMenu.addAction(self._actOpenLogbook) self._fileMenu.addAction(self._actCloseLogbook) self._fileMenu.addSeparator() self._fileMenu.addAction(self._actExit) def _createStatusBar(self): 'Initialize the main window status bar' self.statusBar().showMessage('Ready') def _closeLogbook(self): 'Close the current Logbook' if self._logbook is None: return self._logbook = None self._logbookName = 'None' self._logbookPath = None self._writeSettings() self.setWindowTitle(self.tr('pyDiveLog - %s') % self._logbookName) def _openLogbook(self, path): 'Open an existing Logbook' if self._logbook is not None: self._closeLogbook() if not os.path.exists(path): QMessageBox.warning(self, self.tr('Missing Logbook File'), self.tr('Unable to open Logbook "%s": file not found.') % os.path.basename(path), QMessageBox.Ok, QMessageBox.Ok) return #TODO: Handle a Schema Upgrade in a user-friendly manner self._logbook = Logbook(path, auto_update=False) self._logbookName = os.path.basename(path) self._logbookPath = path self._writeSettings() self.setWindowTitle(self.tr('pyDiveLog - %s') % self._logbookName) def _readSettings(self): 'Read main window settings from the configuration' settings = QSettings() settings.beginGroup('MainWindow') max = settings.value('max') size = settings.value('size') pos = settings.value('pos') file = settings.value('file') settings.endGroup() # Size and Position the Main Window if size is not None: self.resize(size) if pos is not None: self.move(pos) # HAX because QVariant is not exposed in PySide and the default # coercion to string is just stupid if max is not None and (max == 'true'): self.showMaximized() # Open the Logbook if file is not None: self._openLogbook(file) def _writeSettings(self): 'Write settings to the configuration' settings = QSettings() settings.beginGroup('MainWindow') settings.setValue('pos', self.pos()) settings.setValue('size', self.size()) settings.setValue('max', self.isMaximized()) settings.setValue('file', self._logbookPath) settings.endGroup() def closeEvent(self, e): 'Intercept an OnClose event' self._writeSettings() e.accept() #-------------------------------------------------------------------------- # Slots @QtCore.Slot() def _actCloseLogbookTriggered(self): 'Close Logbook Action Event Handler' self._closeLogbook() @QtCore.Slot() def _actNewLogbookTriggered(self): 'New Logbook Action Event Handler' if self._logbook is not None: dir = os.path.dirname(self._logbookPath) else: dir = os.path.expanduser('~') fn = QFileDialog.getSaveFileName(self, caption=self.tr('Save new Logbook as...'), dir=dir, filter='Logbook Files (*.lbk);;All Files (*.*)')[0] if fn == '': return if os.path.exists(fn): if QMessageBox.question(self, self.tr('Create new Logbook?'), self.tr('Logbook "%s" already exists. Would you like to overwrite it?') % os.path.basename(fn), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) != QMessageBox.Yes: return # Try and remove the old Logbook file try: os.remove(fn) except: QMessageBox.error(self, self.tr('Cannot remove Logbook'), self.tr('Unable to remove Logbook file "%s". Please delete this file manually.') % os.path.basename(fn), QMessageBox.Ok, QMessageBox.Ok) return # Create a new Logbook File Logbook.Create(fn) self._openLogbook(fn) @QtCore.Slot() def _actOpenLogbookTriggered(self): 'Open Logbook Action Event Handler' if self._logbook is not None: dir = os.path.dirname(self._logbookPath) else: dir = os.path.expanduser('~') fn = QFileDialog.getOpenFileName(self, caption=self.tr('Select a Logbook file'), dir=dir, filter='Logbook Files (*.lbk);;All Files(*.*)')[0] if fn == '': return if not os.path.exists(fn): if QMessageBox.question(self, self.tr('Create new Logbook?'), self.tr('Logbook "%s" does not exist. Would you like to create it?') % os.path.basename(fn), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) != QMessageBox.Yes: return Logbook.Create(fn) self._openLogbook(fn)
def initUI(self): # textEdit = QTextEdit() # self.setCentralWidget(textEdit) # self.setStyleSheet("QGroupBox { border: 1px solid gray; padding: 5px;}"); # Action to quit program exitAction = QAction(QIcon(None), 'Quit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(self.close) # # Action to update device list # self.refreshAction = QAction(QIcon('img/reload.png'), 'Refresh', self) # self.refreshAction.setShortcut('F5') # self.refreshAction.setStatusTip('Refresh list of connected devices.') # self.refreshAction.triggered.connect(self.updateDeviceList) # Action to show program information helpAction = QAction(QIcon(None), 'Help', self) helpAction.setShortcut('F1') helpAction.triggered.connect(self.showHelpDialog) # Action to help aboutAction = QAction(QIcon(None), 'About', self) aboutAction.triggered.connect(self.showAboutDialog) self.statusBar() # Add the file menu menubar = self.menuBar() fileMenu = menubar.addMenu('&File') # fileMenu.addAction(self.refreshAction) fileMenu.addAction(exitAction) fileMenu = menubar.addMenu('&Help') fileMenu.addAction(helpAction) fileMenu.addAction(aboutAction) # # Add the toolbar # toolbar = self.addToolBar('Exit') # # toolbar.addAction(self.refreshAction) # toolbar.setMovable(False) # Add the main windows widgets self.deviceListWidget = DeviceList(self.programDeviceHandler, self.infoDeviceHandler, self.resetDeviceHandler) self.fileSelectorWidget = FileSelector() self.setStyleSheet(""" QStatusBar { border-top: 1px solid #CCC; } QToolBar { border-top: 1px solid #DDD; border-bottom: 1px solid #CCC; } """) gbox = QGroupBox("Connected USB devices:") gboxLayout = QVBoxLayout() gboxLayout.addWidget(self.deviceListWidget) gbox.setLayout(gboxLayout) self.refreshEvent = QTimer() self.refreshEvent.setInterval(1250) self.refreshEvent.timeout.connect(self.USBUpdate) self.refreshEvent.start() layout = QVBoxLayout() layout.addWidget(self.fileSelectorWidget) layout.addWidget(gbox) self.setCentralWidget(QWidget()) self.centralWidget().setLayout(layout) self.setMinimumSize(620, 700) self.setMaximumWidth(620) self.setWindowFlags(Qt.Window | Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint) self.setGeometry(300, 300, 350, 250) self.setWindowTitle('keyplus layout and firmware loader') self.show()
class AppWindow(QMainWindow): # ===================== # The Main Window Class # ===================== def __init__(self): # ==================== # Constructor Function # ==================== QMainWindow.__init__(self) self.setWindowTitle("Virtua Text Editor") self.setGeometry(300, 300, 1024, 768) QToolTip.setFont(QFont("Ubuntu", 10, QFont.Normal)) self.setToolTip('Application Window') # ================================ # Function to setup menus, etc etc # ================================ self.textEdit = QTextEdit() self.textEdit.setFont(QFont("Ubuntu", 12, QFont.Normal)) self.setCentralWidget(self.textEdit) self.create_menus() self.create_actions() self.fileMenu.addAction(self.newAction) self.fileMenu.addAction(self.openAction) self.fileMenu.addAction(self.saveAction) self.fileMenu.addAction(self.saveasAction) self.fileMenu.addSeparator() self.fileMenu.addAction(self.printAction) self.fileMenu.addSeparator() self.fileMenu.addAction(self.exitAction) self.editMenu.addAction(self.undoAction) self.editMenu.addAction(self.redoAction) self.editMenu.addAction(self.cutAction) self.editMenu.addAction(self.copyAction) self.editMenu.addAction(self.pasteAction) self.editMenu.addSeparator() self.editMenu.addAction(self.selectallAction) self.editMenu.addAction(self.deselectallAction) self.editMenu.addSeparator() self.editMenu.addAction(self.findAction) self.editMenu.addAction(self.findReplaceAction) self.helpMenu.addAction(self.aboutAction) self.app_status_bar = QStatusBar() self.app_status_bar.showMessage('Ready, v0.2', 10000) self.setStatusBar(self.app_status_bar) self.create_toolbar() self.toolbar.addAction(self.newAction) self.toolbar.addSeparator() self.toolbar.addAction(self.cutAction) self.toolbar.addAction(self.copyAction) self.toolbar.addAction(self.pasteAction) self.toolbar.addSeparator() self.toolbar.addAction(self.printAction) self.toolbar.addSeparator() self.toolbar.addAction(self.undoAction) self.toolbar.addAction(self.redoAction) self.toolbar.addSeparator() self.toolbar.addAction(self.findAction) self.toolbar.addAction(self.findReplaceAction) def create_toolbar(self): # =============================== # Function to create the toolbar. # =============================== self.toolbar = self.addToolBar('Main') self.toolbar.setToolButtonStyle(PySide.QtCore.Qt.ToolButtonTextUnderIcon) def newfile(self): self.textEdit.setText('') # TODO: Create the file/open method def openfile(self): print "Open File Menu Selected" # TODO: Create the file/save method def savefile(self): print "Save File Menu Selected" # TODO: Create the file/saveas method def saveasfile(self): print "Save As File Menu Selected" # TODO: Create the print method def print_page(self): print "Print Page Selected" # TODO: Create the find method def find_text(self): print "Find text option selected" # TODO: Create the replace method def find_replace_text(self): print "Replace text selected" def create_actions(self): # ========================================= # Function to create actions for menu items # ========================================= self.newAction = QAction(QIcon('digital_assets/document-new.svg'), 'New', self) self.newAction.setShortcut(QKeySequence.New) self.newAction.setStatusTip("Create a New File") self.newAction.setIconText("New") self.newAction.triggered.connect(self.newfile) self.openAction = QAction(QIcon('digital_assets/document-open.svg'), 'Open', self) self.openAction.setShortcut(QKeySequence.Open) self.openAction.setStatusTip("Open a file") self.openAction.triggered.connect(self.openfile) self.saveAction = QAction(QIcon('digital_assets/document-save.svg'), 'Save', self) self.saveAction.setShortcut(QKeySequence.Save) self.saveAction.setStatusTip("Save a file") self.saveAction.triggered.connect(self.savefile) self.saveasAction = QAction(QIcon('digital_assets/document-save-as.svg'), 'Save As', self) self.saveasAction.setShortcut(QKeySequence.SaveAs) self.saveasAction.setStatusTip("Save a File As....") self.saveasAction.triggered.connect(self.saveasfile) self.printAction = QAction(QIcon('digital_assets/document-print.svg'), 'Print', self) self.printAction.setShortcut(QKeySequence.Print) self.printAction.setStatusTip("Print") self.printAction.triggered.connect(self.print_page) self.exitAction = QAction(QIcon('digital_assets/application-exit.svg'), 'Exit', self) self.exitAction.setShortcut(QKeySequence.Quit) self.exitAction.setStatusTip("Exit the Application") self.exitAction.triggered.connect(self.quit_application) self.undoAction = QAction(QIcon('digital_assets/undo.svg'), 'Undo', self) self.undoAction.setShortcut(QKeySequence.Undo) self.undoAction.setStatusTip("Undo") self.undoAction.triggered.connect(self.textEdit.undo) self.redoAction = QAction(QIcon('digital_assets/redo.svg'), 'Redo', self) self.redoAction.setShortcut(QKeySequence.Redo) self.redoAction.setStatusTip("Redo") self.redoAction.triggered.connect(self.textEdit.redo) self.cutAction = QAction(QIcon('digital_assets/edit-cut.svg'), 'Cut', self) self.cutAction.setShortcut(QKeySequence.Cut) self.cutAction.setStatusTip("Cut") self.cutAction.setEnabled(False) self.cutAction.triggered.connect(self.textEdit.cut) self.copyAction = QAction(QIcon('digital_assets/edit-copy.svg'), 'Copy', self) self.copyAction.setShortcut(QKeySequence.Copy) self.copyAction.setStatusTip("Copy") self.copyAction.setEnabled(False) self.copyAction.triggered.connect(self.textEdit.copy) self.pasteAction = QAction(QIcon('digital_assets/edit-paste.svg'), 'Paste', self) self.pasteAction.setShortcut(QKeySequence.Paste) self.pasteAction.setStatusTip("Paste") self.pasteAction.setEnabled(False) self.pasteAction.triggered.connect(self.textEdit.paste) self.selectallAction = QAction(QIcon('digital_assets/edit-select-all.svg'), 'Select All', self) self.selectallAction.setShortcut(QKeySequence.SelectAll) self.selectallAction.setStatusTip("Select All") self.selectallAction.triggered.connect(self.textEdit.selectAll) self.deselectallAction = QAction(QIcon('digital_assets/edit-select-all.svg'), 'Deselect All', self) self.deselectallAction.setShortcut("Shift+Ctrl+A") self.deselectallAction.setStatusTip("Deselect All") self.deselectallAction.triggered.connect(self.deselect_all_text) self.findAction = QAction(QIcon('digital_assets/edit-find.svg'), 'Find', self) self.findAction.setShortcut(QKeySequence.Find) self.findAction.setStatusTip("Find") self.findAction.triggered.connect(self.find_text) self.findReplaceAction = QAction(QIcon('digital_assets/edit-find-replace.svg'), 'Replace', self) self.findReplaceAction.setShortcut(QKeySequence.Replace) self.findReplaceAction.setShortcut("Replace") self.findReplaceAction.triggered.connect(self.find_replace_text) self.aboutAction = QAction(QIcon('digital_assets/AppIcon.png'), 'About', self) self.aboutAction.setStatusTip("Displays info about the application") self.aboutAction.triggered.connect(self.show_about) def deselect_all_text(self): text_cursor = self.textEdit.textCursor() text_cursor.clearSelection() self.textEdit.setTextCursor(text_cursor) def create_menus(self): # ================================ # Function to create the menu bar. # ================================ self.fileMenu = self.menuBar().addMenu("File") self.fileMenu.setFont(QFont("Ubuntu", 10, QFont.Normal)) self.editMenu = self.menuBar().addMenu("Edit") self.editMenu.setFont(QFont("Ubuntu", 10, QFont.Normal)) self.helpMenu = self.menuBar().addMenu("Help") self.helpMenu.setFont(QFont("Ubuntu", 10, QFont.Normal)) def set_icon(self): # =============================== # Function to set the Window Icon # =============================== appicon = QIcon('digital_assets/AppIcon.png') self.setWindowIcon(appicon) def quit_application(self): # ================================ # Function to quit the application # ================================ userinfo = QMessageBox.question(self, "Confirmation", "This will quit, Do you want to continue?", QMessageBox.Yes | QMessageBox.No) if userinfo == QMessageBox.Yes: templateApp.quit() if userinfo == QMessageBox.No: pass def show_about(self): QMessageBox.about(self, "About Virtua Text Editor", "<b><h3>Virtua Text Editor</h3></b>" "<p><h4>Virtua Text Editor has been written to serve as a template" " that can be used as a basis for creating a working application." " All of the components that make up the core functions of an" " application, the main window, a status bar, menus and dialogs" " are provided here as a basis for writing something new and interesting</h4></p>") def center_application(self): # ============================================ # Function to center the Application on screen # ============================================ qrect = self.frameGeometry() centerpoint = QDesktopWidget().availableGeometry().center() qrect.moveCenter(centerpoint) self.move(qrect.topLeft())
def winsetup(self): self.setWindowIcon(QIcon('img/note.png')) openFile = QAction(self.openicon, 'Open', self) openFile.setShortcut('Ctrl+O') openFile.triggered.connect(self.load) saveFile = QAction(self.saveicon, 'Save', self) saveFile.setShortcut('Ctrl+S') saveFile.triggered.connect(self.save) playFile = QAction(self.playicon, 'Play', self) playFile.setShortcut('Ctrl+P') playFile.triggered.connect(self.play) pausePlayb = QAction(self.pauseicon, 'Pause', self) pausePlayb.setShortcut('Ctrl+R') pausePlayb.triggered.connect(self.pause) stopPlay = QAction(self.stopicon, 'Stop', self) stopPlay.setShortcut('Ctrl+Z') stopPlay.triggered.connect(self.stop) exitAction = QAction(self.quiticon, 'Quit', self) exitAction.setShortcut('Ctrl+X') exitAction.triggered.connect(self.quit) aboutdlg = QAction(self.abouticon, 'About', self) aboutdlg.setShortcut('Ctrl+A') aboutdlg.triggered.connect(self.about) showSett = QAction(self.setticon, 'Settings', self) showSett.triggered.connect(self.settings) menubar = self.menuBar() fileMenu = menubar.addMenu('&File') configMenu = menubar.addMenu('&Options') configMenu.setStyleSheet("border: 1px solid black;") self.setLooped = QAction('Loop', configMenu, checkable=True) if self.progset.value("sound/Looped") == 'true': self.setLooped.setChecked(True) else: self.setLooped.setChecked(False) self.setLooped.setShortcut('Ctrl+L') self.setAutoplay = QAction('Autoplay', configMenu, checkable=True) if self.progset.value("sound/Autoplay") == 'true': self.setAutoplay.setChecked(True) else: self.setAutoplay.setChecked(False) self.setAutoplay.setShortcut('Ctrl+K') configMenu.addAction(self.setAutoplay) configMenu.addAction(self.setLooped) fileMenu.setStyleSheet("border: 1px solid black;") fileMenu.addAction(openFile) fileMenu.addAction(saveFile) fileMenu.addSeparator() self.recentMenu = fileMenu.addMenu('Recent') self.rfUpdate() fileMenu.addSeparator() fileMenu.addAction(showSett) fileMenu.addSeparator() fileMenu.addAction(exitAction) helpMenu = menubar.addMenu('&Help') helpMenu.setStyleSheet("border: 1px solid black;") helpMenu.addAction(aboutdlg) self.numCards = QSpinBox() numCards_text = QLabel(" OPL : ") self.numCards.setRange(1, 100) self.numCards.setValue(int(self.progset.value("sound/numCards", 3))) self.numCards.valueChanged.connect(self.updateMax4ops) self.fourOps = QSpinBox() fourOps_text = QLabel(" 4op Ch : ") self.fourOps.setRange(0, self.numCards.value()*6) self.fourOps.setValue(int(self.progset.value("sound/fourOps", self.numCards.value()*6))) self.twoOps = QSpinBox() twoOps_text = QLabel(" 2op Ch : ") self.twoOps.setValue((self.numCards.value()*12 - self.fourOps.value())) self.twoOps.setRange(self.twoOps.value(), self.twoOps.value()) toolbar = self.addToolBar('Media') toolbar.addAction(playFile) toolbar.addAction(pausePlayb) toolbar.addAction(stopPlay) toolbar.setMovable(False) toolbar.addSeparator() toolbar.addWidget(numCards_text) toolbar.addWidget(self.numCards) toolbar.addSeparator() toolbar.addWidget(fourOps_text) toolbar.addWidget(self.fourOps) #toolbar.addSeparator() #toolbar.addWidget(twoOps_text) #toolbar.addWidget(self.twoOps) self.statusBar() self.setFixedSize(380, 90) self.center() self.setWindowTitle('ADLMIDI pyGUI') self.show() if self.debug: barf("MSG", "Loaded Main Window", True, False) self.update("ready") self.threads = [] self.addWorker(AdlMidi(1)) self.addWorker(AdlMidiSave(2))
class EditSupplyOrderPanel(HorsePanel): supply_order_saved = Signal() def panel_content_hash(self): return (self.current_supply_order_id, self.current_supplier.supplier_id) def needs_close_confirmation(self): return self.model_data_changed def confirm_close(self): return self._save_if_necessary() @Slot() def change_supplier(self): from koi.supply.ChooseSupplierDialog import ChooseSupplierDialog from PySide.QtGui import QDialog d = ChooseSupplierDialog(self) if d.exec_() and d.result( ) == QDialog.Accepted and d.supplier_id != self.current_supplier.supplier_id: mainlog.debug("Supplier chosen {}".format(d.supplier)) self.current_supplier = d.supplier self.supplier_plate_widget.set_contact_data(self.current_supplier) self.data_changed2_slot() @Slot() def print_supply_order(self): if self._save_if_necessary(): try: print_supply_order(self.current_supply_order_id) except Exception as e: showErrorBox(str(e)) def _save_if_necessary(self): """ True if the user has either said he doesn't want to save or he saved successufly. False if the user has cancelled (no save, no "no save") or the save operation has failed """ if self.model_data_changed: ynb = yesNoBox( _("Data were changed"), _("You have changed some of the data in this. Do you want to save before proceeding ?" )) if ynb == QMessageBox.Yes: if self.save( ) != False: # FIXME defensive, make sure it's True # Because when I save, although the order definition is # not meant to change, the order numbers (accounting label, # etc.) might actually change. self.reload() return True else: return False elif ynb == QMessageBox.No: return True elif ynb == QMessageBox.Cancel: return False else: return True def edit_new(self, supplier): """ Start editing a brand new order """ self.current_supplier = supplier self.current_supply_order_id = None self.edit_comment_widget.setText(None) self.delivery_date_widget.set_value(None) self.creation_date_widget.setText("") self.controller_part.model.clear() self.controller_part.model.insertRows(0, 1, QModelIndex()) self.accounting_label = None self._set_view(None, True) mainlog.debug("edit_new : supplier : {}".format( self.current_supplier.supplier_id)) def edit(self, supply_order_id): """ Start editing an existing order """ self._fill_view_with_order_data(supply_order_id) self._set_view(None, False) def reload(self): ndx = self.controller_part.view.currentIndex() self._fill_view_with_order_data(self.current_supply_order_id) self._set_view(ndx, False) def _fill_view_with_order_data(self, order_id): sorder, sorder_parts = supply_order_service.find_by_id(order_id) self.edit_comment_widget.setText(sorder.description) self.delivery_date_widget.set_value(sorder.expected_delivery_date) self.creation_date_widget.setText(date_to_dmy(sorder.creation_date)) self.supplier_reference_widget.setText(sorder.supplier_reference) self.current_supplier = supplier_service.find_by_id(sorder.supplier_id) self.current_supply_order_id = sorder.supply_order_id self.model._buildModelFromObjects(sorder_parts) self.accounting_label = sorder.accounting_label def _set_view(self, ndx=None, start_editing=False): """ Once the data and models are prepared, one comes here to start the editing... """ self.supplier_plate_widget.set_contact_data(self.current_supplier) self.controller_part.view.setFocus() if not ndx: ndx = self.controller_part.model.index(0, 0) # Somehow, editing a cell doesn't set up the currentIndex automatically... self.controller_part.view.setCurrentIndex(ndx) if start_editing: self.controller_part.view.edit(ndx) self.model_data_changed = False self.title_widget.set_modified_flag(False) ref = self.accounting_label or self.supplier_reference_widget.text() if ref: self.set_panel_title(u"{}\n{}".format( ref, self.current_supplier.fullname)) else: self.set_panel_title( _("Supply order") + u"\n" + self.current_supplier.fullname) refs = [] if self.accounting_label: refs.append( u"<span style='color:orange; font-style:normal;'>{}</span>". format(self.accounting_label)) if self.supplier_reference_widget.text(): refs.append( u"<span style='color:black; font-style:normal;'>{}</span>". format(self.supplier_reference_widget.text())) self.in_title_label.setText( _("<h1>Ref. : {}</h1>").format(u" / ".join(refs))) def _validate(self): errs = self.model.validate() if errs: errs = [formatErrorsOnLine(errs)] else: errs = [] if not self.delivery_date_widget.is_valid(): errs.append(_('The date is not valid')) return errs or True def save(self): if self.model_data_changed: focused_widget = QApplication.focusWidget() if isinstance(focused_widget, QLineEdit) and focused_widget.parent() != self: focused_widget.clearFocus() focused_widget = QApplication.focusWidget() validation_results = self._validate() if validation_results != True: showErrorBox(_("The data are not correct"), "<br>-" + "<br>-".join(validation_results)) return False mainlog.debug("save : supplier_id : {}".format( self.current_supplier.supplier_id)) obj = blank_dto(SupplyOrder) obj.supply_order_id = self.current_supply_order_id obj.creation_date = date.today() obj.description = self.edit_comment_widget.toPlainText() obj.supplier_id = self.current_supplier.supplier_id obj.expected_delivery_date = self.delivery_date_widget.value() obj.supplier_reference = self.supplier_reference_widget.text() obj.accounting_label = self.accounting_label def factory(): return blank_dto(SupplyOrderPart) parts_actions = self.model.model_to_objects(factory) try: mainlog.debug("Saving") self.current_supply_order_id = supply_order_service.save( obj, parts_actions) # Reload the data self.reload() mainlog.debug("Emitting change signal") self.supply_order_saved.emit() # self.current_supply_order_id) except Exception as ex: showErrorBox( _("Error while saving"), _("There was an unexpected error while saving your data"), ex, object_name="saveError") if focused_widget: focused_widget.setFocus(Qt.OtherFocusReason) @Slot() def delete(self): if self.current_supply_order_id: s = _("About to delete order {}").format(self.accounting_label) if confirmationBox(s, _("Are you sure ?")): try: supply_order_service.deactivate( self.current_supply_order_id) except Exception as ex: showErrorBox("I could not delete the order", ex=ex) return rep = supply_order_service.find_last_order_id( self.current_supplier.supplier_id) if rep: self.edit(rep) else: self.edit_new(self.current_supplier) else: showErrorBox( _("No order or non-saved order selected"), _("You can only delete an order that has already been saved"), object_name="delete_only_saved_order") return @Slot() def show_actions(self): button = self.action_menu.parent() p = button.mapToGlobal(QPoint(0, button.height())) self.action_menu.exec_(p) @Slot(QStandardItem) def data_changed_slot(self, item): self.model_data_changed = True self.title_widget.set_modified_flag(self.model_data_changed) @Slot() def data_changed2_slot(self): self.model_data_changed = True self.title_widget.set_modified_flag(self.model_data_changed) @Slot() def next_order_for_supplier(self): if self._save_if_necessary(): # This could find nothing if there's no order for the supplier :-) oid = supply_order_service.find_next_for_supplier( self.current_supply_order_id, self.current_supplier.supplier_id) if oid: self.edit(oid) @Slot() def previous_order_for_supplier(self): if self._save_if_necessary(): oid = supply_order_service.find_previous_for_supplier( self.current_supply_order_id, self.current_supplier.supplier_id) if oid: self.edit(oid) def __init__(self, parent): super(EditSupplyOrderPanel, self).__init__(parent) self.current_supply_order_id = None self.proto = [] self.proto.append( TextAreaPrototype('description', _('Description'), editable=True, nullable=False)) self.proto.append( FloatNumberPrototype('quantity', _('Quantity'), editable=True, nullable=False)) self.proto.append( FloatNumberPrototype('unit_price', _('Unit price'), editable=True, nullable=True)) self.delivery_date_prototype = FutureDatePrototype('description', ('Description'), editable=True, nullable=False) self.model = SupplyOrderPartsModel(self, self.proto) self.controller_part = PrototypeController( self, self.proto, ProxyTableView(None, self.proto)) self.controller_part.setModel(self.model) # self.controller_part.view.verticalHeader().hide() self.controller_part.view.horizontalHeader().setResizeMode( 0, QHeaderView.Stretch) self.print_supply_order_action = QAction(_("Print supply order"), self) # , parent self.print_supply_order_action.triggered.connect( self.print_supply_order) self.print_supply_order_action.setShortcut( QKeySequence(Qt.CTRL + Qt.Key_P)) self.print_supply_order_action.setShortcutContext( Qt.WidgetWithChildrenShortcut) self.addAction(self.print_supply_order_action) self.save_supply_order_action = QAction(_("Save supply order"), self) # , parent self.save_supply_order_action.triggered.connect(self.save) self.save_supply_order_action.setShortcut( QKeySequence(Qt.CTRL + Qt.Key_S)) self.save_supply_order_action.setShortcutContext( Qt.WidgetWithChildrenShortcut) self.addAction(self.save_supply_order_action) self.delete_supply_order_action = QAction(_("Deactivate supply order"), self) # , parent self.delete_supply_order_action.triggered.connect(self.delete) self.addAction(self.delete_supply_order_action) self.next_order_for_supplier_action = QAction( _("Next supplier's order"), self) # , parent self.next_order_for_supplier_action.setShortcut( QKeySequence(Qt.CTRL + Qt.Key_PageDown)) self.next_order_for_supplier_action.setShortcutContext( Qt.WidgetWithChildrenShortcut) self.next_order_for_supplier_action.triggered.connect( self.next_order_for_supplier) self.addAction(self.next_order_for_supplier_action) self.previous_order_for_supplier_action = QAction( _("Previous supplier's order"), self) # , parent self.previous_order_for_supplier_action.setShortcut( QKeySequence(Qt.CTRL + Qt.Key_PageDown)) self.previous_order_for_supplier_action.setShortcutContext( Qt.WidgetWithChildrenShortcut) self.previous_order_for_supplier_action.triggered.connect( self.next_order_for_supplier) self.addAction(self.previous_order_for_supplier_action) self.change_supplier_action = QAction(_("Change supplier"), self) # , parent self.change_supplier_action.triggered.connect(self.change_supplier) self.addAction(self.change_supplier_action) # self.controller_operation.view.addAction(self.reprint_delivery_slip) self.controller_part.view.addAction(self.print_supply_order_action) self.controller_part.view.addAction(self.save_supply_order_action) self.controller_part.view.addAction(self.delete_supply_order_action) navigation = NavBar(self, [(self.next_order_for_supplier_action.text(), self.next_order_for_supplier), (self.previous_order_for_supplier_action.text(), self.previous_order_for_supplier), (_("Action"), self.show_actions)]) navigation.buttons[2].setObjectName("specialMenuButton") self.action_menu = QMenu(navigation.buttons[2]) list_actions = [(self.print_supply_order_action, None), (self.save_supply_order_action, None), (self.delete_supply_order_action, None), (self.change_supplier_action, None)] populate_menu(self.action_menu, self, list_actions, context=Qt.WidgetWithChildrenShortcut) self.title_widget = TitleWidget(_("Supply order"), self, navigation) self.supplier_plate_widget = SupplierPlateWidget(self) self.edit_comment_widget = DescribedTextEdit(_("Comments")) self.edit_comment_widget.setMinimumHeight(20) self.edit_comment_widget.setMinimumWidth(600) self.edit_comment_widget.setMaximumHeight(60) self.edit_comment_widget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) self.supplier_reference_widget = QLineEdit() self.delivery_date_widget = DateEntryWidget() self.delivery_date_widget.setMaximumWidth(100) self.creation_date_widget = QLabel() self.in_title_label = QLabel() top_layout1 = QHBoxLayout() top_layout1.addWidget(self.in_title_label) top_layout1.addStretch() top_layout1.addWidget(self.supplier_plate_widget) hlayout = QHBoxLayout() hlayout.addWidget(QLabel(_("Delivery date"))) hlayout.addWidget(self.delivery_date_widget) hlayout.addStretch() hlayout3 = QHBoxLayout() hlayout3.addWidget(QLabel(_("Creation date"))) hlayout3.addWidget(self.creation_date_widget) hlayout3.addStretch() hlayout2 = QHBoxLayout() hlayout2.addWidget(QLabel(_("Supplier's reference"))) hlayout2.addWidget(self.supplier_reference_widget) hlayout2.addStretch() vlayout = QVBoxLayout() vlayout.addLayout(hlayout) # delivery date vlayout.addLayout(hlayout3) # creation date vlayout.addLayout(hlayout2) # reference vlayout.addStretch() top_layout2 = QHBoxLayout() top_layout2.addLayout(vlayout) top_layout2.addWidget(self.edit_comment_widget) top_layout2.addStretch() top_layout2.setStretch(0, 0) top_layout2.setStretch(1, 0) # For some reason, the stretch added above is not enough # to push the whole layout to the left. I have to set # it's stretch factor too... top_layout2.setStretch(2, 100) vhead_layout = QVBoxLayout() vhead_layout.addWidget(self.title_widget) top_layout1.setContentsMargins(4, 0, 4, 0) # vhead_layout.addLayout(top_layout1) vhead_layout.addWidget(InlineSubFrame(top_layout1, None)) vhead_layout.addLayout(top_layout2) # top_layout2.setContentsMargins(4,4,4,4) #vhead_layout.addWidget(InlineSubFrame(top_layout2,None)) vhead_layout.addWidget(self.controller_part.view) vhead_layout.setStretch(0, 0) vhead_layout.setStretch(1, 0) vhead_layout.setStretch(2, 0) vhead_layout.setStretch(3, 10) self.setLayout(vhead_layout) self.controller_part.view.enable_edit_panel() # Handling changes in the model (helpful to know if saving # is necessary) self.model_data_changed = False self.model.rowsInserted.connect(self.data_changed_slot) self.model.rowsRemoved.connect(self.data_changed_slot) self.model.dataChanged.connect(self.data_changed_slot) self.supplier_reference_widget.textChanged.connect( self.data_changed2_slot) self.edit_comment_widget.textChanged.connect(self.data_changed2_slot) self.delivery_date_widget.textChanged.connect(self.data_changed2_slot)
if activeSelection: print("Got an active Selection in the Timeline editor, will add a %s effect.." % effect) for item in activeSelection: hiero.core.log.info("Adding to item: %s" % str(item)) tIn = item.timelineIn() tOut = item.timelineOut() track = item.parentTrack() if isinstance(track, hiero.core.VideoTrack): effectItem = hiero.core.EffectTrackItem(effect) effectItem.setTimelineIn(tIn) effectItem.setTimelineOut(tOut) track.addSubTrackItem(effectItem, 0) self.close() def toggleTabTabTab(): if hiero.ui.tabtabtab.isHidden(): hiero.ui.tabtabtab.showAt(QCursor.pos()) else: hiero.ui.tabtabtab.hide() action = QAction("Effect Browser", None) action.setShortcut(QKeySequence(167)) action.triggered.connect(toggleTabTabTab) hiero.ui.addMenuAction("Window", action) # Keep a reference to the TabTabTabWidget in hiero.ui hiero.ui.tabtabtab = TabTabTabWidget()
class ConfigEditor(QMainWindow): def __init__(self, app, cfg, title='Config Editor'): super(ConfigEditor, self).__init__() self.app = app self.config = cfg self.title = title def setup(self): self.dirty = False self.def_cfg = copy.deepcopy(self.config) self.config.update_from_user_file() self.base_cfg = copy.deepcopy(self.config) self.categories = QListWidget() #self.categories.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Expanding) self.settings = QStackedWidget() #self.categories.setSizePolicy(QSizePolicy.MinimumExpanding,QSizePolicy.Expanding) QObject.connect(self.categories, SIGNAL('itemSelectionChanged()'), self.category_selected) self.widget_list = {} for cat in self.config.get_categories(): self.widget_list[cat] = {} longest_cat = 0 for cat in self.config.get_categories(): if len(cat) > longest_cat: longest_cat = len(cat) self.categories.addItem(cat) settings_layout = QGridLayout() r = 0 c = 0 for setting in self.config.get_settings(cat): info = self.config.get_setting(cat, setting, True) s = QWidget() s.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Fixed) sl = QVBoxLayout() label = QLabel() if info.has_key('alias'): label.setText(info['alias']) else: label.setText(setting) if info.has_key('about'): label.setToolTip(info['about']) sl.addWidget(label) if info['type'] == constants.CT_LINEEDIT: w = LineEdit(self, self.config,cat,setting,info) elif info['type'] == constants.CT_CHECKBOX: w = CheckBox(self, self.config,cat,setting,info) elif info['type'] == constants.CT_SPINBOX: w = SpinBox(self, self.config,cat,setting,info) elif info['type'] == constants.CT_DBLSPINBOX: w = DoubleSpinBox(self, self.config,cat,setting,info) elif info['type'] == constants.CT_COMBO: w = ComboBox(self, self.config,cat,setting,info) w.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Fixed) self.widget_list[cat][setting] = w sl.addWidget(w) s.setLayout(sl) c = self.config.config[cat].index(setting) % 2 settings_layout.addWidget(s, r, c) if c == 1: r += 1 settings = QWidget() settings.setLayout(settings_layout) settings_scroller = QScrollArea() settings_scroller.setWidget(settings) settings_scroller.setWidgetResizable(True) self.settings.addWidget(settings_scroller) font = self.categories.font() fm = QFontMetrics(font) self.categories.setMaximumWidth(fm.widthChar('X')*(longest_cat+4)) self.main = QWidget() self.main_layout = QVBoxLayout() self.config_layout = QHBoxLayout() self.config_layout.addWidget(self.categories) self.config_layout.addWidget(self.settings) self.mainButtons = QDialogButtonBox(QDialogButtonBox.RestoreDefaults | QDialogButtonBox.Reset | QDialogButtonBox.Apply) self.main_apply = self.mainButtons.button(QDialogButtonBox.StandardButton.Apply) self.main_reset = self.mainButtons.button(QDialogButtonBox.StandardButton.Reset) self.main_defaults = self.mainButtons.button(QDialogButtonBox.StandardButton.LastButton) QObject.connect(self.mainButtons, SIGNAL('clicked(QAbstractButton *)'), self.mainbutton_clicked) self.dirty_check() self.main_layout.addLayout(self.config_layout) self.main_layout.addWidget(self.mainButtons) self.main.setLayout(self.main_layout) self.setCentralWidget(self.main) self.setWindowTitle(self.title) self.setUnifiedTitleAndToolBarOnMac(True) self.categories.setCurrentItem(self.categories.item(0)) self.menuBar = QMenuBar() self.filemenu = QMenu('&File') self.quitAction = QAction(self) self.quitAction.setText('&Quit') if platform.system() != 'Darwin': self.quitAction.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_Q)) QObject.connect(self.quitAction, SIGNAL('triggered()'), self.quitApp) self.filemenu.addAction(self.quitAction) self.menuBar.addMenu(self.filemenu) self.setMenuBar(self.menuBar) self.show() self.activateWindow() self.raise_() self.setMinimumWidth(self.geometry().width()*1.2) screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2) def category_selected(self): self.settings.setCurrentIndex(self.config.config.index(self.categories.selectedItems()[0].text())) def mainbutton_clicked(self, button): if button == self.main_reset: for cat in self.base_cfg.get_categories(): for setting in self.base_cfg.get_settings(cat): self.widget_list[cat][setting].updateValue(self.base_cfg.get_setting(cat,setting)) elif button == self.main_defaults: for cat in self.def_cfg.get_categories(): for setting in self.def_cfg.get_settings(cat): self.widget_list[cat][setting].updateValue(self.def_cfg.get_setting(cat,setting)) elif button == self.main_apply: bad_settings = self.validate_settings() if bad_settings == []: self.save_settings() self.main_apply.setEnabled(False) self.main_reset.setEnabled(False) else: msgBox = QMessageBox() msgBox.setText("Must fix the following invalid settings before quitting:") msgBox.setStandardButtons(QMessageBox.Ok) info = '' for setting in bad_settings: new = '%s,%s<br>' % setting info = '%s%s' % (info, new) msgBox.setInformativeText(info) msgBox.exec_() def quitApp(self): self.app.closeAllWindows() def get_changes(self): enc = MyEncoder() if enc.encode(self.def_cfg.config) == enc.encode(self.config.config): return False if enc.encode(self.base_cfg.config) != enc.encode(self.config.config): newC = Config() for c in self.config.config.keys(): for s in self.config.config[c].keys(): if self.config.config[c][s]['value'] != self.def_cfg.config[c][s]['value']: newC.add_setting(c, s, self.config.config[c][s]['value'], stub=True) return json.dumps(newC.config, separators=(',',': '), indent=4, sort_keys=True) else: return None def validate_settings(self): ret = [] for cat in self.config.get_categories(): for setting in self.config.get_settings(cat): info = self.config.get_setting(cat, setting, True) if info.has_key('validate'): if not info['validate'](info): ret.append((cat,setting)) return ret def dirty_check(self): if str(self.base_cfg) != str(self.config): self.dirty = True self.main_apply.setEnabled(True) self.main_reset.setEnabled(True) else: self.dirty = False self.main_apply.setEnabled(False) self.main_reset.setEnabled(False) if str(self.def_cfg) == str(self.config): self.main_defaults.setEnabled(False) else: self.main_defaults.setEnabled(True) def save_settings(self): config = self.get_changes() if config == False: if os.path.isfile(self.config.user_file): os.remove(self.config.user_file) elif config != None: with open(self.config.user_file, 'w+') as f: f.write(config) self.base_cfg = copy.deepcopy(self.config) def closeEvent(self, event=None): self.quitApp()
def _makeMenu(self): '''Makes the menu bar for this widget''' # Get the menu bar object self.menu = self.menuBar() self.fileMenu = self.menu.addMenu('&File') # Open action open = QAction('&Open', self) open.setShortcuts(QKeySequence.Open) open.triggered.connect(self.openFromInput) open.setToolTip('Open an already made input file') self.fileMenu.addAction(open) # Save action save = QAction('&Save', self) save.setShortcuts(QKeySequence.Save) save.triggered.connect(self.saveToInput) save.setToolTip('Save settings to an input file') self.fileMenu.addAction(save) # Save action saveas = QAction('Save As', self) saveas.triggered.connect(self.saveToInputAs) save.setToolTip('Save settings to an input file of a new name') self.fileMenu.addAction(saveas) # Save action savepdf = QAction('Save as PDF', self) savepdf.triggered.connect(self.saveAsPDF) save.setToolTip('Save image to a PDF') self.fileMenu.addAction(savepdf) # Menu separator self.fileMenu.addSeparator() # Import action imp = QAction('&Import raw XY data', self) imp.setShortcut(QKeySequence('Ctrl+I')) imp.triggered.connect(self.importRawData) imp.setToolTip('Import raw data an plot alongside calculated data') self.fileMenu.addAction(imp) # Export action raw = QAction('Export raw XY data', self) raw.triggered.connect(self.exportRawData) raw.setToolTip('Export raw data to a file for use elsewhere') self.fileMenu.addAction(raw) # Export action exp = QAction('&Export calculated XY data', self) exp.setShortcut(QKeySequence('Ctrl+E')) exp.triggered.connect(self.exportXYData) exp.setToolTip('Export calculated data to a file for use elsewhere') self.fileMenu.addAction(exp) # Make script action scr = QAction('Make Sc&ript', self) scr.setShortcut(QKeySequence('Ctrl+R')) scr.triggered.connect(self.makeScript) scr.setToolTip('Create a python script that directly recreates this ' 'spectrum') self.fileMenu.addAction(scr) # Menu separator self.fileMenu.addSeparator() # Quit action quit = QAction('&Quit', self) quit.setShortcuts(QKeySequence.Quit) quit.triggered.connect(QApplication.instance().quit) self.fileMenu.addAction(quit)
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.debug = debug self.progset = QSettings("ADLMIDI-pyGUI", "ADLMIDI-pyGUI") self.about_window = None self.settings_window = None self.paused = False self.MaxRecentFiles = int(self.progset.value("file/MaxRecentFiles", 5)) self.recentList = self.progset.value("file/recent", []) if type(self.recentList) is unicode: self.recentList = [self.recentList] self.banks = [ " 0 = AIL (Star Control 3, Albion, Empire 2, Sensible Soccer, Settlers 2, many others)", "01 = Bisqwit (selection of 4op and 2op)", "02 = HMI (Descent, Asterix)", "03 = HMI (Descent:: Int)", "04 = HMI (Descent:: Ham)", "05 = HMI (Descent:: Rick)", "06 = HMI (Descent 2)", "07 = HMI (Normality)", "08 = HMI (Shattered Steel)", "09 = HMI (Theme Park)", "10 = HMI (3d Table Sports, Battle Arena Toshinden)", "11 = HMI (Aces of the Deep)", "12 = HMI (Earthsiege)", "13 = HMI (Anvil of Dawn)", "14 = DMX (Doom :: partially pseudo 4op)", "15 = DMX (Hexen, Heretic :: partially pseudo 4op)", "16 = DMX (MUS Play :: partially pseudo 4op)", "17 = AIL (Discworld, Grandest Fleet, Pocahontas, Slob Zone 3d, Ultima 4, Zorro)", "18 = AIL (Warcraft 2)", "19 = AIL (Syndicate)", "20 = AIL (Guilty, Orion Conspiracy, Terra Nova Strike Force Centauri :: 4op)", "21 = AIL (Magic Carpet 2)", "22 = AIL (Nemesis)", "23 = AIL (Jagged Alliance)", "24 = AIL (When Two Worlds War :: 4op, MISSING INSTRUMENTS)", "25 = AIL (Bards Tale Construction :: MISSING INSTRUMENTS)", "26 = AIL (Return to Zork)", "27 = AIL (Theme Hospital)", "28 = AIL (National Hockey League PA)", "29 = AIL (Inherit The Earth)", "30 = AIL (Inherit The Earth, file two)", "31 = AIL (Little Big Adventure :: 4op)", "32 = AIL (Wreckin Crew)", "33 = AIL (Death Gate)", "34 = AIL (FIFA International Soccer)", "35 = AIL (Starship Invasion)", "36 = AIL (Super Street Fighter 2 :: 4op)", "37 = AIL (Lords of the Realm :: MISSING INSTRUMENTS)", "38 = AIL (SimFarm, SimHealth :: 4op)", "39 = AIL (SimFarm, Settlers, Serf City)", "40 = AIL (Caesar 2 :: partially 4op, MISSING INSTRUMENTS)", "41 = AIL (Syndicate Wars)", "42 = AIL (Bubble Bobble Feat. Rainbow Islands, Z)", "43 = AIL (Warcraft)", "44 = AIL (Terra Nova Strike Force Centuri :: partially 4op)", "45 = AIL (System Shock :: partially 4op)", "46 = AIL (Advanced Civilization)", "47 = AIL (Battle Chess 4000 :: partially 4op, melodic only)", "48 = AIL (Ultimate Soccer Manager :: partially 4op)", "49 = AIL (Air Bucks, Blue And The Gray, America Invades, Terminator 2029)", "50 = AIL (Ultima Underworld 2)", "51 = AIL (Kasparov's Gambit)", "52 = AIL (High Seas Trader :: MISSING INSTRUMENTS)", "53 = AIL (Master of Magic, Master of Orion 2 :: 4op, std percussion)", "54 = AIL (Master of Magic, Master of Orion 2 :: 4op, orchestral percussion)", "55 = SB (Action Soccer)", "56 = SB (3d Cyberpuck :: melodic only)", "57 = SB (Simon the Sorcerer :: melodic only)", "58 = OP3 (The Fat Man 2op set)", "59 = OP3 (The Fat Man 4op set)", "60 = OP3 (JungleVision 2op set :: melodic only)", "61 = OP3 (Wallace 2op set, Nitemare 3D :: melodic only)", "62 = TMB (Duke Nukem 3D)", "63 = TMB (Shadow Warrior)", "64 = DMX (Raptor)" ] self.openicon = QIcon.fromTheme('document-open', QIcon('img/load.png')) self.saveicon = QIcon.fromTheme('document-save', QIcon('img/save.png')) self.playicon = QIcon.fromTheme('media-playback-start', QIcon('img/play.png')) self.pauseicon = QIcon.fromTheme('media-playback-pause', QIcon('img/pause.png')) self.stopicon = QIcon.fromTheme('media-playback-stop', QIcon('img/stop.png')) self.quiticon = QIcon.fromTheme('application-exit', QIcon('img/quit.png')) self.abouticon = QIcon.fromTheme('help-about', QIcon('img/about.png')) self.setticon = QIcon.fromTheme('preferences-desktop', QIcon('img/settings.png')) self.winsetup() def addWorker(self, worker): worker.message.connect(self.update) worker.finished.connect(self.workerFinished) self.threads.append(worker) def workerFinished(self): pass #barf('MSG', 'Thread completed the task!') def killWorkers(self): pass #for worker in self.threads: # worker.terminate() def winsetup(self): self.setWindowIcon(QIcon('img/note.png')) openFile = QAction(self.openicon, 'Open', self) openFile.setShortcut('Ctrl+O') openFile.triggered.connect(self.load) saveFile = QAction(self.saveicon, 'Save', self) saveFile.setShortcut('Ctrl+S') saveFile.triggered.connect(self.save) playFile = QAction(self.playicon, 'Play', self) playFile.setShortcut('Ctrl+P') playFile.triggered.connect(self.play) pausePlayb = QAction(self.pauseicon, 'Pause', self) pausePlayb.setShortcut('Ctrl+R') pausePlayb.triggered.connect(self.pause) stopPlay = QAction(self.stopicon, 'Stop', self) stopPlay.setShortcut('Ctrl+Z') stopPlay.triggered.connect(self.stop) exitAction = QAction(self.quiticon, 'Quit', self) exitAction.setShortcut('Ctrl+X') exitAction.triggered.connect(self.quit) aboutdlg = QAction(self.abouticon, 'About', self) aboutdlg.setShortcut('Ctrl+A') aboutdlg.triggered.connect(self.about) showSett = QAction(self.setticon, 'Settings', self) showSett.triggered.connect(self.settings) menubar = self.menuBar() fileMenu = menubar.addMenu('&File') configMenu = menubar.addMenu('&Options') configMenu.setStyleSheet("border: 1px solid black;") self.setLooped = QAction('Loop', configMenu, checkable=True) if self.progset.value("sound/Looped") == 'true': self.setLooped.setChecked(True) else: self.setLooped.setChecked(False) self.setLooped.setShortcut('Ctrl+L') self.setAutoplay = QAction('Autoplay', configMenu, checkable=True) if self.progset.value("sound/Autoplay") == 'true': self.setAutoplay.setChecked(True) else: self.setAutoplay.setChecked(False) self.setAutoplay.setShortcut('Ctrl+K') configMenu.addAction(self.setAutoplay) configMenu.addAction(self.setLooped) fileMenu.setStyleSheet("border: 1px solid black;") fileMenu.addAction(openFile) fileMenu.addAction(saveFile) fileMenu.addSeparator() self.recentMenu = fileMenu.addMenu('Recent') self.rfUpdate() fileMenu.addSeparator() fileMenu.addAction(showSett) fileMenu.addSeparator() fileMenu.addAction(exitAction) helpMenu = menubar.addMenu('&Help') helpMenu.setStyleSheet("border: 1px solid black;") helpMenu.addAction(aboutdlg) self.numCards = QSpinBox() numCards_text = QLabel(" OPL : ") self.numCards.setRange(1, 100) self.numCards.setValue(int(self.progset.value("sound/numCards", 3))) self.numCards.valueChanged.connect(self.updateMax4ops) self.fourOps = QSpinBox() fourOps_text = QLabel(" 4op Ch : ") self.fourOps.setRange(0, self.numCards.value()*6) self.fourOps.setValue(int(self.progset.value("sound/fourOps", self.numCards.value()*6))) self.twoOps = QSpinBox() twoOps_text = QLabel(" 2op Ch : ") self.twoOps.setValue((self.numCards.value()*12 - self.fourOps.value())) self.twoOps.setRange(self.twoOps.value(), self.twoOps.value()) toolbar = self.addToolBar('Media') toolbar.addAction(playFile) toolbar.addAction(pausePlayb) toolbar.addAction(stopPlay) toolbar.setMovable(False) toolbar.addSeparator() toolbar.addWidget(numCards_text) toolbar.addWidget(self.numCards) toolbar.addSeparator() toolbar.addWidget(fourOps_text) toolbar.addWidget(self.fourOps) #toolbar.addSeparator() #toolbar.addWidget(twoOps_text) #toolbar.addWidget(self.twoOps) self.statusBar() self.setFixedSize(380, 90) self.center() self.setWindowTitle('ADLMIDI pyGUI') self.show() if self.debug: barf("MSG", "Loaded Main Window", True, False) self.update("ready") self.threads = [] self.addWorker(AdlMidi(1)) self.addWorker(AdlMidiSave(2)) def rfUpdate(self): self.recentMenu.clear() def recentfile(f2l): return lambda: self.load2(f2l) self.recentFileActs = [] recentLength = len(self.recentList) for i in range(self.MaxRecentFiles): try: if i >= recentLength: break rev = (recentLength-1)-i filetoload = self.recentList[rev] filename = path.split(filetoload)[1] self.fileact = QAction(filename, self.recentMenu) self.fileact.triggered.connect(recentfile(filetoload)) self.recentFileActs.append(self.fileact) except Exception: pass for i in range(self.MaxRecentFiles): try: self.recentMenu.addAction(self.recentFileActs[i]) except Exception: pass def get_bank(self): try: selection = self.settings_window.combo.currentText() selection = str(selection[0])+str(selection[1]) return int(selection) except Exception: return 1 def center(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) def about(self): if self.about_window is None: window = QMessageBox(self) self.about_window = window else: window = self.about_window window = self.about_window window.setWindowIcon(QIcon(self.abouticon)) window.setWindowTitle('About ADLMIDI pyGUI') credits = "<center><b>ADLMIDI pyGUI v%s (%s)</b><br>Developed by Tristy H. \"KittyTristy\"<br>[<a href=\"https://github.com/KittyTristy/ADLMIDI-pyGUI\">Website</a>] [<a href=\"mailto:[email protected]\">Email</a>] <br><br><br>" % (__version__, system()) title = "<b>ADLMIDI pyGUI</b> is a GUI wrapper<br>written in Python for use with..<br><br><b>ADLMIDI: MIDI Player<br>for Linux and Windows with OPL3 emulation</b><br>" cw = "(C) -- <a href=\"http://iki.fi/bisqwit/source/adlmidi.html\">http://iki.fi/bisqwit/source/adlmidi.html</a></center>" credits = credits + title + cw window.setText(credits) window.show() window.activateWindow() window.raise_() def settings(self): if self.settings_window is None: window = QDialog(self) self.settings_window = window else: window = self.settings_window window = self.settings_window window.setWindowTitle('Settings') window.notelabel = QLabel("Currently these settings are only guaranteed to work prior to loading the first MIDI!\nYou'll have to restart ADLMIDI pyGui to change them again if they stop working. \n\nSorry! This will be fixed soon!") window.notelabel.setWordWrap(True) window.notelabel.setStyleSheet("font-size: 8pt; border-style: dotted; border-width: 1px; padding: 12px;") window.banklabel = QLabel("<B>Choose Instrument Bank</B>") window.space = QLabel("") window.optlabel = QLabel("<B>Options</B>") window.combo = QComboBox() window.combo.addItems(self.banks) #window.combo.setMaximumWidth(350) window.combo.setMaxVisibleItems(12) window.combo.setStyleSheet("combobox-popup: 0;") window.combo.setCurrentIndex(int(self.progset.value("sound/bank", 1))) window.combo.currentIndexChanged.connect(self.saveSettings) window.perc = QCheckBox("Adlib Percussion Instrument Mode") #window.perc.stateChanged.connect(self.checkOpts) window.tremamp = QCheckBox("Tremolo Amplification Mode") #window.tremamp.stateChanged.connect(self.checkOpts) window.vibamp = QCheckBox("Vibrato Amplification Mode") #window.vibamp.stateChanged.connect(self.checkOpts) window.modscale = QCheckBox("Scaling of Modulator Volume") #window.modscale.stateChanged.connect(self.checkOpts) window.okButton = QPushButton('OK') window.okButton.clicked.connect(window.hide) vbox = QVBoxLayout() vbox.addWidget(window.space) vbox.addWidget(window.banklabel) vbox.addWidget(window.combo) vbox.addWidget(window.space) vbox.addWidget(window.optlabel) vbox.addWidget(window.perc) vbox.addWidget(window.tremamp) vbox.addWidget(window.vibamp) vbox.addWidget(window.modscale) vbox.addWidget(window.notelabel) hbox = QHBoxLayout() hbox.addStretch(1) hbox.addWidget(window.okButton) vbox.addLayout(hbox) window.setLayout(vbox) window.setFixedSize(530, 369) window.show() window.activateWindow() window.raise_() def updateMax4ops(self): self.fourOps.setMaximum(self.numCards.value()*6) self.fourOps.setValue(self.numCards.value()*6) barf("DBG", "Updating Maximum of 4ops Chs to %s" % (self.numCards.value()*6), True, False) #self.twoOps.setValue(self.numCards.value()*12 - self.fourOps.value()) #self.twoOps.setRange(self.twoOps.value(), self.twoOps.value()) def checkOpts(self): global arglist #barf("ACT", "Checking if Options have changed..", True, False) arglist = [] try: if QAbstractButton.isChecked(self.settings_window.perc) and not ('-p' in arglist): arglist.append('-p') elif not QAbstractButton.isChecked(self.settings_window.perc) and ('-p' in arglist): arglist.remove('-p') except Exception: pass try: if QAbstractButton.isChecked(self.settings_window.tremamp) and not ('-t' in arglist): arglist.append('-t') elif not QAbstractButton.isChecked(self.settings_window.tremamp) and ('-t' in arglist): arglist.remove('-t') except Exception: pass try: if QAbstractButton.isChecked(self.settings_window.vibamp) and not ('-v' in arglist): arglist.append('-v') elif not QAbstractButton.isChecked(self.settings_window.vibamp) and ('-v' in arglist): arglist.remove('-v') except Exception: pass try: if QAbstractButton.isChecked(self.settings_window.modscale) and not ('-s' in arglist): arglist.append('-s') elif not QAbstractButton.isChecked(self.settings_window.modscale) and ('-s' in arglist): arglist.remove('-s') except Exception: pass self.sel_bank = self.get_bank() def saveSettings(self): self.progset.setValue("sound/Autoplay", self.setAutoplay.isChecked()) self.progset.setValue("sound/Looped", self.setLooped.isChecked()) self.progset.setValue("sound/numCards", self.numCards.value()) self.progset.setValue("sound/fourOps", self.fourOps.value()) try: self.progset.setValue("sound/bank", self.settings_window.combo.currentIndex()) except Exception: pass if len(self.recentList) >= 1: self.progset.setValue("file/recent", self.recentList[-self.MaxRecentFiles:]) self.progset.setValue("file/MaxRecentFiles", self.MaxRecentFiles) #allkeys = self.progset.allKeys() #for key in allkeys: # barf('DBG', str(key) + " " + str(self.progset.value(key))) def closeEvent(self, event): self.stop() #self.pkill() self.saveSettings() barf("DBG", "Quitting", True, False) def quit(self): self.stop() #self.pkill() self.saveSettings() barf("DBG", "Quitting", True, False) exit(0) def pkill(self): try: p.kill() except Exception: pass ############################################################## ##### Statusbar Functions #################################### ############################################################## def clear(self): try: self.statusBar().removeWidget(self.playStatus) except Exception: pass @Slot(str) def update(self, status=''): self.clear() if status == "ready": text = " <B>Ready</b>" elif status == "play": text = " <B>Now Playing: </B>" + path.split(f.name)[1] elif status == "loop": text = " <B>Looping: </B>" + path.split(f.name)[1] elif status == "stop": text = " <B>Stopped: </B>" + path.split(f.name)[1] elif status == "pause": text = " <B>Paused: </B>" + path.split(f.name)[1] elif status == "loading": text = " <B>Loading.. </B>" elif status == "load": text = " <B>Loaded: </B>" + path.split(f.name)[1] elif status == "saving": text = " <B>Saving.. </B>" elif status == "saved": text = " <B>Saved as: </B>" + "saved/" + path.splitext(path.split(f.name)[1])[0] + ".wav" self.playStatus = QLabel(text) self.statusBar().addPermanentWidget(self.playStatus, 1) ############################################################## ####### Sound Functions ###################################### ############################################################## def play(self): global Paused, arglist if f != None and Paused == False: Paused = False self.stop() self.checkOpts() if not self.setLooped.isChecked(): arglist.append('-nl') arglist.append(str(self.progset.value("sound/bank", 1))) arglist.append(str(self.numCards.value())) arglist.append(str(self.fourOps.value())) for worker in self.threads: if worker.id == 1: worker.start() elif f != None and Paused == True: os.kill(p.pid, signal.SIGCONT) self.update("play") Paused = False def pause(self): global p, Paused if f != None: try: if Paused == False: os.kill(p.pid, signal.SIGSTOP) self.update("pause") Paused = True elif Paused == True: os.kill(p.pid, signal.SIGCONT) self.update("play") Paused = False except Exception: pass def stop(self): global Paused if f != None: Paused = False self.pkill() self.killWorkers() self.update("stop") ############################################################## ##### Load/Save Functions #################################### ############################################################## def load(self): global f lastdir = str(self.progset.value("file/lastdir", "")) fname, _ = QFileDialog.getOpenFileName(None, 'Open File', lastdir, "MIDI Audio File (*.mid *.MID)") if fname != "": f = file(fname, 'r') if not f.name in self.recentList: self.recentList.append(f.name) else: self.recentList.remove(f.name) self.recentList.append(f.name) self.progset.setValue("file/lastdir", path.split(f.name)[0]) self.rfUpdate() self.update("load") self.pkill() if self.debug: barf("SAV", "Loaded %s" % path.split(f.name)[1], True, False) if self.setAutoplay.isChecked(): self.play() else: self.update("load") def load2(self, r_file=None): global f f = file(r_file, 'r') self.recentList.remove(f.name) self.recentList.append(f.name) self.rfUpdate() self.update("load") self.pkill() if self.debug: barf("SAV", "Loaded %s" % path.split(f.name)[1], True, False) if self.setAutoplay.isChecked(): self.play() else: self.update("load") def save(self): if f != None: self.stop() for worker in self.threads: if worker.id == 2: worker.start()
class PresenceOverviewWidget(HorsePanel): @Slot(QModelIndex) def cell_entered(self, ndx): employee_id = self._employee_id_on_row(ndx) if not employee_id: self._show_totals_day_off(None) elif employee_id: chrono.chrono_start() employee = None for i in self.employees: if i.employee_id == employee_id: employee = i break self.detail_subframe.set_title(employee.fullname) self._show_totals_day_off(employee_id) d = date( self.base_date.year, self.base_date.month, min( calendar.monthrange(self.base_date.year, self.base_date.month)[1], max(1, ndx.column()))) chrono.chrono_click("Retrieveing data") tars = dao.task_action_report_dao.get_reports_for_employee_id_on_date( employee_id, d) work_timetracks = dao.timetrack_dao.all_work_for_employee_date_manual( employee_id, d) presence_timetracks = dao.timetrack_dao.all_presence_for_employee_date_managed_by_code_full( employee_id, d) # employee = dao.employee_dao.find_by_id(employee_id) special_activities = dao.special_activity_dao.find_on_day( employee_id, d) chrono.chrono_click("Redrawing") self.time_report_view.redraw(datetime(d.year, d.month, d.day, 6, 0), tars, employee_id, work_timetracks, presence_timetracks, special_activities, view_title=_("Work on {}").format( date_to_dmy(d, full_month=True))) session().close( ) # FIXME Put his one line above; but that's tough ! SQLA doesn't help us much here ! chrono.chrono_click("Session closed") # for event_type, duration in self.day_event_totals[employee_id].items(): # mainlog.debug("{}{}".format(event_type, duration)) self._toggle_days_off_actions() def _employee_id_on_row(self, row_or_ndx): r = row_or_ndx if type(r) != int: r = row_or_ndx.row() return self._table_model.data(self._table_model.index(r, 0), Qt.UserRole) DAY_EVENT_PALETTE = { DayEventType.holidays: (Qt.GlobalColor.white, Qt.GlobalColor.red), DayEventType.day_off: (Qt.GlobalColor.white, Qt.GlobalColor.darkRed), DayEventType.unpaid_day_off: (Qt.GlobalColor.black, Qt.GlobalColor.magenta), DayEventType.free_day: (Qt.GlobalColor.white, Qt.GlobalColor.darkMagenta), DayEventType.overtime: (Qt.GlobalColor.black, Qt.GlobalColor.green), DayEventType.recuperation: (Qt.GlobalColor.white, Qt.GlobalColor.darkGreen), DayEventType.unemployment: (Qt.GlobalColor.white, Qt.GlobalColor.blue), DayEventType.unemployment_short: (Qt.GlobalColor.white, Qt.GlobalColor.darkBlue), DayEventType.work_accident: (Qt.GlobalColor.black, Qt.GlobalColor.yellow), DayEventType.sick_leave: (Qt.GlobalColor.white, Qt.GlobalColor.darkYellow) } MONTH_EVENT_COLUMN = 2 YEAR_EVENT_COLUMN = 3 def _make_total_days_off_panel(self): widget = QFrame() widget.setObjectName('HorseRegularFrame') widget.setFrameShape(QFrame.Panel) widget.setFrameShadow(QFrame.Sunken) layout = QVBoxLayout() #layout.addWidget(QLabel(_("Days off to date"))) self.day_off_total_duration_labels = dict() self.day_off_month_duration_labels = dict() self.day_off_labels = dict() self._day_off_table_model = QStandardItemModel(10, 3) self._day_off_table_model.setHorizontalHeaderLabels( [None, None, _("This\nmonth"), _("Before")]) self.day_off_table_view = QTableView(None) self.day_off_table_view.setModel(self._day_off_table_model) # self.day_off_table_view.setHorizontalHeader(self.headers_view) self.day_off_table_view.verticalHeader().hide() self.day_off_table_view.setAlternatingRowColors(True) self.day_off_table_view.setEditTriggers( QAbstractItemView.NoEditTriggers) self.day_off_table_view.hide() row = 0 for det in DayEventType.symbols(): ndx = self._day_off_table_model.index(row, 0) self._day_off_table_model.setData(ndx, det.description, Qt.DisplayRole) ndx = self._day_off_table_model.index(row, 1) fg, bg = self.DAY_EVENT_PALETTE[det] self._day_off_table_model.setData(ndx, QBrush(bg), Qt.BackgroundRole) self._day_off_table_model.setData(ndx, QBrush(fg), Qt.TextColorRole) self._day_off_table_model.setData(ndx, DayEventType.short_code(det), Qt.DisplayRole) row += 1 layout.addWidget(self.day_off_table_view) grid = QGridLayout() self.days_off_layout = grid grid.setColumnStretch(3, 1) row = 0 grid.addWidget(QLabel(_('Year')), row, self.YEAR_EVENT_COLUMN) grid.addWidget(QLabel(_('Month')), row, self.MONTH_EVENT_COLUMN) row += 1 for det in DayEventType.symbols(): self.day_off_total_duration_labels[det] = QLabel("-") self.day_off_month_duration_labels[det] = QLabel("-") self.day_off_labels[det] = QLabel(det.description) hlayout = QHBoxLayout() sl = QLabel() fg, bg = self.DAY_EVENT_PALETTE[det] def to_html_rgb(color): i = color.red() * 256 * 256 + color.green() * 256 + color.blue( ) return "#{:06X}".format(i) p = QPalette() p.setColor(QPalette.Window, QColor(bg)) p.setColor(QPalette.WindowText, QColor(fg)) sl.setPalette(p) sl.setAlignment(Qt.AlignCenter) sl.setStyleSheet("border: 2px solid black; background: {}".format( to_html_rgb(QColor(bg)))) t = DayEventType.short_code(det) mainlog.debug(t) sl.setAutoFillBackground(True) sl.setText(t) grid.addWidget(sl, row, 0) grid.addWidget(self.day_off_labels[det], row, 1) grid.addWidget(self.day_off_total_duration_labels[det], row, self.YEAR_EVENT_COLUMN) grid.addWidget(self.day_off_month_duration_labels[det], row, self.MONTH_EVENT_COLUMN) hlayout.addStretch() row += 1 layout.addLayout(grid) layout.addStretch() self.day_off_table_view.resizeColumnsToContents() # self.day_off_table_view.setMinimumWidth( self.day_off_table_view.width()) # self.day_off_table_view.resize( self.day_off_table_view.minimumWidth(), # self.day_off_table_view.minimumHeight(),) widget.setLayout(layout) return widget def _show_totals_day_off(self, employee_id): mainlog.debug("_show_totals_day_off : {}".format(employee_id)) def form_layout_row_set_visible(layout, row_ndx, is_visible): for i in range(layout.columnCount()): l = layout.itemAtPosition(row_ndx, i) if l and l.widget(): l.widget().setVisible(is_visible) det_to_show = dict() row = 0 for det in DayEventType.symbols(): yearly = 0 if employee_id in self.all_events_in_year: if det in self.all_events_in_year[employee_id]: yearly = nice_round( self.all_events_in_year[employee_id][det]) monthly = 0 if employee_id in self.day_event_totals: if det in self.day_event_totals[employee_id]: monthly = nice_round( self.day_event_totals[employee_id][det]) # ndx = self._day_off_table_model.index(row,self.YEAR_EVENT_COLUMN) # self._day_off_table_model.setData(ndx, v, Qt.DisplayRole) if yearly or monthly: det_to_show[det] = {'monthly': monthly, 'yearly': yearly} if det_to_show: # If there are some days spent on some counters, then we display # those counters *only* mainlog.debug("_show_totals_day_off : showing some events ".format( str(det_to_show))) row = 0 for det in DayEventType.symbols(): if det in det_to_show: monthly = det_to_show[det]['monthly'] yearly = det_to_show[det]['yearly'] form_layout_row_set_visible(self.days_off_layout, row + 1, True) self.day_off_total_duration_labels[det].setText(yearly or '-') self.day_off_month_duration_labels[det].setText(monthly or '-') else: form_layout_row_set_visible(self.days_off_layout, row + 1, False) else: # If there are no days spent on any counter, then we display # all counters at the 0 mark. mainlog.debug("_show_totals_day_off : showing no event") row = 0 for det in DayEventType.symbols(): form_layout_row_set_visible(self.days_off_layout, row + 1, True) row += 1 # self.day_off_table_view.resizeColumnsToContents() self.days_off_panel.parent().update() @Slot() def refresh_action(self): global dao # mainlog.debug("refresh action started") self.hours_per_pers_subframe.set_title(date_to_my( self.base_date, True)) chrono.chrono_start() all_events_in_month = people_admin_service.events_for_month( self.base_date) employee_with_events = [ event.employee_id for event in all_events_in_month ] # mainlog.debug(all_events_in_month) self.all_events_in_year = people_admin_service.events_for_year( self.base_date.year) self.all_presences = all_presences = dao.employee_dao.presence_overview_for_month( self.base_date) all_correction_times = dict() for s in dao.month_time_synthesis_dao.load_all_synthesis( self.base_date.year, self.base_date.month): all_correction_times[s.employee_id] = s.correction_time special_activities = dao.special_activity_dao.find_on_month( self.base_date) employees = list( filter( lambda e: e.is_active or e.employee_id in all_presences or e. employee_id in all_correction_times or e.employee_id in special_activities or e.employee_id in employee_with_events, dao.employee_dao.list_overview())) self.employees = employees chrono.chrono_click() day_max = calendar.monthrange(self.base_date.year, self.base_date.month)[1] t_start = datetime(self.base_date.year, self.base_date.month, 1) t_end = datetime(self.base_date.year, self.base_date.month, day_max, 23, 59, 59, 999999) self._table_model.setRowCount(len(employees)) self._table_model.setColumnCount(1 + day_max + 3) headers = QStandardItemModel(1, 1 + day_max + 3) headers.setHeaderData(0, Qt.Orientation.Horizontal, _("Employee")) for i in range(day_max): headers.setHeaderData(i + 1, Qt.Orientation.Horizontal, "{}".format(i + 1)) headers.setHeaderData(day_max + 1, Qt.Orientation.Horizontal, _("Correction")) headers.setHeaderData(day_max + 2, Qt.Orientation.Horizontal, _("Total")) headers.setHeaderData(day_max + 3, Qt.Orientation.Horizontal, _("Days off")) self.headers_view.setModel( headers) # qt's doc : The view does *not* take ownership self.header_model = headers self.headers_view.setModel( self.header_model) # qt's doc : The view does *not* take ownership # Compute all mondays indices monday = 0 if t_start.weekday() > 0: monday = 7 - t_start.weekday() all_mondays = [] while monday < day_max: all_mondays.append(monday) monday += 7 today = date.today() # mainlog.debug("Running on employees") for row in range(self._table_model.rowCount()): # Clear the line for col in range(0, 32): ndx = self._table_model.index(row, col) self._table_model.setData(ndx, None, Qt.BackgroundRole) self._table_model.setData(ndx, QBrush(Qt.GlobalColor.black), Qt.TextColorRole) self._table_model.setData(ndx, None, Qt.DisplayRole) self._table_model.setData(ndx, None, Qt.UserRole) self._table_model.setData(ndx, None, Qt.UserRole + 1) # else: # self._table_model.setData(ndx,None,Qt.BackgroundRole) # else: # self._table_model.setData(ndx,None,Qt.DisplayRole) # self._table_model.setData(ndx,None,Qt.BackgroundRole) # Mark mondays for col in all_mondays: # col + 1 to account for the employee column self._table_model.setData( self._table_model.index(row, col + 1), QBrush(QColor(230, 230, 255)), Qt.BackgroundRole) # Mark today if today.month == self.base_date.month and today.year == self.base_date.year: self._table_model.setData( self._table_model.index(row, today.day), QBrush(QColor(255, 255, 128)), Qt.BackgroundRole) row = 0 for employee in employees: # employees are sorted self._table_model.setData(self._table_model.index(row, 0), employee.fullname, Qt.DisplayRole) # FIXME Use a delegate self._table_model.setData(self._table_model.index(row, 0), employee.employee_id, Qt.UserRole) # FIXME Use a delegate correction = 0 if employee.employee_id in all_correction_times: correction = all_correction_times[employee.employee_id] self._table_model.setData( self._table_model.index(row, day_max + 1), duration_to_hm(correction, short_unit=True), Qt.DisplayRole) else: self._table_model.setData( self._table_model.index(row, day_max + 1), None, Qt.DisplayRole) presence = 0 if employee.employee_id in all_presences and len( all_presences[employee.employee_id]) > 0: import functools presence = functools.reduce( lambda acc, s: acc + s, all_presences[employee.employee_id], 0) presence += correction if presence != 0: self._table_model.setData(ndx, QBrush(Qt.GlobalColor.black), Qt.TextColorRole) self._table_model.setData( self._table_model.index(row, day_max + 2), duration_to_hm(presence, short_unit=True), Qt.DisplayRole) else: self._table_model.setData( self._table_model.index(row, day_max + 2), None, Qt.DisplayRole) if employee.employee_id in all_presences and len( all_presences[employee.employee_id]) > 0: for b in range(len(all_presences[employee.employee_id])): ndx = self._table_model.index(row, b + 1) p = all_presences[employee.employee_id][b] if p > 0: self._table_model.setData( ndx, duration_to_hm(p, short_unit=True), Qt.DisplayRole) self._table_model.setData(ndx, p, Qt.UserRole) if p >= 4 and p <= 8: # Regular work load self._table_model.setData( ndx, QBrush(QColor(192, 255, 192)), Qt.BackgroundRole) elif p > 8 or (p < 4 and p > 0): # Problematic work load self._table_model.setData( ndx, QBrush(QColor(255, 192, 192)), Qt.BackgroundRole) if employee.employee_id in special_activities: sa_of_employee = special_activities[employee.employee_id] for sa in sa_of_employee: start = max(t_start, sa.start_time) end = min(t_end, sa.end_time) for i in range(start.day, end.day + 1): ndx = self._table_model.index(row, i) self._table_model.setData(ndx, QBrush(QColor(255, 128, 0)), Qt.BackgroundRole) # self._table_model.setData(self._table_model.index(row,b+1),Qt.AlignRight | Qt.AlignVCenter,Qt.TextAlignmentRole) row += 1 # Display day events employee_id_to_row = dict() # little accelerator for row in range(len(employees)): employee_id_to_row[employees[row].employee_id] = row # Compute days off totals and show them self.day_event_totals = dict([(e.employee_id, dict()) for e in employees]) for day_event in all_events_in_month: # mainlog.debug("employee_id = {}".format(day_event.employee_id)) # if day_event.employee_id not in self.day_event_totals: # mainlog.debug(self.day_event_totals) t = self.day_event_totals[day_event.employee_id] if day_event.event_type not in t: t[day_event.event_type] = day_event.duration else: t[day_event.event_type] += day_event.duration for employee in employees: # employees are sorted t = self.day_event_totals[employee.employee_id] mainlog.debug(t) total_off = sum(t.values()) mainlog.debug(total_off) row = employee_id_to_row[employee.employee_id] mainlog.debug(row) if total_off: self._table_model.setData( self._table_model.index(row, day_max + 3), nice_round(total_off), Qt.DisplayRole) else: self._table_model.setData( self._table_model.index(row, day_max + 3), None, Qt.DisplayRole) # Show days off for day_event in all_events_in_month: row = employee_id_to_row[day_event.employee_id] col = day_event.date.day fg = bg = None if day_event.event_type in self.DAY_EVENT_PALETTE: fg, bg = self.DAY_EVENT_PALETTE[day_event.event_type] else: fg, bg = Qt.GlobalColor.red, Qt.GlobalColor.gray ndx = self._table_model.index(row, col) self._table_model.setData(ndx, day_event.day_event_id, Qt.UserRole + 1) # The problem here is to nicely blend the fact # that you can have a day event mixed with actual work # the very same day. Here's a poor man solution. active_time = self._table_model.data(ndx, Qt.UserRole) if not active_time: self._table_model.setData( ndx, DayEventType.short_code(day_event.event_type), Qt.DisplayRole) self._table_model.setData(ndx, QBrush(fg), Qt.TextColorRole) self._table_model.setData(ndx, QBrush(bg), Qt.BackgroundRole) else: self._table_model.setData(ndx, QBrush(fg), Qt.TextColorRole) self._table_model.setData(ndx, QBrush(bg), Qt.BackgroundRole) self._table_model.setData( ndx, duration_to_hm(active_time, short_unit=True) + DayEventType.short_code(day_event.event_type), Qt.DisplayRole) chrono.chrono_click() #for i in range(len(all_mondays)): self.table_view.resizeColumnsToContents() # mainlog.debug("Reset selection") ndx = self.table_view.currentIndex() self.table_view.selectionModel().clear() # self.table_view.selectionModel().clearSelection() # self.table_view.selectionModel().select( self.table_view.model().index(ndx.row(),ndx.column()), QItemSelectionModel.Select) # self.table_view.selectionModel().select( self.table_view.model().index(ndx.row(),ndx.column()), QItemSelectionModel.Select) self.table_view.selectionModel().setCurrentIndex( self.table_view.model().index(ndx.row(), ndx.column()), QItemSelectionModel.Select) self.cell_entered(self.table_view.currentIndex()) @Slot() def edit_tars(self): employee_id = self._employee_id_on_row(self.table_view.currentIndex()) d = date( self.base_date.year, self.base_date.month, min( calendar.monthrange(self.base_date.year, self.base_date.month)[1], max(1, ndx.column()))) dialog = TimeReportingScannerDialog(self) dialog.set_data(datetime(d.year, d.month, d.day, 6, 0), employee_id) dialog.exec_() if dialog.result() == QDialog.Accepted: # pub.sendMessage('time_report.changed') self.timetrack_changed.emit() self.refresh_action() @Slot() def show_actions(self): button = self.action_menu.parent() p = button.mapToGlobal(QPoint(0, button.height())) self.action_menu.exec_(p) @Slot() def delete_holidays(self): ndx = self.table_view.currentIndex() employee_id = self._employee_id_on_row(ndx) d = date(self.base_date.year, self.base_date.month, ndx.column()) if dao.special_activity_dao.delete_by_employee_and_date( employee_id, d): self.refresh_panel() @Slot() def create_holidays(self): employee_id = self._employee_id_on_row(self.table_view.currentIndex()) left_col = 1000 right_col = 0 for ndx in self.table_view.selectionModel().selectedIndexes(): c = ndx.column() left_col = min(c, left_col) right_col = max(c, right_col) d_start = date( self.base_date.year, self.base_date.month, min( calendar.monthrange(self.base_date.year, self.base_date.month)[1], max(1, left_col))) d_end = date( self.base_date.year, self.base_date.month, min( calendar.monthrange(self.base_date.year, self.base_date.month)[1], max(1, right_col))) dialog = HolidaysDialog(self) sa = SpecialActivity() sa.employee_id = employee_id sa.reporter_id = user_session.user_id sa.encoding_date = date.today() sa.start_time = datetime(d_start.year, d_start.month, d_start.day, 6, 0) sa.end_time = datetime(d_end.year, d_end.month, d_end.day, 14, 0) dialog.setup(sa, dao.employee_dao.find_by_id(employee_id).fullname) # dialog.set_data(employee,self.base_date,c) dialog.exec_() if dialog.result() == QDialog.Accepted: dao.special_activity_dao.save(sa) self.refresh_action() @Slot() def edit_month_correction(self): employee_id = self._employee_id_on_row(self.table_view.currentIndex()) if employee_id: employee = dao.employee_dao.find_by_id(employee_id) c = dao.month_time_synthesis_dao.load_correction_time( employee_id, self.base_date.year, self.base_date.month) dialog = MonthTimeCorrectionDialog(self) dialog.set_data(employee.fullname, self.base_date, c) dialog.exec_() if dialog.result() == QDialog.Accepted: c = dao.month_time_synthesis_dao.save(employee_id, self.base_date.year, self.base_date.month, dialog.correction_time) self.refresh_action() @Slot() def month_today(self): self.base_date = date.today() self.refresh_action() @Slot() def month_before(self): m = self.base_date.month if m > 1: self.base_date = date(self.base_date.year, m - 1, 1) else: self.base_date = date(self.base_date.year - 1, 12, 1) self.refresh_action() @Slot() def month_after(self): m = self.base_date.month if self.base_date.year < date.today().year + 1 \ or m < date.today().month: if m < 12: self.base_date = date(self.base_date.year, m + 1, 1) else: self.base_date = date(self.base_date.year + 1, 1, 1) self.refresh_action() @Slot() def edit_timetrack_no_ndx(self): ndx = self.table_view.currentIndex() if ndx.isValid() and ndx.column() >= 0 and ndx.row() >= 0: self.edit_timetrack(ndx) else: showWarningBox(_("Can't edit"), _("You must first select a day/person.")) timetrack_changed = Signal() @Slot(QModelIndex) def edit_timetrack(self, ndx): global dao global user_session if ndx.column() >= 1: edit_date = date( self.base_date.year, self.base_date.month, ndx.column()) # +1 already in because of employee's names employee_id = self._employee_id_on_row(ndx) tars = dao.task_action_report_dao.get_reports_for_employee_id_on_date( employee_id, edit_date) if len(tars) == 0: d = EditTimeTracksDialog(self, dao, edit_date) d.set_employee_and_date(employee_id, edit_date) d.exec_() if d.result() == QDialog.Accepted: self.refresh_action() self.timetrack_changed.emit() d.deleteLater() else: edit_date = datetime(self.base_date.year, self.base_date.month, ndx.column(), hour=6) from koi.TimeReportingScanner import TimeReportingScannerDialog d = TimeReportingScannerDialog(self) d.set_data(edit_date, employee_id) # or 16 d.exec_() if d.result() == QDialog.Accepted: self.refresh_action() self.timetrack_changed.emit() d.deleteLater() @Slot() def editTaskActionReports(self): if not user_session.has_any_roles(['TimeTrackModify']): return m = self.base_date.month ndx = self.table_view.currentIndex() if ndx.isValid() and ndx.column() >= 0 and ndx.row() >= 0: edit_date = date( self.base_date.year, m, ndx.column()) # +1 already in because of employee's names employee = self._table_model.data( self._table_model.index(ndx.row(), 0), Qt.UserRole) # FIXME Use a delegate d = EditTaskActionReportsDialog(dao, self, edit_date) d.set_employee_date(employee, edit_date) d.exec_() if d.result() == QDialog.Accepted: self.refresh_action() d.deleteLater() else: showWarningBox(_("Can't edit"), _("You must first select a day/person.")) # @Slot(QModelIndex) # def timetrack_changed(self,ndx): # selected_timetrack = self.controller.model.object_at(ndx) # # Update the colors in the timetrack views # # to show what action reports correspond to the # # selected timetrack # self.controller_actions.model.current_timetrack = selected_timetrack # self.controller_actions.model.beginResetModel() # self.controller_actions.model.endResetModel() # # Make sure the first of the action reports is shown in the # # table # action_reports = self.controller_actions.model.objects # for i in range(len(action_reports)-1,-1,-1): # if action_reports[i] and action_reports[i].timetrack == selected_timetrack: # self.controller_actions.view.scrollTo(self.controller_actions.model.index(i,0)) # break def _make_table_header(self): pass def __init__(self, parent, find_order_action_slot): super(PresenceOverviewWidget, self).__init__(parent) self.set_panel_title(_("Presence overview")) self.base_date = date.today() headers = QStandardItemModel(1, 31 + 3) self._table_model = QStandardItemModel(1, 31 + 3, None) self.headers_view = QHeaderView(Qt.Orientation.Horizontal, self) self.header_model = headers self.headers_view.setResizeMode(QHeaderView.ResizeToContents) self.headers_view.setModel( self.header_model) # qt's doc : The view does *not* take ownership self.table_view = TableViewSignaledEvents(None) self.table_view.setModel(self._table_model) self.table_view.setHorizontalHeader(self.headers_view) self.table_view.verticalHeader().hide() self.table_view.setAlternatingRowColors(True) self.table_view.setEditTriggers(QAbstractItemView.NoEditTriggers) self.table_view.setContextMenuPolicy(Qt.CustomContextMenu) self.table_view.customContextMenuRequested.connect( self.popup_context_menu) self.copy_action = QAction(_("Copy order parts"), self.table_view) self.copy_action.triggered.connect(self.copy_slot) self.copy_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_C)) self.copy_action.setShortcutContext(Qt.WidgetWithChildrenShortcut) self.table_view.addAction(self.copy_action) self.select_all_action = QAction(_("Select all"), self.table_view) self.select_all_action.triggered.connect(self.select_all_slot) self.select_all_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_A)) self.select_all_action.setShortcutContext( Qt.WidgetWithChildrenShortcut) self.table_view.addAction(self.select_all_action) # self.table_view.setSelectionBehavior(QAbstractItemView.SelectItems) # self.table_view.setSelectionMode(QAbstractItemView.SingleSelection) navbar = NavBar(self, [(_("Month before"), self.month_before), (_("Today"), self.month_today), (_("Action"), self.show_actions), (_("Month after"), self.month_after), (_("Find"), find_order_action_slot)]) self.action_menu = QMenu(navbar.buttons[2]) navbar.buttons[2].setObjectName("specialMenuButton") navbar.buttons[4].setObjectName("specialMenuButton") self._make_days_off_menu_and_action_group() list_actions = [ # (_("Edit"),self.edit_tars, None, None), (_("Edit"), self.edit_timetrack_no_ndx, None, None), (_("Month correction"), self.edit_month_correction, None, [RoleType.modify_monthly_time_track_correction]), (self.days_off_menu, None), (self.copy_action, None), (self.select_all_action, None) ] # (_("Insert holidays"),self.create_holidays, None, None), # (_("Delete holidays"),self.delete_holidays, None, None) ] populate_menu(self.action_menu, self, list_actions) # mainlog.debug("tile widget") self.title_box = TitleWidget(_("Presence Overview"), self, navbar) self.vlayout = QVBoxLayout(self) self.vlayout.setObjectName("Vlayout") self.vlayout.addWidget(self.title_box) self.hours_per_pers_subframe = SubFrame(_("Overview"), self.table_view, self) self.vlayout.addWidget(self.hours_per_pers_subframe) self.time_report_view = TimeReportView(self) self.days_off_panel = self._make_total_days_off_panel() vbox = QVBoxLayout() vbox.addWidget(self.days_off_panel) vbox.addStretch() vbox.setStretch(0, 0) vbox.setStretch(1, 1) hlayout = QHBoxLayout() hlayout.addWidget(self.time_report_view) hlayout.addLayout(vbox) hlayout.setStretch(0, 1) self.detail_subframe = SubFrame(_("Day"), hlayout, self) self.vlayout.addWidget(self.detail_subframe) self.setLayout(self.vlayout) # dbox = QVBoxLayout() # dbox.addWidget(QLabel("kjkljkj")) # self.total_active_hours = LabeledValue(_("Total activity")) # dbox.addWidget(self.total_active_hours) # hbox = QHBoxLayout() # hbox.addWidget(self.table_view) # hbox.addLayout(dbox) # self.selection_model = self.table_view.selectionModel() # mainlog.debug(m) #sm = QItemSelectionModel(self.table_view.model()) #sm.setModel(self.table_view.model()) # self.table_view.setSelectionModel(self.selection_model) self.table_view.selectionModel().currentChanged.connect( self.cell_entered) self.table_view.doubleClickedCell.connect(self.edit_timetrack) def _selection_to_period(self): left_col = 1000 right_col = 0 for ndx in self.table_view.selectionModel().selectedIndexes(): c = ndx.column() left_col = min(c, left_col) right_col = max(c, right_col) d_start = date( self.base_date.year, self.base_date.month, min( calendar.monthrange(self.base_date.year, self.base_date.month)[1], max(1, left_col))) d_end = date( self.base_date.year, self.base_date.month, min( calendar.monthrange(self.base_date.year, self.base_date.month)[1], max(1, right_col))) return d_start, d_end def _toggle_days_off_actions(self): day_max = calendar.monthrange(self.base_date.year, self.base_date.month)[1] ndx = self.table_view.currentIndex() can_add = can_remove = False if ndx.column() >= 1 and ndx.column() <= day_max: day_event_id = ndx.data(Qt.UserRole + 1) can_add = True # if not day_event_id: # day = ndx.column() - 1 # # employee_id = self._employee_id_on_row(ndx) # if employee_id in self.all_presences: # if not self.all_presences[employee_id][day]: # can_add = True # else: # can_add = True # else: # can_add = True can_remove = day_event_id is not None self.days_off_add_submenu.setEnabled(can_add) for actions in self.days_off_action_group.actions(): actions.setEnabled(can_add) self.day_off_remove_action.setEnabled(can_remove) def _add_day_off(self, action): if action.data() != 'Remove': day_event_type, day_event_duration = action.data() day_event_type = DayEventType.from_str(day_event_type) mainlog.debug("selected action {} {}".format( day_event_type, day_event_duration)) ndx = self.table_view.currentIndex() day_event_id = ndx.data(Qt.UserRole + 1) # if day_event_id: # showWarningBox(_("There's already a day off here")) # return employee_id = self._employee_id_on_row(ndx) if employee_id in self.all_presences: day = ndx.column() - 1 mainlog.debug("_add_day_off : employee_id={}, day={}".format( employee_id, day)) mainlog.debug(self.all_presences[employee_id]) mainlog.debug(type(self.all_presences[employee_id])) # if self.all_presences[employee_id][day]: # showWarningBox(_("One can't add day off where there is activity")) # return else: mainlog.debug( "_add_day_off : employee_id={} not yet known".format( employee_id)) day_event = DayEvent() day_event.employee_id = employee_id day_event.event_type = day_event_type day, last_day = self._selection_to_period() if day_event_duration in (0.5, 1): days_durations = [(day, day_event_duration)] else: days_durations = [] day, last_day = self._selection_to_period() while day <= last_day: days_durations.append( (day, 1)) # One full work day on the day day += timedelta(1) # mainlog.debug(days_durations) mainlog.debug("Creating day event of type {}".format( day_event.event_type)) try: people_admin_service.set_event_on_days(day_event, days_durations) except ServerException as ex: showErrorBox(ex.translated_message) self.refresh_action() def _remove_day_off(self): # Grab all the selected events event_ids = [] for ndx in self.table_view.selectionModel().selectedIndexes(): day_event_id = ndx.data(Qt.UserRole + 1) if day_event_id: mainlog.debug("Removing event: {}".format(day_event_id)) event_ids.append(day_event_id) # Remove them if event_ids: people_admin_service.remove_events(event_ids) self.refresh_action() def _make_days_off_menu_and_action_group(self): # We use a action group to be able to use the data() of actions # when action is tigerred # Call this ONLY ONCE because there are signal/slot connections. self.days_off_menu = QMenu(_("Day off")) self.days_off_add_submenu = QMenu(_("Set day off")) self.days_off_action_group = QActionGroup(self) for det in DayEventType.symbols(): a_one = QAction(_("Set one day"), self.days_off_action_group) a_one.setData((det.value, 1)) a_half = QAction(_("Set half day"), self.days_off_action_group) a_half.setData((det.value, 0.5)) a_period = QAction(_("Set period"), self.days_off_action_group) a_period.setData((det.value, 2)) self.days_off_action_group.addAction(a_one) self.days_off_action_group.addAction(a_half) self.days_off_action_group.addAction(a_period) m = QMenu(_("Set time off for {}").format(det.description)) m.addAction(a_one) m.addAction(a_half) m.addAction(a_period) self.days_off_add_submenu.addMenu(m) self.days_off_action_group.triggered.connect(self._add_day_off) self.day_off_remove_action = QAction(_("Remove day off"), self) self.day_off_remove_action.triggered.connect(self._remove_day_off) # Now we have the actions, we build the menu self.days_off_menu.addMenu(self.days_off_add_submenu) self.days_off_menu.addAction(self.day_off_remove_action) @Slot(QPoint) def popup_context_menu(self, position): self.days_off_menu.exec_(QCursor.pos()) @Slot() def select_all_slot(self): m = self.table_view.model() all = QItemSelection(m.index(0, 0), m.index(m.rowCount() - 1, m.columnCount() - 1)) self.table_view.selectionModel().select(all, QItemSelectionModel.Select) @Slot() def copy_slot(self): # Collect the rows indices indices = self.table_view.selectedIndexes() if not indices: return min_row = max_row = indices[0].row() min_col = max_col = indices[0].column() def min_max(minimum, v, maximum): if v < minimum: return v, maximum elif v > maximum: return minimum, v else: return minimum, maximum for ndx in self.table_view.selectedIndexes(): min_row, max_row = min_max(min_row, ndx.row(), max_row) min_col, max_col = min_max(min_col, ndx.column(), max_col) mainlog.debug("Copy from {},{} to {},{}".format( min_row, min_col, max_row, max_col)) day_max = calendar.monthrange(self.base_date.year, self.base_date.month)[1] s = "" for r in range(min_row, max_row + 1): d = [] for c in range(min_col, max_col + 1): ndx = self._table_model.item(r, c) if c == 0 or c > day_max: d.append(ndx.data(Qt.DisplayRole) or "") else: t = ndx.data(Qt.UserRole + 1) # Day off if t: t = ndx.data(Qt.DisplayRole) else: hours = ndx.data(Qt.UserRole) # Activity hours if hours is not None: t = str(hours).replace('.', ',') else: t = "" d.append(t) s += "\t".join(d) + u"\n" QApplication.clipboard().setText(s)