Beispiel #1
0
 def contextMenuEvent(self, evt):
     """
     Protected method handling context menu events.
     
     @param evt reference to the context menu event (QContextMenuEvent)
     """
     point = evt.globalPos()
     
     if self.__browser:
         point = self.__browser.mapFromGlobal(point)
         if not self.__browser.rect().contains(point, True):
             return
         link = QUrl(self.__browser.anchorAt(point))
     else:
         point = self.__result.mapFromGlobal(point)
         link = self.__result.linkAt(point)
     
     if link.isEmpty() or not link.isValid():
         return
     
     menu = QMenu()
     curTab = menu.addAction(self.tr("Open Link"))
     newTab = menu.addAction(self.tr("Open Link in New Tab"))
     menu.move(evt.globalPos())
     act = menu.exec_()
     if act == curTab:
         self.linkActivated.emit(link)
     elif act == newTab:
         self.__mw.newTab(link)
Beispiel #2
0
 def showContextMenu(self, pos):
     self._cachedPos = pos
     menu = QMenu(self.parent())
     menu.addAction("Add Anchor…", self._createAnchor)
     menu.addAction("Add Component…", self._createComponent)
     menu.exec_(self._cachedPos)
     self._cachedPos = None
Beispiel #3
0
 def contextMenuEvent(self, event):
     menu = QMenu(self)
     local_filename = self.currentItem().text()
     # Get the file extension
     ext = os.path.splitext(local_filename)[1].lower()
     open_internal_action = None
     # Mu micro:bit mode only handles .py & .hex
     if ext == '.py' or ext == '.hex':
         open_internal_action = menu.addAction(_("Open in Mu"))
     # Open outside Mu (things get meta if Mu is the default application)
     open_action = menu.addAction(_("Open"))
     action = menu.exec_(self.mapToGlobal(event.pos()))
     if action == open_action:
         # Get the file's path
         path = os.path.join(self.home, local_filename)
         logger.info("Opening {}".format(path))
         msg = _("Opening '{}'").format(local_filename)
         logger.info(msg)
         self.set_message.emit(msg)
         # Let Qt work out how to open it
         QDesktopServices.openUrl(QUrl.fromLocalFile(path))
     elif action == open_internal_action:
         logger.info("Open {} internally".format(local_filename))
         # Get the file's path
         path = os.path.join(self.home, local_filename)
         # Send the signal bubbling up the tree
         self.open_file.emit(path)
    def slot_transportViewMenu(self):
        menu = QMenu(self)
        actHMS    = menu.addAction("Hours:Minutes:Seconds")
        actBBT    = menu.addAction("Beat:Bar:Tick")
        actFrames = menu.addAction("Frames")

        actHMS.setCheckable(True)
        actBBT.setCheckable(True)
        actFrames.setCheckable(True)

        if self.fCurTransportView == TRANSPORT_VIEW_HMS:
            actHMS.setChecked(True)
        elif self.fCurTransportView == TRANSPORT_VIEW_BBT:
            actBBT.setChecked(True)
        elif self.fCurTransportView == TRANSPORT_VIEW_FRAMES:
            actFrames.setChecked(True)

        actSelected = menu.exec_(QCursor().pos())

        if actSelected == actHMS:
            self.setTransportView(TRANSPORT_VIEW_HMS)
        elif actSelected == actBBT:
            self.setTransportView(TRANSPORT_VIEW_BBT)
        elif actSelected == actFrames:
            self.setTransportView(TRANSPORT_VIEW_FRAMES)
Beispiel #5
0
class CurrentPlaylistTable(MusicTable):
    remove_signal = pyqtSignal([int])   # song id

    def __init__(self, app):
        super().__init__(app)
        self._app = app

        self._row = 0

        self.menu = QMenu()
        self.remove = QAction('从当前列表中移除', self)
        self.menu.addAction(self.remove)

        self.remove.triggered.connect(self.remove_song)

    def contextMenuEvent(self, event):
        point = event.pos()
        item = self.itemAt(point)
        if item is not None:
            row = self.row(item)
            self._row = row
            self.menu.exec(event.globalPos())

    def remove_song(self):
        song = self.songs[self._row]
        self.songs.pop(self._row)
        self.removeRow(self._row)
        self.remove_signal.emit(song.mid)
Beispiel #6
0
    def __init__(self, project, settings):
        QWidget.__init__(self)
        self.ui = Ui_ProjectWidget()
        self.ui.setupUi(self)
        self.project = project
        self.project.filesChanged.connect(self.refresh)
        self.toolbar = QToolBar()
        import_image = lambda: ImportImage.pick(lambda f: self.import_image.emit(f[0]), settings)
        self.toolbar.addAction(ImportImage.icon(), ImportImage.ACTION_TEXT, import_image)
        self.ui.import_image.clicked.connect(import_image)
        self.raw_spectra_model = QStandardItemModel()
        self.calibrated_spectra_model = QStandardItemModel()
        self.finished_spectra_model = QStandardItemModel()

        def button_action(button, signal, widget, model):
            button.clicked.connect(lambda: signal.emit(model.item(widget.selectionModel().selectedRows()[0].row()).data() ) )
            widget.selectionModel().selectionChanged.connect(lambda sel, unsel: button.setEnabled(len(sel.indexes())>0))
            
        for model, widget in [(self.raw_spectra_model, self.ui.raw_spectra), (self.calibrated_spectra_model, self.ui.calibrated_spectra), (self.finished_spectra_model, self.ui.finished_spectra)]:
            widget.setModel(model)
            widget.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
            
        button_action(self.ui.calibrate, self.calibrate, self.ui.raw_spectra, self.raw_spectra_model)
        button_action(self.ui.math, self.math, self.ui.calibrated_spectra, self.calibrated_spectra_model)
        button_action(self.ui.finish, self.finish, self.ui.calibrated_spectra, self.calibrated_spectra_model)
        button_action(self.ui.open_finished, self.finish, self.ui.finished_spectra, self.finished_spectra_model)
        open_finished_menu = QMenu()
        self.ui.open_finished_dirs.setMenu(open_finished_menu)
        open_finished_menu.addAction(QIcon(':/image_20'), 'Exported Images folder', lambda: QDesktopServices.openUrl(QUrl.fromLocalFile(project.directory_path(Project.EXPORTED_IMAGES))))
        open_finished_menu.addAction(QIcon(':/done_20'), 'Finished Spectra folder', lambda: QDesktopServices.openUrl(QUrl.fromLocalFile(project.directory_path(Project.FINISHED_PROFILES))))
        

            
        self.refresh()
    def contextMenuEvent(self, event):
        # Update selection
        self.updateSelection()

        # Set context menu mode
        app = get_app()
        app.context_menu_object = "files"

        menu = QMenu(self)

        menu.addAction(self.win.actionImportFiles)
        menu.addAction(self.win.actionDetailsView)
        if self.selected:
            # If file selected, show file related options
            menu.addSeparator()
            menu.addAction(self.win.actionPreview_File)
            menu.addAction(self.win.actionSplitClip)
            menu.addAction(self.win.actionAdd_to_Timeline)
            menu.addAction(self.win.actionFile_Properties)
            menu.addSeparator()
            menu.addAction(self.win.actionRemove_from_Project)
            menu.addSeparator()

        # Show menu
        menu.exec_(QCursor.pos())
Beispiel #8
0
    def __init__(self):
        super(MainWindow, self).__init__()

        fileMenu = QMenu("&File", self)
        openAction = fileMenu.addAction("&Open...")
        openAction.setShortcut("Ctrl+O")
        saveAction = fileMenu.addAction("&Save As...")
        saveAction.setShortcut("Ctrl+S")
        quitAction = fileMenu.addAction("E&xit")
        quitAction.setShortcut("Ctrl+Q")

        self.setupModel()
        self.setupViews()

        openAction.triggered.connect(self.openFile)
        saveAction.triggered.connect(self.saveFile)
        quitAction.triggered.connect(QApplication.instance().quit)

        self.menuBar().addMenu(fileMenu)
        self.statusBar()

        self.openFile(':/Charts/qtdata.cht')

        self.setWindowTitle("Chart")
        self.resize(870, 550)
    def create_context_menu(self) -> QMenu:
        menu = QMenu(self)
        index = self.model().mapToSource(self.currentIndex())  # type: QModelIndex
        if index.isValid():
            current_index_info = self.model().sourceModel().fileInfo(index)  # type: QFileInfo
            if current_index_info.isDir():
                if os.path.isfile(os.path.join(current_index_info.filePath(), constants.PROJECT_FILE)):
                    open_action = menu.addAction("Open project")
                    open_action.setIcon(QIcon(":/icons/data/icons/appicon.png"))
                else:
                    open_action = menu.addAction("Open folder")
                    open_action.setIcon(QIcon.fromTheme("folder-open"))
                open_action.triggered.connect(self.on_open_action_triggered)

        new_dir_action = menu.addAction("New folder")
        new_dir_action.setIcon(QIcon.fromTheme("folder"))
        new_dir_action.triggered.connect(self.create_directory)

        del_action = menu.addAction("Delete")
        del_action.setIcon(QIcon.fromTheme("edit-delete"))
        del_action.triggered.connect(self.remove)

        menu.addSeparator()
        open_in_explorer_action = menu.addAction("Open in file manager...")
        open_in_explorer_action.triggered.connect(self.on_open_explorer_action_triggered)

        return menu
class Add_to_playlist_btn(QPushButton):
    def __init__(self):
        super().__init__('+')
        self.setToolTip('添加到歌单')
        self.menu = QMenu()
        self.playlists = []

    def mousePressEvent(self, event):
        self.set_playlists_options()
        self.menu.exec(event.globalPos())

    def set_playlists_options(self):
        playlists = ControllerApi.api.get_user_playlist()
        if not ControllerApi.api.is_response_ok(playlists):
            return
        self.playlists = playlists
        self.menu.clear()
        for playlist in playlists:
            if ControllerApi.api.is_playlist_mine(playlist):
                name = playlist['name']
                pid = playlist['id']
                action = QAction(name, self)
                action.triggered.connect(partial(self.add_to_playlist, pid))
                self.menu.addAction(action)

    def add_to_playlist(self, pid):
        if not ControllerApi.state['current_mid']:
            return False
        flag = ControllerApi.api.add_song_to_playlist(ControllerApi.state['current_mid'], pid)
        if flag:
            ControllerApi.notify_widget.show_message('◕◡◔', '加入歌单成功')
        else:
            ControllerApi.notify_widget.show_message('◕◠◔', '加入歌单失败, 可能早已在列表了哦')
Beispiel #11
0
    def cb_backends(self):
        self.cb_backends = QComboBox()

        self.cb_backends.addItem('Auto')

        menuLyricSource = QMenu(self.ui.menuEdit)
        menuLyricSource.setTitle('Lyric source')

        self.lyricGroup = QActionGroup(self)

        def addAction(name, checked=False):
            action = QAction(name, self)
            action.setText(name)
            action.setCheckable(True)
            action.setChecked(checked)
            action.setActionGroup(self.lyricGroup)

            return action

        menuLyricSource.addAction(addAction('Auto', True))
        menuLyricSource.addSeparator()
        menuLyricSource.triggered.connect(self._menu_backend_change)

        for backend in Pyrics.get_backends():
            menuLyricSource.addAction(addAction(backend.__name__))
            self.cb_backends.addItem(backend.__name__)

        self.ui.menuEdit.addMenu(menuLyricSource)
        self.ui.toolBar.addWidget(self.cb_backends)

        self.cb_backends.currentIndexChanged.connect(self._cb_backend_change)
Beispiel #12
0
    def _treeContextMenu(self, point):
        """
        Context menu on the tree. This allows for quick access to adding and cloning nodes.
        Input:
            point[QPoint]: Point where the context menu was requested
        """
        item = self.itemAt(point)
        if not item:
            return
        block = self._item_block_map.get(item)
        if not block:
            return

        if not block.star and not block.user_added:
            return

        menu = QMenu()
        menu.addAction(self.add_action)
        if block.star:
            self.add_action.setText("Add")
        else:
            self.add_action.setText("Clone")
            menu.addAction(self.remove_action)

        result = menu.exec_(self.mapToGlobal(point))
        if result == self.add_action:
            self.copyBlock(block)
        elif result == self.remove_action:
            text = "Are you sure you want to delete %s" % block.path
            button = QMessageBox.question(self, "Confirm remove", text, QMessageBox.Yes, QMessageBox.No)
            if button == QMessageBox.Yes:
                self.removeBlock(block)
Beispiel #13
0
    def contextMenuEvent(self, event):
        from_index = self._table.indexAt(event.pos())
        if not (0 <= from_index.row() < self.model.rowCount()):
            return

        # The context menu event is the same regardless of the selected column
        # Therefore ColumnID is set such that the label name is retrieved
        from_index_to_name = self.model.index(from_index.row(), LabelListModel.ColumnID.Name)

        from_name = self.model.data(from_index_to_name, Qt.DisplayRole)
        menu = QMenu(parent=self)
        menu.addAction(
            "Clear {}".format(from_name),
            partial(self.clearRequested.emit, from_index_to_name.row(), str(from_name))
        )

        if self.support_merges and self.allowDelete:
            for to_row in range(self.model.rowCount()):
                to_index = self.model.index(to_row, LabelListModel.ColumnID.Name)
                to_name = self.model.data(to_index, Qt.DisplayRole)
                action = menu.addAction( "Merge {} into {}".format( from_name, to_name ),
                                         partial( self.mergeRequested.emit, from_index_to_name.row(), str(from_name),
                                                                            to_row,           str(to_name)) )
                if to_row == from_index_to_name.row():
                    action.setEnabled(False)

        menu.exec_( self.mapToGlobal(event.pos()) )
    def __init__(self, parent=None):
        super(ZMQPublisherInfoWidget, self).__init__(parent)

        ui_class, widget_class = uic.loadUiType(os.path.split(__file__)[0] + "/zmqPubSubInfoWidget.ui")
        self.ui = ui_class()
        self.ui.setupUi(self)

        self.status = {
            "pub": {
                "address": None,
                "running": False
            },
            "sub": {
                "address": None,
                "running": False
            }
        }

        self.ui.toggleSubStatus.clicked.connect(partial(self.ui.toggleSubStatus.setEnabled, False))
        self.ui.togglePubStatus.clicked.connect(partial(self.ui.togglePubStatus.setEnabled, False))
        self.ui.toggleSubStatus.clicked.connect(self.subStatusToggled.emit)
        self.ui.togglePubStatus.clicked.connect(self.pubStatusToggled.emit)

        menu = QMenu("options")
        self.change_pub_addr_action = menu.addAction("Change Address", self.changePubAddress.emit)
        self.ui.togglePubStatus.setMenu(menu)

        menu = QMenu("options")
        self.change_sub_addr_action = menu.addAction("Change Address", self.changeSubAddress.emit)
        self.ui.toggleSubStatus.setMenu(menu)

        self.status_style = "background-color: %s; border: 3px inset gray; padding: 5px"
Beispiel #15
0
    def contextMenuEvent(self, event):
        menu = QMenu()
        removeAction = menu.addAction(QA.translate('QOcrWidget', "Remove"))
        #Action = menu.addAction(self.scene().tr("Remove"))
        menu.addSeparator()
        textAction = menu.addAction(QA.translate('QOcrWidget', "Text"))
        graphicsAction = menu.addAction(QA.translate('QOcrWidget', "Graphics"))

        ## verification of the type of the selection and
        ## setting a check box near the type that is in use
        textAction.setCheckable(True)
        graphicsAction.setCheckable(True)

        if self.kind == 1:
            textAction.setChecked(True)
        elif self.kind == 2:
            graphicsAction.setChecked(True)

        selectedAction = menu.exec_(event.screenPos())

        if selectedAction == removeAction:
            self.scene().removeArea(self)
        elif selectedAction == textAction:
            self.kind = 1
        elif selectedAction == graphicsAction:
            self.kind = 2
 def createSubMenu(self, menu, view, hitTestResult):
     """
     Public method to create the personal information sub-menu.
     
     @param menu reference to the main menu (QMenu)
     @param view reference to the view (HelpBrowser)
     @param hitTestResult reference to the hit test result
         (QWebHitTestResult)
     """
     self.__view = view
     self.__element = hitTestResult.element()
     
     if not hitTestResult.isContentEditable():
         return
     
     if not self.__loaded:
         self.__loadSettings()
     
     submenu = QMenu(self.tr("Insert Personal Information"), menu)
     submenu.setIcon(UI.PixmapCache.getIcon("pim.png"))
     
     for key, info in sorted(self.__allInfo.items()):
         if info:
             act = submenu.addAction(
                 self.__translations[key], self.__insertData)
             act.setData(info)
     
     submenu.addSeparator()
     submenu.addAction(self.tr("Edit Personal Information"),
                       self.showConfigurationDialog)
     
     menu.addMenu(submenu)
     menu.addSeparator()
Beispiel #17
0
    def create_context_menu_window(self, tabWidget, window):
        ctrlMenu = QMenu("")


        title_action = QAction('Window menu', tabWidget)
        title_action.setDisabled(True)

        sep_action = QAction('',tabWidget)
        sep_action.setSeparator(True)
        sep_action2 = QAction('',tabWidget)
        sep_action2.setSeparator(True)

        dock_action = QAction('Dock Window',tabWidget)
        dock_action.triggered.connect(lambda ignore, area=tabWidget, window = window : self.cmenu_dock_window(area,window))

        rename_win_action = QAction('Rename Window',self.tabWidget)
        rename_win_action.triggered.connect(lambda ignore, window = window : self.cmenu_rename_wind(window))

        bg_action = QAction('Set background',tabWidget)
        bg_action.triggered.connect(lambda ignore, wind = window  : self.cmenu_set_bg_window(wind))

        ctrlMenu.addAction(title_action)
        ctrlMenu.addAction(sep_action)
        ctrlMenu.addAction(dock_action)
        ctrlMenu.addAction(sep_action2)
        ctrlMenu.addAction(rename_win_action)
        ctrlMenu.addAction(bg_action)
        return ctrlMenu
Beispiel #18
0
    def addShowActions(self):
        """Adds a submenu giving access to the (other)
        opened viewer documents"""
        mds = self._actionCollection.viewer_document_select
        docs = mds.viewdocs()
        document_actions = {}
        multi_docs = len(docs) > 1
        if self._panel.widget().currentViewdoc():
            current_doc_filename = self._panel.widget().currentViewdoc().filename()

        m = self._menu
        sm = QMenu(m)
        sm.setTitle(_("Show..."))
        sm.setEnabled(multi_docs)
        ag = QActionGroup(m)
        ag.triggered.connect(self._panel.slotShowViewdoc)

        for d in docs:
            action = QAction(sm)
            action.setText(d.name())
            action._document_filename = d.filename()
            # TODO: Tooltips aren't shown by Qt (it seems)
            action.setToolTip(d.filename())
            action.setCheckable(True)
            action.setChecked(d.filename() == current_doc_filename)

            ag.addAction(action)
            sm.addAction(action)

        m.addSeparator()
        m.addMenu(sm)
Beispiel #19
0
    def __init__(self):
        super(MainWindow, self).__init__()
        fileMenu = QMenu("&File", self)
        newAction = fileMenu.addAction("&New...")
        newAction.setShortcut("Ctrl+N")
        self.printAction = fileMenu.addAction("&Print...", self.printFile)
        self.printAction.setShortcut("Ctrl+P")
        self.printAction.setEnabled(False)
        quitAction = fileMenu.addAction("&Exit")
        quitAction.setShortcut("Ctrl+Q")

        helpMenu = QMenu("&Help", self)
        aboutAction = helpMenu.addAction("&About")

        self.menuBar().addMenu(fileMenu)
        self.menuBar().addMenu(helpMenu)

        self.solvers = QTabWidget()
        self.solvers.setTabsClosable(True)
        self.solvers.tabCloseRequested.connect(self.closeTab)

        newAction.triggered.connect(self.openDialog)
        quitAction.triggered.connect(self.close)
        aboutAction.triggered.connect(self.openAbout)

        self.setCentralWidget(self.solvers)
        self.setWindowTitle("Pulppy Software")
Beispiel #20
0
	def init_stat_bar(self):
		self.status_bar = self.statusBar()
		self.status_bar.setMaximumHeight(20)
		self.status_bar.setSizeGripEnabled(False)
		self.stat_info = QLabel()
		self.stat_info.setIndent(5)
		self.sort_main = QAction("Asc", self)
		sort_menu = QMenu()
		self.sort_main.setMenu(sort_menu)
		s_by_title = QAction("Title", sort_menu)
		s_by_artist = QAction("Artist", sort_menu)
		sort_menu.addAction(s_by_title)
		sort_menu.addAction(s_by_artist)
		self.status_bar.addPermanentWidget(self.stat_info)
		#self.status_bar.addAction(self.sort_main)
		self.temp_msg = QLabel()
		self.temp_timer = QTimer()

		self.manga_list_view.gallery_model.ROWCOUNT_CHANGE.connect(self.stat_row_info)
		self.manga_list_view.gallery_model.db_emitter.COUNT_CHANGE.connect(self.stat_row_info)
		self.manga_list_view.gallery_model.STATUSBAR_MSG.connect(self.stat_temp_msg)
		self.manga_list_view.STATUS_BAR_MSG.connect(self.stat_temp_msg)
		self.manga_table_view.STATUS_BAR_MSG.connect(self.stat_temp_msg)
		self.stat_row_info()
		app_constants.STAT_MSG_METHOD = self.stat_temp_msg
Beispiel #21
0
	def __init__(self, **kwargs):
		super(SearchOptionsButton, self).__init__(**kwargs)

		self.setText(self.tr('Options'))

		menu = QMenu()
		self.actionCi = menu.addAction(self.tr('Case insensitive'))

		menu.addSeparator()
		self.actionFormat = QActionGroup(self)
		self.actionPlain = menu.addAction(self.tr('Plain text'))
		self.actionPlain.setEnabled(False)
		self.actionRe = menu.addAction(self.tr('Regular expression'))
		self.actionGlob = menu.addAction(self.tr('Glob pattern'))
		self.actionGlob.setEnabled(False)
		self.actionFormat.addAction(self.actionPlain)
		self.actionFormat.addAction(self.actionRe)
		self.actionFormat.addAction(self.actionGlob)

		self.actionRoot = menu.addAction(self.tr('Search in best root dir'))

		for act in [self.actionCi, self.actionRe, self.actionPlain, self.actionGlob, self.actionRoot]:
			act.setCheckable(True)
		self.actionRe.setChecked(True)

		self.setMenu(menu)
Beispiel #22
0
    def create_context_menu(self) -> QMenu:
        menu = QMenu()
        if self.context_menu_pos is None:
            return menu

        selected_label_index = self.model().get_selected_label_index(row=self.rowAt(self.context_menu_pos.y()),
                                                                     column=self.columnAt(self.context_menu_pos.x()))

        if self.model().row_count > 0:
            if selected_label_index == -1:
                label_action = menu.addAction("Create label...")
                label_action.setIcon(QIcon.fromTheme("list-add"))
            else:
                label_action = menu.addAction("Edit label...")
                label_action.setIcon(QIcon.fromTheme("configure"))

            label_action.triggered.connect(self.on_create_or_edit_label_action_triggered)
            menu.addSeparator()

            zoom_menu = menu.addMenu("Zoom font size")
            zoom_menu.addAction(self.zoom_in_action)
            zoom_menu.addAction(self.zoom_out_action)
            zoom_menu.addAction(self.zoom_original_action)
            menu.addSeparator()

        return menu
Beispiel #23
0
class ValueDomainNodeInfo(PredicateNodeInfo):
    """
    This class implements the information box for the Value Domain node.
    """
    def __init__(self, mainwindow, parent=None):
        """
        Initialize the Value Domain node information box.
        """
        super().__init__(mainwindow, parent)

        self.datatypeKey = Key('Datatype', self)
        self.datatypeMenu = QMenu(self)
        for action in self.mainwindow.actionsChangeValueDomainDatatype:
            self.datatypeMenu.addAction(action)
        self.datatypeButton = Button()
        self.datatypeButton.setMenu(self.datatypeMenu)
        self.datatypeButton.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)

        self.nodePropLayout.addRow(self.datatypeKey, self.datatypeButton)

    def updateData(self, node):
        """
        Fetch new information and fill the widget with data.
        :type node: AbstractNode
        """
        super().updateData(node)
        datatype = node.datatype
        for action in self.mainwindow.actionsChangeValueDomainDatatype:
            action.setChecked(action.data() is datatype)
        self.datatypeButton.setText(datatype.value)
Beispiel #24
0
class ApplicationWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setWindowTitle("application main window")

        self.file_menu = QMenu('&File', self)
        self.file_menu.addAction('&Quit', self.fileQuit,
        QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
        self.menuBar().addMenu(self.file_menu)

        self.help_menu = QMenu('&Help', self)
        self.menuBar().addSeparator()
        self.menuBar().addMenu(self.help_menu)

        self.main_widget = QWidget(self)

        l = QVBoxLayout(self.main_widget)
        sc = MyStaticMplCanvas(self.main_widget, width=5, height=4, dpi=100)
        dc = MyDynamicMplCanvas(self.main_widget, width=5, height=4, dpi=100)
        l.addWidget(sc)
        l.addWidget(dc)

        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)

        self.statusBar().showMessage("All hail matplotlib!", 2000)

    def fileQuit(self):
        self.close()

    def closeEvent(self, ce):
        self.fileQuit()
    def show_id_context_menu(self, position):
        current_id = -1
        try:
            current_id = int(self.__ui.lbl_uav_id.text())
        except Exception:
            #print("Don't show the menu")
            return

        menu = QMenu()
        menu.addAction("Show Mission for " + str(current_id))
        menu.addAction("Show Fence for " + str(current_id))

        global_position = self.__ui.lbl_uav_id.mapToGlobal(position)
        selectedItem = menu.exec(global_position)
        
        if selectedItem.text()[0:12] == "Show Mission":
            if self.fetching_mission_for == -1: #prevent concurrent fetches
                self.fetching_mission_for = current_id
                
                self.wpFetchThread = WaypointFetchThread(self, self.__hm_state,
                                                        current_id)
                self.wpFetchThread.start()

            elif self.fetching_mission_for != current_id:
                QMessageBox.error(self, "Still fetching waypoints for " + str(current_id),
                    "Still fetching waypoints for " + str(current_id) + "\n\nCan't fetch multiple waypoints concurrently.  Wait a few more seconds for the previous fetch operation to finish.")
                return
        
        elif selectedItem.text()[0:10] == "Show Fence":
            self.fenFetchThread = FenceFetchThread(self, self.__hm_state,
                                                    current_id)
            self.fenFetchThread.start()
Beispiel #26
0
    def buildWidget(self):
        layout = QHBoxLayout(self)
        layout.setContentsMargins(0,0,0,0)
        SettingMenu = QMenu()
        exitButton = QAction(QIcon('exit24.png'), 'Set As High', self)
        exitButton.triggered.connect(self.setHigh)
        SettingMenu.addAction(exitButton)
        setlowButton = QAction(QIcon('exit24.png'), 'Set As Low', self)
        setlowButton.triggered.connect(self.setLow)
        SettingMenu.addAction(setlowButton)

        self.tb_down = QToolButton()
        self.tb_down.pressed.connect(self.on_click_down)
        self.tb_down.released.connect(self.on_released)
        self.tb_down.setArrowType(Qt.LeftArrow)

        self.tb_up = QToolButton()
        self.tb_up.pressed.connect(self.on_click_up)
        self.tb_up.released.connect(self.on_released)
        self.tb_up.setArrowType(Qt.RightArrow)

        if self.showToggleButton:
            tb_set = QToolButton()
            tb_set.clicked.connect(self.on_click_set_value)
            tb_set.setText('<>')
            if self.showSettingMenu:
                tb_set.setMenu(SettingMenu)
                tb_set.setPopupMode(QToolButton.DelayedPopup)

        layout.addWidget(self.tb_down)
        layout.addWidget(self.bar)
        layout.addWidget(self.tb_up)
        if self.showToggleButton:
            layout.addWidget(tb_set)
        layout.setSpacing(0)
Beispiel #27
0
    def create_context_menu(self):
        menu = QMenu()
        menu.setToolTipsVisible(True)
        self._add_zoom_actions_to_menu(menu)

        if self.something_is_selected:
            filter_bw = Filter.read_configured_filter_bw()
            text = self.tr("Apply bandpass filter (filter bw={0:n})".format(filter_bw))
            create_from_frequency_selection = menu.addAction(text)
            create_from_frequency_selection.triggered.connect(self.on_create_from_frequency_selection_triggered)
            create_from_frequency_selection.setIcon(QIcon.fromTheme("view-filter"))

            try:
                cancel_button = " or ".join(k.toString() for k in QKeySequence.keyBindings(QKeySequence.Cancel))
            except Exception as e:
                logger.debug("Error reading cancel button: " + str(e))
                cancel_button = "Esc"

            create_from_frequency_selection.setToolTip("You can abort filtering with <b>{}</b>.".format(cancel_button))

        configure_filter_bw = menu.addAction(self.tr("Configure filter bandwidth..."))
        configure_filter_bw.triggered.connect(self.on_configure_filter_bw_triggered)
        configure_filter_bw.setIcon(QIcon.fromTheme("configure"))

        menu.addSeparator()

        export_fta_action = menu.addAction("Export spectrogram...")
        export_fta_action.triggered.connect(self.on_export_fta_action_triggered)

        return menu
Beispiel #28
0
 def open_pl_menu(self, position):
     menu = QMenu()
     # if len(self.combo_pl_names) > 0:
     play_now = menu.addAction("Play this playlist now")
     pl_now_icon = QIcon()
     pl_now_icon.addPixmap(QPixmap(":icons/play.png"), QIcon.Normal, QIcon.Off)
     play_now.setIcon(pl_now_icon)
     add_to_current = menu.addAction("Add this playlist to Now Playing")
     add_curr_icon = QIcon()
     add_curr_icon.addPixmap(QPixmap(":icons/add.png"), QIcon.Normal, QIcon.Off)
     add_to_current.setIcon(add_curr_icon)
     new_playlist = menu.addAction("Add New Playlist")
     new_pl_icon = QIcon()
     new_pl_icon.addPixmap(QPixmap(":icons/playlist_add.png"), QIcon.Normal, QIcon.Off)
     new_playlist.setIcon(new_pl_icon)
     create_from_albums = menu.addAction("Create play lists from Album names")
     create_icon = QIcon()
     create_icon.addPixmap(QPixmap(":icons/book_cd.png"), QIcon.Normal, QIcon.Off)
     create_from_albums.setIcon(create_icon)
     if len(self.combo_pl_names) <= 0:
         play_now.setEnabled(False)
         add_to_current.setEnabled(False)
     action = menu.exec_(self.combo_pl_names.mapToGlobal(position))
     if action == play_now:
         # print("Play this one now :- " + self.combo_pl_names.currentText())
         my_func.play_list_now(self)
     if action == add_to_current:
         # print("Add this one to Now Playing :- " + self.combo_pl_names.currentText())
         my_func.add_play_list_to_now(self)
     if action == new_playlist:
         # print("I want to add a new playlist")
         my_func.add_new_playlist(self)
     if action == create_from_albums:
         # print("Create play lists from Album names")
         my_func.make_playlists_from_albums(self)
Beispiel #29
0
class PredicateNodeInfo(NodeInfo):
    """
    This class implements the information box for predicate nodes.
    """
    def __init__(self, mainwindow, parent=None):
        """
        Initialize the predicate node information box.
        """
        super().__init__(mainwindow, parent)

        self.brushKey = Key('Color', self)
        self.brushMenu = QMenu(self)
        for action in self.mainwindow.actionsChangeNodeBrush:
            self.brushMenu.addAction(action)
        self.brushButton = Button()
        self.brushButton.setMenu(self.brushMenu)
        self.brushButton.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)

        self.nodePropLayout.addRow(self.brushKey, self.brushButton)

    def updateData(self, node):
        """
        Fetch new information and fill the widget with data.
        :type node: AbstractNode
        """
        super().updateData(node)
        for action in self.mainwindow.actionsChangeNodeBrush:
            color = action.data()
            brush = QBrush(QColor(color.value))
            if node.brush == brush:
                self.brushButton.setIcon(ColoredIcon(12, 12, color.value, '#000000'))
                self.brushButton.setText(color.value)
                break
Beispiel #30
0
class Systray(QObject):
    trayIconMenu = None

    def __init__(self, parent):
        super().__init__(parent)

        self.trayIconMenu = QMenu(None)

        icon = QIcon(":/image/thunder.ico")

        self.trayIcon = CompatSystemTrayIcon(self)
        self.trayIcon.setIcon(icon)
        self.trayIcon.setContextMenu(self.trayIconMenu)
        self.trayIcon.setVisible(True)

        self.trayIcon.activated.connect(self.slotSystrayActivated)
        self.trayIconMenu.addAction(app.mainWin.action_exit)

    @pyqtSlot(QSystemTrayIcon.ActivationReason)
    def slotSystrayActivated(self, reason):
        if reason == QSystemTrayIcon.Context:  # right
            pass
        elif reason == QSystemTrayIcon.MiddleClick:  # middle
            pass
        elif reason == QSystemTrayIcon.DoubleClick:  # double click
            pass
        elif reason == QSystemTrayIcon.Trigger:  # left
            if app.mainWin.isHidden() or app.mainWin.isMinimized():
                app.mainWin.restore()
            else:
                app.mainWin.minimize()
    def _addVCSMenu(self, mainMenu):
        """
        Protected method used to add the VCS menu to all project browsers.
        
        @param mainMenu reference to the menu to be amended
        """
        self.vcsMenuActions = []
        self.vcsAddMenuActions = []

        menu = QMenu(self.tr("Version Control"))

        act = menu.addAction(
            UI.PixmapCache.getIcon(
                os.path.join("VcsPlugins", "vcsPySvn", "icons", "pysvn.png")),
            self.vcs.vcsName(), self._VCSInfoDisplay)
        font = act.font()
        font.setBold(True)
        act.setFont(font)
        menu.addSeparator()

        act = menu.addAction(UI.PixmapCache.getIcon("vcsUpdate.png"),
                             self.tr('Update from repository'),
                             self._VCSUpdate)
        self.vcsMenuActions.append(act)
        act = menu.addAction(UI.PixmapCache.getIcon("vcsCommit.png"),
                             self.tr('Commit changes to repository...'),
                             self._VCSCommit)
        self.vcsMenuActions.append(act)
        menu.addSeparator()
        act = menu.addAction(UI.PixmapCache.getIcon("vcsAdd.png"),
                             self.tr('Add to repository'), self._VCSAdd)
        self.vcsAddMenuActions.append(act)
        if 1 in self.browser.specialMenuEntries:
            self.vcsMenuAddTree = menu.addAction(
                UI.PixmapCache.getIcon("vcsAdd.png"),
                self.tr('Add tree to repository'), self._VCSAddTree)
            self.vcsAddMenuActions.append(self.vcsMenuAddTree)
        act = menu.addAction(UI.PixmapCache.getIcon("vcsRemove.png"),
                             self.tr('Remove from repository (and disk)'),
                             self._VCSRemove)
        self.vcsMenuActions.append(act)
        menu.addSeparator()
        act = menu.addAction(self.tr('Copy'), self.__SVNCopy)
        self.vcsMenuActions.append(act)
        act = menu.addAction(self.tr('Move'), self.__SVNMove)
        self.vcsMenuActions.append(act)
        if pysvn.svn_version >= (1, 5, 0) and pysvn.version >= (1, 6, 0):
            menu.addSeparator()
            act = menu.addAction(self.tr("Add to Changelist"),
                                 self.__SVNAddToChangelist)
            self.vcsMenuActions.append(act)
            act = menu.addAction(self.tr("Remove from Changelist"),
                                 self.__SVNRemoveFromChangelist)
            self.vcsMenuActions.append(act)
        menu.addSeparator()
        act = menu.addAction(UI.PixmapCache.getIcon("vcsLog.png"),
                             self.tr('Show log'), self._VCSLog)
        self.vcsMenuActions.append(act)
        act = menu.addAction(UI.PixmapCache.getIcon("vcsLog.png"),
                             self.tr('Show log browser'), self._VCSLogBrowser)
        self.vcsMenuActions.append(act)
        menu.addSeparator()
        act = menu.addAction(UI.PixmapCache.getIcon("vcsStatus.png"),
                             self.tr('Show status'), self._VCSStatus)
        self.vcsMenuActions.append(act)
        act = menu.addAction(UI.PixmapCache.getIcon("vcsRepo.png"),
                             self.tr('Show repository info'), self.__SVNInfo)
        self.vcsMenuActions.append(act)
        menu.addSeparator()
        act = menu.addAction(UI.PixmapCache.getIcon("vcsDiff.png"),
                             self.tr('Show differences'), self._VCSDiff)
        self.vcsMenuActions.append(act)
        act = menu.addAction(UI.PixmapCache.getIcon("vcsSbsDiff.png"),
                             self.tr('Show differences side-by-side'),
                             self.__SVNSbsDiff)
        self.vcsMenuActions.append(act)
        act = menu.addAction(UI.PixmapCache.getIcon("vcsDiff.png"),
                             self.tr('Show differences (extended)'),
                             self.__SVNExtendedDiff)
        self.vcsMenuActions.append(act)
        act = menu.addAction(
            UI.PixmapCache.getIcon("vcsSbsDiff.png"),
            self.tr('Show differences side-by-side (extended)'),
            self.__SVNSbsExtendedDiff)
        self.vcsMenuActions.append(act)
        act = menu.addAction(UI.PixmapCache.getIcon("vcsDiff.png"),
                             self.tr('Show differences (URLs)'),
                             self.__SVNUrlDiff)
        self.vcsMenuActions.append(act)
        self.blameAct = menu.addAction(self.tr('Show annotated file'),
                                       self.__SVNBlame)
        self.vcsMenuActions.append(self.blameAct)
        menu.addSeparator()
        act = menu.addAction(UI.PixmapCache.getIcon("vcsRevert.png"),
                             self.tr('Revert changes'), self._VCSRevert)
        self.vcsMenuActions.append(act)
        act = menu.addAction(UI.PixmapCache.getIcon("vcsMerge.png"),
                             self.tr('Merge changes'), self._VCSMerge)
        self.vcsMenuActions.append(act)
        act = menu.addAction(self.tr('Conflicts resolved'), self.__SVNResolve)
        self.vcsMenuActions.append(act)
        menu.addSeparator()
        act = menu.addAction(UI.PixmapCache.getIcon("vcsLock.png"),
                             self.tr('Lock'), self.__SVNLock)
        self.vcsMenuActions.append(act)
        act = menu.addAction(UI.PixmapCache.getIcon("vcsUnlock.png"),
                             self.tr('Unlock'), self.__SVNUnlock)
        self.vcsMenuActions.append(act)
        act = menu.addAction(UI.PixmapCache.getIcon("vcsUnlock.png"),
                             self.tr('Break Lock'), self.__SVNBreakLock)
        self.vcsMenuActions.append(act)
        act = menu.addAction(UI.PixmapCache.getIcon("vcsUnlock.png"),
                             self.tr('Steal Lock'), self.__SVNStealLock)
        self.vcsMenuActions.append(act)
        menu.addSeparator()
        act = menu.addAction(self.tr('Set Property'), self.__SVNSetProp)
        self.vcsMenuActions.append(act)
        act = menu.addAction(self.tr('List Properties'), self.__SVNListProps)
        self.vcsMenuActions.append(act)
        act = menu.addAction(self.tr('Delete Property'), self.__SVNDelProp)
        self.vcsMenuActions.append(act)
        menu.addSeparator()
        menu.addAction(self.tr('Select all local file entries'),
                       self.browser.selectLocalEntries)
        menu.addAction(self.tr('Select all versioned file entries'),
                       self.browser.selectVCSEntries)
        menu.addAction(self.tr('Select all local directory entries'),
                       self.browser.selectLocalDirEntries)
        menu.addAction(self.tr('Select all versioned directory entries'),
                       self.browser.selectVCSDirEntries)
        menu.addSeparator()
        menu.addAction(self.tr("Configure..."), self.__SVNConfigure)

        mainMenu.addSeparator()
        mainMenu.addMenu(menu)
        self.menu = menu
Beispiel #32
0
class GitStashBrowserDialog(QWidget, Ui_GitStashBrowserDialog):
    """
    Class implementing a dialog to show the stashes.
    """
    NameColumn = 0
    DateColumn = 1
    MessageColumn = 2

    Separator = "@@||@@"

    TotalStatisticsRole = Qt.UserRole
    FileStatisticsRole = Qt.UserRole + 1

    def __init__(self, vcs, parent=None):
        """
        Constructor
        
        @param vcs reference to the vcs object
        @param parent reference to the parent widget (QWidget)
        """
        super(GitStashBrowserDialog, self).__init__(parent)
        self.setupUi(self)

        self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)

        self.__position = QPoint()

        self.__fileStatisticsRole = Qt.UserRole
        self.__totalStatisticsRole = Qt.UserRole + 1

        self.stashList.header().setSortIndicator(0, Qt.AscendingOrder)

        self.refreshButton = self.buttonBox.addButton(
            self.tr("&Refresh"), QDialogButtonBox.ActionRole)
        self.refreshButton.setToolTip(
            self.tr("Press to refresh the list of stashes"))
        self.refreshButton.setEnabled(False)

        self.vcs = vcs
        self.__resetUI()

        self.__ioEncoding = Preferences.getSystem("IOEncoding")

        self.process = QProcess()
        self.process.finished.connect(self.__procFinished)
        self.process.readyReadStandardOutput.connect(self.__readStdout)
        self.process.readyReadStandardError.connect(self.__readStderr)

        self.__contextMenu = QMenu()
        self.__differencesAct = self.__contextMenu.addAction(
            self.tr("Show"), self.__showPatch)
        self.__contextMenu.addSeparator()
        self.__applyAct = self.__contextMenu.addAction(
            self.tr("Restore && Keep"), self.__apply)
        self.__popAct = self.__contextMenu.addAction(
            self.tr("Restore && Delete"), self.__pop)
        self.__contextMenu.addSeparator()
        self.__branchAct = self.__contextMenu.addAction(
            self.tr("Create Branch"), self.__branch)
        self.__contextMenu.addSeparator()
        self.__dropAct = self.__contextMenu.addAction(self.tr("Delete"),
                                                      self.__drop)
        self.__clearAct = self.__contextMenu.addAction(self.tr("Delete All"),
                                                       self.__clear)

    def closeEvent(self, e):
        """
        Protected slot implementing a close event handler.
        
        @param e close event (QCloseEvent)
        """
        if self.process is not None and \
           self.process.state() != QProcess.NotRunning:
            self.process.terminate()
            QTimer.singleShot(2000, self.process.kill)
            self.process.waitForFinished(3000)

        self.__position = self.pos()

        e.accept()

    def show(self):
        """
        Public slot to show the dialog.
        """
        if not self.__position.isNull():
            self.move(self.__position)
        self.__resetUI()

        super(GitStashBrowserDialog, self).show()

    def __resetUI(self):
        """
        Private method to reset the user interface.
        """
        self.stashList.clear()

    def __resizeColumnsStashes(self):
        """
        Private method to resize the shelve list columns.
        """
        self.stashList.header().resizeSections(QHeaderView.ResizeToContents)
        self.stashList.header().setStretchLastSection(True)

    def __generateStashEntry(self, name, date, message):
        """
        Private method to generate the stash items.
        
        @param name name of the stash (string)
        @param date date the stash was created (string)
        @param message stash message (string)
        """
        QTreeWidgetItem(self.stashList, [name, date, message])

    def __getStashEntries(self):
        """
        Private method to retrieve the list of stashes.
        """
        self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True)
        self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)

        self.inputGroup.setEnabled(True)
        self.inputGroup.show()
        self.refreshButton.setEnabled(False)

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        QApplication.processEvents()

        self.buf = []
        self.errors.clear()
        self.intercept = False

        args = self.vcs.initCommand("stash")
        args.append("list")
        args.append("--format=format:%gd{0}%ai{0}%gs%n".format(self.Separator))

        self.process.kill()

        self.process.setWorkingDirectory(self.repodir)

        self.inputGroup.setEnabled(True)
        self.inputGroup.show()

        self.process.start('git', args)
        procStarted = self.process.waitForStarted(5000)
        if not procStarted:
            self.inputGroup.setEnabled(False)
            self.inputGroup.hide()
            E5MessageBox.critical(
                self, self.tr('Process Generation Error'),
                self.tr(
                    'The process {0} could not be started. '
                    'Ensure, that it is in the search path.').format('git'))

    def start(self, projectDir):
        """
        Public slot to start the git stash command.
        
        @param projectDir name of the project directory (string)
        """
        self.errorGroup.hide()
        QApplication.processEvents()

        self.__projectDir = projectDir

        # find the root of the repo
        self.repodir = self.__projectDir
        while not os.path.isdir(os.path.join(self.repodir, self.vcs.adminDir)):
            self.repodir = os.path.dirname(self.repodir)
            if os.path.splitdrive(self.repodir)[1] == os.sep:
                return

        self.activateWindow()
        self.raise_()

        self.stashList.clear()
        self.__started = True
        self.__getStashEntries()

    def __procFinished(self, exitCode, exitStatus):
        """
        Private slot connected to the finished signal.
        
        @param exitCode exit code of the process (integer)
        @param exitStatus exit status of the process (QProcess.ExitStatus)
        """
        self.__processBuffer()
        self.__finish()

    def __finish(self):
        """
        Private slot called when the process finished or the user pressed
        the button.
        """
        if self.process is not None and \
           self.process.state() != QProcess.NotRunning:
            self.process.terminate()
            QTimer.singleShot(2000, self.process.kill)
            self.process.waitForFinished(3000)

        QApplication.restoreOverrideCursor()

        self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
        self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)

        self.inputGroup.setEnabled(False)
        self.inputGroup.hide()
        self.refreshButton.setEnabled(True)

    def __processBuffer(self):
        """
        Private method to process the buffered output of the git stash command.
        """
        for line in self.buf:
            name, date, message = line.split(self.Separator)
            date = date.strip().rsplit(":", 1)[0]
            self.__generateStashEntry(name, date, message.strip())

        self.__resizeColumnsStashes()

        if self.__started:
            self.stashList.setCurrentItem(self.stashList.topLevelItem(0))
            self.__started = False

    def __readStdout(self):
        """
        Private slot to handle the readyReadStandardOutput signal.
        
        It reads the output of the process and inserts it into a buffer.
        """
        self.process.setReadChannel(QProcess.StandardOutput)

        while self.process.canReadLine():
            line = str(self.process.readLine(), self.__ioEncoding,
                       'replace').strip()
            if line:
                self.buf.append(line)

    def __readStderr(self):
        """
        Private slot to handle the readyReadStandardError signal.
        
        It reads the error output of the process and inserts it into the
        error pane.
        """
        if self.process is not None:
            s = str(self.process.readAllStandardError(), self.__ioEncoding,
                    'replace')
            self.errorGroup.show()
            self.errors.insertPlainText(s)
            self.errors.ensureCursorVisible()

    @pyqtSlot(QAbstractButton)
    def on_buttonBox_clicked(self, button):
        """
        Private slot called by a button of the button box clicked.
        
        @param button button that was clicked (QAbstractButton)
        """
        if button == self.buttonBox.button(QDialogButtonBox.Close):
            self.close()
        elif button == self.buttonBox.button(QDialogButtonBox.Cancel):
            self.cancelled = True
            self.__finish()
        elif button == self.refreshButton:
            self.on_refreshButton_clicked()

    @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem)
    def on_stashList_currentItemChanged(self, current, previous):
        """
        Private slot called, when the current item of the stash list changes.
        
        @param current reference to the new current item (QTreeWidgetItem)
        @param previous reference to the old current item (QTreeWidgetItem)
        """
        self.statisticsList.clear()
        self.filesLabel.setText("")
        self.insertionsLabel.setText("")
        self.deletionsLabel.setText("")

        if current:
            if current.data(0, self.TotalStatisticsRole) is None:
                args = self.vcs.initCommand("stash")
                args.append("show")
                args.append('--numstat')
                args.append(current.text(self.NameColumn))

                output = ""
                process = QProcess()
                process.setWorkingDirectory(self.repodir)
                process.start('git', args)
                procStarted = process.waitForStarted(5000)
                if procStarted:
                    finished = process.waitForFinished(30000)
                    if finished and process.exitCode() == 0:
                        output = str(process.readAllStandardOutput(),
                                     Preferences.getSystem("IOEncoding"),
                                     'replace')

                if output:
                    totals = {"files": 0, "additions": 0, "deletions": 0}
                    fileData = []
                    for line in output.splitlines():
                        additions, deletions, name = \
                            line.strip().split(None, 2)
                        totals["files"] += 1
                        if additions != "-":
                            totals["additions"] += int(additions)
                        if deletions != "-":
                            totals["deletions"] += int(deletions)
                        fileData.append({
                            "file":
                            name,
                            "total": ("-" if additions == "-" else
                                      str(int(additions) + int(deletions))),
                            "added":
                            additions,
                            "deleted":
                            deletions
                        })
                    current.setData(0, self.TotalStatisticsRole, totals)
                    current.setData(0, self.FileStatisticsRole, fileData)
                else:
                    return

            for dataDict in current.data(0, self.FileStatisticsRole):
                QTreeWidgetItem(self.statisticsList, [
                    dataDict["file"], dataDict["total"], dataDict["added"],
                    dataDict["deleted"]
                ])
            self.statisticsList.header().resizeSections(
                QHeaderView.ResizeToContents)
            self.statisticsList.header().setStretchLastSection(True)

            totals = current.data(0, self.TotalStatisticsRole)
            self.filesLabel.setText(
                self.tr("%n file(s) changed", None, totals["files"]))
            self.insertionsLabel.setText(
                self.tr("%n line(s) inserted", None, int(totals["additions"])))
            self.deletionsLabel.setText(
                self.tr("%n line(s) deleted", None, int(totals["deletions"])))

    @pyqtSlot(QPoint)
    def on_stashList_customContextMenuRequested(self, pos):
        """
        Private slot to show the context menu of the stash list.
        
        @param pos position of the mouse pointer (QPoint)
        """
        enable = len(self.stashList.selectedItems()) == 1
        self.__differencesAct.setEnabled(enable)
        self.__applyAct.setEnabled(enable)
        self.__popAct.setEnabled(enable)
        self.__branchAct.setEnabled(enable)
        self.__dropAct.setEnabled(enable)
        self.__clearAct.setEnabled(self.stashList.topLevelItemCount() > 0)

        self.__contextMenu.popup(self.mapToGlobal(pos))

    @pyqtSlot()
    def on_refreshButton_clicked(self):
        """
        Private slot to refresh the list of shelves.
        """
        self.start(self.__projectDir)

    @pyqtSlot()
    def on_sendButton_clicked(self):
        """
        Private slot to send the input to the git process.
        """
        inputTxt = self.input.text()
        inputTxt += os.linesep

        if self.passwordCheckBox.isChecked():
            self.errors.insertPlainText(os.linesep)
            self.errors.ensureCursorVisible()
        else:
            self.errors.insertPlainText(inputTxt)
            self.errors.ensureCursorVisible()
        self.errorGroup.show()

        self.process.write(inputTxt)

        self.passwordCheckBox.setChecked(False)
        self.input.clear()

    @pyqtSlot()
    def on_input_returnPressed(self):
        """
        Private slot to handle the press of the return key in the input field.
        """
        self.intercept = True
        self.on_sendButton_clicked()

    @pyqtSlot(bool)
    def on_passwordCheckBox_toggled(self, checked):
        """
        Private slot to handle the password checkbox toggled.
        
        @param checked flag indicating the status of the check box (boolean)
        """
        if checked:
            self.input.setEchoMode(QLineEdit.Password)
        else:
            self.input.setEchoMode(QLineEdit.Normal)

    def keyPressEvent(self, evt):
        """
        Protected slot to handle a key press event.
        
        @param evt the key press event (QKeyEvent)
        """
        if self.intercept:
            self.intercept = False
            evt.accept()
            return
        super(GitStashBrowserDialog, self).keyPressEvent(evt)

    def __showPatch(self):
        """
        Private slot to show the contents of the selected stash.
        """
        stashName = self.stashList.selectedItems()[0].text(self.NameColumn)
        self.vcs.gitStashShowPatch(self.__projectDir, stashName)

    def __apply(self):
        """
        Private slot to apply the selected stash but keep it.
        """
        stashName = self.stashList.selectedItems()[0].text(self.NameColumn)
        self.vcs.gitStashApply(self.__projectDir, stashName)

    def __pop(self):
        """
        Private slot to apply the selected stash and delete it.
        """
        stashName = self.stashList.selectedItems()[0].text(self.NameColumn)
        self.vcs.gitStashPop(self.__projectDir, stashName)
        self.on_refreshButton_clicked()

    def __branch(self):
        """
        Private slot to create a branch from the selected stash.
        """
        stashName = self.stashList.selectedItems()[0].text(self.NameColumn)
        self.vcs.gitStashBranch(self.__projectDir, stashName)
        self.on_refreshButton_clicked()

    def __drop(self):
        """
        Private slot to delete the selected stash.
        """
        stashName = self.stashList.selectedItems()[0].text(self.NameColumn)
        res = self.vcs.gitStashDrop(self.__projectDir, stashName)
        if res:
            self.on_refreshButton_clicked()

    def __clear(self):
        """
        Private slot to delete all stashes.
        """
        res = self.vcs.gitStashClear(self.__projectDir)
        if res:
            self.on_refreshButton_clicked()
Beispiel #33
0
class Dialog(QDialog):
    NumGridRows = 3
    NumButtons = 4

    def __init__(self, extra, synth, decoders, set_decoder):
        super(Dialog, self).__init__()

        self.synth = synth
        self.decoders = decoders
        self.set_decoder = set_decoder

        self.createMenu()
        self.createAudioControls()
        self.createDatasetControls()
        self.createGridGroupBox()

        mainLayout = QVBoxLayout()
        mainLayout.setMenuBar(self.menuBar)
        vLayout = QVBoxLayout()
        vLayout.addWidget(self.audioControls)
        # vLayout.addWidget(self.datasetControls)
        vLayout.addWidget(self.gridGroupBox)
        hLayout = QHBoxLayout()
        vGroupBox = QGroupBox()
        vGroupBox.setLayout(vLayout)
        hLayout.addWidget(vGroupBox)
        hLayout.addWidget(extra)
        hGroupBox = QGroupBox()
        hGroupBox.setLayout(hLayout)
        hGroupBox.setFlat(True)
        title = QLabel("Sounderfeit")
        title.setStyleSheet("font-size: 20pt; font-weight: bold;")
        mainLayout.addWidget(title)
        mainLayout.addWidget(hGroupBox)
        self.setLayout(mainLayout)

        self.setWindowTitle("Sounderfeit")

    def createMenu(self):
        self.menuBar = QMenuBar()

        self.fileMenu = QMenu("&File", self)
        self.exitAction = self.fileMenu.addAction("E&xit")
        self.menuBar.addMenu(self.fileMenu)

        self.exitAction.triggered.connect(self.accept)

    def createAudioControls(self):
        self.audioControls = QGroupBox("Audio")
        vlayout = QVBoxLayout()

        layout = QHBoxLayout()
        button = QPushButton("Play")
        button.clicked.connect(lambda: self.synth.start())
        layout.addWidget(button)
        button = QPushButton("Stop")
        button.clicked.connect(lambda: self.synth.stop())
        layout.addWidget(button)

        layout2 = QVBoxLayout()
        for n, d in enumerate(self.decoders):
            button = QRadioButton(d)
            button.setChecked(n == 0)

            def make_clicked(d, button):
                def clicked():
                    if button.isChecked():
                        self.set_decoder(d)
                        print('Decoder set to', d)
                        self.synth.setMode(0)

                return clicked

            button.clicked.connect(make_clicked(d, button))
            layout2.addWidget(button)
        button = QRadioButton("STK Bowed")
        button.clicked.connect(lambda: self.synth.setMode(1))
        layout2.addWidget(button)

        vlayout.addLayout(layout)
        vlayout.addLayout(layout2)
        self.audioControls.setLayout(vlayout)

    def createDatasetControls(self):
        self.datasetControls = QGroupBox("Dataset")
        layout = QHBoxLayout()
        button = QPushButton("Load")
        layout.addWidget(button)
        button = QPushButton("Train")
        layout.addWidget(button)

        self.datasetControls.setLayout(layout)

    def createGridGroupBox(self):
        self.gridGroupBox = QGroupBox("Parameters")
        layout = QGridLayout()
        volume_slider = QSlider()
        volume_slider.setRange(0, 128)
        volume_slider.setValue(64)
        position_slider = QSlider()
        position_slider.setRange(0, 64)
        position_slider.setValue(32)
        pressure_slider = QSlider()
        pressure_slider.setRange(0, 128)
        pressure_slider.setValue(64)
        latent1_slider = QSlider()
        latent1_slider.setRange(0, 128)
        latent1_slider.setValue(64)
        layout.addWidget(volume_slider, 0, 0, alignment=Qt.AlignHCenter)
        layout.addWidget(QLabel('volume'), 1, 0, alignment=Qt.AlignHCenter)
        layout.addWidget(position_slider, 0, 1, alignment=Qt.AlignHCenter)
        layout.addWidget(QLabel('position'), 1, 1, alignment=Qt.AlignHCenter)
        layout.addWidget(pressure_slider, 0, 2, alignment=Qt.AlignHCenter)
        layout.addWidget(QLabel('pressure'), 1, 2, alignment=Qt.AlignHCenter)
        layout.addWidget(latent1_slider, 0, 3, alignment=Qt.AlignHCenter)
        layout.addWidget(QLabel('latent1'), 1, 3, alignment=Qt.AlignHCenter)
        self.gridGroupBox.setLayout(layout)

        position_slider.valueChanged.connect(
            lambda: self.synth.setParam(0, position_slider.value()))

        pressure_slider.valueChanged.connect(
            lambda: self.synth.setParam(1, pressure_slider.value()))

        volume_slider.valueChanged.connect(
            lambda: self.synth.setParam(2,
                                        volume_slider.value() / 128.0))

        latent1_slider.valueChanged.connect(
            lambda: self.synth.setParam(3,
                                        latent1_slider.value() / 128.0))
Beispiel #34
0
class Tray(QSystemTrayIcon):
    def __init__(self, app):
        """
        type app: feeluown.app.App
        """
        super().__init__()
        self._app = app
        self._app_old_state = None  #: app window state before minimized

        # setup context menu
        self._menu = QMenu()
        self._status_action = QAction('...')
        self._toggle_player_action = QAction(QIcon.fromTheme('media-play'),
                                             TOGGLE_PLAYER_TEXT[0])
        self._next_action = QAction(QIcon.fromTheme('media-skip-forward'),
                                    '下一首')
        self._prev_action = QAction(QIcon.fromTheme('media-skip-backward'),
                                    '上一首')
        self._quit_action = QAction(QIcon.fromTheme('exit'), '退出')
        # add toggle_app action for macOS, on other platforms, user
        # can click the tray icon to toggle_app
        if IS_MACOS:
            self._toggle_app_action = QAction(QIcon.fromTheme('window'),
                                              TOGGLE_APP_TEXT[1])
        else:
            self._toggle_app_action = None
            self.activated.connect(self._toggle_app_state)  # noqa

        # bind signals
        self._quit_action.triggered.connect(self._app.exit)
        self._toggle_player_action.triggered.connect(self._app.player.toggle)
        self._prev_action.triggered.connect(self._app.playlist.previous)
        self._next_action.triggered.connect(self._app.playlist.next)
        if self._toggle_app_action is not None:
            self._toggle_app_action.triggered.connect(self._toggle_app_state)
        self._app.player.state_changed.connect(self.on_player_state_changed)
        self._app.playlist.song_changed.connect(self.on_player_song_changed)
        self._app.theme_mgr.theme_changed.connect(self.on_theme_changed)
        q_app = QApplication.instance()
        q_app.applicationStateChanged.connect(self.on_app_state_changed)

        self._app.installEventFilter(self)
        self.setContextMenu(self._menu)
        self.setup_ui()

    def initialize(self):
        self._set_icon()
        self._status_action.setIcon(self.icon())
        self.show()

    def setup_ui(self):
        self._menu.addAction(self._status_action)
        self._menu.addAction(self._toggle_player_action)
        self._menu.addAction(self._prev_action)
        self._menu.addAction(self._next_action)
        self._menu.addSeparator()
        if self._toggle_app_action is not None:
            self._menu.addAction(self._toggle_app_action)
        self._menu.addAction(self._quit_action)
        self._status_action.setEnabled(False)

    def _toggle_app_state(self):
        """activate/deactivate app"""
        if self._app.isHidden():
            self._app.show()
            self._app.activateWindow()
        elif self._app.isMinimized():
            self._app.setWindowState(self._app_old_state)
        else:
            self._app.hide()

    def _set_icon(self):
        # respect system icon
        icon = QIcon.fromTheme('feeluown-tray',
                               QIcon(self._app.theme_mgr.get_icon('tray')))
        self.setIcon(icon)

    def on_theme_changed(self, _):
        self._set_icon()

    def on_player_song_changed(self, song):
        if song is not None:
            status = f'{song.title_display} - {song.artists_name_display}'
            if self._app.config.NOTIFY_ON_TRACK_CHANGED:
                # TODO: show song cover if possible
                self.showMessage(song.title_display,
                                 song.artists_name_display,
                                 msecs=self._app.config.NOTIFY_DURATION)
            self._status_action.setText(elided_text(status, 120))
            self._status_action.setToolTip(status)
            self.setToolTip(status)

    def on_player_state_changed(self, state):
        if state == State.playing:
            self._toggle_player_action.setText(TOGGLE_PLAYER_TEXT[1])
            self._toggle_player_action.setIcon(QIcon.fromTheme('media-pause'))
            self._toggle_player_action.setEnabled(True)
        else:
            self._toggle_player_action.setText(TOGGLE_PLAYER_TEXT[0])
            self._toggle_player_action.setIcon(QIcon.fromTheme('media-play'))
            if state == State.stopped:
                self._toggle_player_action.setEnabled(False)
            else:
                self._toggle_player_action.setEnabled(True)

    def on_app_state_changed(self, state):
        if state == Qt.ApplicationActive:
            # On macOS, when the app is hidden, there will be an icon on the
            # macOS dock, if user click the dock, we should activate the app window.
            # For other platforms(Win32/Linux), the dock icon is not visible if
            # the window is hidden/closed.
            #
            # When the state will be changed to QApplicationActive?
            # * the dock icon is clicked (on macOS)
            # * the Qt.Tool widget got focus (on macOS and Linux)
            # * the Qt.Window widget got focus (on Linux)
            if IS_MACOS:
                self._app.show()
                self._app.activateWindow()
        elif state == Qt.ApplicationInactive:
            # when app window is not the top window, it changes to inactive
            if self._toggle_app_action is not None:
                self._toggle_app_action.setText(TOGGLE_APP_TEXT[0])

    def eventFilter(self, obj, event):
        """event filter for app"""
        app_text_idx = None
        if event.type() == QEvent.WindowStateChange:
            # when window is maximized before minimized, the window state will
            # be Qt.WindowMinimized | Qt.WindowMaximized
            if obj.windowState() & Qt.WindowMinimized:
                self._app_old_state = event.oldState()
                app_text_idx = 0
            else:
                app_text_idx = 1
        elif event.type() == QEvent.Hide:
            app_text_idx = 0
        elif event.type() == QEvent.Show:
            app_text_idx = 1
        if app_text_idx is not None and self._toggle_app_action is not None:
            self._toggle_app_action.setText(TOGGLE_APP_TEXT[app_text_idx])
        return False
Beispiel #35
0
class EditorWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.resize(settings().value("MainWindow/size") or QSize(1280, 720))
        self.setWindowTitle("untitled")
        if int(settings().value("MainWindow/maximized") or 0):
            self.showMaximized()

        self.setCentralWidget(QWidget())
        self.setMenuBar(QMenuBar())
        self.setStatusBar(QStatusBar())
        self.centralWidget().setLayout(QHBoxLayout())
        self.centralWidget().layout().setSpacing(0)
        self.centralWidget().layout().setContentsMargins(0, 0, 0, 0)

        self.splitter = QSplitter()
        self.centralWidget().layout().addWidget(self.splitter)

        self.projectTree = ProjectTree(self)
        # self.projectTree.hide()
        self.splitter.addWidget(self.projectTree)

        self.tabwidget = TabWidget(self)
        self.splitter.addWidget(self.tabwidget)

        self.splitter.setSizes((int(settings().value("Sizes/splitter0")
                                    or self.splitter.sizeHint().width() * .2),
                                int(settings().value("Sizes/splitter1")
                                    or self.splitter.sizeHint().width() * .8)))

        #menüler
        self.fileMenu = QMenu(self.tr("File"))
        self.newFileActionMenu = QMenu(self.tr("New"))
        self.newPlainFileAction = QAction(self.tr("File"),
                                          icon=QIcon(":/img/text-plain.svg"))
        self.newFileActionMenu.addAction(self.newPlainFileAction)
        self.newPythonFileAction = QAction(self.tr("Python File"),
                                           icon=QIcon(":/img/text-python.svg"))
        self.newFileActionMenu.addAction(self.newPythonFileAction)
        self.newDirectoryAction = QAction(self.tr("Directory"),
                                          icon=QIcon(":/img/folder.svg"))
        self.newFileActionMenu.addAction(self.newDirectoryAction)
        self.newPythonPackageAction = QAction(
            self.tr("Python Package"), icon=QIcon(":/img/folder-python.svg"))
        self.newFileActionMenu.addAction(self.newPythonPackageAction)
        self.newFileActionMenu.addSeparator()
        self.newHtmlFileAction = QAction(self.tr("Html File"),
                                         icon=QIcon(":/img/text-html.svg"))
        self.newFileActionMenu.addAction(self.newHtmlFileAction)
        self.newCssFileAction = QAction(self.tr("Css File"),
                                        icon=QIcon(":/img/text-css.svg"))
        self.newFileActionMenu.addAction(self.newCssFileAction)
        self.newJsFileAction = QAction(self.tr("JavaScript File"),
                                       icon=QIcon(":/img/text-javascript.svg"))
        self.newFileActionMenu.addAction(self.newJsFileAction)
        self.newJsonFileAction = QAction(self.tr("Json File"),
                                         icon=QIcon(":/img/text-plain.svg"))
        self.newFileActionMenu.addAction(self.newJsonFileAction)
        self.newXmlFileAction = QAction(self.tr("Xml File"),
                                        icon=QIcon(":/img/text-xml.svg"))
        self.newFileActionMenu.addAction(self.newXmlFileAction)
        self.newYamlFileAction = QAction(self.tr("Yaml File"),
                                         icon=QIcon(":/img/text-plain.svg"))
        self.newFileActionMenu.addAction(self.newYamlFileAction)
        self.newSqlFileAction = QAction(self.tr("Sqlite File"),
                                        icon=QIcon(":/img/text-sql.svg"))
        self.newFileActionMenu.addAction(self.newSqlFileAction)
        self.newMdFileAction = QAction(self.tr("Markdown File"),
                                       icon=QIcon(":/img/text-plain.svg"))
        self.newFileActionMenu.addAction(self.newMdFileAction)
        self.fileMenu.addMenu(self.newFileActionMenu)

        self.newProjectAction = QAction(self.tr("New Project"))
        self.fileMenu.addAction(self.newProjectAction)
        self.openFileAction = QAction(self.tr("Open File..."))
        self.openFileAction.setShortcut("Ctrl+O")
        self.fileMenu.addAction(self.openFileAction)
        self.openProjectAction = QAction(self.tr("Open Project..."))
        self.openProjectAction.setShortcut("Ctrl+Alt+O")
        self.fileMenu.addAction(self.openProjectAction)
        self.openRecentFileActionMenu = QMenu(self.tr("Open Recent..."))
        self.fileMenu.addMenu(self.openRecentFileActionMenu)
        self.saveFileAction = QAction(self.tr("Save"))
        self.saveFileAction.setShortcut("Ctrl+S")
        self.fileMenu.addAction(self.saveFileAction)
        self.saveAsAction = QAction(self.tr("Save As..."))
        self.saveAsAction.setShortcut("Ctrl+Alt+S")
        self.fileMenu.addAction(self.saveAsAction)
        self.fileMenu.addSeparator()
        self.closeFileAction = QAction(self.tr("Close File"))
        self.closeFileAction.setShortcut("Ctrl+W")
        self.fileMenu.addAction(self.closeFileAction)
        self.closeAllFilesAction = QAction(self.tr("Close All File"))
        self.fileMenu.addAction(self.closeAllFilesAction)
        self.fileMenu.addSeparator()
        self.exitAction = QAction(self.tr("Exit"))
        self.exitAction.setShortcut("Ctrl+Q")
        self.fileMenu.addAction(self.exitAction)
        self.menuBar().addMenu(self.fileMenu)

        self.editMenu = QMenu(self.tr("Edit"))
        self.undoAction = QAction(self.tr("Undo"))
        self.undoAction.setShortcut("Ctrl+Z")
        self.undoAction.setShortcutVisibleInContextMenu(True)
        self.editMenu.addAction(self.undoAction)
        self.redoAction = QAction(self.tr("Redo"))
        self.redoAction.setShortcut("Ctrl+Y")
        self.redoAction.setShortcutVisibleInContextMenu(True)
        self.editMenu.addAction(self.redoAction)
        self.editMenu.addSeparator()
        self.copyAction = QAction(self.tr("Copy"))
        self.copyAction.setShortcutVisibleInContextMenu(True)
        self.copyAction.setShortcut("Ctrl+C")
        self.editMenu.addAction(self.copyAction)
        self.cutAction = QAction(self.tr("Cut"))
        self.cutAction.setShortcut("Ctrl+X")
        self.cutAction.setShortcutVisibleInContextMenu(True)
        self.editMenu.addAction(self.cutAction)
        self.pasteAction = QAction(self.tr("Paste"))
        self.pasteAction.setShortcut("Ctrl+V")
        self.pasteAction.setShortcutVisibleInContextMenu(True)
        self.editMenu.addAction(self.pasteAction)
        self.editMenu.addSeparator()
        # self.wrapActionMenu = QMenu(self.tr("Wrap"))
        # self.editMenu.addMenu(self.wrapActionMenu)
        self.menuBar().addMenu(self.editMenu)

        self.findMenu = QMenu(self.tr("Find"))
        self.findAction = QAction(self.tr("Find..."))
        self.findAction.setShortcut("Ctrl+F")
        self.findMenu.addAction(self.findAction)
        self.findNextAction = QAction(self.tr("Find Next"))
        self.findNextAction.setShortcut("F3")
        self.findMenu.addAction(self.findNextAction)
        self.findPreviousAction = QAction(self.tr("Find Previous"))
        self.findPreviousAction.setShortcut("Shift+F3")
        self.findMenu.addAction(self.findPreviousAction)
        self.findMenu.addSeparator()
        self.replaceAction = QAction(self.tr("Replace"))
        self.replaceAction.setShortcut("Ctrl+H")
        self.findMenu.addAction(self.replaceAction)
        self.replaceNextAction = QAction(self.tr("Replace Next"))
        self.replaceNextAction.setShortcut("Ctrl+Shift+H")
        self.findMenu.addAction(self.replaceNextAction)
        self.menuBar().addMenu(self.findMenu)

        # self.viewMenu = QMenu(self.tr("View"))
        # self.layoutActionMenu = QMenu(self.tr("Layout"))
        # self.viewMenu.addMenu(self.layoutActionMenu)
        # self.groupsActionMenu = QMenu(self.tr("Groups"))
        # self.viewMenu.addMenu(self.groupsActionMenu)
        # self.focusGroupActionMenu = QMenu(self.tr("Focus Group"))
        # self.viewMenu.addMenu(self.focusGroupActionMenu)
        # self.moveFileGroupActionMenu = QMenu(self.tr("Move File to Group"))
        # self.viewMenu.addMenu(self.moveFileGroupActionMenu)
        # self.viewMenu.addSeparator()
        # self.syntaxActionMenu = QMenu(self.tr("Syntax"))
        # self.viewMenu.addMenu(self.syntaxActionMenu)
        # self.indentationActionMenu = QMenu(self.tr("Indentation"))
        # self.viewMenu.addMenu(self.indentationActionMenu)
        # self.lineEndingsActionMenu = QMenu(self.tr("Line Endings"))
        # self.viewMenu.addMenu(self.lineEndingsActionMenu)
        # self.viewMenu.addSeparator()
        # self.menuBar().addMenu(self.viewMenu)

        self.toolsMenu = QMenu(self.tr("Tools"))
        self.snippetsAction = QAction(self.tr("Snippets..."))
        self.toolsMenu.addAction(self.snippetsAction)
        self.toolsMenu.addSeparator()
        self.runAction = QAction(self.tr("Run"))
        self.runAction.setShortcut("F5")
        self.toolsMenu.addAction(self.runAction)
        self.runWithAction = QAction(self.tr("Run With..."))
        self.runWithAction.setShortcut("F6")
        self.toolsMenu.addAction(self.runWithAction)
        self.toolsMenu.addSeparator()
        self.recordMacroAction = QAction(self.tr("Record Macro"))
        self.toolsMenu.addAction(self.recordMacroAction)
        self.playbackMacroAction = QAction(self.tr("Playback Macro"))
        self.toolsMenu.addAction(self.playbackMacroAction)
        self.saveMacroAction = QAction(self.tr("Save Macro..."))
        self.toolsMenu.addAction(self.saveMacroAction)
        self.macrosActionMenu = QMenu(self.tr("Macros"))
        self.toolsMenu.addMenu(self.macrosActionMenu)
        self.menuBar().addMenu(self.toolsMenu)

        self.helpMenu = QMenu(self.tr("Help"))
        self.documentationAction = QAction(self.tr("Documentation"))
        self.helpMenu.addAction(self.documentationAction)
        self.donateAction = QAction(self.tr("Donate"))
        self.helpMenu.addAction(self.donateAction)
        self.helpMenu.addSeparator()
        self.checkAction = QAction(self.tr("Check for Updates..."))
        self.helpMenu.addAction(self.checkAction)
        self.changelogAction = QAction(self.tr("Changelog..."))
        self.helpMenu.addAction(self.changelogAction)
        self.aboutAction = QAction(self.tr("About Untitled Editor"))
        self.helpMenu.addAction(self.aboutAction)
        self.menuBar().addMenu(self.helpMenu)

    def setWindowTitle(self, title):
        super().setWindowTitle(title + " - " + "Untitled Editor")

    def closeEvent(self, *args, **kwargs):
        settings().setValue("Sizes/splitter0", self.projectTree.width())
        settings().setValue("Sizes/splitter1", self.tabwidget.width())
        settings().setValue("MainWindow/maximized", int(self.isMaximized()))
        settings().setValue("MainWindow/size", self.size())

        settings().sync()

    def retranslateui(self):
        pass
Beispiel #36
0
class MainWindowUI(object):
    def setup_ui(self, MainWin):

        # Main Window
        MainWin.setObjectName("MainWindow")
        MainWin.setWindowTitle(MainWin.tr("BDBag"))
        MainWin.resize(680, 600)
        self.centralWidget = QWidget(MainWin)
        self.centralWidget.setObjectName("centralWidget")
        MainWin.setCentralWidget(self.centralWidget)
        self.verticalLayout = QVBoxLayout(self.centralWidget)
        self.verticalLayout.setContentsMargins(11, 11, 11, 11)
        self.verticalLayout.setSpacing(6)
        self.verticalLayout.setObjectName("verticalLayout")

        # Actions

        # Create/Update
        self.actionCreateOrUpdate = QAction(MainWin)
        self.actionCreateOrUpdate.setObjectName("actionCreateOrUpdate")

        # Revert
        self.actionRevert = QAction(MainWin)
        self.actionRevert.setObjectName("actionRevert")
        self.actionRevert.setText(MainWin.tr("Revert"))
        self.actionRevert.setToolTip(
            MainWin.tr("Revert a bag directory back to a normal directory."))
        self.actionRevert.setShortcut(MainWin.tr("Ctrl+R"))

        # Validate Fast
        self.actionValidateFast = QAction(MainWin)
        self.actionValidateFast.setObjectName("actionValidateFast")
        self.actionValidateFast.setText(MainWin.tr("Validate: Fast"))
        self.actionValidateFast.setToolTip(
            MainWin.
            tr("Perform fast validation by checking the payload file counts and sizes against the Payload-0xum "
               "value from the bag manifest"))
        self.actionValidateFast.setShortcut(MainWin.tr("Ctrl+F"))

        # Validate Full
        self.actionValidateFull = QAction(MainWin)
        self.actionValidateFull.setObjectName("actionValidateFull")
        self.actionValidateFull.setText(MainWin.tr("Validate: Full"))
        self.actionValidateFull.setToolTip(
            MainWin.
            tr("Perform full validation by calculating checksums for all files and comparing them against "
               "entries in the bag manifest(s)"))
        self.actionValidateFull.setShortcut(MainWin.tr("Ctrl+V"))

        # Fetch Missing
        self.actionFetchMissing = QAction(MainWin)
        self.actionFetchMissing.setObjectName("actionFetchMissing")
        self.actionFetchMissing.setText(MainWin.tr("Fetch: Missing"))
        self.actionFetchMissing.setToolTip(
            MainWin.
            tr("Fetch only those remote files that are not already present in the bag"
               ))
        self.actionFetchMissing.setShortcut(MainWin.tr("Ctrl+M"))

        # Fetch All
        self.actionFetchAll = QAction(MainWin)
        self.actionFetchAll.setObjectName("actionFetchAll")
        self.actionFetchAll.setText(MainWin.tr("Fetch: All"))
        self.actionFetchAll.setToolTip(
            MainWin.
            tr("Fetch all remote files, even if they are already present in the bag"
               ))
        self.actionFetchAll.setShortcut(MainWin.tr("Ctrl+A"))

        # Archive ZIP
        self.actionArchiveZIP = QAction(MainWin)
        self.actionArchiveZIP.setObjectName("actionArchiveZIP")
        self.actionArchiveZIP.setText(MainWin.tr("Archive: ZIP"))
        self.actionArchiveZIP.setToolTip(
            MainWin.tr("Create a ZIP format archive of the bag."))
        self.actionArchiveZIP.setShortcut(MainWin.tr("Ctrl+Z"))

        # Archive TGZ
        self.actionArchiveTGZ = QAction(MainWin)
        self.actionArchiveTGZ.setObjectName("actionArchiveTGZ")
        self.actionArchiveTGZ.setText(MainWin.tr("Archive: TGZ"))
        self.actionArchiveTGZ.setToolTip(
            MainWin.tr("Create a TAR/GZIP format archive of the bag."))
        self.actionArchiveTGZ.setShortcut(MainWin.tr("Ctrl+T"))

        # Options
        self.actionOptions = QAction(MainWin)
        self.actionOptions.setObjectName("actionOptions")
        self.actionOptions.setText(MainWin.tr("Options"))
        self.actionOptions.setToolTip(MainWin.tr("Configuration options."))
        self.actionOptions.setShortcut(MainWin.tr("Ctrl+O"))

        # Cancel
        self.actionCancel = QAction(MainWin)
        self.actionCancel.setObjectName("actionCancel")
        self.actionCancel.setText(MainWin.tr("Cancel"))
        self.actionCancel.setToolTip(
            MainWin.tr("Cancel the current background task."))
        self.actionCancel.setShortcut(MainWin.tr("Ctrl+C"))

        # About
        self.actionAbout = QAction(MainWin)
        self.actionAbout.setObjectName("actionAbout")
        self.actionAbout.setText(MainWin.tr("About"))
        self.actionAbout.setToolTip(MainWin.tr("Show version information."))
        self.actionAbout.setShortcut(MainWin.tr("Ctrl+B"))

        # Tree View
        self.treeView = QTreeView(self.centralWidget)
        self.treeView.setObjectName("treeView")
        self.treeView.setStyleSheet("""
            QTreeView {
                    border: 2px solid grey;
                    border-radius: 5px;
            }
            """)
        self.verticalLayout.addWidget(self.treeView)

        # Log Widget

        self.logTextBrowser = log_widget.QPlainTextEditLogger(
            self.centralWidget)
        self.logTextBrowser.widget.setObjectName("logTextBrowser")
        self.logTextBrowser.widget.setStyleSheet("""
            QPlainTextEdit {
                    border: 2px solid grey;
                    border-radius: 5px;
                    background-color: lightgray;
            }
            """)
        self.verticalLayout.addWidget(self.logTextBrowser.widget)

        # Menu Bar

        self.menuBar = QMenuBar(MainWin)
        self.menuBar.setObjectName("menuBar")
        MainWin.setMenuBar(self.menuBar)

        # Bag Menu
        self.menuBag = QMenu(self.menuBar)
        self.menuBag.setObjectName("menuBag")
        self.menuBag.setTitle(MainWin.tr("Bag"))
        self.menuBar.addAction(self.menuBag.menuAction())
        self.menuBag.addAction(self.actionCreateOrUpdate)
        self.menuBag.addAction(self.actionRevert)
        self.menuBag.addAction(self.actionCancel)
        self.menuBag.addAction(self.actionOptions)

        # Fetch Menu
        self.menuFetch = QMenu(self.menuBag)
        self.menuFetch.setObjectName("menuFetch")
        self.menuFetch.setTitle(MainWin.tr("Fetch"))
        self.menuFetch.addAction(self.actionFetchMissing)
        self.menuFetch.addAction(self.actionFetchAll)
        self.menuBag.addAction(self.menuFetch.menuAction())

        # Validate Menu
        self.menuValidate = QMenu(self.menuBag)
        self.menuValidate.setObjectName("menuValidate")
        self.menuValidate.setTitle(MainWin.tr("Validate"))
        self.menuValidate.addAction(self.actionValidateFast)
        self.menuValidate.addAction(self.actionValidateFull)
        self.menuBag.addAction(self.menuValidate.menuAction())

        # Archive Menu
        self.menuArchive = QMenu(self.menuBag)
        self.menuArchive.setObjectName("menuArchive")
        self.menuArchive.setTitle(MainWin.tr("Archive"))
        self.menuArchive.addAction(self.actionArchiveZIP)
        self.menuArchive.addAction(self.actionArchiveTGZ)
        self.menuBag.addAction(self.menuArchive.menuAction())

        # Help Menu
        self.menuHelp = QMenu(self.menuBar)
        self.menuHelp.setObjectName("menuHelp")
        self.menuHelp.setTitle(MainWin.tr("Help"))
        self.menuHelp.addAction(self.actionAbout)
        self.menuBar.addAction(self.menuHelp.menuAction())

        # Tool Bar

        self.mainToolBar = QToolBar(MainWin)
        self.mainToolBar.setObjectName("mainToolBar")
        self.mainToolBar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        MainWin.addToolBar(Qt.TopToolBarArea, self.mainToolBar)

        # Create/Update
        self.mainToolBar.addAction(self.actionCreateOrUpdate)
        self.actionCreateOrUpdate.setIcon(
            self.actionCreateOrUpdate.parentWidget().style().standardIcon(
                getattr(QStyle, "SP_FileDialogNewFolder")))

        # Revert
        self.mainToolBar.addAction(self.actionRevert)
        self.actionRevert.setIcon(
            self.actionRevert.parentWidget().style().standardIcon(
                getattr(QStyle, "SP_DialogOkButton")))

        # Fetch
        self.mainToolBar.addAction(self.actionFetchMissing)
        self.actionFetchMissing.setIcon(
            self.actionFetchMissing.parentWidget().style().standardIcon(
                getattr(QStyle, "SP_ArrowDown")))
        self.mainToolBar.addAction(self.actionFetchAll)
        self.actionFetchAll.setIcon(
            self.actionFetchAll.parentWidget().style().standardIcon(
                getattr(QStyle, "SP_ArrowDown")))

        # Validate
        self.mainToolBar.addAction(self.actionValidateFast)
        self.actionValidateFast.setIcon(
            self.actionValidateFast.parentWidget().style().standardIcon(
                getattr(QStyle, "SP_DialogApplyButton")))
        self.mainToolBar.addAction(self.actionValidateFull)
        self.actionValidateFull.setIcon(
            self.actionValidateFull.parentWidget().style().standardIcon(
                getattr(QStyle, "SP_DialogApplyButton")))

        # Archive
        self.mainToolBar.addAction(self.actionArchiveZIP)
        self.actionArchiveZIP.setIcon(
            self.actionArchiveZIP.parentWidget().style().standardIcon(
                getattr(QStyle, "SP_DialogSaveButton")))
        self.mainToolBar.addAction(self.actionArchiveTGZ)
        self.actionArchiveTGZ.setIcon(
            self.actionArchiveTGZ.parentWidget().style().standardIcon(
                getattr(QStyle, "SP_DialogSaveButton")))

        # Options
        self.mainToolBar.addAction(self.actionOptions)
        self.actionOptions.setIcon(
            self.actionOptions.parentWidget().style().standardIcon(
                getattr(QStyle, "SP_FileDialogDetailedView")))

        # Cancel
        self.mainToolBar.addAction(self.actionCancel)
        self.actionCancel.setIcon(
            self.actionCancel.parentWidget().style().standardIcon(
                getattr(QStyle, "SP_BrowserStop")))

        # Status Bar

        self.statusBar = QStatusBar(MainWin)
        self.statusBar.setToolTip("")
        self.statusBar.setStatusTip("")
        self.statusBar.setObjectName("statusBar")
        MainWin.setStatusBar(self.statusBar)

        # Progress Bar

        self.progressBar = QProgressBar(self.centralWidget)
        self.progressBar.setValue(0)
        self.progressBar.setTextVisible(False)
        self.progressBar.setObjectName("progressBar")
        self.progressBar.setStyleSheet("""
            QProgressBar {
                    border: 2px solid grey;
                    border-radius: 5px;
                    text-align: center;
            }
            QProgressBar::chunk {
                    background-color: darkblue;
                    width: 10px;
                    margin: 0.5px;
            }
            """)
        self.verticalLayout.addWidget(self.progressBar)

        # finalize UI setup
        self.toggleCreateOrUpdate(MainWin)
        QMetaObject.connectSlotsByName(MainWin)

    def toggleCreateOrUpdate(self, MainWin):
        if MainWin.isBag:
            self.actionCreateOrUpdate.setText(MainWin.tr("Update"))
            self.actionCreateOrUpdate.setToolTip(
                MainWin.tr("Update a bag in an existing directory"))
            self.actionCreateOrUpdate.setShortcut(MainWin.tr("Ctrl+U"))
        else:
            self.actionCreateOrUpdate.setText(MainWin.tr("Create"))
            self.actionCreateOrUpdate.setToolTip(
                MainWin.tr("Create a new bag from an existing directory"))
            self.actionCreateOrUpdate.setShortcut(MainWin.tr("Ctrl+N"))
Beispiel #37
0
    def create_menu(self, position):
        menu = QMenu()
        selected = self.selectedItems()
        if not selected:
            menu.addAction(_("New contact"),
                           lambda: self.parent.new_contact_dialog())
            menu.addAction(_("Import file"), lambda: self.import_contacts())
            menu.addAction(_("Export file"), lambda: self.export_contacts())
        else:
            names = [item.text(0) for item in selected]
            keys = [item.text(1) for item in selected]
            column = self.currentColumn()
            column_title = self.headerItem().text(column)
            column_data = '\n'.join([item.text(column) for item in selected])
            menu.addAction(
                _("Copy {}").format(column_title),
                lambda: self.parent.app.clipboard().setText(column_data))
            if column in self.editable_columns:
                item = self.currentItem()
                menu.addAction(
                    _("Edit {}").format(column_title),
                    lambda: self.editItem(item, column))
            menu.addAction(_("Pay to"),
                           lambda: self.parent.payto_contacts(keys))
            menu.addAction(_("Delete"),
                           lambda: self.parent.delete_contacts(keys))
            URLs = [
                block_explorer_URL(self.config, 'addr', key)
                for key in filter(is_address, keys)
            ]
            if URLs:
                menu.addAction(_("View on block explorer"),
                               lambda: map(webbrowser.open, URLs))

        run_hook('create_contact_menu', menu, selected)
        menu.exec_(self.viewport().mapToGlobal(position))
class ApplicationWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setWindowTitle("application main window")

        self.file_menu = QMenu('&File', self)
        self.file_menu.addAction('&Quit', self.fileQuit,
                                 QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
        self.menuBar().addMenu(self.file_menu)

        self.help_menu = QMenu('&Help', self)
        self.menuBar().addSeparator()
        self.menuBar().addMenu(self.help_menu)

        self.help_menu.addAction('&About', self.about)

        self.main_widget = QWidget(self)

        l = QVBoxLayout(self.main_widget)
        sc = MyStaticMplCanvas(self.main_widget,
                               width=5,
                               height=4,
                               dpi=100,
                               title='Title 1')
        dc = MyDynamicMplCanvas(self.main_widget,
                                width=5,
                                height=4,
                                dpi=100,
                                title='Title 2')
        scntb = NavigationToolbar(sc, self.main_widget)  # full toolbar
        dcntb = NavToolbar(dc, self.main_widget)  # only save button

        l.addWidget(sc)
        l.addWidget(scntb)
        #l.addWidget(dc)
        #l.addWidget(dcntb)

        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)

        self.statusBar().showMessage("All hail matplotlib!", 2000)

    def fileQuit(self):
        self.close()

    def closeEvent(self, ce):
        self.fileQuit()

    def about(self):
        QMessageBox.about(
            self, "About", """embedding_in_qt5.py example
  Copyright 2015 BoxControL

  This program is a simple example of a Qt5 application embedding matplotlib
  canvases. It is base on example from matplolib documentation, and initially was
  developed from Florent Rougon and Darren Dale.

  http://matplotlib.org/examples/user_interfaces/embedding_in_qt4.html

  It may be used and modified with no restriction; raw copies as well as
  modified versions may be distributed without limitation.""")
Beispiel #39
0
class CalcDlg(QWidget):
    """Main dialog for calculator program.
    """
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.calc = CalcCore()
        self.setWindowTitle('rpCalc')
        modPath = os.path.abspath(sys.path[0])
        if modPath.endswith('.zip') or modPath.endswith('.exe'):
            modPath = os.path.dirname(modPath)  # for py2exe/cx_freeze
        iconPathList = [iconPath, os.path.join(modPath, 'icons/'),
                         os.path.join(modPath, '../icons')]
        self.icons = icondict.IconDict()
        self.icons.addIconPath(filter(None, iconPathList))
        self.icons.addIconPath([path for path in iconPathList if path])
        try:
            QApplication.setWindowIcon(self.icons['calc_lg'])
        except KeyError:
            pass
        self.setFocusPolicy(Qt.StrongFocus)
        self.helpView = None
        self.extraView = None
        self.regView = None
        self.histView = None
        self.memView = None
        self.altBaseView = None
        self.optDlg = None
        self.popupMenu = QMenu(self)
        self.popupMenu.addAction('Registers on &LCD', self.toggleReg)
        self.popupMenu.addSeparator()
        self.popupMenu.addAction('Show &Register List', self.viewReg)
        self.popupMenu.addAction('Show &History List', self.viewHist)
        self.popupMenu.addAction('Show &Memory List', self.viewMem)
        self.popupMenu.addSeparator()
        self.popupMenu.addAction('Show Other &Bases', self.viewAltBases)
        self.popupMenu.addSeparator()
        self.popupMenu.addAction('Show Help &File', self.help)
        self.popupMenu.addAction('&About rpCalc', self.about)
        self.popupMenu.addSeparator()
        self.popupMenu.addAction('&Quit', self.close)
        topLay = QVBoxLayout(self)
        self.setLayout(topLay)
        topLay.setSpacing(4)
        topLay.setContentsMargins(6, 6, 6, 6)
        lcdBox = LcdBox()
        topLay.addWidget(lcdBox)
        lcdLay = QGridLayout(lcdBox)
        lcdLay.setColumnStretch(1, 1)
        lcdLay.setRowStretch(3, 1)
        self.extraLabels = [QLabel(' T:',), QLabel(' Z:',),
                            QLabel(' Y:',)]
        for i in range(3):
            lcdLay.addWidget(self.extraLabels[i], i, 0, Qt.AlignLeft)
        self.extraLcds = [Lcd(1.5, 13), Lcd(1.5, 13), Lcd(1.5, 13)]
        lcdLay.addWidget(self.extraLcds[2], 0, 1, Qt.AlignRight)
        lcdLay.addWidget(self.extraLcds[1], 1, 1, Qt.AlignRight)
        lcdLay.addWidget(self.extraLcds[0], 2, 1, Qt.AlignRight)
        if not self.calc.option.boolData('ViewRegisters'):
            for w in self.extraLabels + self.extraLcds:
                w.hide()
        self.lcd = Lcd(2.0, 13)
        lcdLay.addWidget(self.lcd, 3, 0, 1, 2, Qt.AlignRight)
        self.setLcdHighlight()
        self.updateLcd()
        self.updateColors()

        self.cmdLay = QGridLayout()
        topLay.addLayout(self.cmdLay)
        self.cmdDict = {}
        self.addCmdButton('x^2', 0, 0)
        self.addCmdButton('sqRT', 0, 1)
        self.addCmdButton('y^X', 0, 2)
        self.addCmdButton('xRT', 0, 3)
        self.addCmdButton('RCIP', 0, 4)
        self.addCmdButton('SIN', 1, 0)
        self.addCmdButton('COS', 1, 1)
        self.addCmdButton('TAN', 1, 2)
        self.addCmdButton('LN', 1, 3)
        self.addCmdButton('e^X', 1, 4)
        self.addCmdButton('ASIN', 2, 0)
        self.addCmdButton('ACOS', 2, 1)
        self.addCmdButton('ATAN', 2, 2)
        self.addCmdButton('LOG', 2, 3)
        self.addCmdButton('tn^X', 2, 4)
        self.addCmdButton('STO', 3, 0)
        self.addCmdButton('RCL', 3, 1)
        self.addCmdButton('R<', 3, 2)
        self.addCmdButton('R>', 3, 3)
        self.addCmdButton('x<>y', 3, 4)
        self.addCmdButton('SHOW', 4, 0)
        self.addCmdButton('CLR', 4, 1)
        self.addCmdButton('PLCS', 4, 2)
        self.addCmdButton('SCI', 4, 3)
        self.addCmdButton('DEG', 4, 4)
        self.addCmdButton('EXIT', 5, 0)
        self.addCmdButton('Pi', 5, 1)
        self.addCmdButton('EXP', 5, 2)
        self.addCmdButton('CHS', 5, 3)
        self.addCmdButton('<-', 5, 4)

        self.mainLay = QGridLayout()
        topLay.addLayout(self.mainLay)
        self.mainDict = {}
        self.addMainButton(0, 'OPT', 0, 0)
        self.addMainButton(Qt.Key_Slash, '/', 0, 1)
        self.addMainButton(Qt.Key_Asterisk, '*', 0, 2)
        self.addMainButton(Qt.Key_Minus, '-', 0, 3)
        self.addMainButton(Qt.Key_7, '7', 1, 0)
        self.addMainButton(Qt.Key_8, '8', 1, 1)
        self.addMainButton(Qt.Key_9, '9', 1, 2)
        self.addMainButton(Qt.Key_Plus, '+', 1, 3, 1, 0)
        self.addMainButton(Qt.Key_4, '4', 2, 0)
        self.addMainButton(Qt.Key_5, '5', 2, 1)
        self.addMainButton(Qt.Key_6, '6', 2, 2)
        self.addMainButton(Qt.Key_1, '1', 3, 0)
        self.addMainButton(Qt.Key_2, '2', 3, 1)
        self.addMainButton(Qt.Key_3, '3', 3, 2)
        self.addMainButton(Qt.Key_Enter, 'ENT', 3, 3, 1, 0)
        self.addMainButton(Qt.Key_0, '0', 4, 0, 0, 1)
        self.addMainButton(Qt.Key_Period, '.', 4, 2)

        self.mainDict[Qt.Key_Return] = \
                     self.mainDict[Qt.Key_Enter]
        # added for european keyboards:
        self.mainDict[Qt.Key_Comma] = \
                     self.mainDict[Qt.Key_Period]
        self.cmdDict['ENT'] = self.mainDict[Qt.Key_Enter]
        self.cmdDict['OPT'] = self.mainDict[0]

        self.entryStr = ''
        self.showMode = False

        statusBox = QFrame()
        statusBox.setFrameStyle(QFrame.Panel | QFrame.Sunken)
        statusBox.setSizePolicy(QSizePolicy(QSizePolicy.Preferred,
                                                  QSizePolicy.Preferred))
        topLay.addWidget(statusBox)
        statusLay = QHBoxLayout(statusBox)
        self.entryLabel = QLabel(statusBox)
        statusLay.addWidget(self.entryLabel)
        statusLay.setContentsMargins(1, 1, 1, 1)
        self.statusLabel = QLabel(statusBox)
        self.statusLabel.setAlignment(Qt.AlignRight)
        statusLay.addWidget(self.statusLabel)

        if self.calc.option.boolData('ExtraViewStartup'):
            self.viewReg()
        if self.calc.option.boolData('AltBaseStartup'):
            self.viewAltBases()

        xSize = self.calc.option.intData('MainDlgXSize', 0, 10000)
        ySize = self.calc.option.intData('MainDlgYSize', 0, 10000)
        if xSize and ySize:
            self.resize(xSize, ySize)
        self.move(self.calc.option.intData('MainDlgXPos', 0, 10000),
                  self.calc.option.intData('MainDlgYPos', 0, 10000))

        self.updateEntryLabel('rpCalc Version {0}'.format(__version__))
        QTimer.singleShot(5000, self.updateEntryLabel)

    def updateEntryLabel(self, subsText=''):
        """Set entry & status label text, use entryStr or subsText, options.
        """
        numFormat = self.calc.option.boolData('ForceSciNotation') and 'sci' \
                    or 'fix'
        decPlcs = self.calc.option.intData('NumDecimalPlaces', 0, 9)
        angle = self.calc.option.strData('AngleUnit')
        self.statusLabel.setText('{0} {1}  {2}'.format(numFormat, decPlcs,
                                                       angle))
        self.entryLabel.setText(subsText or '> {0}'.format(self.entryStr))

    def setOptions(self):
        """Starts option dialog, called by option key.
        """
        oldViewReg = self.calc.option.boolData('ViewRegisters')
        self.optDlg = optiondlg.OptionDlg(self.calc.option, self)
        self.optDlg.startGroupBox('Startup', 8)
        optiondlg.OptionDlgBool(self.optDlg, 'SaveStacks',
                                'Save previous entries')
        optiondlg.OptionDlgBool(self.optDlg, 'ExtraViewStartup',
                                'Auto open extra data view')
        optiondlg.OptionDlgBool(self.optDlg, 'AltBaseStartup',
                                'Auto open alternate base view')
        self.optDlg.startGroupBox('Display', 8)
        optiondlg.OptionDlgInt(self.optDlg, 'NumDecimalPlaces',
                               'Number of decimal places', 0, 9)
        optiondlg.OptionDlgBool(self.optDlg, 'ThousandsSeparator',
                                'Separate thousands with spaces')
        optiondlg.OptionDlgBool(self.optDlg, 'ForceSciNotation',
                                'Always show exponent')
        optiondlg.OptionDlgBool(self.optDlg, 'UseEngNotation',
                                'Use engineering notation')
        optiondlg.OptionDlgBool(self.optDlg, 'TrimExponents',
                                'Hide exponent leading zeros')
        optiondlg.OptionDlgBool(self.optDlg, 'ViewRegisters',
                                'View Registers on LCD')
        optiondlg.OptionDlgBool(self.optDlg, 'HideLcdHighlight',
                                'Hide LCD highlight')
        self.optDlg.startNewColumn()
        optiondlg.OptionDlgRadio(self.optDlg, 'AngleUnit', 'Angular Units',
                                 [('deg', 'Degrees'), ('rad', 'Radians')])
        self.optDlg.startGroupBox('Alternate Bases')
        optiondlg.OptionDlgInt(self.optDlg, 'AltBaseBits', 'Size limit',
                               CalcCore.minNumBits, CalcCore.maxNumBits,
                               True, 4, False, ' bits')
        optiondlg.OptionDlgBool(self.optDlg, 'UseTwosComplement',
                                'Use two\'s complement\nnegative numbers')
        self.optDlg.startGroupBox('Extra Views',)
        optiondlg.OptionDlgPush(self.optDlg, 'View Extra Data', self.viewExtra)
        optiondlg.OptionDlgPush(self.optDlg, 'View Other Bases',
                                self.viewAltBases)
        optiondlg.OptionDlgPush(self.optDlg, 'View Help file', self.help)
        optiondlg.OptionDlgInt(self.optDlg, 'MaxHistLength',
                               'Saved history steps', CalcCore.minMaxHist,
                               CalcCore.maxMaxHist, True, 10)
        if self.optDlg.exec_() == QDialog.Accepted:
            self.calc.option.writeChanges()
            newViewReg = self.calc.option.boolData('ViewRegisters')
            if newViewReg != oldViewReg:
                if newViewReg:
                    for w in self.extraLabels + self.extraLcds:
                        w.show()
                else:
                    for w in self.extraLabels + self.extraLcds:
                        w.hide()
                qApp.processEvents()
                self.adjustSize()
            if self.altBaseView:
                self.altBaseView.updateOptions()
            self.setLcdHighlight()
            self.calc.updateXStr()
        self.optDlg = None

    def setLcdHighlight(self):
        """Set lcd highlight based on option.
        """
        opt = self.calc.option.boolData('HideLcdHighlight') and \
              QLCDNumber.Flat or QLCDNumber.Filled
        self.lcd.setSegmentStyle(opt)
        for lcd in self.extraLcds:
            lcd.setSegmentStyle(opt)

    def updateColors(self):
        """Adjust the colors to the current option settings.
        """
        if self.calc.option.boolData('UseDefaultColors'):
            return
        pal = QApplication.palette()
        background = QColor(self.calc.option.intData('BackgroundR',
                                                           0, 255),
                                  self.calc.option.intData('BackgroundG',
                                                           0, 255),
                                  self.calc.option.intData('BackgroundB',
                                                           0, 255))
        foreground = QColor(self.calc.option.intData('ForegroundR',
                                                           0, 255),
                                  self.calc.option.intData('ForegroundG',
                                                           0, 255),
                                  self.calc.option.intData('ForegroundB',
                                                           0, 255))
        pal.setColor(QPalette.Base, background)
        pal.setColor(QPalette.Text, foreground)
        QApplication.setPalette(pal)

    def viewExtra(self, defaultTab=0):
        """Show extra data view.
        """
        if self.optDlg:
            self.optDlg.reject()   # unfortunately necessary?
        if not self.extraView:
            self.extraView = extradisplay.ExtraDisplay(self)
        self.extraView.tabUpdate(defaultTab)
        self.extraView.tab.setCurrentIndex(defaultTab)
        self.extraView.show()

    def viewReg(self):
        """Show extra data view with register tab open.
        """
        self.viewExtra(0)

    def viewHist(self):
        """Show extra data view with history tab open.
        """
        self.viewExtra(1)

    def viewMem(self):
        """Show extra data view with memory tab open.
        """
        self.viewExtra(2)

    def updateExtra(self):
        """Update current extra and alt base views.
        """
        if self.extraView and self.extraView.isVisible():
            self.extraView.updateData()
        if self.altBaseView:
            self.altBaseView.updateData()

    def toggleReg(self):
        """Toggle register display on LCD.
        """
        viewReg = not self.calc.option.boolData('ViewRegisters')
        self.calc.option.changeData('ViewRegisters',
                                    viewReg and 'yes' or 'no', 1)
        if viewReg:
            for w in self.extraLabels + self.extraLcds:
                w.show()
        else:
            for w in self.extraLabels + self.extraLcds:
                w.hide()
        self.adjustSize()
        self.calc.updateXStr()

    def viewAltBases(self):
        """Show alternate base view.
        """
        if self.optDlg:
            self.optDlg.reject()   # unfortunately necessary?
        if not self.altBaseView:
            self.altBaseView = altbasedialog.AltBaseDialog(self)
        self.altBaseView.updateData()
        self.altBaseView.show()

    def findHelpFile(self):
        """Return the path to the help file.
        """
        modPath = os.path.abspath(sys.path[0])
        if modPath.endswith('.zip') or modPath.endswith('.exe'):
            modPath = os.path.dirname(modPath)  # for py2exe/cx_freeze
        pathList = [helpFilePath, os.path.join(modPath, '../doc/'),
                    modPath, 'doc/']
        for path in pathList:
            if path:
                try:
                    fullPath = os.path.join(path, 'README.html')
                    with open(fullPath, 'r', encoding='utf-8') as f:
                        pass
                    return fullPath
                except IOError:
                    pass
        return ''

    def help(self):
        """View the ReadMe file.
        """
        if self.optDlg:
            self.optDlg.reject()   # unfortunately necessary?
        if not self.helpView:
            path = self.findHelpFile()
            if not path:
                QMessageBox.warning(self, 'rpCalc',
                                          'Read Me file not found')
                return
            self.helpView = helpview.HelpView(path, 'rpCalc README File',
                                              self.icons, self)
        self.helpView.show()

    def about(self):
        """About this program.
        """
        QMessageBox.about(self, 'rpCalc',
                                'rpCalc, Version {0}\n by {1}'.
                                format(__version__, __author__))

    def addCmdButton(self, text, row, col):
        """Adds a CalcButton for command functions.
        """
        button = CalcButton(text)
        self.cmdDict[text.upper()] = button
        self.cmdLay.addWidget(button, row, col)
        button.activated.connect(self.issueCmd)

    def addMainButton(self, key, text, row, col, extraRow=0, extraCol=0):
        """Adds a CalcButton for number and 4-function keys.
        """
        button = CalcButton(text)
        self.mainDict[key] = button
        self.mainLay.addWidget(button, row, col, 1+extraRow, 1+extraCol)
        button.activated.connect(self.issueCmd)

    def updateLcd(self):
        """Sets display back to CalcCore string.
        """
        numDigits = int(self.calc.option.numData('NumDecimalPlaces', 0, 9)) + 9
        if self.calc.option.boolData('ThousandsSeparator') or \
                self.calc.option.boolData('UseEngNotation'):
            numDigits += 2
        self.lcd.setDisplay(self.calc.xStr, numDigits)
        if self.calc.option.boolData('ViewRegisters'):
            nums = [self.calc.formatNum(num) for num in self.calc.stack[1:]]
            for num, lcd in zip(nums, self.extraLcds):
                lcd.setDisplay(num, numDigits)
        self.updateExtra()

    def issueCmd(self, text):
        """Sends command text to CalcCore - connected to button signals.
        """
        mode = self.calc.flag
        text = str(text).upper()
        if text == 'OPT':
            self.setOptions()
        elif text == 'SHOW':
            if not self.showMode:
                valueStr = self.calc.sciFormatX(11).replace('e', ' E', 1)
                self.lcd.setNumDigits(19)
                self.lcd.display(valueStr)
                self.showMode = True
                return
        elif text == 'EXIT':
            self.close()
            return
        else:
            self.calc.cmd(text)
        if text in ('SCI', 'DEG', 'OPT') or mode == Mode.decPlcMode:
            self.updateEntryLabel()
        self.showMode = False
        self.updateLcd()

    def textEntry(self, ch):
        """Searches for button match from text entry.
        """
        if not ch:
            return False
        if ord(ch) == 8:   # backspace key
            self.entryStr = self.entryStr[:-1]
        elif ord(ch) == 27:  # escape key
            self.entryStr = ''
        elif ch == '\t':     # tab key
            cmds = [key for key in self.cmdDict.keys() if
                    key.startswith(self.entryStr.upper())]
            if len(cmds) == 1:
                button = self.cmdDict[cmds[0]]
                button.clickEvent()
                button.tmpDown(300)
                self.entryStr = ''
            else:
                QApplication.beep()
        elif ch == ':' and not self.entryStr:
            self.entryStr = ':'   # optional command prefix
        else:
            newStr = (self.entryStr + ch).upper()
            if newStr == ':Q':    # vim-like shortcut
                newStr = 'EXIT'
            button = self.cmdDict.get(newStr.lstrip(':'))
            if button:
                button.clickEvent()
                button.tmpDown(300)
                self.entryStr = ''
            else:
                if [key for key in self.cmdDict.keys() if
                    key.startswith(newStr.lstrip(':'))]:
                    self.entryStr += ch
                else:
                    QApplication.beep()
                    return False
        self.updateEntryLabel()
        return True

    def keyPressEvent(self, keyEvent):
        """Event handler for keys - checks for numbers and typed commands.
        """
        button = self.mainDict.get(keyEvent.key())
        if not self.entryStr and button:
            button.clickEvent()
            button.setDown(True)
            return
        letter = str(keyEvent.text()).upper()
        if keyEvent.modifiers() == Qt.AltModifier:
            if self.altBaseView and self.altBaseView.isVisible():
                if letter in ('X', 'O', 'B', 'D'):
                    self.altBaseView.setCodedBase(letter, False)
                elif letter == 'V':
                    self.altBaseView.copyValue()
                elif letter == 'C':
                    self.altBaseView.close()
        elif not self.entryStr and self.calc.base == 16 and \
                 'A' <= letter <= 'F':
            self.issueCmd(keyEvent.text())
        elif self.altBaseView and self.altBaseView.isVisible() and \
                (self.calc.xStr == ' 0' or \
                 (self.calc.stack[0] == 0.0 and self.calc.base != 10)) and \
                self.calc.flag == Mode.entryMode and \
                letter in ('X', 'O', 'B', 'D'):
            self.altBaseView.setCodedBase(letter, True)
        elif not self.entryStr and keyEvent.key() == Qt.Key_Backspace:
            button = self.cmdDict['<-']
            button.clickEvent()
            button.tmpDown(300)
        elif not self.entryStr and keyEvent.key() == Qt.Key_Escape:
            self.popupMenu.popup(self.mapToGlobal(QPoint(0, 0)))
        elif not self.textEntry(str(keyEvent.text())):
            QWidget.keyPressEvent(self, keyEvent)

    def keyReleaseEvent(self, keyEvent):
        """Event handler for keys - sets button back to raised position.
        """
        button = self.mainDict.get(keyEvent.key())
        if not self.entryStr and button:
            button.setDown(False)

    def closeEvent(self, event):
        """Saves the stack prior to closing.
        """
        self.calc.saveStack()
        self.calc.option.changeData('MainDlgXSize', self.width(), True)
        self.calc.option.changeData('MainDlgYSize', self.height(), True)
        self.calc.option.changeData('MainDlgXPos', self.x(), True)
        self.calc.option.changeData('MainDlgYPos', self.y(), True)
        if self.extraView:
            self.calc.option.changeData('ExtraViewXSize',
                                        self.extraView.width(), True)
            self.calc.option.changeData('ExtraViewYSize',
                                        self.extraView.height(), True)
            self.calc.option.changeData('ExtraViewXPos',
                                        self.extraView.x(), True)
            self.calc.option.changeData('ExtraViewYPos',
                                        self.extraView.y(), True)
        if self.altBaseView:
            self.calc.option.changeData('AltBaseXPos',
                                        self.altBaseView.x(), True)
            self.calc.option.changeData('AltBaseYPos',
                                        self.altBaseView.y(), True)
        self.calc.option.writeChanges()
        QWidget.closeEvent(self, event)
Beispiel #40
0
class ApplicationWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setWindowTitle("程序主窗口")

        self.files = []

        #---------file menu -------------------------------
        self.file_menu = QMenu('&File', self)
        self.file_menu.addAction('&Quit', self.fileQuit,
                                 QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
        self.menuBar().addMenu(self.file_menu)
        #======================================================

        # ---------ta menu ----------------------------------------------
        self.ta_menu = QMenu('&Ta', self)

        # ++++++++++++++++RSI analyse++++++++++++++++++++++++
        self.add_menu_item(self.ta_menu, 'Ca&p 独立', self.taRSI,
                           QtCore.Qt.CTRL + QtCore.Qt.Key_P)

        #+++++++++++++++++Cap analyse+++++++++++++++++++++++++
        self.add_menu_item(self.ta_menu, '&Cap 集成', self.taCap,
                           QtCore.Qt.CTRL + QtCore.Qt.Key_A)

        # ================================================================

        # ---------control START/STOP menu ----------------------------------------------
        '''
        elf.start_menu = QMenu('&Start', self)
        3self.menuBar().addMenu(self.start_menu)
        #self.start_menu.addAction('&Start', self.taStart)
        # 添加事件
        self.start_menu.get.connect(self.taStart)
        '''

        #---------help menu ---------------------------------
        self.help_menu = QMenu('&Help', self)
        self.menuBar().addSeparator()
        self.menuBar().addMenu(self.help_menu)
        self.help_menu.addAction('&About', self.about)
        # ======================================================
        '''
        self.main_widget = QWidget(self)

        l = QVBoxLayout(self.main_widget)
        self.fig=Widget(self.main_widget, width=16, height=12, dpi=100)
        l.addWidget(self.fig)

        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)
        '''
        # 状态条显示2秒
        self.statusBar().showMessage("hello matplotlib", 2000)

    # start stop
    def taStart(self):
        QMessageBox.about(self, "taStart", "taStart")

    #资金流分析
    def taCap(self):
        cap_path = 'data0322'
        filters = ['CAP-002', '005.dat']
        if len(self.files) == 0:
            self.files = tls.get_filelist_from_path(cap_path, filters)

        stock, week, cap_data, kdata = tls.read_stock_data(self.files[0])
        count = len(cap_data)
        self.files = self.files[1:]
        x = np.arange(0, count, 1)
        klen = len(kdata)

        if klen == count:
            flow = (cap_data['HugeBuy'] - cap_data['HugeSell'] +
                    cap_data['BigBuy'] - cap_data['BigSell']).values
            # 累计主力总资金流
            total_flow = [flow[0]]
            for i in range(1, count):
                total_flow.append(total_flow[i - 1] + flow[i])

            self.fig.draw_fig(0,
                              x,
                              kdata.loc[:, 'close'],
                              text=stock,
                              ylabel='close')

            self.fig.draw_fig(1, x, total_flow, ylabel='flow')

            self.fig.draw_fig(2, x, flow, ylabel='delta')

        self.fig.set_xlabel(stock)
        main_ui.setWindowTitle(CAPITION + '  ' + stock)
        #self.fig.update_fig()

    # 资金流分析
    def taRSI(self):
        cap_path = 'data0322'
        filters = ['CAP-002', '005.dat']
        if len(self.files) == 0:
            self.files = tls.get_filelist_from_path(cap_path, filters)

        stock, week, cap_data, kdata = tls.read_stock_data(self.files[0])
        count = len(cap_data)
        self.files = self.files[1:]
        x = np.arange(0, count, 1)
        klen = len(kdata)

        if klen == count:
            flow = (cap_data['HugeBuy'] - cap_data['HugeSell'] +
                    cap_data['BigBuy'] - cap_data['BigSell']).values
            # 累计主力总资金流
            total_flow = [flow[0]]
            for i in range(1, count):
                total_flow.append(total_flow[i - 1] + flow[i])

        tls.draw_kline(stock, kdata, 0, 0, week, 100, 311, total_flow)

    # 增加菜单项
    def add_menu_item(self, menu, menu_name, menu_op, op_link):
        menu.addAction(menu_name, menu_op, op_link)
        self.menuBar().addMenu(menu)

    def fileQuit(self):
        self.close()

    def closeEvent(self, ce):
        self.fileQuit()

    def about(self):
        QMessageBox.about(
            self, "About", """embedding_in_qt5.py example
        Copyright 2015 BoxControL

        This program is a simple example of a Qt5 application embedding matplotlib
        canvases. It is base on example from matplolib documentation, and initially was
        developed from Florent Rougon and Darren Dale.

        http://matplotlib.org/examples/user_interfaces/embedding_in_qt4.html

        It may be used and modified with no restriction; raw copies as well as
        modified versions may be distributed without limitation.
        """)
Beispiel #41
0
    def contextMenuEvent(self, event):
        # Update selection
        self.updateSelection()

        # Set context menu mode
        app = get_app()
        app.context_menu_object = "files"

        menu = QMenu(self)

        menu.addAction(self.win.actionImportFiles)
        menu.addSeparator()
        if self.selected:
            # If file selected, show file related options
            menu.addAction(self.win.actionFile_Properties)
            menu.addAction(self.win.actionPreview_File)
            menu.addAction(self.win.actionSplitClip)
            menu.addAction(self.win.actionAdd_to_Timeline)
            menu.addSeparator()
            #menu.addAction(self.win.actionFile_Properties)
            menu.addAction(self.win.actionRemove_from_Project)
            menu.addSeparator()
        menu.addAction(self.win.actionThumbnailView)

        # Show menu
        menu.exec_(QCursor.pos())
Beispiel #42
0
class MainWindow(QMainWindow, Ui_MainWindow, buscaLargura, buscaProfundidade):
    def __init__(self, parent=None):
        QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.setupUi(self)

        #para colocar robo animado
        self.movie = QMovie("robot.gif")
        self.movie.frameChanged.connect(self.repaint)
        self.movie.start()

        self.timer = QTimer(self)

        self.paredes = 0
        self.caminho = 1
        self.entrada = 2
        self.saida = 3
        self.pegadas = 4
        self.jaVisitado = 5
        self.labirinto = []

        #para armazenar historico do percurso
        self.fila_i = []
        self.fila_j = []
        self.fila_pegadas = []

        self.createActions()
        self.createMenus()
        self.pushButton01.clicked.connect(self.simule)
        self.pushButton02.clicked.connect(self.limparCaminhada)

        self.events()
        self.timer.setInterval(200)
        self.timer.start()

    #funcao que anima robo
    def paintEvent(self, event):
        currentFrame = self.movie.currentPixmap()
        frameRect = currentFrame.rect()
        frameRect.moveCenter(self.rect().center())
        if frameRect.intersects(event.rect()):
            painter = QPainter(self)
            painter.drawPixmap(frameRect.left(), frameRect.top(), currentFrame)

    def events(self):
        self.timer.timeout.connect(self.update)

    def update(self):
        if (len(self.labirinto) > 0 and len(self.fila_pegadas) > 0):
            self.alteraLabirinto()
            self.aplicateColors()
            self.pushButton02.setEnabled(True)

    def simule(self):
        if (self.radioButton01.isChecked()):
            self.limparCaminhada()
            self.buscaEmLargura()
        elif (self.radioButton02.isChecked()):
            self.limparCaminhada()
            self.buscaEmProfundidade()
        else:
            return

    def limparCaminhada(self):
        self.clear()
        self.labirinto = np.loadtxt(self.filename[0],
                                    dtype='int',
                                    delimiter='	')
        self.aplicateColors()
        self.fila_i.clear()
        self.fila_j.clear()
        self.fila_pegadas.clear()

    def alteraLabirinto(self):
        if (len(self.fila_pegadas) > 0):
            self.labirinto[self.fila_i[0]][
                self.fila_j[0]] = self.fila_pegadas[0]
            self.fila_i.pop(0)
            self.fila_j.pop(0)
            self.fila_pegadas.pop(0)

    def buscaEmLargura(self):
        self.variavel = buscaLargura(self.filename[0])
        self.fila_i, self.fila_j, self.fila_pegadas = self.variavel.percorreLabirinto(
        )
        #print(self.fila_i, self.fila_j, self.fila_pegadas)

    def buscaEmProfundidade(self):
        self.variavel = buscaProfundidade(self.filename[0])
        self.fila_i, self.fila_j, self.fila_pegadas = self.variavel.percorreLabirinto(
        )
        #print(self.fila_i, self.fila_j, self.fila_pegadas)

    def createActions(self):
        self.openAct = QAction("&Open Archive",
                               self,
                               shortcut="Ctrl+O",
                               triggered=self.open)

    def open(self):
        self.filename = QFileDialog.getOpenFileName(self, 'Open File',
                                                    os.getenv('HOME'))
        self.labirinto = np.loadtxt(self.filename[0],
                                    dtype='int',
                                    delimiter='	')

        self.movie = QMovie()  #retirando robozinho

        self.aplicateColors()

        self.pushButton01.setEnabled(True)
        self.radioButton01.setEnabled(True)
        self.radioButton02.setEnabled(True)
        #print(self.labirinto)
        #self.label.setText(filename[0])

    def clear(self):
        while self.gridLayout_3.count():
            item = self.gridLayout_3.takeAt(0)
            widget = item.widget()
            widget.deleteLater()

    def createMenus(self):
        self.fileMenu = QMenu("&Menu", self)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.openAct)
        self.fileMenu.addSeparator()

        self.menuBar().addMenu(self.fileMenu)

    def aplicateColors(self):
        sleep(0.2)
        self.clear()
        for i in range(len(self.labirinto)):
            for j in range(len(self.labirinto)):
                if (self.labirinto[i][j] == self.caminho
                        or self.labirinto[i][j] == self.jaVisitado):
                    self.b1 = QPushButton("pushButton_" + str(i) + "_" +
                                          str(j))
                    self.b1.setStyleSheet("background-color : white")
                    self.b1.setFixedSize(int(500 / len(self.labirinto)),
                                         int(500 / len(self.labirinto)))
                    self.b1.setText(" ")
                    self.b1.setEnabled(False)
                    self.gridLayout_3.addWidget(self.b1, i, j)
                elif (self.labirinto[i][j] == self.paredes):
                    self.b1 = QPushButton("pushButton_" + str(i) + "_" +
                                          str(j))
                    self.b1.setStyleSheet("background-color : black")
                    self.b1.setFixedSize(int(500 / len(self.labirinto)),
                                         int(500 / len(self.labirinto)))
                    self.b1.setText(" ")
                    self.b1.setEnabled(False)
                    self.gridLayout_3.addWidget(self.b1, i, j)
                elif (self.labirinto[i][j] == self.entrada):
                    self.b1 = QPushButton("pushButton_" + str(i) + "_" +
                                          str(j))
                    self.b1.setStyleSheet("background-color : red")
                    self.b1.setFixedSize(int(500 / len(self.labirinto)),
                                         int(500 / len(self.labirinto)))
                    self.b1.setText(" ")
                    self.b1.setEnabled(False)
                    self.gridLayout_3.addWidget(self.b1, i, j)
                elif (self.labirinto[i][j] == self.saida):
                    self.b1 = QPushButton("pushButton_" + str(i) + "_" +
                                          str(j))
                    self.b1.setStyleSheet("background-color : green")
                    self.b1.setFixedSize(int(500 / len(self.labirinto)),
                                         int(500 / len(self.labirinto)))
                    self.b1.setText(" ")
                    self.b1.setEnabled(False)
                    self.gridLayout_3.addWidget(self.b1, i, j)
                elif (self.labirinto[i][j] == self.pegadas):
                    self.b1 = QPushButton("pushButton_" + str(i) + "_" +
                                          str(j))
                    self.b1.setStyleSheet("background-color : yellow")
                    self.b1.setFixedSize(int(500 / len(self.labirinto)),
                                         int(500 / len(self.labirinto)))
                    self.b1.setText(" ")
                    self.b1.setEnabled(False)
                    self.gridLayout_3.addWidget(self.b1, i, j)
                else:
                    return
Beispiel #43
0
class outlineBasics(QAbstractItemView):
    def __init__(self, parent=None):
        self._indexesToOpen = None
        self.menuCustomIcons = None

    def getSelection(self):
        sel = []
        for i in self.selectedIndexes():
            if i.column() != 0:
                continue
            if not i in sel:
                sel.append(i)
        return sel

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.RightButton:
            self.menu = self.makePopupMenu()
            self.menu.popup(event.globalPos())
        # We don't call QAbstractItemView.mouseReleaseEvent because
        # outlineBasics is never subclassed alone. So the others views
        # (outlineView, corkView, treeView) that subclass outlineBasics
        # call their respective mother class.

    def makePopupMenu(self):
        index = self.currentIndex()
        sel = self.getSelection()
        clipboard = qApp.clipboard()

        menu = QMenu(self)

        # Get index under cursor
        pos = self.viewport().mapFromGlobal(QCursor.pos())
        mouseIndex = self.indexAt(pos)

        # Get index's title
        if mouseIndex.isValid():
            title = mouseIndex.internalPointer().title()

        elif self.rootIndex().parent().isValid():
            # mouseIndex is the background of an item, so we check the parent
            mouseIndex = self.rootIndex().parent()
            title = mouseIndex.internalPointer().title()

        else:
            title = qApp.translate("outlineBasics", "Root")

        if len(title) > 25:
            title = title[:25] + "…"

        # Open Item action
        self.actOpen = QAction(
            QIcon.fromTheme("go-right"),
            qApp.translate("outlineBasics", "Open {}".format(title)), menu)
        self.actOpen.triggered.connect(self.openItem)
        menu.addAction(self.actOpen)

        # Open item(s) in new tab
        if mouseIndex in sel and len(sel) > 1:
            actionTitle = qApp.translate("outlineBasics",
                                         "Open {} items in new tabs").format(
                                             len(sel))
            self._indexesToOpen = sel
        else:
            actionTitle = qApp.translate("outlineBasics",
                                         "Open {} in a new tab").format(title)
            self._indexesToOpen = [mouseIndex]

        self.actNewTab = QAction(QIcon.fromTheme("go-right"), actionTitle,
                                 menu)
        self.actNewTab.triggered.connect(self.openItemsInNewTabs)
        menu.addAction(self.actNewTab)

        menu.addSeparator()

        # Add text / folder
        self.actAddFolder = QAction(
            QIcon.fromTheme("folder-new"),
            qApp.translate("outlineBasics", "New &Folder"), menu)
        self.actAddFolder.triggered.connect(self.addFolder)
        menu.addAction(self.actAddFolder)

        self.actAddText = QAction(QIcon.fromTheme("document-new"),
                                  qApp.translate("outlineBasics", "New &Text"),
                                  menu)
        self.actAddText.triggered.connect(self.addText)
        menu.addAction(self.actAddText)

        menu.addSeparator()

        # Copy, cut, paste, duplicate
        self.actCut = QAction(QIcon.fromTheme("edit-cut"),
                              qApp.translate("outlineBasics", "C&ut"), menu)
        self.actCut.triggered.connect(self.cut)
        menu.addAction(self.actCut)

        self.actCopy = QAction(QIcon.fromTheme("edit-copy"),
                               qApp.translate("outlineBasics", "&Copy"), menu)
        self.actCopy.triggered.connect(self.copy)
        menu.addAction(self.actCopy)

        self.actPaste = QAction(QIcon.fromTheme("edit-paste"),
                                qApp.translate("outlineBasics", "&Paste"),
                                menu)
        self.actPaste.triggered.connect(self.paste)
        menu.addAction(self.actPaste)

        # Rename / duplicate / remove items
        self.actDelete = QAction(QIcon.fromTheme("edit-delete"),
                                 qApp.translate("outlineBasics", "&Delete"),
                                 menu)
        self.actDelete.triggered.connect(self.delete)
        menu.addAction(self.actDelete)

        self.actRename = QAction(QIcon.fromTheme("edit-rename"),
                                 qApp.translate("outlineBasics", "&Rename"),
                                 menu)
        self.actRename.triggered.connect(self.rename)
        menu.addAction(self.actRename)

        menu.addSeparator()

        # POV
        self.menuPOV = QMenu(qApp.translate("outlineBasics", "Set POV"), menu)
        mw = mainWindow()
        a = QAction(QIcon.fromTheme("dialog-no"),
                    qApp.translate("outlineBasics", "None"), self.menuPOV)
        a.triggered.connect(lambda: self.setPOV(""))
        self.menuPOV.addAction(a)
        self.menuPOV.addSeparator()

        menus = []
        for i in [
                qApp.translate("outlineBasics", "Main"),
                qApp.translate("outlineBasics", "Secondary"),
                qApp.translate("outlineBasics", "Minor")
        ]:
            m = QMenu(i, self.menuPOV)
            menus.append(m)
            self.menuPOV.addMenu(m)

        mpr = QSignalMapper(self.menuPOV)
        for i in range(mw.mdlCharacter.rowCount()):
            a = QAction(mw.mdlCharacter.icon(i), mw.mdlCharacter.name(i),
                        self.menuPOV)
            a.triggered.connect(mpr.map)
            mpr.setMapping(a, int(mw.mdlCharacter.ID(i)))

            imp = toInt(mw.mdlCharacter.importance(i))

            menus[2 - imp].addAction(a)

        mpr.mapped.connect(self.setPOV)
        menu.addMenu(self.menuPOV)

        # Status
        self.menuStatus = QMenu(qApp.translate("outlineBasics", "Set Status"),
                                menu)
        # a = QAction(QIcon.fromTheme("dialog-no"), qApp.translate("outlineBasics", "None"), self.menuStatus)
        # a.triggered.connect(lambda: self.setStatus(""))
        # self.menuStatus.addAction(a)
        # self.menuStatus.addSeparator()

        mpr = QSignalMapper(self.menuStatus)
        for i in range(mw.mdlStatus.rowCount()):
            a = QAction(mw.mdlStatus.item(i, 0).text(), self.menuStatus)
            a.triggered.connect(mpr.map)
            mpr.setMapping(a, i)
            self.menuStatus.addAction(a)
        mpr.mapped.connect(self.setStatus)
        menu.addMenu(self.menuStatus)

        # Labels
        self.menuLabel = QMenu(qApp.translate("outlineBasics", "Set Label"),
                               menu)
        mpr = QSignalMapper(self.menuLabel)
        for i in range(mw.mdlLabels.rowCount()):
            a = QAction(
                mw.mdlLabels.item(i, 0).icon(),
                mw.mdlLabels.item(i, 0).text(), self.menuLabel)
            a.triggered.connect(mpr.map)
            mpr.setMapping(a, i)
            self.menuLabel.addAction(a)
        mpr.mapped.connect(self.setLabel)
        menu.addMenu(self.menuLabel)

        menu.addSeparator()

        # Custom icons
        if self.menuCustomIcons:
            menu.addMenu(self.menuCustomIcons)
        else:
            self.menuCustomIcons = QMenu(
                qApp.translate("outlineBasics", "Set Custom Icon"), menu)
            a = QAction(qApp.translate("outlineBasics", "Restore to default"),
                        self.menuCustomIcons)
            a.triggered.connect(lambda: self.setCustomIcon(""))
            self.menuCustomIcons.addAction(a)
            self.menuCustomIcons.addSeparator()

            txt = QLineEdit()
            txt.textChanged.connect(self.filterLstIcons)
            txt.setPlaceholderText("Filter icons")
            txt.setStyleSheet(
                "QLineEdit { background: transparent; border: none; }")
            act = QWidgetAction(self.menuCustomIcons)
            act.setDefaultWidget(txt)
            self.menuCustomIcons.addAction(act)

            self.lstIcons = QListWidget()
            for i in customIcons():
                item = QListWidgetItem()
                item.setIcon(QIcon.fromTheme(i))
                item.setData(Qt.UserRole, i)
                item.setToolTip(i)
                self.lstIcons.addItem(item)
            self.lstIcons.itemClicked.connect(self.setCustomIconFromItem)
            self.lstIcons.setViewMode(self.lstIcons.IconMode)
            self.lstIcons.setUniformItemSizes(True)
            self.lstIcons.setResizeMode(self.lstIcons.Adjust)
            self.lstIcons.setMovement(self.lstIcons.Static)
            self.lstIcons.setStyleSheet(
                "background: transparent; background: none;")
            self.filterLstIcons("")
            act = QWidgetAction(self.menuCustomIcons)
            act.setDefaultWidget(self.lstIcons)
            self.menuCustomIcons.addAction(act)

            menu.addMenu(self.menuCustomIcons)

        # Disabling stuff
        if not clipboard.mimeData().hasFormat("application/xml"):
            self.actPaste.setEnabled(False)

        if len(sel) == 0:
            self.actCopy.setEnabled(False)
            self.actCut.setEnabled(False)
            self.actRename.setEnabled(False)
            self.actDelete.setEnabled(False)
            self.menuPOV.setEnabled(False)
            self.menuStatus.setEnabled(False)
            self.menuLabel.setEnabled(False)
            self.menuCustomIcons.setEnabled(False)

        if len(sel) > 1:
            self.actRename.setEnabled(False)

        return menu

    def openItem(self):
        #idx = self.currentIndex()
        idx = self._indexesToOpen[0]
        from manuskript.functions import MW
        MW.openIndex(idx)

    def openItemsInNewTabs(self):
        from manuskript.functions import MW
        MW.openIndexes(self._indexesToOpen)

    def rename(self):
        if len(self.getSelection()) == 1:
            index = self.currentIndex()
            self.edit(index)
        elif len(self.getSelection()) > 1:
            # FIXME: add smart rename
            pass

    def addFolder(self):
        self.addItem("folder")

    def addText(self):
        self.addItem("text")

    def addItem(self, _type="folder"):
        if len(self.selectedIndexes()) == 0:
            parent = self.rootIndex()
        else:
            parent = self.currentIndex()

        if _type == "text":
            _type = settings.defaultTextType

        item = outlineItem(title=qApp.translate("outlineBasics", "New"),
                           _type=_type)
        self.model().appendItem(item, parent)

    def copy(self):
        mimeData = self.model().mimeData(
            self.selectionModel().selectedIndexes())
        qApp.clipboard().setMimeData(mimeData)

    def paste(self, mimeData=None):
        """
        Paste item from mimeData to selected item. If mimeData is not given,
        it is taken from clipboard. If not item selected, paste into root.
        """
        index = self.currentIndex()
        if len(self.getSelection()) == 0:
            index = self.rootIndex()

        if not mimeData:
            mimeData = qApp.clipboard().mimeData()

        self.model().dropMimeData(mimeData, Qt.CopyAction, -1, 0, index)

    def cut(self):
        self.copy()
        self.delete()

    def delete(self):
        """
        Shows a warning, and then deletes currently selected indexes.
        """
        if not settings.dontShowDeleteWarning:
            msg = QMessageBox(
                QMessageBox.Warning,
                qApp.translate("outlineBasics", "About to remove"),
                qApp.translate(
                    "outlineBasics",
                    "<p><b>You're about to delete {} item(s).</b></p><p>Are you sure?</p>"
                ).format(len(self.getSelection())),
                QMessageBox.Yes | QMessageBox.Cancel)

            chk = QCheckBox("&Don't show this warning in the future.")
            msg.setCheckBox(chk)
            ret = msg.exec()

            if ret == QMessageBox.Cancel:
                return

            if chk.isChecked():
                settings.dontShowDeleteWarning = True

        self.model().removeIndexes(self.getSelection())

    def duplicate(self):
        """
        Duplicates item(s), while preserving clipboard content.
        """
        mimeData = self.model().mimeData(
            self.selectionModel().selectedIndexes())
        self.paste(mimeData)

    def move(self, delta=1):
        """
        Move selected items up or down.
        """

        # we store selected indexes
        currentID = self.model().ID(self.currentIndex())
        selIDs = [self.model().ID(i) for i in self.selectedIndexes()]

        # Block signals
        self.blockSignals(True)
        self.selectionModel().blockSignals(True)

        # Move each index individually
        for idx in self.selectedIndexes():
            self.moveIndex(idx, delta)

        # Done the hardcore way, so inform views
        self.model().layoutChanged.emit()

        # restore selection
        selIdx = [self.model().getIndexByID(ID) for ID in selIDs]
        sm = self.selectionModel()
        sm.clear()
        [sm.select(idx, sm.Select) for idx in selIdx]
        sm.setCurrentIndex(self.model().getIndexByID(currentID), sm.Select)
        #self.setSmsgBoxelectionModel(sm)

        # Unblock signals
        self.blockSignals(False)
        self.selectionModel().blockSignals(False)

    def moveIndex(self, index, delta=1):
        """
        Move the item represented by index. +1 means down, -1 means up.
        """

        if not index.isValid():
            return

        if index.parent().isValid():
            parentItem = index.parent().internalPointer()
        else:
            parentItem = index.model().rootItem

        parentItem.childItems.insert(index.row() + delta,
                                     parentItem.childItems.pop(index.row()))
        parentItem.updateWordCount()

    def moveUp(self):
        self.move(-1)

    def moveDown(self):
        self.move(+1)

    def splitDialog(self):
        """
        Opens a dialog to split selected items.

        Call context: if at least one index is selected. Folder or text.
        """

        indexes = self.getSelection()
        if len(indexes) == 0:
            # No selection, we use parent
            indexes = [self.rootIndex()]

        splitDialog(self, indexes)

    def merge(self):
        """
        Merges selected items together.

        Call context: Multiple selection, same parent.
        """

        # Get selection
        indexes = self.getSelection()
        # Get items
        items = [i.internalPointer() for i in indexes if i.isValid()]
        # Remove folders
        items = [i for i in items if not i.isFolder()]

        # Check that we have at least 2 items
        if len(items) < 2:
            statusMessage(qApp.translate(
                "outlineBasics",
                "Select at least two items. Folders are ignored."),
                          importance=2)
            return

        # Check that all share the same parent
        p = items[0].parent()
        for i in items:
            if i.parent() != p:
                statusMessage(qApp.translate(
                    "outlineBasics",
                    "All items must be on the same level (share the same parent)."
                ),
                              importance=2)
                return

        # Sort items by row
        items = sorted(items, key=lambda i: i.row())

        items[0].mergeWith(items[1:])

    def setPOV(self, POV):
        for i in self.getSelection():
            self.model().setData(i.sibling(i.row(), Outline.POV), str(POV))

    def setStatus(self, status):
        for i in self.getSelection():
            self.model().setData(i.sibling(i.row(), Outline.status),
                                 str(status))

    def setLabel(self, label):
        for i in self.getSelection():
            self.model().setData(i.sibling(i.row(), Outline.label), str(label))

    def setCustomIcon(self, customIcon):
        for i in self.getSelection():
            item = i.internalPointer()
            item.setCustomIcon(customIcon)

    def setCustomIconFromItem(self, item):
        icon = item.data(Qt.UserRole)
        self.setCustomIcon(icon)
        self.menu.close()

    def filterLstIcons(self, text):
        for l in self.lstIcons.findItems("", Qt.MatchContains):
            l.setHidden(not text in l.data(Qt.UserRole))
    def showContextMenu(self, clickedObjectItem, screenPos):
        selection = self.mMapScene.selectedObjectItems()
        if (clickedObjectItem and not selection.contains(clickedObjectItem)):
            selection.clear()
            selection.insert(clickedObjectItem)
            self.mMapScene.setSelectedObjectItems(selection)
        if selection.isEmpty():
            return

        selectedObjects = self.mapDocument().selectedObjects()
        objectGroups = self.mapDocument().map().objectGroups()

        menu = QMenu()
        duplicateAction = menu.addAction(
            self.tr("Duplicate %n Object(s)", "", selection.size()),
            self.duplicateObjects)
        removeAction = menu.addAction(
            self.tr("Remove %n Object(s)", "", selection.size()),
            self.removeObjects)

        duplicateAction.setIcon(QIcon("/images/16x16/stock-duplicate-16.png"))
        removeAction.setIcon(QIcon("/images/16x16/edit-delete.png"))

        menu.addSeparator()
        menu.addAction(self.tr("Flip Horizontally"), self.flipHorizontally,
                       QKeySequence(self.tr("X")))
        menu.addAction(self.tr("Flip Vertically"), self.flipVertically,
                       QKeySequence(self.tr("Y")))

        objectGroup = RaiseLowerHelper.sameObjectGroup(selection)
        if (objectGroup and objectGroup.drawOrder()
                == ObjectGroup.DrawOrder.IndexOrder):
            menu.addSeparator()
            menu.addAction(self.tr("Raise Object"), self.raise_,
                           QKeySequence(self.tr("PgUp")))
            menu.addAction(self.tr("Lower Object"), self.lower,
                           QKeySequence(self.tr("PgDown")))
            menu.addAction(self.tr("Raise Object to Top"), self.raiseToTop,
                           QKeySequence(self.tr("Home")))
            menu.addAction(self.tr("Lower Object to Bottom"),
                           self.lowerToBottom, QKeySequence(self.tr("End")))

        if (objectGroups.size() > 1):
            menu.addSeparator()
            moveToLayerMenu = menu.addMenu(
                self.tr("Move %n Object(s) to Layer", "",
                        selectedObjects.size()))
            for objectGroup in objectGroups:
                action = moveToLayerMenu.addAction(objectGroup.name())
                action.setData(objectGroup)

        menu.addSeparator()
        propIcon = QIcon("images/16x16/document-properties.png")
        propertiesAction = menu.addAction(propIcon,
                                          self.tr("Object &Properties..."))
        # TODO Implement editing of properties for multiple objects
        propertiesAction.setEnabled(selectedObjects.size() == 1)

        Utils.setThemeIcon(removeAction, "edit-delete")
        Utils.setThemeIcon(propertiesAction, "document-properties")

        action = menu.exec(screenPos)
        if not action:
            return

        if action == propertiesAction:
            mapObject = selectedObjects.first()
            self.mapDocument().setCurrentObject(mapObject)
            self.mapDocument().emitEditCurrentObject()
            return

        objectGroup = action.data()
        if type(objectGroup) == ObjectGroup:
            self.mapDocument().moveObjectsToGroup(
                self.mapDocument().selectedObjects(), objectGroup)
Beispiel #45
0
    def device_discovery(self, devs):
        """Called when new devices have been added"""
        for menu in self._all_role_menus:
            role_menu = menu["rolemenu"]
            mux_menu = menu["muxmenu"]
            dev_group = QActionGroup(role_menu)
            dev_group.setExclusive(True)
            for d in devs:
                dev_node = QAction(d.name,
                                   role_menu,
                                   checkable=True,
                                   enabled=True)
                role_menu.addAction(dev_node)
                dev_group.addAction(dev_node)
                dev_node.toggled.connect(self._inputdevice_selected)

                map_node = None
                if d.supports_mapping:
                    map_node = QMenu("    Input map", role_menu, enabled=False)
                    map_group = QActionGroup(role_menu)
                    map_group.setExclusive(True)
                    # Connect device node to map node for easy
                    # enabling/disabling when selection changes and device
                    # to easily enable it
                    dev_node.setData((map_node, d))
                    for c in ConfigManager().get_list_of_configs():
                        node = QAction(c,
                                       map_node,
                                       checkable=True,
                                       enabled=True)
                        node.toggled.connect(self._inputconfig_selected)
                        map_node.addAction(node)
                        # Connect all the map nodes back to the device
                        # action node where we can access the raw device
                        node.setData(dev_node)
                        map_group.addAction(node)
                        # If this device hasn't been found before, then
                        # select the default mapping for it.
                        if d not in self._available_devices:
                            last_map = Config().get("device_config_mapping")
                            if d.name in last_map and last_map[d.name] == c:
                                node.setChecked(True)
                    role_menu.addMenu(map_node)
                dev_node.setData((map_node, d, mux_menu))

        # Update the list of what devices we found
        # to avoid selecting default mapping for all devices when
        # a new one is inserted
        self._available_devices = ()
        for d in devs:
            self._available_devices += (d, )

        # Only enable MUX nodes if we have enough devies to cover
        # the roles
        for mux_node in self._all_mux_nodes:
            (mux, sub_nodes) = mux_node.data()
            if len(mux.supported_roles()) <= len(self._available_devices):
                mux_node.setEnabled(True)

        # TODO: Currently only supports selecting default mux
        if self._all_mux_nodes[0].isEnabled():
            self._all_mux_nodes[0].setChecked(True)

        # If the previous length of the available devies was 0, then select
        # the default on. If that's not available then select the first
        # on in the list.
        # TODO: This will only work for the "Normal" mux so this will be
        #       selected by default
        if Config().get("input_device") in [d.name for d in devs]:
            for dev_menu in self._all_role_menus[0]["rolemenu"].actions():
                if dev_menu.text() == Config().get("input_device"):
                    dev_menu.setChecked(True)
        else:
            # Select the first device in the first mux (will always be "Normal"
            # mux)
            self._all_role_menus[0]["rolemenu"].actions()[0].setChecked(True)
            logger.info("Select first device")

        self._update_input_device_footer()
Beispiel #46
0
    def makePopupMenu(self):
        index = self.currentIndex()
        sel = self.getSelection()
        clipboard = qApp.clipboard()

        menu = QMenu(self)

        # Get index under cursor
        pos = self.viewport().mapFromGlobal(QCursor.pos())
        mouseIndex = self.indexAt(pos)

        # Get index's title
        if mouseIndex.isValid():
            title = mouseIndex.internalPointer().title()

        elif self.rootIndex().parent().isValid():
            # mouseIndex is the background of an item, so we check the parent
            mouseIndex = self.rootIndex().parent()
            title = mouseIndex.internalPointer().title()

        else:
            title = qApp.translate("outlineBasics", "Root")

        if len(title) > 25:
            title = title[:25] + "…"

        # Open Item action
        self.actOpen = QAction(
            QIcon.fromTheme("go-right"),
            qApp.translate("outlineBasics", "Open {}".format(title)), menu)
        self.actOpen.triggered.connect(self.openItem)
        menu.addAction(self.actOpen)

        # Open item(s) in new tab
        if mouseIndex in sel and len(sel) > 1:
            actionTitle = qApp.translate("outlineBasics",
                                         "Open {} items in new tabs").format(
                                             len(sel))
            self._indexesToOpen = sel
        else:
            actionTitle = qApp.translate("outlineBasics",
                                         "Open {} in a new tab").format(title)
            self._indexesToOpen = [mouseIndex]

        self.actNewTab = QAction(QIcon.fromTheme("go-right"), actionTitle,
                                 menu)
        self.actNewTab.triggered.connect(self.openItemsInNewTabs)
        menu.addAction(self.actNewTab)

        menu.addSeparator()

        # Add text / folder
        self.actAddFolder = QAction(
            QIcon.fromTheme("folder-new"),
            qApp.translate("outlineBasics", "New &Folder"), menu)
        self.actAddFolder.triggered.connect(self.addFolder)
        menu.addAction(self.actAddFolder)

        self.actAddText = QAction(QIcon.fromTheme("document-new"),
                                  qApp.translate("outlineBasics", "New &Text"),
                                  menu)
        self.actAddText.triggered.connect(self.addText)
        menu.addAction(self.actAddText)

        menu.addSeparator()

        # Copy, cut, paste, duplicate
        self.actCut = QAction(QIcon.fromTheme("edit-cut"),
                              qApp.translate("outlineBasics", "C&ut"), menu)
        self.actCut.triggered.connect(self.cut)
        menu.addAction(self.actCut)

        self.actCopy = QAction(QIcon.fromTheme("edit-copy"),
                               qApp.translate("outlineBasics", "&Copy"), menu)
        self.actCopy.triggered.connect(self.copy)
        menu.addAction(self.actCopy)

        self.actPaste = QAction(QIcon.fromTheme("edit-paste"),
                                qApp.translate("outlineBasics", "&Paste"),
                                menu)
        self.actPaste.triggered.connect(self.paste)
        menu.addAction(self.actPaste)

        # Rename / duplicate / remove items
        self.actDelete = QAction(QIcon.fromTheme("edit-delete"),
                                 qApp.translate("outlineBasics", "&Delete"),
                                 menu)
        self.actDelete.triggered.connect(self.delete)
        menu.addAction(self.actDelete)

        self.actRename = QAction(QIcon.fromTheme("edit-rename"),
                                 qApp.translate("outlineBasics", "&Rename"),
                                 menu)
        self.actRename.triggered.connect(self.rename)
        menu.addAction(self.actRename)

        menu.addSeparator()

        # POV
        self.menuPOV = QMenu(qApp.translate("outlineBasics", "Set POV"), menu)
        mw = mainWindow()
        a = QAction(QIcon.fromTheme("dialog-no"),
                    qApp.translate("outlineBasics", "None"), self.menuPOV)
        a.triggered.connect(lambda: self.setPOV(""))
        self.menuPOV.addAction(a)
        self.menuPOV.addSeparator()

        menus = []
        for i in [
                qApp.translate("outlineBasics", "Main"),
                qApp.translate("outlineBasics", "Secondary"),
                qApp.translate("outlineBasics", "Minor")
        ]:
            m = QMenu(i, self.menuPOV)
            menus.append(m)
            self.menuPOV.addMenu(m)

        mpr = QSignalMapper(self.menuPOV)
        for i in range(mw.mdlCharacter.rowCount()):
            a = QAction(mw.mdlCharacter.icon(i), mw.mdlCharacter.name(i),
                        self.menuPOV)
            a.triggered.connect(mpr.map)
            mpr.setMapping(a, int(mw.mdlCharacter.ID(i)))

            imp = toInt(mw.mdlCharacter.importance(i))

            menus[2 - imp].addAction(a)

        mpr.mapped.connect(self.setPOV)
        menu.addMenu(self.menuPOV)

        # Status
        self.menuStatus = QMenu(qApp.translate("outlineBasics", "Set Status"),
                                menu)
        # a = QAction(QIcon.fromTheme("dialog-no"), qApp.translate("outlineBasics", "None"), self.menuStatus)
        # a.triggered.connect(lambda: self.setStatus(""))
        # self.menuStatus.addAction(a)
        # self.menuStatus.addSeparator()

        mpr = QSignalMapper(self.menuStatus)
        for i in range(mw.mdlStatus.rowCount()):
            a = QAction(mw.mdlStatus.item(i, 0).text(), self.menuStatus)
            a.triggered.connect(mpr.map)
            mpr.setMapping(a, i)
            self.menuStatus.addAction(a)
        mpr.mapped.connect(self.setStatus)
        menu.addMenu(self.menuStatus)

        # Labels
        self.menuLabel = QMenu(qApp.translate("outlineBasics", "Set Label"),
                               menu)
        mpr = QSignalMapper(self.menuLabel)
        for i in range(mw.mdlLabels.rowCount()):
            a = QAction(
                mw.mdlLabels.item(i, 0).icon(),
                mw.mdlLabels.item(i, 0).text(), self.menuLabel)
            a.triggered.connect(mpr.map)
            mpr.setMapping(a, i)
            self.menuLabel.addAction(a)
        mpr.mapped.connect(self.setLabel)
        menu.addMenu(self.menuLabel)

        menu.addSeparator()

        # Custom icons
        if self.menuCustomIcons:
            menu.addMenu(self.menuCustomIcons)
        else:
            self.menuCustomIcons = QMenu(
                qApp.translate("outlineBasics", "Set Custom Icon"), menu)
            a = QAction(qApp.translate("outlineBasics", "Restore to default"),
                        self.menuCustomIcons)
            a.triggered.connect(lambda: self.setCustomIcon(""))
            self.menuCustomIcons.addAction(a)
            self.menuCustomIcons.addSeparator()

            txt = QLineEdit()
            txt.textChanged.connect(self.filterLstIcons)
            txt.setPlaceholderText("Filter icons")
            txt.setStyleSheet(
                "QLineEdit { background: transparent; border: none; }")
            act = QWidgetAction(self.menuCustomIcons)
            act.setDefaultWidget(txt)
            self.menuCustomIcons.addAction(act)

            self.lstIcons = QListWidget()
            for i in customIcons():
                item = QListWidgetItem()
                item.setIcon(QIcon.fromTheme(i))
                item.setData(Qt.UserRole, i)
                item.setToolTip(i)
                self.lstIcons.addItem(item)
            self.lstIcons.itemClicked.connect(self.setCustomIconFromItem)
            self.lstIcons.setViewMode(self.lstIcons.IconMode)
            self.lstIcons.setUniformItemSizes(True)
            self.lstIcons.setResizeMode(self.lstIcons.Adjust)
            self.lstIcons.setMovement(self.lstIcons.Static)
            self.lstIcons.setStyleSheet(
                "background: transparent; background: none;")
            self.filterLstIcons("")
            act = QWidgetAction(self.menuCustomIcons)
            act.setDefaultWidget(self.lstIcons)
            self.menuCustomIcons.addAction(act)

            menu.addMenu(self.menuCustomIcons)

        # Disabling stuff
        if not clipboard.mimeData().hasFormat("application/xml"):
            self.actPaste.setEnabled(False)

        if len(sel) == 0:
            self.actCopy.setEnabled(False)
            self.actCut.setEnabled(False)
            self.actRename.setEnabled(False)
            self.actDelete.setEnabled(False)
            self.menuPOV.setEnabled(False)
            self.menuStatus.setEnabled(False)
            self.menuLabel.setEnabled(False)
            self.menuCustomIcons.setEnabled(False)

        if len(sel) > 1:
            self.actRename.setEnabled(False)

        return menu
Beispiel #47
0
 def show_menu(self, p):
     """右键菜单"""
     menu = QMenu(self)
     action_info = menu.addAction('卸载')
     action_info.triggered.connect(self.uninstall)
     menu.exec_(QCursor.pos())
    def create_menu(self, position):
        menu = QMenu()
        idx = self.indexAt(position)
        column = idx.column() or self.Columns.NAME
        selected_keys = []
        for s_idx in self.selected_in_column(self.Columns.NAME):
            sel_key = self.model().itemFromIndex(s_idx).data(Qt.UserRole)
            selected_keys.append(sel_key)
        if not selected_keys or not idx.isValid():
            menu.addAction(_("New contact"), lambda: self.parent.new_contact_dialog())
            menu.addAction(_("Import file"), lambda: self.import_contacts())
            menu.addAction(_("Export file"), lambda: self.export_contacts())
        else:
            column_title = self.model().horizontalHeaderItem(column).text()
            column_data = '\n'.join(self.model().itemFromIndex(s_idx).text()
                                    for s_idx in self.selected_in_column(column))
            menu.addAction(_("Copy {}").format(column_title), lambda: self.place_text_on_clipboard(column_data, title=column_title))
            if column in self.editable_columns:
                item = self.model().itemFromIndex(idx)
                if item.isEditable():
                    # would not be editable if openalias
                    persistent = QPersistentModelIndex(idx)
                    menu.addAction(_("Edit {}").format(column_title), lambda p=persistent: self.edit(QModelIndex(p)))
            menu.addAction(_("Pay to"), lambda: self.parent.payto_contacts(selected_keys))
            menu.addAction(_("Delete"), lambda: self.parent.delete_contacts(selected_keys))
            URLs = [block_explorer_URL(self.config, 'addr', key) for key in filter(is_address, selected_keys)]
            if URLs:
                menu.addAction(_("View on block explorer"), lambda: [webopen(u) for u in URLs])

        run_hook('create_contact_menu', menu, selected_keys)
        menu.exec_(self.viewport().mapToGlobal(position))
Beispiel #49
0
	def contextMenuEvent(self, event):
		# Context menu
		menu = QMenu(self.centralWidget)
		# Populating the menu with actions
		menu.addAction(self.newAction)
		menu.addAction(self.openAction)
		menu.addAction(self.saveAction)
		# Separator
		separator = QAction(self)
		separator.setSeparator(True)
		menu.addAction(separator)
		menu.addAction(self.copyAction)
		menu.addAction(self.pasteAction)
		menu.addAction(self.cutAction)
		# Launching the menu
		menu.exec(event.globalPos())
Beispiel #50
0
class MainUI(QtWidgets.QMainWindow, main_window_class):
    connectionLostSignal = pyqtSignal(str, str)
    connectionInitiatedSignal = pyqtSignal(str)
    batteryUpdatedSignal = pyqtSignal(int, object, object)
    connectionDoneSignal = pyqtSignal(str)
    connectionFailedSignal = pyqtSignal(str, str)
    disconnectedSignal = pyqtSignal(str)
    linkQualitySignal = pyqtSignal(int)

    _input_device_error_signal = pyqtSignal(str)
    _input_discovery_signal = pyqtSignal(object)
    _log_error_signal = pyqtSignal(object, str)

    def __init__(self, *args):
        super(MainUI, self).__init__(*args)
        self.setupUi(self)

        # Restore window size if present in the config file
        try:
            size = Config().get("window_size")
            self.resize(size[0], size[1])
        except KeyError:
            pass

        # self.setWindowState(QtCore.Qt.WindowMaximized)

        ######################################################
        # By lxrocks
        # 'Skinny Progress Bar' tweak for Yosemite
        # Tweak progress bar - artistic I am not - so pick your own colors !!!
        # Only apply to Yosemite
        ######################################################
        import platform

        if platform.system() == 'Darwin':

            (Version, junk, machine) = platform.mac_ver()
            logger.info("This is a MAC - checking if we can apply Progress "
                        "Bar Stylesheet for Yosemite Skinny Bars ")
            yosemite = (10, 10, 0)
            tVersion = tuple(map(int, (Version.split("."))))

            if tVersion >= yosemite:
                logger.info("Found Yosemite - applying stylesheet")

                tcss = """
                    QProgressBar {
                        border: 1px solid grey;
                        border-radius: 5px;
                        text-align: center;
                    }
                    QProgressBar::chunk {
                        background-color: """ + COLOR_BLUE + """;
                    }
                 """
                self.setStyleSheet(tcss)

            else:
                logger.info("Pre-Yosemite - skinny bar stylesheet not applied")

        ######################################################

        self.cf = Crazyflie(ro_cache=None,
                            rw_cache=cfclient.config_path + "/cache")

        cflib.crtp.init_drivers(
            enable_debug_driver=Config().get("enable_debug_driver"))

        zmq_params = ZMQParamAccess(self.cf)
        zmq_params.start()

        zmq_leds = ZMQLEDDriver(self.cf)
        zmq_leds.start()

        self.scanner = ScannerThread()
        self.scanner.interfaceFoundSignal.connect(self.foundInterfaces)
        self.scanner.start()

        # Create and start the Input Reader
        self._statusbar_label = QLabel("No input-device found, insert one to"
                                       " fly.")
        self.statusBar().addWidget(self._statusbar_label)

        self.joystickReader = JoystickReader()
        self._active_device = ""
        # self.configGroup = QActionGroup(self._menu_mappings, exclusive=True)

        self._mux_group = QActionGroup(self._menu_inputdevice)
        self._mux_group.setExclusive(True)

        # TODO: Need to reload configs
        # ConfigManager().conf_needs_reload.add_callback(self._reload_configs)

        self.connect_input = QShortcut("Ctrl+I", self.connectButton,
                                       self._connect)
        self.cf.connection_failed.add_callback(
            self.connectionFailedSignal.emit)
        self.connectionFailedSignal.connect(self._connection_failed)

        self._input_device_error_signal.connect(
            self._display_input_device_error)
        self.joystickReader.device_error.add_callback(
            self._input_device_error_signal.emit)
        self._input_discovery_signal.connect(self.device_discovery)
        self.joystickReader.device_discovery.add_callback(
            self._input_discovery_signal.emit)

        # Hide the 'File' menu on OS X, since its only item, 'Exit', gets
        # merged into the application menu.
        if sys.platform == 'darwin':
            self.menuFile.menuAction().setVisible(False)

        # Connect UI signals
        self.logConfigAction.triggered.connect(self._show_connect_dialog)
        self.interfaceCombo.currentIndexChanged['QString'].connect(
            self.interfaceChanged)
        self.connectButton.clicked.connect(self._connect)
        self.scanButton.clicked.connect(self._scan)
        self.menuItemConnect.triggered.connect(self._connect)
        self.menuItemConfInputDevice.triggered.connect(
            self._show_input_device_config_dialog)
        self.menuItemExit.triggered.connect(self.closeAppRequest)
        self.batteryUpdatedSignal.connect(self._update_battery)
        self._menuitem_rescandevices.triggered.connect(self._rescan_devices)
        self._menuItem_openconfigfolder.triggered.connect(
            self._open_config_folder)

        self.address.setValue(0xE7E7E7E7E7)

        self._auto_reconnect_enabled = Config().get("auto_reconnect")
        self.autoReconnectCheckBox.toggled.connect(
            self._auto_reconnect_changed)
        self.autoReconnectCheckBox.setChecked(Config().get("auto_reconnect"))

        self._disable_input = False

        self.joystickReader.input_updated.add_callback(
            lambda *args: self._disable_input or self.cf.commander.
            send_setpoint(*args))

        self.joystickReader.assisted_input_updated.add_callback(
            lambda *args: self._disable_input or self.cf.commander.
            send_velocity_world_setpoint(*args))

        self.joystickReader.heighthold_input_updated.add_callback(
            lambda *args: self._disable_input or self.cf.commander.
            send_zdistance_setpoint(*args))

        self.joystickReader.hover_input_updated.add_callback(
            self.cf.commander.send_hover_setpoint)

        # Connection callbacks and signal wrappers for UI protection
        self.cf.connected.add_callback(self.connectionDoneSignal.emit)
        self.connectionDoneSignal.connect(self._connected)
        self.cf.disconnected.add_callback(self.disconnectedSignal.emit)
        self.disconnectedSignal.connect(self._disconnected)
        self.cf.connection_lost.add_callback(self.connectionLostSignal.emit)
        self.connectionLostSignal.connect(self._connection_lost)
        self.cf.connection_requested.add_callback(
            self.connectionInitiatedSignal.emit)
        self.connectionInitiatedSignal.connect(self._connection_initiated)
        self._log_error_signal.connect(self._logging_error)

        self.batteryBar.setTextVisible(False)
        self.batteryBar.setStyleSheet(progressbar_stylesheet(COLOR_BLUE))

        self.linkQualityBar.setTextVisible(False)
        self.linkQualityBar.setStyleSheet(progressbar_stylesheet(COLOR_BLUE))

        # Connect link quality feedback
        self.cf.link_quality_updated.add_callback(self.linkQualitySignal.emit)
        self.linkQualitySignal.connect(
            lambda percentage: self.linkQualityBar.setValue(percentage))

        self._selected_interface = None
        self._initial_scan = True
        self._scan()

        # Parse the log configuration files
        self.logConfigReader = LogConfigReader(self.cf)

        self._current_input_config = None
        self._active_config = None
        self._active_config = None

        self.inputConfig = None

        # Add things to helper so tabs can access it
        cfclient.ui.pluginhelper.cf = self.cf
        cfclient.ui.pluginhelper.inputDeviceReader = self.joystickReader
        cfclient.ui.pluginhelper.logConfigReader = self.logConfigReader
        cfclient.ui.pluginhelper.mainUI = self

        self.logConfigDialogue = LogConfigDialogue(cfclient.ui.pluginhelper)
        self._bootloader_dialog = BootloaderDialog(cfclient.ui.pluginhelper)
        self._cf2config_dialog = Cf2ConfigDialog(cfclient.ui.pluginhelper)
        self._cf1config_dialog = Cf1ConfigDialog(cfclient.ui.pluginhelper)
        self.menuItemBootloader.triggered.connect(self._bootloader_dialog.show)
        self._about_dialog = AboutDialog(cfclient.ui.pluginhelper)
        self.menuItemAbout.triggered.connect(self._about_dialog.show)
        self._menu_cf2_config.triggered.connect(self._cf2config_dialog.show)
        self._menu_cf1_config.triggered.connect(self._cf1config_dialog.show)

        # Load and connect tabs
        self.tabsMenuItem = QMenu("Tabs", self.menuView, enabled=True)
        self.menuView.addMenu(self.tabsMenuItem)

        # self.tabsMenuItem.setMenu(QtWidgets.QMenu())
        tabItems = {}
        self.loadedTabs = []
        for tabClass in cfclient.ui.tabs.available:
            tab = tabClass(self.tabs, cfclient.ui.pluginhelper)
            item = QtWidgets.QAction(tab.getMenuName(), self, checkable=True)
            item.toggled.connect(tab.toggleVisibility)
            self.tabsMenuItem.addAction(item)
            tabItems[tab.getTabName()] = item
            self.loadedTabs.append(tab)
            if not tab.enabled:
                item.setEnabled(False)

        # First instantiate all tabs and then open them in the correct order
        try:
            for tName in Config().get("open_tabs").split(","):
                logger.info("opening tabs [{}]".format(tName))
                t = tabItems[tName]
                if (t is not None and t.isEnabled()):
                    # Toggle though menu so it's also marked as open there
                    t.toggle()
        except Exception as e:
            logger.warning("Exception while opening tabs [{}]".format(e))

        # Loading toolboxes (A bit of magic for a lot of automatic)
        self.toolboxesMenuItem = QMenu("Toolboxes",
                                       self.menuView,
                                       enabled=True)
        self.menuView.addMenu(self.toolboxesMenuItem)

        self.toolboxes = []
        for t_class in cfclient.ui.toolboxes.toolboxes:
            toolbox = t_class(cfclient.ui.pluginhelper)
            dockToolbox = MyDockWidget(toolbox.getName())
            dockToolbox.setWidget(toolbox)
            self.toolboxes += [
                dockToolbox,
            ]

            # Add menu item for the toolbox
            item = QtWidgets.QAction(toolbox.getName(), self)
            item.setCheckable(True)
            item.triggered.connect(self.toggleToolbox)
            self.toolboxesMenuItem.addAction(item)

            dockToolbox.closed.connect(lambda: self.toggleToolbox(False))

            # Setup some introspection
            item.dockToolbox = dockToolbox
            item.menuItem = item
            dockToolbox.dockToolbox = dockToolbox
            dockToolbox.menuItem = item

        # References to all the device sub-menus in the "Input device" menu
        self._all_role_menus = ()
        # Used to filter what new devices to add default mapping to
        self._available_devices = ()
        # Keep track of mux nodes so we can enable according to how many
        # devices we have
        self._all_mux_nodes = ()

        # Check which Input muxes are available
        self._mux_group = QActionGroup(self._menu_inputdevice)
        self._mux_group.setExclusive(True)
        for m in self.joystickReader.available_mux():
            node = QAction(m.name,
                           self._menu_inputdevice,
                           checkable=True,
                           enabled=False)
            node.toggled.connect(self._mux_selected)
            self._mux_group.addAction(node)
            self._menu_inputdevice.addAction(node)
            self._all_mux_nodes += (node, )
            mux_subnodes = ()
            for name in m.supported_roles():
                sub_node = QMenu("    {}".format(name),
                                 self._menu_inputdevice,
                                 enabled=False)
                self._menu_inputdevice.addMenu(sub_node)
                mux_subnodes += (sub_node, )
                self._all_role_menus += ({
                    "muxmenu": node,
                    "rolemenu": sub_node
                }, )
            node.setData((m, mux_subnodes))

        self._mapping_support = True

        self.sendHexButton.clicked.connect(self.send_hex)

    def send_hex(self):
        import struct
        from cflib.crtp.crtpstack import CRTPPacket, CRTPPort
        hex_string = self.hexEdit.text()
        hex_string = hex_string.replace(":", " ")
        pk = CRTPPacket()
        pk.header = 0x00
        pk.data = bytes.fromhex(hex_string)
        self.cf.send_packet(pk)

    def disable_input(self, disable):
        """
        Disable the gamepad input to be able to send setpoint from a tab
        """
        self._disable_input = disable

    def interfaceChanged(self, interface):
        if interface == INTERFACE_PROMPT_TEXT:
            self._selected_interface = None
        else:
            self._selected_interface = interface
        self._update_ui_state()

    def foundInterfaces(self, interfaces):
        selected_interface = self._selected_interface

        self.interfaceCombo.clear()
        self.interfaceCombo.addItem(INTERFACE_PROMPT_TEXT)

        formatted_interfaces = []
        for i in interfaces:
            if len(i[1]) > 0:
                interface = "%s - %s" % (i[0], i[1])
            else:
                interface = i[0]
            formatted_interfaces.append(interface)
        self.interfaceCombo.addItems(formatted_interfaces)

        if self._initial_scan:
            self._initial_scan = False

            try:
                if len(Config().get("link_uri")) > 0:
                    formatted_interfaces.index(Config().get("link_uri"))
                    selected_interface = Config().get("link_uri")
            except KeyError:
                #  The configuration for link_uri was not found
                pass
            except ValueError:
                #  The saved URI was not found while scanning
                pass

        if len(interfaces) == 1 and selected_interface is None:
            selected_interface = interfaces[0][0]

        newIndex = 0
        if selected_interface is not None:
            try:
                newIndex = formatted_interfaces.index(selected_interface) + 1
            except ValueError:
                pass

        self.interfaceCombo.setCurrentIndex(newIndex)

        self.uiState = UIState.DISCONNECTED
        self._update_ui_state()

    def _update_ui_state(self):
        if self.uiState == UIState.DISCONNECTED:
            self.setWindowTitle("Not connected")
            canConnect = self._selected_interface is not None
            self.menuItemConnect.setText("Connect to Crazyflie")
            self.menuItemConnect.setEnabled(canConnect)
            self.connectButton.setText("Connect")
            self.connectButton.setToolTip("Connect to the Crazyflie on"
                                          "the selected interface (Ctrl+I)")
            self.connectButton.setEnabled(canConnect)
            self.scanButton.setText("Scan")
            self.scanButton.setEnabled(True)
            self.address.setEnabled(True)
            self.batteryBar.setValue(3000)
            self._menu_cf2_config.setEnabled(False)
            self._menu_cf1_config.setEnabled(True)
            self.linkQualityBar.setValue(0)
            self.menuItemBootloader.setEnabled(True)
            self.logConfigAction.setEnabled(False)
            self.interfaceCombo.setEnabled(True)
        elif self.uiState == UIState.CONNECTED:
            s = "Connected on %s" % self._selected_interface
            self.setWindowTitle(s)
            self.menuItemConnect.setText("Disconnect")
            self.menuItemConnect.setEnabled(True)
            self.connectButton.setText("Disconnect")
            self.connectButton.setToolTip("Disconnect from"
                                          "the Crazyflie (Ctrl+I)")
            self.scanButton.setEnabled(False)
            self.logConfigAction.setEnabled(True)
            # Find out if there's an I2C EEPROM, otherwise don't show the
            # dialog.
            if len(self.cf.mem.get_mems(MemoryElement.TYPE_I2C)) > 0:
                self._menu_cf2_config.setEnabled(True)
            self._menu_cf1_config.setEnabled(False)
        elif self.uiState == UIState.CONNECTING:
            s = "Connecting to {} ...".format(self._selected_interface)
            self.setWindowTitle(s)
            self.menuItemConnect.setText("Cancel")
            self.menuItemConnect.setEnabled(True)
            self.connectButton.setText("Cancel")
            self.connectButton.setToolTip("Cancel connecting to the Crazyflie")
            self.scanButton.setEnabled(False)
            self.address.setEnabled(False)
            self.menuItemBootloader.setEnabled(False)
            self.interfaceCombo.setEnabled(False)
        elif self.uiState == UIState.SCANNING:
            self.setWindowTitle("Scanning ...")
            self.connectButton.setText("Connect")
            self.menuItemConnect.setEnabled(False)
            self.connectButton.setText("Connect")
            self.connectButton.setEnabled(False)
            self.scanButton.setText("Scanning...")
            self.scanButton.setEnabled(False)
            self.address.setEnabled(False)
            self.menuItemBootloader.setEnabled(False)
            self.interfaceCombo.setEnabled(False)

    @pyqtSlot(bool)
    def toggleToolbox(self, display):
        menuItem = self.sender().menuItem
        dockToolbox = self.sender().dockToolbox

        if display and not dockToolbox.isVisible():
            dockToolbox.widget().enable()
            self.addDockWidget(dockToolbox.widget().preferedDockArea(),
                               dockToolbox)
            dockToolbox.show()
        elif not display:
            dockToolbox.widget().disable()
            self.removeDockWidget(dockToolbox)
            dockToolbox.hide()
            menuItem.setChecked(False)

    def _rescan_devices(self):
        self._statusbar_label.setText("No inputdevice connected!")
        self._menu_devices.clear()
        self._active_device = ""
        self.joystickReader.stop_input()

        # for c in self._menu_mappings.actions():
        #    c.setEnabled(False)
        # devs = self.joystickReader.available_devices()
        # if (len(devs) > 0):
        #    self.device_discovery(devs)

    def _show_input_device_config_dialog(self):
        self.inputConfig = InputConfigDialogue(self.joystickReader)
        self.inputConfig.show()

    def _auto_reconnect_changed(self, checked):
        self._auto_reconnect_enabled = checked
        Config().set("auto_reconnect", checked)
        logger.info("Auto reconnect enabled: {}".format(checked))

    def _show_connect_dialog(self):
        self.logConfigDialogue.show()

    def _update_battery(self, timestamp, data, logconf):
        self.batteryBar.setValue(int(data["pm.vbat"] * 1000))

        color = COLOR_BLUE
        # TODO firmware reports fully-charged state as 'Battery',
        # rather than 'Charged'
        if data["pm.state"] in [BatteryStates.CHARGING, BatteryStates.CHARGED]:
            color = COLOR_GREEN
        elif data["pm.state"] == BatteryStates.LOW_POWER:
            color = COLOR_RED

        self.batteryBar.setStyleSheet(progressbar_stylesheet(color))
        self._aff_volts.setText(("%.3f" % data["pm.vbat"]))

    def _connected(self):
        self.uiState = UIState.CONNECTED
        self._update_ui_state()

        Config().set("link_uri", str(self._selected_interface))

        lg = LogConfig("Battery", 1000)
        lg.add_variable("pm.vbat", "float")
        lg.add_variable("pm.state", "int8_t")
        try:
            self.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self.batteryUpdatedSignal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))

        mems = self.cf.mem.get_mems(MemoryElement.TYPE_DRIVER_LED)
        if len(mems) > 0:
            mems[0].write_data(self._led_write_done)

    def _disconnected(self):
        self.uiState = UIState.DISCONNECTED
        self._update_ui_state()

    def _connection_initiated(self):
        self.uiState = UIState.CONNECTING
        self._update_ui_state()

    def _led_write_done(self, mem, addr):
        logger.info("LED write done callback")

    def _logging_error(self, log_conf, msg):
        QMessageBox.about(
            self, "Log error", "Error when starting log config"
            " [{}]: {}".format(log_conf.name, msg))

    def _connection_lost(self, linkURI, msg):
        if not self._auto_reconnect_enabled:
            if self.isActiveWindow():
                warningCaption = "Communication failure"
                error = "Connection lost to {}: {}".format(linkURI, msg)
                QMessageBox.critical(self, warningCaption, error)
                self.uiState = UIState.DISCONNECTED
                self._update_ui_state()
        else:
            self._connect()

    def _connection_failed(self, linkURI, error):
        if not self._auto_reconnect_enabled:
            msg = "Failed to connect on {}: {}".format(linkURI, error)
            warningCaption = "Communication failure"
            QMessageBox.critical(self, warningCaption, msg)
            self.uiState = UIState.DISCONNECTED
            self._update_ui_state()
        else:
            self._connect()

    def closeEvent(self, event):
        self.hide()
        self.cf.close_link()
        Config().save_file()

    def resizeEvent(self, event):
        Config().set(
            "window_size",
            [event.size().width(), event.size().height()])

    def _connect(self):
        if self.uiState == UIState.CONNECTED:
            self.cf.close_link()
        elif self.uiState == UIState.CONNECTING:
            self.cf.close_link()
            self.uiState = UIState.DISCONNECTED
            self._update_ui_state()
        else:
            self.cf.open_link(self._selected_interface)

    def _scan(self):
        self.uiState = UIState.SCANNING
        self._update_ui_state()
        self.scanner.scanSignal.emit(self.address.value())

    def _display_input_device_error(self, error):
        self.cf.close_link()
        QMessageBox.critical(self, "Input device error", error)

    def _mux_selected(self, checked):
        """Called when a new mux is selected. The menu item contains a
        reference to the raw mux object as well as to the associated device
        sub-nodes"""
        if not checked:
            (mux, sub_nodes) = self.sender().data()
            for s in sub_nodes:
                s.setEnabled(False)
        else:
            (mux, sub_nodes) = self.sender().data()
            for s in sub_nodes:
                s.setEnabled(True)
            self.joystickReader.set_mux(mux=mux)

            # Go though the tree and select devices/mapping that was
            # selected before it was disabled.
            for role_node in sub_nodes:
                for dev_node in role_node.children():
                    if type(dev_node) is QAction and dev_node.isChecked():
                        dev_node.toggled.emit(True)

            self._update_input_device_footer()

    def _get_dev_status(self, device):
        msg = "{}".format(device.name)
        if device.supports_mapping:
            map_name = "No input mapping"
            if device.input_map:
                map_name = device.input_map_name
            msg += " ({})".format(map_name)
        return msg

    def _update_input_device_footer(self):
        """Update the footer in the bottom of the UI with status for the
        input device and its mapping"""

        msg = ""

        if len(self.joystickReader.available_devices()) > 0:
            mux = self.joystickReader._selected_mux
            msg = "Using {} mux with ".format(mux.name)
            for key in list(mux._devs.keys())[:-1]:
                if mux._devs[key]:
                    msg += "{}, ".format(self._get_dev_status(mux._devs[key]))
                else:
                    msg += "N/A, "
            # Last item
            key = list(mux._devs.keys())[-1]
            if mux._devs[key]:
                msg += "{}".format(self._get_dev_status(mux._devs[key]))
            else:
                msg += "N/A"
        else:
            msg = "No input device found"
        self._statusbar_label.setText(msg)

    def _inputdevice_selected(self, checked):
        """Called when a new input device has been selected from the menu. The
        data in the menu object is the associated map menu (directly under the
        item in the menu) and the raw device"""
        (map_menu, device, mux_menu) = self.sender().data()
        if not checked:
            if map_menu:
                map_menu.setEnabled(False)
                # Do not close the device, since we don't know exactly
                # how many devices the mux can have open. When selecting a
                # new mux the old one will take care of this.
        else:
            if map_menu:
                map_menu.setEnabled(True)

            (mux, sub_nodes) = mux_menu.data()
            for role_node in sub_nodes:
                for dev_node in role_node.children():
                    if type(dev_node) is QAction and dev_node.isChecked():
                        if device.id == dev_node.data()[1].id \
                                and dev_node is not self.sender():
                            dev_node.setChecked(False)

            role_in_mux = str(self.sender().parent().title()).strip()
            logger.info("Role of {} is {}".format(device.name, role_in_mux))

            Config().set("input_device", str(device.name))

            self._mapping_support = self.joystickReader.start_input(
                device.name, role_in_mux)
        self._update_input_device_footer()

    def _inputconfig_selected(self, checked):
        """Called when a new configuration has been selected from the menu. The
        data in the menu object is a referance to the device QAction in parent
        menu. This contains a referance to the raw device."""
        if not checked:
            return

        selected_mapping = str(self.sender().text())
        device = self.sender().data().data()[1]
        self.joystickReader.set_input_map(device.name, selected_mapping)
        self._update_input_device_footer()

    def device_discovery(self, devs):
        """Called when new devices have been added"""
        for menu in self._all_role_menus:
            role_menu = menu["rolemenu"]
            mux_menu = menu["muxmenu"]
            dev_group = QActionGroup(role_menu)
            dev_group.setExclusive(True)
            for d in devs:
                dev_node = QAction(d.name,
                                   role_menu,
                                   checkable=True,
                                   enabled=True)
                role_menu.addAction(dev_node)
                dev_group.addAction(dev_node)
                dev_node.toggled.connect(self._inputdevice_selected)

                map_node = None
                if d.supports_mapping:
                    map_node = QMenu("    Input map", role_menu, enabled=False)
                    map_group = QActionGroup(role_menu)
                    map_group.setExclusive(True)
                    # Connect device node to map node for easy
                    # enabling/disabling when selection changes and device
                    # to easily enable it
                    dev_node.setData((map_node, d))
                    for c in ConfigManager().get_list_of_configs():
                        node = QAction(c,
                                       map_node,
                                       checkable=True,
                                       enabled=True)
                        node.toggled.connect(self._inputconfig_selected)
                        map_node.addAction(node)
                        # Connect all the map nodes back to the device
                        # action node where we can access the raw device
                        node.setData(dev_node)
                        map_group.addAction(node)
                        # If this device hasn't been found before, then
                        # select the default mapping for it.
                        if d not in self._available_devices:
                            last_map = Config().get("device_config_mapping")
                            if d.name in last_map and last_map[d.name] == c:
                                node.setChecked(True)
                    role_menu.addMenu(map_node)
                dev_node.setData((map_node, d, mux_menu))

        # Update the list of what devices we found
        # to avoid selecting default mapping for all devices when
        # a new one is inserted
        self._available_devices = ()
        for d in devs:
            self._available_devices += (d, )

        # Only enable MUX nodes if we have enough devies to cover
        # the roles
        for mux_node in self._all_mux_nodes:
            (mux, sub_nodes) = mux_node.data()
            if len(mux.supported_roles()) <= len(self._available_devices):
                mux_node.setEnabled(True)

        # TODO: Currently only supports selecting default mux
        if self._all_mux_nodes[0].isEnabled():
            self._all_mux_nodes[0].setChecked(True)

        # If the previous length of the available devies was 0, then select
        # the default on. If that's not available then select the first
        # on in the list.
        # TODO: This will only work for the "Normal" mux so this will be
        #       selected by default
        if Config().get("input_device") in [d.name for d in devs]:
            for dev_menu in self._all_role_menus[0]["rolemenu"].actions():
                if dev_menu.text() == Config().get("input_device"):
                    dev_menu.setChecked(True)
        else:
            # Select the first device in the first mux (will always be "Normal"
            # mux)
            self._all_role_menus[0]["rolemenu"].actions()[0].setChecked(True)
            logger.info("Select first device")

        self._update_input_device_footer()

    def _open_config_folder(self):
        QDesktopServices.openUrl(
            QUrl("file:///" + QDir.toNativeSeparators(cfclient.config_path)))

    def closeAppRequest(self):

        subprocess.Popen("./run_cfclient.sh stop", shell=True)
        self.close()
Beispiel #51
0
    def create_menu(self, position):
        selected = self.get_selected_outpoints()
        if not selected:
            return
        menu = QMenu()
        menu.setSeparatorsCollapsible(True)  # consecutive separators are merged together
        coins = [self.utxo_dict[name] for name in selected]
        menu.addAction(_("Spend"), lambda: self.set_spend_list(coins))
        assert len(coins) >= 1, len(coins)
        if len(coins) == 1:
            utxo = coins[0]
            addr = utxo.address
            txid = utxo.prevout.txid.hex()
            # "Details"
            tx = self.wallet.db.get_transaction(txid)
            if tx:
                label = self.wallet.get_label(txid) or None # Prefer None if empty (None hides the Description: field in the window)
                menu.addAction(_("Details"), lambda: self.parent.show_transaction(tx, tx_desc=label))
            # "Copy ..."
            idx = self.indexAt(position)
            if not idx.isValid():
                return
            self.add_copy_menu(menu, idx)
            # "Freeze coin"
            if not self.wallet.is_frozen_coin(utxo):
                menu.addAction(_("Freeze Coin"), lambda: self.parent.set_frozen_state_of_coins([utxo], True))
            else:
                menu.addSeparator()
                menu.addAction(_("Coin is frozen"), lambda: None).setEnabled(False)
                menu.addAction(_("Unfreeze Coin"), lambda: self.parent.set_frozen_state_of_coins([utxo], False))
                menu.addSeparator()
            # "Freeze address"
            if not self.wallet.is_frozen_address(addr):
                menu.addAction(_("Freeze Address"), lambda: self.parent.set_frozen_state_of_addresses([addr], True))
            else:
                menu.addSeparator()
                menu.addAction(_("Address is frozen"), lambda: None).setEnabled(False)
                menu.addAction(_("Unfreeze Address"), lambda: self.parent.set_frozen_state_of_addresses([addr], False))
                menu.addSeparator()
        else:
            # multiple items selected
            menu.addSeparator()
            addrs = [utxo.address for utxo in coins]
            is_coin_frozen = [self.wallet.is_frozen_coin(utxo) for utxo in coins]
            is_addr_frozen = [self.wallet.is_frozen_address(utxo.address) for utxo in coins]
            if not all(is_coin_frozen):
                menu.addAction(_("Freeze Coins"), lambda: self.parent.set_frozen_state_of_coins(coins, True))
            if any(is_coin_frozen):
                menu.addAction(_("Unfreeze Coins"), lambda: self.parent.set_frozen_state_of_coins(coins, False))
            if not all(is_addr_frozen):
                menu.addAction(_("Freeze Addresses"), lambda: self.parent.set_frozen_state_of_addresses(addrs, True))
            if any(is_addr_frozen):
                menu.addAction(_("Unfreeze Addresses"), lambda: self.parent.set_frozen_state_of_addresses(addrs, False))

        menu.exec_(self.viewport().mapToGlobal(position))
Beispiel #52
0
    def create_menu(self, position):
        menu = QMenu()
        menu.setSeparatorsCollapsible(
            True)  # consecutive separators are merged together
        selected = self.selected_in_column(self.Columns.NODE_ALIAS)
        if not selected:
            menu.addAction(
                _("Import channel backup"),
                lambda: self.parent.do_process_from_text_channel_backup())
            menu.exec_(self.viewport().mapToGlobal(position))
            return
        multi_select = len(selected) > 1
        if multi_select:
            return
        idx = self.indexAt(position)
        if not idx.isValid():
            return
        item = self.model().itemFromIndex(idx)
        if not item:
            return
        channel_id = idx.sibling(idx.row(),
                                 self.Columns.NODE_ALIAS).data(ROLE_CHANNEL_ID)
        if channel_id in self.lnworker.channel_backups:
            menu.addAction(_("Request force-close"),
                           lambda: self.request_force_close(channel_id))
            menu.addAction(_("Delete"),
                           lambda: self.remove_channel_backup(channel_id))
            menu.exec_(self.viewport().mapToGlobal(position))
            return
        chan = self.lnworker.channels[channel_id]
        menu.addAction(_("Details..."),
                       lambda: self.parent.show_channel(channel_id))
        cc = self.add_copy_menu(menu, idx)
        cc.addAction(
            _("Node ID"),
            lambda: self.place_text_on_clipboard(chan.node_id.hex(),
                                                 title=_("Node ID")))
        cc.addAction(
            _("Long Channel ID"),
            lambda: self.place_text_on_clipboard(channel_id.hex(),
                                                 title=_("Long Channel ID")))
        if not chan.is_closed():
            if not chan.is_frozen_for_sending():
                menu.addAction(
                    _("Freeze (for sending)"),
                    lambda: self.freeze_channel_for_sending(chan, True))
            else:
                menu.addAction(
                    _("Unfreeze (for sending)"),
                    lambda: self.freeze_channel_for_sending(chan, False))
            if not chan.is_frozen_for_receiving():
                menu.addAction(_("Freeze (for receiving)"),
                               lambda: chan.set_frozen_for_receiving(True))
            else:
                menu.addAction(_("Unfreeze (for receiving)"),
                               lambda: chan.set_frozen_for_receiving(False))

        funding_tx = self.parent.wallet.db.get_transaction(
            chan.funding_outpoint.txid)
        if funding_tx:
            menu.addAction(_("View funding transaction"),
                           lambda: self.parent.show_transaction(funding_tx))
        if not chan.is_closed():
            menu.addSeparator()
            if chan.peer_state == PeerState.GOOD:
                menu.addAction(_("Close channel"),
                               lambda: self.close_channel(channel_id))
            menu.addAction(_("Force-close channel"),
                           lambda: self.force_close(channel_id))
        else:
            item = chan.get_closing_height()
            if item:
                txid, height, timestamp = item
                closing_tx = self.lnworker.lnwatcher.db.get_transaction(txid)
                if closing_tx:
                    menu.addAction(
                        _("View closing transaction"),
                        lambda: self.parent.show_transaction(closing_tx))
        menu.addSeparator()
        menu.addAction(_("Export backup"),
                       lambda: self.export_channel_backup(channel_id))
        if chan.is_redeemed():
            menu.addSeparator()
            menu.addAction(_("Delete"),
                           lambda: self.remove_channel(channel_id))
        menu.exec_(self.viewport().mapToGlobal(position))
Beispiel #53
0
 def create_menu(self, position: QPoint):
     org_idx: QModelIndex = self.indexAt(position)
     idx = self.proxy.mapToSource(org_idx)
     if not idx.isValid():
         # can happen e.g. before list is populated for the first time
         return
     tx_item = self.hm.transactions.value_from_pos(idx.row())
     column = idx.column()
     if column == HistoryColumns.STATUS_ICON:
         column_title = _('Transaction ID')
         column_data = tx_item['txid']
     else:
         column_title = self.hm.headerData(column, Qt.Horizontal,
                                           Qt.DisplayRole)
         column_data = self.hm.data(idx, Qt.DisplayRole).value()
     tx_hash = tx_item['txid']
     tx = self.wallet.transactions[tx_hash]
     tx_URL = block_explorer_URL(self.config, 'tx', tx_hash)
     height = self.wallet.get_tx_height(tx_hash).height
     is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx)
     is_unconfirmed = height <= 0
     pr_key = self.wallet.invoices.paid.get(tx_hash)
     menu = QMenu()
     if height == TX_HEIGHT_LOCAL:
         menu.addAction(_("Remove"), lambda: self.remove_local_tx(tx_hash))
     menu.addAction(
         _("Copy {}").format(column_title),
         lambda: self.parent.app.clipboard().setText(column_data))
     for c in self.editable_columns:
         if self.isColumnHidden(c): continue
         label = self.hm.headerData(c, Qt.Horizontal, Qt.DisplayRole)
         # TODO use siblingAtColumn when min Qt version is >=5.11
         persistent = QPersistentModelIndex(
             org_idx.sibling(org_idx.row(), c))
         menu.addAction(_("Edit {}").format(label),
                        lambda p=persistent: self.edit(QModelIndex(p)))
     menu.addAction(_("Details"), lambda: self.show_transaction(tx_hash))
     if is_unconfirmed and tx:
         # note: the current implementation of RBF *needs* the old tx fee
         rbf = is_mine and not tx.is_final() and fee is not None
         if rbf:
             menu.addAction(_("Increase fee"),
                            lambda: self.parent.bump_fee_dialog(tx))
         else:
             child_tx = self.wallet.cpfp(tx, 0)
             if child_tx:
                 menu.addAction(_("Child pays for parent"),
                                lambda: self.parent.cpfp(tx, child_tx))
     if pr_key:
         menu.addAction(read_QIcon("seal"), _("View invoice"),
                        lambda: self.parent.show_invoice(pr_key))
     if tx_URL:
         menu.addAction(_("View on block explorer"),
                        lambda: webbrowser.open(tx_URL))
     menu.exec_(self.viewport().mapToGlobal(position))
class CodeMetricsDialog(QDialog, Ui_CodeMetricsDialog):
    """
    Class implementing a dialog to display the code metrics.
    """
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent parent widget (QWidget)
        """
        super(CodeMetricsDialog, self).__init__(parent)
        self.setupUi(self)
        
        self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)
        
        self.summaryList.headerItem().setText(
            self.summaryList.columnCount(), "")
        self.summaryList.header().resizeSection(0, 200)
        self.summaryList.header().resizeSection(1, 100)
        
        self.resultList.headerItem().setText(self.resultList.columnCount(), "")
        
        self.cancelled = False
        
        self.__menu = QMenu(self)
        self.__menu.addAction(self.tr("Collapse all"),
                              self.__resultCollapse)
        self.__menu.addAction(self.tr("Expand all"), self.__resultExpand)
        self.resultList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.resultList.customContextMenuRequested.connect(
            self.__showContextMenu)
        
        self.__fileList = []
        self.__project = None
        self.filterFrame.setVisible(False)
        
    def __resizeResultColumns(self):
        """
        Private method to resize the list columns.
        """
        self.resultList.header().resizeSections(QHeaderView.ResizeToContents)
        self.resultList.header().setStretchLastSection(True)
        
    def __createResultItem(self, parent, values):
        """
        Private slot to create a new item in the result list.
        
        @param parent parent of the new item (QTreeWidget or QTreeWidgetItem)
        @param values values to be displayed (list)
        @return the generated item
        """
        itm = QTreeWidgetItem(parent)
        for col in range(len(values)):
            itm.setData(col, Qt.DisplayRole, values[col])
        for col in range(1, 7):
            itm.setTextAlignment(col, Qt.Alignment(Qt.AlignRight))
        return itm
        
    def __resizeSummaryColumns(self):
        """
        Private method to resize the list columns.
        """
        self.summaryList.header().resizeSections(QHeaderView.ResizeToContents)
        self.summaryList.header().setStretchLastSection(True)
        
    def __createSummaryItem(self, col0, col1):
        """
        Private slot to create a new item in the summary list.
        
        @param col0 string for column 0 (string)
        @param col1 string for column 1 (string)
        """
        itm = QTreeWidgetItem(self.summaryList, [col0, col1])
        itm.setTextAlignment(1, Qt.Alignment(Qt.AlignRight))
        
    def prepare(self, fileList, project):
        """
        Public method to prepare the dialog with a list of filenames.
        
        @param fileList list of filenames (list of strings)
        @param project reference to the project object (Project)
        """
        self.__fileList = fileList[:]
        self.__project = project
        
        self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
        self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
        
        self.filterFrame.setVisible(True)
        
        self.__data = self.__project.getData("OTHERTOOLSPARMS", "CodeMetrics")
        if self.__data is None or "ExcludeFiles" not in self.__data:
            self.__data = {"ExcludeFiles": ""}
        self.excludeFilesEdit.setText(self.__data["ExcludeFiles"])
        
    def start(self, fn):
        """
        Public slot to start the code metrics determination.
        
        @param fn file or list of files or directory to show
                the code metrics for (string or list of strings)
        """
        self.cancelled = False
        self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True)
        self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)
        QApplication.processEvents()
        
        loc = QLocale()
        if isinstance(fn, list):
            files = fn
        elif os.path.isdir(fn):
            files = Utilities.direntries(fn, True, '*.py', False)
        else:
            files = [fn]
        files.sort()
        # check for missing files
        for f in files[:]:
            if not os.path.exists(f):
                files.remove(f)
        
        self.checkProgress.setMaximum(len(files))
        QApplication.processEvents()
        
        total = {}
        CodeMetrics.summarize(total, 'files', len(files))
        
        progress = 0
        
        try:
            # disable updates of the list for speed
            self.resultList.setUpdatesEnabled(False)
            self.resultList.setSortingEnabled(False)
            
            # now go through all the files
            for file in files:
                if self.cancelled:
                    return
                
                stats = CodeMetrics.analyze(file, total)
                
                v = self.__getValues(loc, stats, 'TOTAL ')
                fitm = self.__createResultItem(self.resultList, [file] + v)
                
                identifiers = stats.identifiers
                for identifier in identifiers:
                    v = self.__getValues(loc, stats, identifier)
                    
                    self.__createResultItem(fitm, [identifier] + v)
                self.resultList.expandItem(fitm)
                
                progress += 1
                self.checkProgress.setValue(progress)
                QApplication.processEvents()
        finally:
            # reenable updates of the list
            self.resultList.setSortingEnabled(True)
            self.resultList.setUpdatesEnabled(True)
        self.__resizeResultColumns()
        
        # now do the summary stuff
        docstrings = total['lines'] - total['comments'] - \
            total['empty lines'] - total['non-commentary lines']
        self.__createSummaryItem(self.tr("files"),
                                 loc.toString(total['files']))
        self.__createSummaryItem(self.tr("lines"),
                                 loc.toString(total['lines']))
        self.__createSummaryItem(self.tr("bytes"),
                                 loc.toString(total['bytes']))
        self.__createSummaryItem(self.tr("comments"),
                                 loc.toString(total['comments']))
        self.__createSummaryItem(self.tr("empty lines"),
                                 loc.toString(total['empty lines']))
        self.__createSummaryItem(self.tr("non-commentary lines"),
                                 loc.toString(total['non-commentary lines']))
        self.__createSummaryItem(self.tr("documentation lines"),
                                 loc.toString(docstrings))
        self.__resizeSummaryColumns()
        self.__finish()
        
    def __getValues(self, loc, stats, identifier):
        """
        Private method to extract the code metric values.
        
        @param loc reference to the locale object (QLocale)
        @param stats reference to the code metric statistics object
        @param identifier identifier to get values for
        @return list of values suitable for display (list of strings)
        """
        counters = stats.counters.get(identifier, {})
        v = []
        for key in ('start', 'end', 'lines', 'nloc', 'comments', 'empty'):
            if counters.get(key, 0):
                v.append(counters[key])
            else:
                v.append('')
        return v
        
    def __finish(self):
        """
        Private slot called when the action finished or the user pressed the
        button.
        """
        self.cancelled = True
        self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
        self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
        
        if qVersion() >= "5.0.0":
            self.resultList.header().setSectionResizeMode(
                QHeaderView.Interactive)
            self.summaryList.header().setSectionResizeMode(
                QHeaderView.Interactive)
        else:
            self.resultList.header().setResizeMode(QHeaderView.Interactive)
            self.summaryList.header().setResizeMode(QHeaderView.Interactive)
        
    def on_buttonBox_clicked(self, button):
        """
        Private slot called by a button of the button box clicked.
        
        @param button button that was clicked (QAbstractButton)
        """
        if button == self.buttonBox.button(QDialogButtonBox.Close):
            self.close()
        elif button == self.buttonBox.button(QDialogButtonBox.Cancel):
            self.__finish()
        
    @pyqtSlot()
    def on_startButton_clicked(self):
        """
        Private slot to start a code metrics run.
        """
        fileList = self.__fileList[:]
        
        filterString = self.excludeFilesEdit.text()
        if "ExcludeFiles" not in self.__data or \
           filterString != self.__data["ExcludeFiles"]:
            self.__data["ExcludeFiles"] = filterString
            self.__project.setData("OTHERTOOLSPARMS", "CodeMetrics",
                                   self.__data)
        filterList = filterString.split(",")
        if filterList:
            for filter in filterList:
                fileList = [f for f in fileList
                            if not fnmatch.fnmatch(f, filter.strip())]
        
        self.resultList.clear()
        self.summaryList.clear()
        self.start(fileList)
        
    def __showContextMenu(self, coord):
        """
        Private slot to show the context menu of the listview.
        
        @param coord the position of the mouse pointer (QPoint)
        """
        if self.resultList.topLevelItemCount() > 0:
            self.__menu.popup(self.mapToGlobal(coord))
        
    def __resultCollapse(self):
        """
        Private slot to collapse all entries of the resultlist.
        """
        for index in range(self.resultList.topLevelItemCount()):
            self.resultList.topLevelItem(index).setExpanded(False)
        
    def __resultExpand(self):
        """
        Private slot to expand all entries of the resultlist.
        """
        for index in range(self.resultList.topLevelItemCount()):
            self.resultList.topLevelItem(index).setExpanded(True)
Beispiel #55
0
class Palette_Docker(DockWidget):
    # Init the docker

    def __init__(self):
        super(Palette_Docker, self).__init__()
        # make base-widget and layout
        widget = QWidget()
        layout = QVBoxLayout()
        buttonLayout = QHBoxLayout()
        widget.setLayout(layout)
        self.setWindowTitle(i18n("Python Palette Docker"))

        # Make a combobox and add palettes
        self.cmb_palettes = QComboBox()
        allPalettes = Application.resources("palette")
        for palette_name in allPalettes:
            self.cmb_palettes.addItem(palette_name)
            self.cmb_palettes.model().sort(0)

        if len(allPalettes.keys()) > 0:
            self.currentPalette = Palette(allPalettes[list(
                allPalettes.keys())[0]])
        else:
            self.currentPalette = None

        self.cmb_palettes.currentTextChanged.connect(self.slot_paletteChanged)
        layout.addWidget(self.cmb_palettes)  # add combobox to the layout
        self.paletteView = PaletteView()
        self.paletteView.setPalette(self.currentPalette)
        layout.addWidget(self.paletteView)
        self.paletteView.entrySelectedForeGround.connect(
            self.slot_swatchSelected)

        self.colorComboBox = QComboBox()
        self.colorList = list()
        buttonLayout.addWidget(self.colorComboBox)
        self.bnSetColor = QToolButton()
        self.bnSetColor.setText(i18n("Set"))
        self.bnSetColor.clicked.connect(self.slot_get_color_from_combobox)
        buttonLayout.addWidget(self.bnSetColor)

        self.addEntry = QAction(self)
        self.addEntry.setIconText(i18n("+"))
        self.addEntry.triggered.connect(self.slot_add_entry)
        self.addGroup = QAction(self)
        self.addGroup.triggered.connect(self.slot_add_group)
        self.addGroup.setText(i18n("Add Group"))
        self.addGroup.setIconText(str("\U0001F4C2"))
        self.removeEntry = QAction(self)
        self.removeEntry.setText(i18n("Remove Entry"))
        self.removeEntry.setIconText("-")
        self.removeEntry.triggered.connect(self.slot_remove_entry)
        addEntryButton = QToolButton()
        addEntryButton.setDefaultAction(self.addEntry)
        buttonLayout.addWidget(addEntryButton)
        addGroupButton = QToolButton()
        addGroupButton.setDefaultAction(self.addGroup)
        buttonLayout.addWidget(addGroupButton)
        removeEntryButton = QToolButton()
        removeEntryButton.setDefaultAction(self.removeEntry)
        buttonLayout.addWidget(removeEntryButton)

        # QActions
        self.extra = QToolButton()
        self.editPaletteData = QAction(self)
        self.editPaletteData.setText(i18n("Edit Palette Settings"))
        self.editPaletteData.triggered.connect(self.slot_edit_palette_data)
        self.extra.setDefaultAction(self.editPaletteData)
        buttonLayout.addWidget(self.extra)
        self.actionMenu = QMenu()
        self.exportToGimp = QAction(self)
        self.exportToGimp.setText(i18n("Export as GIMP Palette File"))
        self.exportToGimp.triggered.connect(self.slot_export_to_gimp_palette)
        self.exportToInkscape = QAction(self)
        self.exportToInkscape.setText(
            i18n("Export as Inkscape SVG with Swatches"))
        self.exportToInkscape.triggered.connect(
            self.slot_export_to_inkscape_svg)
        self.sortColors = QAction(self)
        self.sortColors.setText(i18n("Sort Colors"))
        self.sortColors.triggered.connect(self.slot_sort_colors)
        self.actionMenu.addAction(self.editPaletteData)
        self.actionMenu.addAction(self.exportToGimp)
        self.actionMenu.addAction(self.exportToInkscape)
        # self.actionMenu.addAction(self.sortColors)

        self.extra.setMenu(self.actionMenu)

        layout.addLayout(buttonLayout)
        self.slot_fill_combobox()
        self.setWidget(widget)  # add widget to the docker

    def slot_paletteChanged(self, name):
        allPalettes = Application.resources("palette")
        if len(allPalettes) > 0 and name in allPalettes:
            self.currentPalette = Palette(
                Application.resources("palette")[name])
            self.paletteView.setPalette(self.currentPalette)
            self.slot_fill_combobox()

    @pyqtSlot('KisSwatch')
    def slot_swatchSelected(self, entry):
        if (self.canvas()) is not None:
            if (self.canvas().view()) is not None:
                name = entry.name()
                if len(entry.id) > 0:
                    name = entry.id() + " - " + entry.name()
                if len(name) > 0:
                    if name in self.colorList:
                        self.colorComboBox.setCurrentIndex(
                            self.colorList.index(name))
                color = self.currentPalette.colorForEntry(entry)
                self.canvas().view().setForeGroundColor(color)

    '''
    A function for making a combobox with the available colors. We use QCompleter on the colorComboBox so that people
    can type in the name of a color to select it. This is useful for people with carefully made palettes where the colors
    are named properly, which makes it easier for them to find colors.
    '''

    def slot_fill_combobox(self):
        if self.currentPalette is None:
            pass
        palette = self.currentPalette
        self.colorComboBox.clear()
        self.colorList = list()
        #        for info in palette.infoList():
        #            entry = info.swatch
        #            color = palette.colorForEntry(entry).colorForCanvas(self.canvas())
        #            colorSquare = QPixmap(12, 12)
        #            if entry.spotColor() is True:
        #                img = colorSquare.toImage()
        #                circlePainter = QPainter()
        #                img.fill(self.colorComboBox.palette().color(QPalette.Base))
        #                circlePainter.begin(img)
        #                brush = QBrush(Qt.SolidPattern)
        #                brush.setColor(color)
        #                circlePainter.setBrush(brush)
        #                circlePainter.pen().setWidth(0)
        #                circlePainter.drawEllipse(0, 0, 11, 11)
        #                circlePainter.end()
        #                colorSquare = QPixmap.fromImage(img)
        #            else:
        #                colorSquare.fill(color)
        #            name = entry.name()
        #            if len(entry.id()) > 0:
        #                name = entry.id() + " - " + entry.name()
        #            self.colorList.append(name)
        #            self.colorComboBox.addItem(QIcon(colorSquare), name)
        self.colorComboBox.setEditable(True)
        self.colorComboBox.setInsertPolicy(QComboBox.NoInsert)
        self.colorComboBox.completer().setCompletionMode(
            QCompleter.PopupCompletion)
        self.colorComboBox.completer().setCaseSensitivity(False)
        self.colorComboBox.completer().setFilterMode(Qt.MatchContains)

    def slot_get_color_from_combobox(self):
        if self.currentPalette is not None:
            entry = self.currentPalette.colorSetEntryByIndex(
                self.colorComboBox.currentIndex())
            self.slot_swatchSelected(entry)

    def slot_add_entry(self):
        if (self.canvas()) is not None:
            if (self.canvas().view()) is not None:
                color = self.canvas().view().foregroundColor()
                success = self.paletteView.addEntryWithDialog(color)
                if success is True:
                    self.slot_fill_combobox()

    def slot_add_group(self):
        success = self.paletteView.addGroupWithDialog()
        if success is True:
            self.slot_fill_combobox()

    def slot_remove_entry(self):
        success = self.paletteView.removeSelectedEntryWithDialog()
        if success is True:
            self.slot_fill_combobox()

    '''
    A function for giving a gui to edit palette metadata... I also want this to be the way to edit the settings of the
    palette docker.
    '''

    def slot_edit_palette_data(self):
        dialog = QDialog(self)
        tabWidget = QTabWidget()
        dialog.setWindowTitle(i18n("Edit Palette Data"))
        dialog.setLayout(QVBoxLayout())
        dialog.layout().addWidget(tabWidget)
        paletteWidget = QWidget()
        paletteWidget.setLayout(QVBoxLayout())
        tabWidget.addTab(paletteWidget, i18n("Palette Data"))
        paletteName = QLineEdit()
        paletteName.setText(self.cmb_palettes.currentText())
        paletteWidget.layout().addWidget(paletteName)
        paletteColumns = QSpinBox()
        paletteColumns.setValue(self.currentPalette.columnCount())
        paletteWidget.layout().addWidget(paletteColumns)
        paletteComment = QPlainTextEdit()
        paletteComment.appendPlainText(self.currentPalette.comment())
        paletteWidget.layout().addWidget(paletteComment)
        buttons = QDialogButtonBox(QDialogButtonBox.Ok)
        dialog.layout().addWidget(buttons)
        buttons.accepted.connect(dialog.accept)
        # buttons.rejected.connect(dialog.reject())

        if dialog.exec_() == QDialog.Accepted:
            Resource = Application.resources("palette")[
                self.cmb_palettes.currentText()]
            Resource.setName(paletteName.text())
            self.currentPalette = Palette(Resource)
            self.currentPalette.setColumnCount(paletteColumns.value())
            self.paletteView.setPalette(self.currentPalette)
            self.slot_fill_combobox()
            self.currentPalette.setComment(paletteComment.toPlainText())
            self.currentPalette.save()

    def slot_export_to_gimp_palette(self):
        palette_exporter_gimppalette.gimpPaletteExporter(
            self.cmb_palettes.currentText())

    def slot_export_to_inkscape_svg(self):
        palette_exporter_inkscapeSVG.inkscapeSVGExporter(
            self.cmb_palettes.currentText())

    def slot_sort_colors(self):
        colorSorter = palette_sortColors.sortColors(
            self.cmb_palettes.currentText())
        self.paletteView.setPalette(colorSorter.palette())

    def canvasChanged(self, canvas):
        self.cmb_palettes.clear()
        allPalettes = Application.resources("palette")
        for palette_name in allPalettes:
            self.cmb_palettes.addItem(palette_name)
            self.cmb_palettes.model().sort(0)

        if self.currentPalette == None and len(allPalettes.keys()) > 0:
            self.currentPalette = Palette(allPalettes[list(
                allPalettes.keys())[0]])
Beispiel #56
0
    def _on_contextmenu(self, pos):
        """ ContextMenu
        """
        index = self.indexAt(pos).row()
        glbl_pt = self.mapToGlobal(pos)
        context_menu = QMenu(self)
        if index != -1:
            mem_prot = self._ranges_model.item(index, 2).text()
            # is readable
            if 'r' in mem_prot:
                context_menu.addAction(
                    'Dump Binary', lambda: self._on_dumprange(
                        self._ranges_model.item(index, 0).text(),
                        self._ranges_model.item(index, 1).text()))
                context_menu.addSeparator()

            context_menu.addAction(
                'Add Watcher', lambda: self._on_addwatcher(
                    self._ranges_model.item(index, 0).text()))

            context_menu.addAction(
                'Copy address', lambda: utils.copy_hex_to_clipboard(
                    self._ranges_model.item(index, 0).text()))
            context_menu.addSeparator()

            if self._ranges_model.item(index, 5):
                file_path = self._ranges_model.item(index, 5).text()
                if file_path:
                    context_menu.addAction(
                        'Copy Path',
                        lambda: utils.copy_str_to_clipboard(file_path))
                    context_menu.addSeparator()
                    if self._app_window.dwarf._platform == 'linux':
                        context_menu.addAction(
                            'Show ELF Info',
                            lambda: self._on_parse_elf(file_path))
                        context_menu.addSeparator()

            if self.search_enabled:
                context_menu.addSeparator()
                context_menu.addAction('Search', self._on_cm_search)
                context_menu.addSeparator()

        context_menu.addAction('Refresh', self.update_ranges)
        context_menu.exec_(glbl_pt)
Beispiel #57
0
    def descrittivo_finestraMain(self):
        """questa è la doc string della funzione, richiamabile con nomemodulo.nomefunzione.__doc__
        Qui definisco come è fatta la finestra principale"""

        # creo una statusbar (nella mainwindow in basso) che mostra la scritta "Caricamento completato..."
        self.statusBar().showMessage("Caricamento completato - Ver.0.1.180714")

        # creo una barra dei menu (in alto nella mainwindow)
        barraMenu = self.menuBar()
        # aggiungo alla barra dei menu creata sopra la prima voce: "File"
        fileMenu = barraMenu.addMenu("&File")

        # alla voce File creata sopra aggiungo una sotto voce "Nuovo".
        # queste sottovoci vengono chiamate QAction (azioni della barra del menu).
        Azione_Nuovo = QAction("Indirizzo", self)
        fileMenu.addAction(
            Azione_Nuovo
        )  #aggiungo alla barra dei menu creata prima l'azione appena creta

        # ora voglio aggiungere una voce che sia un "sotto menu".
        # Quindi creo prima di tutto un QMenu
        serverString_subMenu = QMenu("Stringa Server", self)
        # creo un'azione che andrò poi a legare stavolta al sottomenu
        importAct = QAction("Import mail", self)
        # aggiungo l'azione creata sopra al sottomenu
        serverString_subMenu.addAction(importAct)

        # aggiungo il sottomenu al menu principale creato prima.
        fileMenu.addMenu(serverString_subMenu)

        # creo anche la voce (azione) esci e la aggiungo nel sottomenu
        esciAct = QAction(
            QIcon("exit.png"), "&Esci", self
        )  #NB alla voce esci ho associato anche un'icona (png presente nella cartella)
        esciAct.setShortcut("Ctrl+Q")
        esciAct.setStatusTip("Exit Application")
        fileMenu.addAction(
            esciAct
        )  #NB l'ordine in cui vengono aggiunti gli oggetti nel menu è poi l'ordine delle voci

        # ora definisco cosa fanno le voci (azioni) nella barra dei menu
        Azione_Nuovo.triggered.connect(self.on_click5)
        esciAct.triggered.connect(qApp.quit)

        # **** parametri della finestra  ****
        left = 300
        top = 300
        width = 300
        height = 300

        self.setWindowTitle("Test a caso")
        self.setGeometry(left, top, width, height)

        #pulsante esercizio 1
        self.button = QPushButton("Esercizio 1", self)
        self.button.move(20, 40)
        self.button.clicked.connect(self.on_click)

        #pulsante esercizio 2
        self.button2 = QPushButton("Esercizio 2", self)
        self.button2.move(20, 80)
        self.button2.clicked.connect(self.on_click2)

        #pulsante esercizio 3
        self.button3 = QPushButton("Esercizio 3", self)
        self.button3.move(20, 120)
        self.button3.clicked.connect(self.on_click3)

        #pulsante cambio finestra
        self.button4 = QPushButton("Opzioni", self)
        self.button4.move(20, 160)
        self.button4.clicked.connect(self.on_click4)

        self.serverstring = QLineEdit(self)
        self.serverstring.move(20, 200)
        self.serverstring.text = self.stringaServer
Beispiel #58
0
 def create_menu(self, position):
     wallet = self.parent.wallet
     items = self.selected_in_column(0)
     if len(items) > 1:
         keys = [item.data(ROLE_REQUEST_ID) for item in items]
         invoices = [wallet.invoices.get(key) for key in keys]
         can_batch_pay = all([
             i.type == PR_TYPE_ONCHAIN
             and wallet.get_invoice_status(i) == PR_UNPAID for i in invoices
         ])
         menu = QMenu(self)
         if can_batch_pay:
             menu.addAction(
                 _("Batch pay invoices") + "...",
                 lambda: self.parent.pay_multiple_invoices(invoices))
         menu.addAction(_("Delete invoices"),
                        lambda: self.parent.delete_invoices(keys))
         menu.exec_(self.viewport().mapToGlobal(position))
         return
     idx = self.indexAt(position)
     item = self.item_from_index(idx)
     item_col0 = self.item_from_index(
         idx.sibling(idx.row(), self.Columns.DATE))
     if not item or not item_col0:
         return
     key = item_col0.data(ROLE_REQUEST_ID)
     invoice = self.parent.wallet.get_invoice(key)
     menu = QMenu(self)
     self.add_copy_menu(menu, idx)
     if invoice.is_lightning():
         menu.addAction(_("Details"),
                        lambda: self.parent.show_lightning_invoice(invoice))
     else:
         if len(invoice.outputs) == 1:
             menu.addAction(
                 _("Copy Address"),
                 lambda: self.parent.do_copy(invoice.get_address(),
                                             title='Bitcoin Address'))
         menu.addAction(_("Details"),
                        lambda: self.parent.show_onchain_invoice(invoice))
     status = wallet.get_invoice_status(invoice)
     if status == PR_UNPAID:
         menu.addAction(
             _("Pay") + "...", lambda: self.parent.do_pay_invoice(invoice))
     if status == PR_FAILED:
         menu.addAction(_("Retry"),
                        lambda: self.parent.do_pay_invoice(invoice))
     if self.parent.wallet.lnworker:
         log = self.parent.wallet.lnworker.logs.get(key)
         if log:
             menu.addAction(_("View log"), lambda: self.show_log(key, log))
     menu.addAction(_("Delete"), lambda: self.parent.delete_invoices([key]))
     menu.exec_(self.viewport().mapToGlobal(position))
Beispiel #59
0
    def myContextMenu(self, pos):
        menu = QMenu(self)

        menu.addAction('&+', self.addSticker, 'Ctrl+T')
        menu.addAction('&background color', self.backgroundColorDialog,
                       'Ctrl+B')
        menu.addAction('text colo&r', self.textColorDialog, 'Ctrl+R')
        menu.addAction('text f&ormat', self.fontDialog, 'Ctrl+O')
        menu.addAction('&save', self.save, 'Ctrl+S')
        menu.addAction('&load', self.load, 'Ctrl+L')
        menu.addAction('&close', self.close, 'Ctrl+W')
        menu.addAction('&quit', qApp.myQuit, 'Ctrl+Q')
        menu.addAction('reo&pen last closed', self.loadLastClosed,
                       'Shift+Ctrl+T')

        menu.exec_(self.mapToGlobal(pos))
Beispiel #60
0
class Gala(QWidget):
    """ Main window that holds the main layout """

    MAX_TIME = 604800  # self.maxTime == Monday 12:00 am or 0 seconds

    def __init__(self, parent=None):
        super().__init__()

        self.threads = []

        self.ignoreQuit = True
        self.columnWidth = 100
        self.numRow = 20
        self.numColumn = 2

        self.validDate = ["mon", "tues", "wed", "thurs", "fri", "sat", "sun"]
        self.AM = "am"
        self.PM = "pm"

        self.data_path = os.path.abspath("UserData/GalaData.json")
        self.icon_path = os.path.abspath("Icon/orange.png")

        self.trayMenu = QMenu(self)
        self.trayMenu.addAction("Open", self.open_)
        self.trayMenu.addAction("Hide", self.hide)
        self.trayMenu.addAction("Quit", self.quit)

        self.tray = QSystemTrayIcon(QIcon(self.icon_path), self)
        self.tray.setContextMenu(self.trayMenu)
        self.tray.activated.connect(self.onClickEvent)
        self.tray.show()

        self.firstHeader = "Time"
        self.secondHeader = "Description"

        self.table = QTableWidget(self)
        self.table.setRowCount(self.numRow)
        self.table.setColumnCount(self.numColumn)
        self.table.setHorizontalHeaderLabels(
            [self.firstHeader, self.secondHeader])
        #self.table.setColumnWidth(0, self.columnWidth)
        #self.table.setColumnWidth(1, self.columnWidth)

        self.tableScrollW = self.table.verticalScrollBar().sizeHint().width()
        self.tableHeaderW = self.table.horizontalHeader().length()
        self.tableVertHeaderW = self.table.verticalHeader().width()
        self.tableFrameW = self.table.frameWidth() * 2
        self.tableWidth = (self.tableScrollW + self.tableHeaderW +
                           self.tableFrameW)
        self.table.setFixedWidth(self.tableWidth)

        self.table.verticalHeader().hide()

        self.header = self.table.horizontalHeader()
        self.header.setSectionResizeMode(0, QHeaderView.Interactive)
        self.header.setSectionResizeMode(1, QHeaderView.Stretch)
        self.headerMidPoint = self.header.length() / 2
        self.header.setMinimumSectionSize(self.headerMidPoint * 0.10)
        self.header.setMaximumSectionSize(self.headerMidPoint * 1.90)

        self.saveButton = self.createButton("Save", self.saveButtonClick)
        self.galaButton = self.createButton("Gala", self.galaButtonClick)
        self.loadButton = self.createButton("Load", self.loadButtonClick)
        self.infoButton = self.createButton("Info", self.infoButtonClick)
        # self.checkButton = self.createButton("Check", self.checkButtonClick)
        self.clearButton = self.createButton("Clear", self.clearButtonClick)

        layout = QGridLayout(self)
        layout.addWidget(self.table, 0, 0, 1, 6)
        layout.addWidget(self.loadButton, 1, 0)
        layout.addWidget(self.saveButton, 1, 1)
        layout.addWidget(self.clearButton, 1, 2)
        # layout.addWidget(self.checkButton, 1, 3)
        layout.addWidget(self.infoButton, 1, 4)
        layout.addWidget(self.galaButton, 1, 5)
        # only vertical resize allowed
        #layout.setSizeConstraint(QLayout.SetFixedSize)
        self.setLayout(layout)

        self.autoLoad()  # load user data

        height = self.table.verticalHeader().width() * 20
        width = self.sizeHint().width()
        self.resize(width, height)
        self.setWindowIcon(QIcon(self.icon_path))
        self.setFixedWidth(width)
        self.setWindowTitle("Gala")

    def autoLoad(self):
        self.load()

    def createButton(self, text, func):
        btn = QToolButton()
        btn.setText(text)
        btn.clicked.connect(func)
        return btn

    def onClickEvent(self, event):
        self.open_()

    def closeEvent(self, closeEvent):
        if self.ignoreQuit:
            closeEvent.ignore()
            self.hide()
        else:
            QCoreApplication.exit()

    def hideEvent(self, hideEvent):
        self.hide()

    def galaButtonClick(self):
        if self.validTimes(msgHint="Failed to start.") == True:
            for i in range(0, len(self.threads)):
                self.threads[i].stop()

            self.hide()

            now = Gala.timeNow()
            minTime = None
            num = None
            for row in range(0, self.numRow):
                txt = self.table.item(row, 0).text()
                if txt == "": continue

                end = Gala.parseTime(txt)
                end = Gala.normalizeTime(end[0], end[1], end[2])
                if end < now:
                    deltaTime = Gala.MAX_TIME - abs(end - now)
                else:
                    deltaTime = end - now

                if minTime is None or deltaTime < minTime:
                    minTime = deltaTime
                    num = row

            galaThread = GalaThread(
                self.table.item(num, 0).text(),
                self.table.item(num, 1).text())
            galaThread.signal.connect(self.delivMsg)
            galaThread.start()

            self.threads.append(galaThread)

    def saveButtonClick(self):
        self.setFocus()

        if self.validTimes(msgHint="Failed to save.") == True:
            os.makedirs("UserData", exist_ok=True)
            with open(self.data_path, 'w') as f:
                data = self.convertTableToJson()
                f.write(data)
                f.close()

    def loadButtonClick(self):
        self.load()

    def infoButtonClick(self):
        ex = GalaPopup(
            "Examples", "Tues 1:00 pm | Fri 3:00 pm | Sat 8:30 am\n\n"
            "Valid days\n"
            "Mon | Tues | Wed | Thurs | Fri | Sat | Sun\n\n"
            "Valid times\n"
            "12:00 am ... 11:59 pm")
        ex.setWindowTitle("Info")
        ex.exec_()

    def checkButtonClick(self):
        pass

    def clearButtonClick(self):
        self.clearTable()

    def load(self):
        self.loadJsonToTable(self.data_path)

    def open_(self):
        self.setVisible(True)
        self.raise_()

    def quit(self):
        self.ignoreQuit = False
        self.close()

    def hide(self):
        self.setVisible(False)

    @staticmethod
    def timeNow():
        now = datetime.datetime.now()
        nowTime = Gala.normalizeTime(now.weekday(), now.hour, now.minute)
        return nowTime

    @staticmethod
    def parseTime(text):
        text = text.split()

        weekday = text[0].lower()
        weekday = Weekday[weekday].value

        time = text[1].split(':')
        hour = int(time[0])
        min_ = int(time[1])

        amPM = text[2].lower()
        if amPM == "pm" and hour in range(1, 12):
            hour += 12
        elif hour is 12 and amPM is "am":
            hour -= 12

        return [weekday, hour, min_]

    @staticmethod
    def normalizeTime(day, hour, min_):
        """ 
         days      = [Mon...Sun] = [0...6]
         hours     = [0...24]
         minutes   = [0...60]
         Normalize to/with Monday 00:00 (12:00 am) as 0 or self.maxNorm
         in seconds.
         Example: Thursday 14:00 (2:00 pm) = 396,000 seconds from 0 
        """
        day = day * 24 * 60 * 60
        hour = hour * 60 * 60
        min_ = min_ * 60
        normTime = day + hour + min_

        return normTime

    def delivMsg(self, timeMsg, msg):
        msgBox = GalaPopup("Gala delivery", timeMsg, msg)
        msgBox.exec_()

    def errTimeMsg(self, row, msgHint=""):
        errMsg = self.table.item(row, 0).text()
        err = GalaPopup(
            msgHint, "Invalid time at row " + str(row + 1) + ":\n\n" + errMsg)
        err.setWindowTitle("Invalid time")
        err.exec_()

    def validTimes(self, msgHint=""):
        """ Validate time
        Assume (or enforce) time format as "DATE TIME AM/PM".
        Example (from string to an array): ["Tues", "11:00", "am"]
        """
        # TODO More strict time check. i.e right now Tues 0:00 pm is okay...
        # maybe more checks or simplify some steps?
        for row in range(0, self.numRow):
            galaTime = self.table.item(row, 0)

            if galaTime is None or galaTime.text() is "": continue

            galaTime = galaTime.text().split()
            if len(galaTime) != 3:
                self.errTimeMsg(row, msgHint)
                return False

            date = galaTime[0]
            time = galaTime[1]
            am_pm = galaTime[2]

            if self.isDate(date) and self.isTime(time) and self.isAmPm(am_pm):
                continue
            else:
                self.errTimeMsg(row, msgHint)
                return False

        return True

    def isDate(self, date):
        date = date.lower()
        if date in self.validDate:
            return True
        return False

    def isTime(self, time):
        time = time.split(':')
        if len(time) != 2:
            return False

        hour = int(time[0])
        minute = int(time[1])
        hourRange = lambda: range(1, 13)
        minuteRange = lambda: range(0, 61)

        if hour in hourRange() and minute in minuteRange():
            return True
        else:
            return False

    def isAmPm(self, am_pm):
        if am_pm.lower() == self.AM or am_pm.lower() == self.PM:
            return True
        else:
            return False

    def clearTable(self):
        for row in range(0, self.numRow):
            for col in range(0, self.numColumn):
                g = QTableWidgetItem("")
                self.table.setItem(row, col, g)

    def convertTableToJson(self):
        items = []
        for row in range(0, self.numRow):
            item = {}
            item["row"] = row

            for col in range(0, self.numColumn):
                tableItem = self.table.item(row, col)
                if tableItem is None:
                    text = None
                else:
                    text = tableItem.text()

                if col == 0:
                    item["time"] = text
                elif col == 1:
                    item["description"] = text

            items.append(item)

        galaItems = {"gala_items": items}
        jsonString = json.dumps(galaItems, indent=4)
        return jsonString

    def loadJsonToTable(self, path):
        if not os.path.isfile(path):
            return 0

        galaData = open(path).read()
        galaData = json.loads(galaData)

        for i in range(0, len(galaData["gala_items"])):
            row = galaData["gala_items"][i]["row"]
            time = galaData["gala_items"][i]["time"]
            info = galaData["gala_items"][i]["description"]

            self.table.setItem(row, 0, QTableWidgetItem(time))
            self.table.setItem(row, 1, QTableWidgetItem(info))

    def convertTableToDict(self):
        jobArr = []
        for row in range(0, self.numRow):
            newJob = {}
            for col in range(0, self.numColumn):
                if col == 1:
                    newJob["time"] = self.table.item(row, col)
                elif col == 2:
                    newJob["description"] = self.table.item(row, col)
            jobArr.append(newJob)
        return jobArr