コード例 #1
0
ファイル: views.py プロジェクト: asymworks/python-divelog
 def showContextMenu(self, point):
     'Show the Columns context menu'
     if self.model() is None:
         return
     
     # If we are viewing a proxy model, skip to the source model
     mdl = self.model()
     while isinstance(mdl, QAbstractProxyModel):
         mdl = mdl.sourceModel()
     
     if mdl is None or not hasattr(mdl, 'columns'):
         return
     
     # Generate and show the Menu
     m = QMenu()
     for i in range(len(mdl.columns)):
         c = mdl.columns[i]
         if c.internal:
             continue
         
         a = QAction(mdl.headerData(i, Qt.Horizontal, Qt.DisplayRole), m)
         a.setCheckable(True)
         a.setChecked(not self.isColumnHidden(i))
         a.triggered.connect(partial(self.showHideColumn, c=i, s=self.isColumnHidden(i)))
         m.addAction(a)
         
     m.exec_(self.header().mapToGlobal(point))
コード例 #2
0
 def note_context_menu(self, pos):
     menu = QMenu(self.ui.notesList)
     menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Edit'),
                    self.edit_note)
     menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'),
                    self.remove_note)
     menu.exec_(self.ui.notesList.mapToGlobal(pos))
コード例 #3
0
    def loadContextMenu(self, *args):

        menu = QMenu(self.w_tree)
        path = self.w_tree.currentItem().text(0)
        if os.path.isdir(path):
            dirPath = path
        else:
            dirPath = os.path.dirname(path)
        if os.path.exists(dirPath):
            menu.addAction(unicode("Open Folder", errors='replace'),
                           self.openFolder)
        menu.addAction(unicode("Copy Path", errors='replace'), self.copyPath)
        separator = QAction(self.w_tree)
        separator.setSeparator(True)
        menu.addAction(separator)
        menu.addAction(unicode("Replace Path", errors='replace'),
                       self.replacePath)
        separator = QAction(self.w_tree)
        separator.setSeparator(True)
        menu.addAction(separator)
        if self.unusedExists():
            menu.addAction(unicode("Remove Unused Files", errors='replace'),
                           self.removeUnused)
        pos = QCursor.pos()
        point = QtCore.QPoint(pos.x() + 10, pos.y())
        menu.exec_(point)
コード例 #4
0
ファイル: list.py プロジェクト: AnderSilva/everpad
 def tag_context_menu(self, pos):
     index = self.ui.tagsList.currentIndex()
     item = self.tagsModel.itemFromIndex(index)
     if hasattr(item, 'tag'):
         menu = QMenu(self.ui.tagsList)
         menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'), self.remove_tag)
         menu.exec_(self.ui.tagsList.mapToGlobal(pos))
コード例 #5
0
 def __menu(self, pos):
     u"""Slot d'apparition du menu contextuel"""
     menu = QMenu()
     menu.addAction("Supprimer", self, SLOT("supprimer()"),
                    QKeySequence.Delete)
     menu.addAction("Nouveau", self, SLOT("nouveau()"), QKeySequence.New)
     menu.exec_(self._ui.tv.mapToGlobal(pos))
コード例 #6
0
ファイル: resources.py プロジェクト: wanghg1992/everpad
 def click(self, res, event):
     """Open resource"""
     button = event.button()
     if button == Qt.LeftButton:
         subprocess.Popen(['xdg-open', res.file_path])
     elif button == Qt.RightButton:
         menu = QMenu(self.parent)
         menu.addAction(
             self.app.translate('ResourceEdit', 'Put to Content'),
             Slot()(partial(
                 self.to_content,
                 res=res,
             )),
         )
         if not self.parent.note_edit.in_content(res):
             menu.addAction(
                 self.app.translate('ResourceEdit', 'Remove Resource'),
                 Slot()(partial(
                     self.remove,
                     res=res,
                 )))
         menu.addAction(self.app.translate('ResourceEdit', 'Save As'),
                        Slot()(partial(
                            self.save,
                            res=res,
                        )))
         menu.exec_(event.globalPos())
コード例 #7
0
ファイル: editor.py プロジェクト: altawu/everpad
 def click(self, res, event):
     """Open resource"""
     button = event.button()
     if button == Qt.LeftButton:
         subprocess.Popen(['xdg-open', res.file_path])
     elif button == Qt.RightButton:
         menu = QMenu(self.parent)
         if res.mime.find('image') == 0:
             menu.addAction(
                 self.parent.tr('Put to Content'), Slot()(partial(
                     self.to_content, res=res,
                 )),
             )
         if not self.parent.note_edit.in_content(res):
             menu.addAction(
                 self.parent.tr('Remove Resource'), Slot()(partial(
                     self.remove, res=res,
                 ))
             )
         menu.addAction(
             self.parent.tr('Save As'), Slot()(partial(
                 self.save, res=res,
             ))
         )
         menu.exec_(event.globalPos())
コード例 #8
0
 def tag_context_menu(self, pos):
     index = self.ui.tagsList.currentIndex()
     item = self.tagsModel.itemFromIndex(index)
     if hasattr(item, 'tag'):
         menu = QMenu(self.ui.tagsList)
         menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'),
                        self.remove_tag)
         menu.exec_(self.ui.tagsList.mapToGlobal(pos))
コード例 #9
0
ファイル: list.py プロジェクト: berzjackson/everpad
 def notebook_context_menu(self, pos):
     index = self.ui.notebooksList.currentIndex()
     item = self.notebooksModel.itemFromIndex(index)
     if hasattr(item, 'notebook'):
         menu = QMenu(self.ui.notebooksList)
         menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Rename'), self.rename_notebook)
         menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'), self.remove_notebook)
         menu.exec_(self.ui.notebooksList.mapToGlobal(pos))
コード例 #10
0
class HierarchyTreeView(QTreeView):


    def __init__(self):
        super(HierarchyTreeView, self).__init__()
        
        #ukljucuje kontekstni meni
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.openMenu)
        
    
    def openMenu(self, position):
        self.contextMenu = QMenu()
        newMenu = QMenu("New") 
        self.contextMenu.addMenu(newMenu)
        
        actionNewProj = QAction("NewProject", None)
        actionNewProj.triggered.connect(self.addNode)
        
        actionRename = QAction("Rename", None)
        actionRename.triggered.connect(self.renameNode)
        
        actionRemProj = QAction("Delete", None)
        actionRemProj.triggered.connect(self.removeNode)
        
        newMenu.addAction(actionNewProj)
        self.contextMenu.addAction(actionRename)
        self.contextMenu.addAction(actionRemProj)
        
        #prikaz kontekstnog menija
        self.contextMenu.exec_(self.viewport().mapToGlobal(position))
        
    def addNode(self):
        model = self.model()
        
        node = Node("NoviCvor")
        
        
        
        if not self.currentIndex().isValid():
            model.insertRow(model.rowCount(self.currentIndex()), node)
        else:
            model.insertRow(model.rowCount(self.currentIndex()), node, self.currentIndex())
        self.expand(self.currentIndex())
    
    def removeNode(self):
        model = self.model()
        model.removeRow(self.currentIndex().internalPointer().getIndex(), self.currentIndex().parent())    
        
    def renameNode(self):
        self.currentIndex().internalPointer().setName("NOVO")
    
    
    def mousePressEvent(self, event):
        if(self.selectionMode() == QAbstractItemView.SingleSelection):
            self.clearSelection()
            self.setCurrentIndex(QModelIndex())
        super(HierarchyTreeView, self).mousePressEvent(event)
コード例 #11
0
    def mousePressEvent(self, mouse_event):
        if mouse_event.button() == Qt.RightButton:
            if self._spec_index is None:
                print("spec_index is None")
                print(self)
                print(self._running_providers)
                return
            pos = mouse_event.pos()
            items = [
                item for item in self.items(pos)
                if isinstance(item, NodeItem) and item._label.text()
            ]
            if len(items) != 1:
                print("wrong number of things",
                      [x._label.text() for x in items])
                return

            name = items[0]._label.text().rstrip('(default)').strip()
            if name not in self._spec_index.provider_names:
                print(name, "Not in list of providers")
                return
            provider = self._spec_index.providers[name]

            def start_trigger():
                # TODO: replace 'capability_server' with user provided server name
                service_name = '/{0}/start_capability'.format(
                    'capability_server')
                rospy.wait_for_service(service_name)
                start_capability = rospy.ServiceProxy(service_name,
                                                      StartCapability)
                start_capability(provider.implements, name)

            def stop_trigger():
                # TODO: replace 'capability_server' with user provided server name
                service_name = '/{0}/stop_capability'.format(
                    'capability_server')
                rospy.wait_for_service(service_name)
                stop_capability = rospy.ServiceProxy(service_name,
                                                     StopCapability)
                stop_capability(provider.implements)

            if name not in self._running_providers:
                trigger = start_trigger
                msg = "start => "
            else:
                trigger = stop_trigger
                msg = "stop => "

            menu = QMenu()
            action = menu.addAction(msg + name)
            action.triggered.connect(trigger)
            pos = mouse_event.globalPos()
            pos = QPoint(pos.x(), pos.y())
            menu.exec_(pos)
        else:
            InteractiveGraphicsView.mousePressEvent(self, mouse_event)
コード例 #12
0
ファイル: list.py プロジェクト: guofengstc/everpad
 def notebook_context_menu(self, pos):
     index = self.ui.notebooksList.currentIndex()
     item = self.notebooksModel.itemFromIndex(index)
     if hasattr(item, 'notebook'):
         menu = QMenu(self.ui.notebooksList)
         menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Rename'),
                        self.rename_notebook)
         menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'),
                        self.remove_notebook)
         menu.exec_(self.ui.notebooksList.mapToGlobal(pos))
コード例 #13
0
ファイル: main.py プロジェクト: montreal91/workshop
    def __LobbyListMenu( self, position ):
        lobby_menu      = QMenu()

        rm_from_lobby   = QAction( self )
        rm_from_lobby.setText( "Remove player from lobby" )
        rm_from_lobby.triggered.connect( self._RemoveFromLobbyListAction )

        lobby_menu.addAction( rm_from_lobby )

        lobby_menu.exec_( self.window.lobby_lst.viewport().mapToGlobal( position ) )
コード例 #14
0
ファイル: main_window.py プロジェクト: toroettg/SeriesMarker
 def _handle_context_menu(self, pos):
     index = self.ui.tree_view.indexAt(pos)
     if index.isValid():
         pos = self.ui.tree_view.viewport().mapToGlobal(pos)
         menu = QMenu()
         menu.addAction(self.ui.action_mark_watched)
         menu.addAction(self.ui.action_mark_unwatched)
         menu.addSeparator()
         menu.addAction(self.ui.action_remove)
         menu.exec_(pos)
コード例 #15
0
ファイル: editor.py プロジェクト: fabianofranz/everpad
 def click(self, res, event):
     """Open resource"""
     button = event.button()
     if button == Qt.LeftButton:
         subprocess.Popen(["xdg-open", res.file_path])
     elif button == Qt.RightButton:
         menu = QMenu(self.parent)
         if not res.in_content:
             menu.addAction(self.parent.tr("Remove Resource"), Slot()(partial(self.remove, res=res)))
         menu.addAction(self.parent.tr("Save As"), Slot()(partial(self.save, res=res)))
         menu.exec_(event.globalPos())
コード例 #16
0
ファイル: cmdprompt.py プロジェクト: JTrantow/Embroidermodder
    def contextMenuEvent(self, event):
        """
        Handles the ``contextMenuEvent`` event for :class:`CmdPromptInput`.

        :param `event`: a `QContextMenuEvent` event to be processed.
        """
        menu = QMenu(self)
        menu.addSeparator()
        # TODO: Extra stuff
        menu.addAction(QAction("TODO: Add Extra stuff", self))
        menu.exec_(event.globalPos())
コード例 #17
0
    def contextMenuEvent(self, event):
        """
        Handles the ``contextMenuEvent`` event for :class:`CmdPromptInput`.

        :param `event`: a `QContextMenuEvent` event to be processed.
        """
        menu = QMenu(self)
        menu.addSeparator()
        # TODO: Extra stuff
        menu.addAction(QAction("TODO: Add Extra stuff", self))
        menu.exec_(event.globalPos())
コード例 #18
0
    def loadContextMenu(self):
        def cmd_loadSelected():
            selObjects = pymel.core.ls(sl=1)
            if not selObjects: return
            cuItem = self.treeWidget.currentItem()
            cuItem.setText(1, selObjects[0].name())

        menu = QMenu(self.treeWidget)
        menu.addAction("Load Object", cmd_loadSelected)
        pos = QCursor.pos()
        point = QtCore.QPoint(pos.x() + 10, pos.y())
        menu.exec_(point)
コード例 #19
0
ファイル: moviemenu.py プロジェクト: mkawserm/iMovMan
 def send_to_popup(self):
     drive_option=QMenu(self.parent())
     opts=config.SEND_TO[0:(len(config.SEND_TO)-1)]
     for cnf in opts:
         k=QAction(QIcon(appicon("explore")),cnf,self )
         k.triggered.connect(self.click_event)
         drive_option.addAction(k)
     drive_option.exec_(QtGui.QCursor.pos())
     
     
     
     
     
     
コード例 #20
0
ファイル: main.py プロジェクト: montreal91/workshop
    def __PlayersListMenu( self, position ):
        list_menu           = QMenu()

        add_player_to_lobby = QAction( self )
        add_player_to_lobby.setText( "Add player to lobby" )
        add_player_to_lobby.triggered.connect( self._AddToLobbyAction )

        rm_player           = QAction( self )
        rm_player.setText( "Remove player" )
        rm_player.triggered.connect( self._RemoveFromPlayersListAction )

        list_menu.addAction( rm_player )
        list_menu.addAction( add_player_to_lobby )

        list_menu.exec_( self.window.players_lst.viewport().mapToGlobal( position ) )
コード例 #21
0
    def mousePressEvent(self, mouse_event):
        if mouse_event.button() == Qt.RightButton:
            if self._spec_index is None:
                print("spec_index is None")
                print(self)
                print(self._running_providers)
                return
            pos = mouse_event.pos()
            items = [item for item in self.items(pos) if isinstance(item, NodeItem) and item._label.text()]
            if len(items) != 1:
                print("wrong number of things", [x._label.text() for x in items])
                return

            name = items[0]._label.text().rstrip('(default)').strip()
            if name not in self._spec_index.provider_names:
                print(name, "Not in list of providers")
                return
            provider = self._spec_index.providers[name]

            def start_trigger():
                # TODO: replace 'capability_server' with user provided server name
                service_name = '/{0}/start_capability'.format('capability_server')
                rospy.wait_for_service(service_name)
                start_capability = rospy.ServiceProxy(service_name, StartCapability)
                start_capability(provider.implements, name)

            def stop_trigger():
                # TODO: replace 'capability_server' with user provided server name
                service_name = '/{0}/stop_capability'.format('capability_server')
                rospy.wait_for_service(service_name)
                stop_capability = rospy.ServiceProxy(service_name, StopCapability)
                stop_capability(provider.implements)

            if name not in self._running_providers:
                trigger = start_trigger
                msg = "start => "
            else:
                trigger = stop_trigger
                msg = "stop => "

            menu = QMenu()
            action = menu.addAction(msg + name)
            action.triggered.connect(trigger)
            pos = mouse_event.globalPos()
            pos = QPoint(pos.x(), pos.y())
            menu.exec_(pos)
        else:
            InteractiveGraphicsView.mousePressEvent(self, mouse_event)
コード例 #22
0
ファイル: genericSymbols.py プロジェクト: blipvert/opengeode
 def contextMenuEvent(self, event):
     ''' When user right-clicks: display context menu '''
     png_action = 'Export branch to PNG, SVG or PDF'
     hl_action = 'Hyperlink'
     my_menu = QMenu(png_action)
     if not hasattr(self, '_no_hyperlink'):
         my_menu.addAction(hl_action)
     my_menu.addAction(png_action)
     action = my_menu.exec_(event.screenPos())
     if action:
         if action.text() == png_action:
             # Save a picture of the selected symbol and all its children
             filename = QFileDialog.getSaveFileName(self.window(),
                     'Export picture', '.',
                     'Picture (*.png, *.svg, *.pdf)')[0]
             if not filename:
                 return
             save_fmt = filename.split(os.extsep)[-1]
             if save_fmt not in ('png', 'svg', 'pdf'):
                 return
             self.scene().export_branch_to_picture(self, filename, save_fmt)
         elif action.text() == hl_action:
             if self.text:
                 self.hyperlink_dialog.setParent(
                         self.scene().views()[0], Qt.Dialog)
                 self.hlink_field.setText(self.text.hyperlink)
                 self.hyperlink_dialog.show()
コード例 #23
0
    def popup_menu(self, position):

        selected_row = self.view.rowAt(position.y())

        if selected_row >= 0 and self._used_categories and len(
                self._used_categories) > 1:
            category_menu = QMenu(_("Categories"))
            selected_doc = self.model.object_at(selected_row)

            category_actions = []
            for category in self._used_categories:
                a = QAction(category.full_name, category_menu)
                a.setData(category)

                a.setEnabled(selected_doc.document_category_id !=
                             category.document_category_id)

                category_menu.addAction(a)
                category_actions.append(a)

            action = category_menu.exec_(QCursor.pos())

            if action:
                new_category = action.data()

                if selected_doc.document_category_id != new_category.document_category_id:
                    selected_doc.document_category_id = new_category.document_category_id
                    self.model.signal_object_change(selected_doc)
コード例 #24
0
    def showContextMenu(self, pos):
        """
        Shows a context menu to add a node in the graph widget
        """
        gpos = self.graphicsView.mapToGlobal(pos)
        menu = QMenu()
        actionAddNode = menu.addAction("Add Node")
        QAction = menu.exec_(gpos)

        if (actionAddNode == QAction):
            (text,
             ok) = QInputDialog.getText(self.graphicsView, "Insert Node Name",
                                        "Please insert a name for the node")
            if ok:
                if text not in self.nodesToQNodes:
                    #User clicked on ok. Otherwise do nothing
                    self.gv.add_node(text)
                    node = self.gv.get_node(text)
                    qnode = self.createQtNode(node, 0, 0,
                                              QColor(204, 255, 255))

                    self.graphicsView.scene().addItem(qnode)
                    qnode.setPos(self.graphicsView.mapToScene(gpos))
                    qnode.setPos(qnode.x(), qnode.y() - 200)
                    self.nodesToQNodes[node] = qnode
                else:
                    msg = QMessageBox()
                    msg.setText("The node already exists.")
                    msg.exec_()
                self.searchNode(text)
コード例 #25
0
    def popup(self,pos):
        menu = QMenu()

        saveRepAction = QAction(self)
        saveRepAction.setText('Save representation...')
        saveRepAction.triggered.connect(lambda: self.saveRep(self.indexAt(pos)))
        menu.addAction(saveRepAction)
        action = menu.exec_(self.mapToGlobal(pos))
コード例 #26
0
ファイル: plotter.py プロジェクト: Yakisoba007/PyTrigno
 def contextMenuEvent(self, e):
     ''' calls context menu if right click:
      - set server
      - trigger server (storts or stops the server)
     in case of righ click on point, a plot is added
     '''
     i = 0
     for pp in self.points:
         i += 1
         if (e.pos()-pp).manhattanLength() > 5:
             continue
         else:
             self.addPlot(str(i))
             return
     menu = QMenu()
     menu.addAction("Set Server", self.setServer)
     menu.addAction("Trigger Server", self.stream)
     menu.exec_(e.globalPos())
コード例 #27
0
ファイル: PushupList.py プロジェクト: davcri/Pushup-app
 def _customMenu(self):
     selectedItems = self.pushupsListWidget.selectedItems()
     
     if selectedItems is not None :
         selectedItem = selectedItems[0] 
         
         if selectedItem.parent() is not None : # Child Item selected
             menu = QMenu()
             
             delete = QAction(self.pushupsListWidget)
             delete.setText("Delete this pushup")
             delete.triggered.connect(self._emitDeleteSignal)
             menu.addAction(delete)
             menu.exec_(QCursor.pos())
         else : # Top level Item selected
             menu = QMenu()
          
             delete = QAction(self.pushupsListWidget)
             delete.setText("Delete this day and all of its exercises")
             delete.triggered.connect(self._emitDeleteDaySignal)
             menu.addAction(delete)
             menu.exec_(QCursor.pos())
コード例 #28
0
ファイル: PushupList.py プロジェクト: davcri/Pushup-app
    def _customMenu(self):
        selectedItems = self.pushupsListWidget.selectedItems()

        if selectedItems is not None:
            selectedItem = selectedItems[0]

            if selectedItem.parent() is not None:  # Child Item selected
                menu = QMenu()

                delete = QAction(self.pushupsListWidget)
                delete.setText("Delete this pushup")
                delete.triggered.connect(self._emitDeleteSignal)
                menu.addAction(delete)
                menu.exec_(QCursor.pos())
            else:  # Top level Item selected
                menu = QMenu()

                delete = QAction(self.pushupsListWidget)
                delete.setText("Delete this day and all of its exercises")
                delete.triggered.connect(self._emitDeleteDaySignal)
                menu.addAction(delete)
                menu.exec_(QCursor.pos())
コード例 #29
0
ファイル: color_widget.py プロジェクト: d42/Fourierism
class ColorWidget(QFrame):
    color_changed = Signal(int)

    def __init__(self, parent=None):
        self.color = QColor(0, 0, 0)
        super().__init__(parent)
        self.setFrameStyle(QFrame.Panel | QFrame.Raised)

        dial = QColorDial(self)
        dial.sliderMoved.connect(self.set_color)

        action = QWidgetAction(self)
        action.setDefaultWidget(dial)
        self.menu = QMenu()
        self.menu.addAction(action)

        #self.addAction(action)
        #self.setContextMenuPolicy(Qt.ActionsContextMenu)

    def paintEvent(self, event):
        super().paintEvent(event)

        painter = QPainter(self)
        painter.fillRect(event.rect(), self.color)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.menu.exec_(self.mapToGlobal(event.pos()))

    def sizeHint(self):
        return QSize(24, 20)

    def set_color(self, color):
        self.color = QColor(color, color, color)
        self.color_changed.emit(color)
        self.update()
コード例 #30
0
ファイル: color_widget.py プロジェクト: d42/Fourierism
class ColorWidget(QFrame):
    color_changed = Signal(int)

    def __init__(self, parent=None):
        self.color = QColor(0, 0, 0)
        super().__init__(parent)
        self.setFrameStyle(QFrame.Panel|QFrame.Raised)

        dial = QColorDial(self)
        dial.sliderMoved.connect(self.set_color)

        action = QWidgetAction(self)
        action.setDefaultWidget(dial)
        self.menu = QMenu()
        self.menu.addAction(action)

        #self.addAction(action)
        #self.setContextMenuPolicy(Qt.ActionsContextMenu)

    def paintEvent(self, event):
        super().paintEvent(event)

        painter = QPainter(self)
        painter.fillRect(event.rect(), self.color)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.menu.exec_(self.mapToGlobal(event.pos()))

    def sizeHint(self):
        return QSize(24, 20)

    def set_color(self, color):
        self.color = QColor(color, color, color)
        self.color_changed.emit(color)
        self.update()
コード例 #31
0
ファイル: auto_re.py プロジェクト: gitter-badger/auto_re
    def _tree_customContextMenuRequesssted(self, pos):
        idx = self.tv.indexAt(pos)
        if not idx.isValid():
            return

        addr = idx.data(role=self.ADDR_ROLE)
        if not addr:
            return

        name_idx = idx.sibling(idx.row(), 1)
        old_name = name_idx.data()

        menu = QMenu()
        rename_action = menu.addAction('Rename `%s`...' % old_name)
        rename_action.setShortcut('n')
        action = menu.exec_(self.tv.mapToGlobal(pos))
        if action == rename_action:
            return self._rename_ea_requested(addr, name_idx)
コード例 #32
0
 def showAttributeMenu(self, attribute):
     m = QMenu()
     m.addAction('Overlay/Filter')
     c = m.addMenu('Compare to')
     for h in self.headers:
         c.addAction(h)
     m.addAction('Sort...')
     choice = m.exec_(QCursor.pos())
     
     if choice != None:
         choice = choice.text()
         if choice == 'Overlay/Filter':
             self.changeOverlay(attribute)
         elif choice == 'Sort...':
             # TODO
             pass
         else:
             self.showScatterplot(choice,attribute)
コード例 #33
0
ファイル: __init__.py プロジェクト: paulwinex/super_shader
def open_new_shader_menu():
    """
    Open menu using QMenu with all maps
    :return: 
    """
    try:
        from PySide.QtGui import QMenu, QAction, QCursor
    except:
        from PySide2.QtGui import QCursor
        from PySide2.QtWidgets import QMenu, QAction
    maps = SuperShader._get_maps()
    if not maps:
        return
    menu = QMenu(hou.ui.mainQtWindow())
    menu.setStyleSheet(hou.ui.qtStyleSheet())
    for m in maps:
        if m.get('allow_creation'):
            menu.addAction(QAction(m['name'], menu))
    act = menu.exec_(QCursor.pos())
    if not act:
        return
    new_shader_map = ([x for x in maps if x['name'] == act.text()] or [None])[0]
    return new_shader_map
コード例 #34
0
 def __menu(self, pos):
     u"""Slot d'apparition du menu contextuel"""
     menu = QMenu()
     menu.addAction("Supprimer", self, SLOT("supprimer()"), QKeySequence.Delete)
     menu.addAction("Nouveau", self, SLOT("nouveau()"), QKeySequence.New)
     menu.exec_(self._ui.tv.mapToGlobal(pos))
コード例 #35
0
ファイル: code_edit.py プロジェクト: hofoen/pcef-core
class CodeEdit(QPlainTextEdit, StyledObject):
    """
    The code editor text edit. This is a specialized QPlainTextEdit made to
    expose additional signals, styling and methods. It also provides a custom
    context menu and methods to add actions, separators and sub-menus.

    Most of the code editor functionnalities are provided by installing modes on
    the PCEF instance.

    Additional signals:
        - dirtyChanged(bool)
        - focusedIn(QFocusEvent)
        - keyPressed(QKeyEvent)
        - keyReleased(QKeyEvent)
        - mousePressed(QMouseEvent)
        - mouseReleased(QMouseEvent)
        - newTextSet()
        - prePainting(QPaintEvent)
        - postPainting(QPaintEvent)
        - visibleBlocksChanged()

    """
    QSS = """QPlainTextEdit
    {
        background-color: %(b)s;
        color: %(t)s;
        selection-background-color: %(bs)s;
        selection-color: %(ts)s;
        border: none;
        border-radius: 0px;
    }
    """

    #---------------------------------------------------------------------------
    # Signals
    #---------------------------------------------------------------------------
    #: Signal emitted when the dirty state of the document changed
    dirtyChanged = Signal(bool)
    #: Signal emitted when a key is pressed
    keyPressed = Signal(QKeyEvent)
    #: Signal emitted when a key is released
    keyReleased = Signal(QKeyEvent)
    #: Signal emitted when a mouse button is pressed
    mousePressed = Signal(QMouseEvent)
    #: Signal emitted when a mouse button is released
    mouseReleased = Signal(QMouseEvent)
    #: Signal emitted on a wheel event
    mouseWheelActivated = Signal(QWheelEvent)
    #: Signal emitted before painting the core widget
    prePainting = Signal(QPaintEvent)
    #: Signal emitted after painting the core widget
    postPainting = Signal(QPaintEvent)
    #: Signal emitted at the end of the keyPressed event
    postKeyPressed = Signal(QKeyEvent)
    #: Signal emitted when the list of visible blocks changed
    visibleBlocksChanged = Signal()
    #: Signal emitted when setPlainText is invoked
    newTextSet = Signal()
    #: Signal emitted when focusInEvent is is called
    focusedIn = Signal(QFocusEvent)
    #: Signal emitted when the text is saved with pcef.saveFileFromEditor.
    #  The signal is emitted with the complete file path
    textSaved = Signal(str)

    #---------------------------------------------------------------------------
    # Properties
    #---------------------------------------------------------------------------
    def __get_dirty(self):
        return self.__dirty

    def __set_dirty(self, dirty):
        if dirty != self.__dirty:
            self.__dirty = dirty
            self.dirtyChanged.emit(dirty)

    @property
    def contextMenu(self):
        return self.__context_menu

    #: Tells whether the editor is dirty(changes have been made to the document)
    dirty = property(__get_dirty, __set_dirty)

    #---------------------------------------------------------------------------
    # Methods
    #---------------------------------------------------------------------------
    def __init__(self, parent=None):
        """
        Creates the widget.

        :param parent: Optional parent widget
        """
        QPlainTextEdit.__init__(self, parent)
        StyledObject.__init__(self)
        #: Tag member used to remeber the filename of the edited text if any
        self.tagFilename = None
        #: Tag member used to remeber the filename of the edited text if any
        self.tagEncoding = 'utf8'
        #: Weakref to the editor
        self.editor = None

        self.__originalText = ""

        #: dirty flag
        self.__dirty = False
        #: our custom context menu
        self.__context_menu = QMenu()
        #: The list of active extra-selections (TextDecoration)
        self.__selections = []
        self.__numBlocks = -1

        self.visible_blocks = []

        #: Shortcut to the fontMetrics
        self.fm = self.fontMetrics()

        self.textChanged.connect(self.__onTextChanged)
        self.blockCountChanged.connect(self.__onBlocksChanged)
        self.verticalScrollBar().valueChanged.connect(self.__onBlocksChanged)
        self.newTextSet.connect(self.__onBlocksChanged)
        self.cursorPositionChanged.connect(self.__onBlocksChanged)
        self.setLineWrapMode(QPlainTextEdit.NoWrap)
        self.setMouseTracking(True)

        self._onStyleChanged()

    def addAction(self, action):
        """
        Adds an action to the text edit context menu

        :param action: QAction
        """
        QTextEdit.addAction(self, action)
        self.__context_menu.addAction(action)

    def addSeparator(self):
        """
        Adds a separator to the context menu
        """
        self.__context_menu.addSeparator()

    def addDecoration(self, decoration):
        """
        Add a text decoration

        :param decoration: Text decoration
        :type decoration: pcef.core.TextDecoration
        """
        self.__selections.append(decoration)
        self.__selections = sorted(self.__selections, key=lambda sel: sel.draw_order)
        self.setExtraSelections(self.__selections)

    def removeDecoration(self, decoration):
        """
        Remove text decoration.

        :param decoration: The decoration to remove
        :type decoration: pcef.core.TextDecoration
        """
        try:
            self.__selections.remove(decoration)
            self.setExtraSelections(self.__selections)
        except ValueError:
            pass

    def setShowWhitespaces(self, show):
        """
        Shows/Hides whitespaces.

        :param show: True to show whitespaces, False to hide them
        :type show: bool
        """
        doc = self.document()
        options = doc.defaultTextOption()
        if show:
            options.setFlags(options.flags() | QTextOption.ShowTabsAndSpaces)
        else:
            options.setFlags(options.flags() & ~QTextOption.ShowTabsAndSpaces)
        doc.setDefaultTextOption(options)

    def indent(self, size):
        """
        Indent current line or selection

        :param size: indent size in spaces
        :type size: int
        """
        cursor = self.textCursor()
        cursor.beginEditBlock()
        sel_start = cursor.selectionStart()
        sel_end = cursor.selectionEnd()
        has_selection = True
        if not cursor.hasSelection():
            cursor.select(QTextCursor.LineUnderCursor)
            has_selection = False
        nb_lines = len(cursor.selection().toPlainText().splitlines())
        cursor.setPosition(cursor.selectionStart())
        for i in range(nb_lines):
            cursor.movePosition(QTextCursor.StartOfLine)
            cursor.insertText(" " * size)
            cursor.movePosition(QTextCursor.EndOfLine)
            cursor.setPosition(cursor.position() + 1)
        cursor.setPosition(sel_start + size)
        if has_selection:
            cursor.setPosition(sel_end + (nb_lines * size),
                               QTextCursor.KeepAnchor)
        cursor.endEditBlock()
        self.setTextCursor(cursor)

    def unIndent(self, size):
        """
        Un-indent current line or selection by tab_size
        """
        cursor = self.textCursor()
        assert isinstance(cursor, QTextCursor)
        cursor.beginEditBlock()
        pos = cursor.position()
        sel_start = cursor.selectionStart()
        sel_end = cursor.selectionEnd()
        has_selection = True
        if not cursor.hasSelection():
            cursor.select(QTextCursor.LineUnderCursor)
            has_selection = False
        nb_lines = len(cursor.selection().toPlainText().splitlines())
        cursor.setPosition(cursor.selectionStart())
        cpt = 0
        for i in range(nb_lines):
            cursor.select(QTextCursor.LineUnderCursor)
            if cursor.selectedText().startswith(" " * size):
                cursor.movePosition(QTextCursor.StartOfLine)
                [cursor.deleteChar() for _ in range(size)]
                pos = pos - size
                cpt += 1
            else:
                cursor.clearSelection()
                # next line
            cursor.movePosition(QTextCursor.EndOfLine)
            cursor.setPosition(cursor.position() + 1)
        if cpt:
            cursor.setPosition(sel_start - size)
        else:
            cursor.setPosition(sel_start)
        if has_selection:
            cursor.setPosition(sel_end - (cpt * size),
                               QTextCursor.KeepAnchor)
        cursor.endEditBlock()
        self.setTextCursor(cursor)

    def updateOriginalText(self):
        self.__originalText = self.toPlainText()

    def _onStyleChanged(self):
        """
        Updates widget style when style changed.
        """
        self.setFont(QFont(self.currentStyle.fontName,
                           self.currentStyle.fontSize))
        self.fm = self.fontMetrics()
        qss = self.QSS % {
            'b': self.currentStyle.backgroundColor,
            't': self.currentStyle.tokenColor(Token),
            "bs": self.currentStyle.selectionBackgroundColor,
            "ts": self.currentStyle.selectionTextColor}
        self.setShowWhitespaces(self.currentStyle.showWhitespaces)
        self.setStyleSheet(qss)

    def paintEvent(self, event):
        """
        Emits prePainting and postPainting signals

        :param event: QPaintEvent
        """
        self.prePainting.emit(event)
        QPlainTextEdit.paintEvent(self, event)
        self.postPainting.emit(event)

    def keyPressEvent(self, event):
        """
        Performs indentation if tab key presed, else emits the keyPressed signal

        :param event: QKeyEvent
        """
        # assert isinstance(event, QKeyEvent)
        event.stop = False
        # replace tabs by space
        if event.key() == Qt.Key_Tab:
            cursor = self.textCursor()
            assert isinstance(cursor, QTextCursor)
            if not cursor.hasSelection():
                # insert tab at cursor pos
                cursor.insertText(" " * self.editor().TAB_SIZE)
            else:
                # indent whole selection
                self.indent(self.editor().TAB_SIZE)
            event.stop = True
        self.keyPressed.emit(event)
        if not event.stop:
            QPlainTextEdit.keyPressEvent(self, event)
        self.postKeyPressed.emit(event)

    def keyReleaseEvent(self, event):
        """
        Performs indentation if tab key pressed, else emits the keyPressed signal

        :param event: QKeyEvent
        """
        assert isinstance(event, QKeyEvent)
        event.stop = False
        self.keyReleased.emit(event)
        if not event.stop:
            QPlainTextEdit.keyReleaseEvent(self, event)

    def focusInEvent(self, event):
        """
        Emits the focusedIn signal
        :param event:
        :return:
        """
        self.focusedIn.emit(event)
        QPlainTextEdit.focusInEvent(self, event)

    def mousePressEvent(self, event):
        """
        Emits mousePressed signal

        :param event: QMouseEvent
        """
        event.stop = False
        self.mousePressed.emit(event)
        if not event.stop:
            QPlainTextEdit.mousePressEvent(self, event)

    def mouseReleaseEvent(self, event):
        """
        Emits mouseReleased signal.

        :param event: QMouseEvent
        """
        event.stop = False
        self.mouseReleased.emit(event)
        if not event.stop:
            QPlainTextEdit.mouseReleaseEvent(self, event)

    def wheelEvent(self, event):
        """
        Emits the mouseWheelActivated signal.

        :param event: QMouseEvent
        """
        event.stop = False
        self.mouseWheelActivated.emit(event)
        if not event.stop:
            QPlainTextEdit.wheelEvent(self, event)

    def mouseMoveEvent(self, event):
        assert isinstance(event, QMouseEvent)
        c = self.cursorForPosition(event.pos())
        for sel in self.__selections:
            if sel.containsCursor(c) and sel.tooltip:
                QToolTip.showText(self.mapToGlobal(event.pos()), sel.tooltip, self)
                break
        QPlainTextEdit.mouseMoveEvent(self, event)

    def contextMenuEvent(self, event):
        """ Shows our own context menu """
        self.__context_menu.exec_(event.globalPos())

    def resizeEvent(self, event):
        """ Updates visible blocks on resize """
        self.__onBlocksChanged()
        QPlainTextEdit.resizeEvent(self, event)

    def __onTextChanged(self):
        """ Sets dirty to true """
        if self.toPlainText() != self.__originalText:
            # self.__originalText = self.toPlainText()
            self.dirty = True
        else:
            self.dirty = False

    def setPlainText(self, txt):
        """ Sets the text edit content and emits newTextSet signal.
        :param txt: New text to display
        """
        self.__originalText = txt
        QPlainTextEdit.setPlainText(self, txt)
        self.newTextSet.emit()

    def __onBlocksChanged(self):
        """
        Updates the list of visible blocks and emits visibleBlocksChanged
        signal.
        """
        visible_blocks = []
        block = self.firstVisibleBlock()
        row = block.blockNumber() + 1
        width = self.width()
        w = width - 2
        h = self.fm.height()
        bbox = self.blockBoundingGeometry(block)
        top = bbox.translated(self.contentOffset()).top()
        bottom = top + bbox.height()
        zoneTop = 0  # event.rect().top()
        zoneBottom = self.height()  # event.rect().bottom()
        visible_blocks_append = visible_blocks.append
        while block.isValid() and top <= zoneBottom:
            if block.isVisible() and bottom >= zoneTop:
                visible_blocks_append(
                    VisibleBlock(row, block, (0, top, w, h))
                )
            block = block.next()
            row += 1
            top = bottom
            bottom = top + self.blockBoundingRect(block).height()
        self.visible_blocks = visible_blocks
        self.visibleBlocksChanged.emit()

    def fold(self, start, end, fold=True):
        """ Fold/Unfold a block of text delimitted by start/end line numbers
        :param start: Start folding line (this line is not fold, only the next
        ones)
        :param end: End folding line.
        :param fold: True to fold, False to unfold
        """
        doc = self.document()
        assert isinstance(doc, QTextDocument)
        for i in range(start + 1, end):
            block = self.document().findBlockByNumber(i)
            assert isinstance(block, QTextBlock)
            block.setVisible(not fold)
            doc.markContentsDirty(block.position(), block.length())
        self.update()
        self.viewport().repaint()
        self.__onBlocksChanged()
コード例 #36
0
ファイル: gui.py プロジェクト: RonnChyran/DesuraTools-py
class MainWindow(QMainWindow, Ui_MainWindow):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.current_profileid = ""
        self.setupUi(self)
        self.logger = get_logger('desuratools', 'desuratools.log')
        self.logger.info('Logger Created')
        boldfont = QApplication.font()
        boldfont.setBold(True)
        self.addToSteam_action = self.action_factory("Add to Steam", self.add_to_steam)
        self.addToSteam_action.setFont(boldfont)

        self.installGame_action = self.action_factory("Install", self.install_game)
        self.installGame_action.setFont(boldfont)

        self.desuraPage_action = self.action_factory("View Profile", self.open_desura_page)
        self.uninstallGame_action = self.action_factory("Uninstall", self.uninstall_game)
        self.verifyGame_action = self.action_factory("Verify", self.verify_game)

        self.ownedGames_menu = QMenu(self)
        self.ownedGames_menu.addActions([
            self.installGame_action,
            self.desuraPage_action
        ])

        self.installedGames_menu = QMenu(self)
        self.installedGames_menu.addActions([
            self.addToSteam_action,
            self.desuraPage_action,
            self.uninstallGame_action,
            self.verifyGame_action
        ])

        self.selectAllButton.clicked.connect(self.select_all_games)
        self.desuraAccountName_verify.clicked.connect(self.populate_owned_games)
        self.installButton.clicked.connect(self.process_install_button)
        self.generateDesuraReport_action.activated.connect(self.generate_report)
        self.tabWidget.currentChanged.connect(self.swap_tabs)
        self.ownedGames_list.itemSelectionChanged.connect(self.update_gameinfo)
        self.installedGames_list.itemSelectionChanged.connect(self.update_gameinfo)
        self.refreshButton.clicked.connect(self.refresh_list)
        self.refreshLists_action.activated.connect(self.refresh_all)

        self.installedGames_list.customContextMenuRequested.connect(self.show_game_context)
        self.installedGames_list.doubleClicked.connect(self.add_to_steam)

        self.installedGames_list.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.ownedGames_list.setSelectionMode(QAbstractItemView.ExtendedSelection)

        self.steamID_input.addItems(steamutils.get_customurls_on_machine())
        self.ownedGames_list.addItem("Verify your Desura username to see your owned games")

        QApplication.processEvents()
        self.loading_dialog = ProgressBarDialog()
        self.loading_dialog.show()
        QApplication.processEvents()
        self.populate_installed_games()
        self.load_data()
        self.loading_dialog.close()
        self.raise_()

    def verify_user(self, profileid=None):
        if profileid is None:
            profileid=self.current_profileid
        if len(profileid) == 0:
            return False

        try:
            username = gameslist.username_from_profile_id(profileid)
        except gameslist.NoSuchProfileError:
            return False

        if windows.desura_running(username):
            return True

        verify_dialog = QMessageBox()
        verify_dialog.setText("<b>Verify your identity</b><br />Sign in to Desura to continue with account <b>{0}</b> to confirm your identity".format(username))
        verify_dialog.setInformativeText("<i>Waiting for Desura sign-in...</i>")
        verify_dialog.setWindowTitle("Sign into Desura to continue")
        verify_dialog.setStandardButtons(QMessageBox.Cancel)
        verify_dialog.setIcon(QMessageBox.Information)
        verify_dialog.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint)
        desurawaiter = DesuraWaiter(username)
        desurawaiter.finished.connect(verify_dialog.close)
        desurawaiter.start()
        verify_dialog.exec_()
        if windows.desura_running(username):
            return True
        else:
            desurawaiter.terminate()
            return False

    def load_data(self):
        try:
            with open(os.path.join(windows.data_dir(), 'desuratools.json'), 'r') as savefile:
                try:
                    data = json.loads(savefile.read())
                except Exception:
                    self.desuraAccountName_input.setText("")
                    return
                self.desuraAccountName_input.setText(data['desuraname'])
                if data['desuraname'] != "":
                    self.populate_owned_games()
                steamid = self.steamID_input.findText(data['steamname'])
                self.steamID_input.setCurrentIndex(steamid)
        except IOError:
            pass

    def closeEvent(self, *args, **kwargs):
        self.logger.info("Saving to file")
        savefile = open(os.path.join(windows.data_dir(), 'desuratools.json'), 'w')
        savefile.write(
            json.dumps({
                'desuraname': self.current_profileid,
                'steamname': self.steamID_input.currentText()
            })
        )
        savefile.close()
        QApplication.quit()

    def populate_qlistwidget(self, game, qlistwidget, iconurls=False):
        if iconurls:
            itemicon = self.qpixmap_from_url(game.icon)
            QApplication.processEvents()
        else:
            itemicon = QPixmap(game.icon)
            QApplication.processEvents()
        item = QListWidgetItem(itemicon, game.name, qlistwidget)
        item.setData(Qt.UserRole, game)
        qlistwidget.addItem(item)

    def populate_owned_games(self):
        self.statusBar.showMessage("Waiting for Desura... Please Wait")
        try:
            if not self.set_current_account():
                if len(self.desuraAccountName_input.text()) > 0:
                    self.statusBar.showMessage("Invalid Desura Account")
                else:
                    self.statusBar.showMessage("")
                return
            self.ownedGames_list.clear()
            self.loading_dialog.setAccount(gameslist.username_from_profile_id(self.current_profileid))
            QApplication.processEvents()
            self.loading_dialog.setMaximum(len(gameslist.GamesList(self.current_profileid).get_games()))
            QApplication.processEvents()
            for game in gameslist.GamesList(self.current_profileid).get_games():
                self.populate_qlistwidget(game, self.ownedGames_list, True)
                QApplication.processEvents()
                self.loading_dialog.increment(1, game.name)
                QApplication.processEvents()
                self.logger.info("Added Game {0}".format(game.name))
                self.statusBar.showMessage("Added Game {0}".format(game.name))
        except gameslist.PrivateProfileError:
            self.logger.error("Failed to load games -  Private Desura Profile")
            self.statusBar.showMessage("Failed to load games - Private Desura Profiles not supported")

            error_message(
                "The Desura Profile {0} is set to Private. <br/>DesuraTools works only with public Desura Profiles."
                .format(self.current_profileid)
            ).exec_()
            return

        except gameslist.NoSuchProfileError:
            self.logger.error("Failed to load games - Desura account not found")
            self.statusBar.showMessage("Failed to load games - Desura account not found")
            return
        except gameslist.InvalidDesuraProfileError:
            self.logger.error("Failed to load games - Desura Profile ID invalid")

        self.ownedGames_list.customContextMenuRequested.connect(self.show_game_context)
        self.ownedGames_list.doubleClicked.connect(self.install_game)
        self.statusBar.showMessage("All owned Desura games loaded for account {0}".format(
            gameslist.username_from_profile_id(self.current_profileid))
        )
        self.logger.info("All owned Desura games loaded for Desura profile id {0}".format(self.current_profileid))

    def set_current_account(self, profileid=None):
        if profileid is None:
            profileid = self.desuraAccountName_input.text()
        if not self.verify_user(profileid):
            return False
        try:
            gameslist.GamesList(profileid)
        except gameslist.InvalidDesuraProfileError:
            raise
        self.current_profileid = profileid
        self.logger.info("Set current profileid to {0}".format(self.current_profileid))
        self.setWindowTitle("DesuraTools - {0}".format(gameslist.username_from_profile_id(self.current_profileid)))
        return True

    def populate_installed_games(self):
        for game in installedgames.get_games():
            self.populate_qlistwidget(game, self.installedGames_list)

    def swap_tabs(self):
        gamelist = self.get_current_list()
        if gamelist[1] == 0:
            self.installButton.setText("Add Selected to Steam")
        if gamelist[1] == 1:
            self.installButton.setText("Install Selected")
        self.gameIcon_label.clear()
        self.gameName_label.clear()
        self.gameShortName_label.clear()

    def show_game_context(self):
        gamelist = self.get_current_list()
        if gamelist[0].itemAt(gamelist[0].mapFromGlobal(QCursor.pos())) is gamelist[0].currentItem():
                if gamelist[1] == 0:
                    self.installedGames_menu.exec_(QCursor.pos())
                else:
                    self.ownedGames_menu.exec_(QCursor.pos())

    def process_install_button(self):
        gamelist = self.get_current_list()
        if gamelist[1] == 1:
            self.install_game()
        if gamelist[1] == 0:
            self.add_to_steam()
            self.get_steam_manager().save()

    def install_game(self):
        self.statusBar.showMessage("Sign into Desura to install")
        if not self.verify_user():
            self.statusBar.showMessage("Failed to verify user")
            return
        gamelist = self.get_current_list()
        if gamelist[1] == 1:
            for item in gamelist[0].selectedItems():
                game = item.data(Qt.UserRole)
                self.logger.info(' '.join(["Installing", game.name]))
                self.statusBar.showMessage(' '.join(["Installing", game.name]))
                game.install()

    def uninstall_game(self):
        self.statusBar.showMessage("Sign into Desura to uninstall")
        if not self.verify_user():
            self.statusBar.showMessage("Failed to verify user")
            return
        gamelist = self.get_current_list()
        if gamelist[1] == 0:
            if len(gamelist[0].selectedItems()) > 1:
                confirm_uninstall = user_choice(
                    "Are you sure you want to uninstall {0} games?".format(len(gamelist[0].selectedItems())),
                    "Confirm batch uninstallation",
                    QMessageBox.Information,
                    acceptbutton="Uninstall"
                )
                result = confirm_uninstall.exec_()
                if result is not QMessageBox.AcceptRole:
                    self.logger.info("Uninstall {0} games canceled".format(len(gamelist[0].selectedItems())))
                    self.statusBar.showMessage("Uninstall {0} games canceled".format(len(gamelist[0].selectedItems())))
                    return
            for item in gamelist[0].selectedItems():
                game = item.data(Qt.UserRole)
                self.logger.info(' '.join(["Uninstalling", game.name]))
                self.statusBar.showMessage(' '.join(["Uninstalling", game.name]))
                game.uninstall()

    def verify_game(self):
        self.statusBar.showMessage("Sign into Desura to verify")
        if not self.verify_user():
            self.statusBar.showMessage("Failed to verify user")
            return
        gamelist = self.get_current_list()
        if gamelist[1] == 0:
            for item in gamelist[0].selectedItems():
                game = item.data(Qt.UserRole)
                self.logger.info(' '.join(["Verifying", game.name]))
                self.statusBar.showMessage(' '.join(["Verifying", game.name]))
                game.verify()

    def add_to_steam(self):
        if not self.check_if_steam_running():
            return
        gamelist = self.get_current_list()
        if gamelist[1] == 0:
            for item in gamelist[0].selectedItems():
                game = item.data(Qt.UserRole)

                if 'ID64:' in self.steamID_input.currentText():
                    steamid = long(self.steamID_input.currentText().replace('ID64:', ''))
                else:
                    steamid = steam_user_manager.communityid64_from_name(self.steamID_input.currentText())
                QApplication.processEvents()
                if not steamutils.check_steam_version(steamid, game.name):
                    if not steamutils.shortcut_exists(self.get_steam_manager(), game.name):
                        steamutils.insert_shortcut(self.get_steam_manager(), game.name, game.exe, icons.choose_icon(game))
                        self.statusBar.showMessage("Added {0} to the Steam library".format(game.name))
                        QApplication.processEvents()
                    else:
                        self.statusBar.showMessage("{0} already exists in the Steam library".format(game.name))
                        QApplication.processEvents()
                else:
                    self.statusBar.showMessage("Steam account {0} already owns the Steam version of {1}".format(
                        self.steamID_input.currentText(), game.name)
                    )
                    QApplication.processEvents()

    def get_steam_manager(self):
        steamid = steam_user_manager.communityid32_from_name(self.steamID_input.currentText())
        vdf = steam_user_manager.shortcuts_file_for_user_id(steamid)
        return steam_shortcut_manager.SteamShortcutManager(vdf)

    def update_gameinfo(self):
        gamelist = self.get_current_list()
        if len(gamelist[0].selectedItems()) == 1:
            game = gamelist[0].currentItem().data(Qt.UserRole)
            self.gameName_label.setText(game.name)
            self.gameShortName_label.setText(game.shortname)

            if gamelist[1] == 0:
                self.gameIcon_label.setPixmap(QPixmap(game.icon))
            if gamelist[1] == 1:
                self.gameIcon_label.setPixmap(self.qpixmap_from_url(game.icon))
        else:
            self.gameName_label.setText("{0} Items Selected".format(str(len(gamelist[0].selectedItems()))))
            self.gameIcon_label.clear()
            self.gameShortName_label.clear()

    def refresh_list(self):
        gamelist = self.get_current_list()
        gamelist[0].clear()
        if gamelist[1] == 0:
            self.populate_installed_games()
        if gamelist[1] == 1:
            self.populate_owned_games()

    def refresh_all(self):
        self.installedGames_list.clear()
        self.ownedGames_list.clear()
        self.populate_installed_games()
        self.populate_owned_games()

    def select_all_games(self):
        self.get_current_list()[0].selectAll()

    def open_desura_page(self):
        gamelist = self.get_current_list()
        for item in gamelist[0].selectedItems():
            game = item.data(Qt.UserRole)
            game.storepage()

    def get_current_list(self):
        if self.tabWidget.currentIndex() == 0:
            return self.installedGames_list, 0
        if self.tabWidget.currentIndex() == 1:
            return self.ownedGames_list, 1

    def check_if_steam_running(self):
        if windows.steam_running():
            self.statusBar.showMessage("Steam is currently running")

            ask_close_steam = user_choice(
                "<b>Steam is currently running</b><br />Please close Steam before adding a game",
                "Close Steam before continuing",
                QMessageBox.Warning,
                acceptbutton="Close Steam"
                )
            result = ask_close_steam.exec_()

            if result == QMessageBox.AcceptRole:
                self.logger.info("Waiting for Steam to close")
                self.statusBar.showMessage("Waiting for Steam to close.. Please wait")
                windows.close_steam()
                return True
            else:
                self.logger.error("Could not add game to Steam - Steam still running")
                self.statusBar.showMessage("Could not add game to Steam - Steam still running")
                return False
        else:
            return True

    def generate_report(self):
        if len(self.current_profileid) == 0:
            self.statusBar.showMessage("Please enter your Desura username")
            return
        self.logger.info("Generating Report")
        self.statusBar.showMessage("Generating Report")
        webbrowser.open(str(DesuraReport(self.current_profileid)))

    def action_factory(self, text, connect):
        action = QAction(text, self)
        action.activated.connect(connect)
        return action

    @staticmethod
    def qpixmap_from_url(url):
            img_data = urllib.urlopen(url).read()
            itemicon = QPixmap()
            itemicon.loadFromData(img_data)
            return itemicon
コード例 #37
0
class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.current_profileid = ""
        self.setupUi(self)
        self.logger = get_logger('desuratools', 'desuratools.log')
        self.logger.info('Logger Created')
        boldfont = QApplication.font()
        boldfont.setBold(True)
        self.addToSteam_action = self.action_factory("Add to Steam",
                                                     self.add_to_steam)
        self.addToSteam_action.setFont(boldfont)

        self.installGame_action = self.action_factory("Install",
                                                      self.install_game)
        self.installGame_action.setFont(boldfont)

        self.desuraPage_action = self.action_factory("View Profile",
                                                     self.open_desura_page)
        self.uninstallGame_action = self.action_factory(
            "Uninstall", self.uninstall_game)
        self.verifyGame_action = self.action_factory("Verify",
                                                     self.verify_game)

        self.ownedGames_menu = QMenu(self)
        self.ownedGames_menu.addActions(
            [self.installGame_action, self.desuraPage_action])

        self.installedGames_menu = QMenu(self)
        self.installedGames_menu.addActions([
            self.addToSteam_action, self.desuraPage_action,
            self.uninstallGame_action, self.verifyGame_action
        ])

        self.selectAllButton.clicked.connect(self.select_all_games)
        self.desuraAccountName_verify.clicked.connect(
            self.populate_owned_games)
        self.installButton.clicked.connect(self.process_install_button)
        self.generateDesuraReport_action.activated.connect(
            self.generate_report)
        self.tabWidget.currentChanged.connect(self.swap_tabs)
        self.ownedGames_list.itemSelectionChanged.connect(self.update_gameinfo)
        self.installedGames_list.itemSelectionChanged.connect(
            self.update_gameinfo)
        self.refreshButton.clicked.connect(self.refresh_list)
        self.refreshLists_action.activated.connect(self.refresh_all)

        self.installedGames_list.customContextMenuRequested.connect(
            self.show_game_context)
        self.installedGames_list.doubleClicked.connect(self.add_to_steam)

        self.installedGames_list.setSelectionMode(
            QAbstractItemView.ExtendedSelection)
        self.ownedGames_list.setSelectionMode(
            QAbstractItemView.ExtendedSelection)

        self.steamID_input.addItems(steamutils.get_customurls_on_machine())
        self.ownedGames_list.addItem(
            "Verify your Desura username to see your owned games")

        QApplication.processEvents()
        self.loading_dialog = ProgressBarDialog()
        self.loading_dialog.show()
        QApplication.processEvents()
        self.populate_installed_games()
        self.load_data()
        self.loading_dialog.close()
        self.raise_()

    def verify_user(self, profileid=None):
        if profileid is None:
            profileid = self.current_profileid
        if len(profileid) == 0:
            return False

        try:
            username = gameslist.username_from_profile_id(profileid)
        except gameslist.NoSuchProfileError:
            return False

        if windows.desura_running(username):
            return True

        verify_dialog = QMessageBox()
        verify_dialog.setText(
            "<b>Verify your identity</b><br />Sign in to Desura to continue with account <b>{0}</b> to confirm your identity"
            .format(username))
        verify_dialog.setInformativeText(
            "<i>Waiting for Desura sign-in...</i>")
        verify_dialog.setWindowTitle("Sign into Desura to continue")
        verify_dialog.setStandardButtons(QMessageBox.Cancel)
        verify_dialog.setIcon(QMessageBox.Information)
        verify_dialog.setWindowFlags(Qt.CustomizeWindowHint
                                     | Qt.WindowTitleHint)
        desurawaiter = DesuraWaiter(username)
        desurawaiter.finished.connect(verify_dialog.close)
        desurawaiter.start()
        verify_dialog.exec_()
        if windows.desura_running(username):
            return True
        else:
            desurawaiter.terminate()
            return False

    def load_data(self):
        try:
            with open(os.path.join(windows.data_dir(), 'desuratools.json'),
                      'r') as savefile:
                try:
                    data = json.loads(savefile.read())
                except Exception:
                    self.desuraAccountName_input.setText("")
                    return
                self.desuraAccountName_input.setText(data['desuraname'])
                if data['desuraname'] != "":
                    self.populate_owned_games()
                steamid = self.steamID_input.findText(data['steamname'])
                self.steamID_input.setCurrentIndex(steamid)
        except IOError:
            pass

    def closeEvent(self, *args, **kwargs):
        self.logger.info("Saving to file")
        savefile = open(os.path.join(windows.data_dir(), 'desuratools.json'),
                        'w')
        savefile.write(
            json.dumps({
                'desuraname': self.current_profileid,
                'steamname': self.steamID_input.currentText()
            }))
        savefile.close()
        QApplication.quit()

    def populate_qlistwidget(self, game, qlistwidget, iconurls=False):
        if iconurls:
            itemicon = self.qpixmap_from_url(game.icon)
            QApplication.processEvents()
        else:
            itemicon = QPixmap(game.icon)
            QApplication.processEvents()
        item = QListWidgetItem(itemicon, game.name, qlistwidget)
        item.setData(Qt.UserRole, game)
        qlistwidget.addItem(item)

    def populate_owned_games(self):
        self.statusBar.showMessage("Waiting for Desura... Please Wait")
        try:
            if not self.set_current_account():
                if len(self.desuraAccountName_input.text()) > 0:
                    self.statusBar.showMessage("Invalid Desura Account")
                else:
                    self.statusBar.showMessage("")
                return
            self.ownedGames_list.clear()
            self.loading_dialog.setAccount(
                gameslist.username_from_profile_id(self.current_profileid))
            QApplication.processEvents()
            self.loading_dialog.setMaximum(
                len(gameslist.GamesList(self.current_profileid).get_games()))
            QApplication.processEvents()
            for game in gameslist.GamesList(
                    self.current_profileid).get_games():
                self.populate_qlistwidget(game, self.ownedGames_list, True)
                QApplication.processEvents()
                self.loading_dialog.increment(1, game.name)
                QApplication.processEvents()
                self.logger.info("Added Game {0}".format(game.name))
                self.statusBar.showMessage("Added Game {0}".format(game.name))
        except gameslist.PrivateProfileError:
            self.logger.error("Failed to load games -  Private Desura Profile")
            self.statusBar.showMessage(
                "Failed to load games - Private Desura Profiles not supported")

            error_message(
                "The Desura Profile {0} is set to Private. <br/>DesuraTools works only with public Desura Profiles."
                .format(self.current_profileid)).exec_()
            return

        except gameslist.NoSuchProfileError:
            self.logger.error(
                "Failed to load games - Desura account not found")
            self.statusBar.showMessage(
                "Failed to load games - Desura account not found")
            return
        except gameslist.InvalidDesuraProfileError:
            self.logger.error(
                "Failed to load games - Desura Profile ID invalid")

        self.ownedGames_list.customContextMenuRequested.connect(
            self.show_game_context)
        self.ownedGames_list.doubleClicked.connect(self.install_game)
        self.statusBar.showMessage(
            "All owned Desura games loaded for account {0}".format(
                gameslist.username_from_profile_id(self.current_profileid)))
        self.logger.info(
            "All owned Desura games loaded for Desura profile id {0}".format(
                self.current_profileid))

    def set_current_account(self, profileid=None):
        if profileid is None:
            profileid = self.desuraAccountName_input.text()
        if not self.verify_user(profileid):
            return False
        try:
            gameslist.GamesList(profileid)
        except gameslist.InvalidDesuraProfileError:
            raise
        self.current_profileid = profileid
        self.logger.info("Set current profileid to {0}".format(
            self.current_profileid))
        self.setWindowTitle("DesuraTools - {0}".format(
            gameslist.username_from_profile_id(self.current_profileid)))
        return True

    def populate_installed_games(self):
        for game in installedgames.get_games():
            self.populate_qlistwidget(game, self.installedGames_list)

    def swap_tabs(self):
        gamelist = self.get_current_list()
        if gamelist[1] == 0:
            self.installButton.setText("Add Selected to Steam")
        if gamelist[1] == 1:
            self.installButton.setText("Install Selected")
        self.gameIcon_label.clear()
        self.gameName_label.clear()
        self.gameShortName_label.clear()

    def show_game_context(self):
        gamelist = self.get_current_list()
        if gamelist[0].itemAt(gamelist[0].mapFromGlobal(
                QCursor.pos())) is gamelist[0].currentItem():
            if gamelist[1] == 0:
                self.installedGames_menu.exec_(QCursor.pos())
            else:
                self.ownedGames_menu.exec_(QCursor.pos())

    def process_install_button(self):
        gamelist = self.get_current_list()
        if gamelist[1] == 1:
            self.install_game()
        if gamelist[1] == 0:
            self.add_to_steam()
            self.get_steam_manager().save()

    def install_game(self):
        self.statusBar.showMessage("Sign into Desura to install")
        if not self.verify_user():
            self.statusBar.showMessage("Failed to verify user")
            return
        gamelist = self.get_current_list()
        if gamelist[1] == 1:
            for item in gamelist[0].selectedItems():
                game = item.data(Qt.UserRole)
                self.logger.info(' '.join(["Installing", game.name]))
                self.statusBar.showMessage(' '.join(["Installing", game.name]))
                game.install()

    def uninstall_game(self):
        self.statusBar.showMessage("Sign into Desura to uninstall")
        if not self.verify_user():
            self.statusBar.showMessage("Failed to verify user")
            return
        gamelist = self.get_current_list()
        if gamelist[1] == 0:
            if len(gamelist[0].selectedItems()) > 1:
                confirm_uninstall = user_choice(
                    "Are you sure you want to uninstall {0} games?".format(
                        len(gamelist[0].selectedItems())),
                    "Confirm batch uninstallation",
                    QMessageBox.Information,
                    acceptbutton="Uninstall")
                result = confirm_uninstall.exec_()
                if result is not QMessageBox.AcceptRole:
                    self.logger.info("Uninstall {0} games canceled".format(
                        len(gamelist[0].selectedItems())))
                    self.statusBar.showMessage(
                        "Uninstall {0} games canceled".format(
                            len(gamelist[0].selectedItems())))
                    return
            for item in gamelist[0].selectedItems():
                game = item.data(Qt.UserRole)
                self.logger.info(' '.join(["Uninstalling", game.name]))
                self.statusBar.showMessage(' '.join(
                    ["Uninstalling", game.name]))
                game.uninstall()

    def verify_game(self):
        self.statusBar.showMessage("Sign into Desura to verify")
        if not self.verify_user():
            self.statusBar.showMessage("Failed to verify user")
            return
        gamelist = self.get_current_list()
        if gamelist[1] == 0:
            for item in gamelist[0].selectedItems():
                game = item.data(Qt.UserRole)
                self.logger.info(' '.join(["Verifying", game.name]))
                self.statusBar.showMessage(' '.join(["Verifying", game.name]))
                game.verify()

    def add_to_steam(self):
        if not self.check_if_steam_running():
            return
        gamelist = self.get_current_list()
        if gamelist[1] == 0:
            for item in gamelist[0].selectedItems():
                game = item.data(Qt.UserRole)

                if 'ID64:' in self.steamID_input.currentText():
                    steamid = long(self.steamID_input.currentText().replace(
                        'ID64:', ''))
                else:
                    steamid = steam_user_manager.communityid64_from_name(
                        self.steamID_input.currentText())
                QApplication.processEvents()
                if not steamutils.check_steam_version(steamid, game.name):
                    if not steamutils.shortcut_exists(self.get_steam_manager(),
                                                      game.name):
                        steamutils.insert_shortcut(self.get_steam_manager(),
                                                   game.name, game.exe,
                                                   icons.choose_icon(game))
                        self.statusBar.showMessage(
                            "Added {0} to the Steam library".format(game.name))
                        QApplication.processEvents()
                    else:
                        self.statusBar.showMessage(
                            "{0} already exists in the Steam library".format(
                                game.name))
                        QApplication.processEvents()
                else:
                    self.statusBar.showMessage(
                        "Steam account {0} already owns the Steam version of {1}"
                        .format(self.steamID_input.currentText(), game.name))
                    QApplication.processEvents()

    def get_steam_manager(self):
        steamid = steam_user_manager.communityid32_from_name(
            self.steamID_input.currentText())
        vdf = steam_user_manager.shortcuts_file_for_user_id(steamid)
        return steam_shortcut_manager.SteamShortcutManager(vdf)

    def update_gameinfo(self):
        gamelist = self.get_current_list()
        if len(gamelist[0].selectedItems()) == 1:
            game = gamelist[0].currentItem().data(Qt.UserRole)
            self.gameName_label.setText(game.name)
            self.gameShortName_label.setText(game.shortname)

            if gamelist[1] == 0:
                self.gameIcon_label.setPixmap(QPixmap(game.icon))
            if gamelist[1] == 1:
                self.gameIcon_label.setPixmap(self.qpixmap_from_url(game.icon))
        else:
            self.gameName_label.setText("{0} Items Selected".format(
                str(len(gamelist[0].selectedItems()))))
            self.gameIcon_label.clear()
            self.gameShortName_label.clear()

    def refresh_list(self):
        gamelist = self.get_current_list()
        gamelist[0].clear()
        if gamelist[1] == 0:
            self.populate_installed_games()
        if gamelist[1] == 1:
            self.populate_owned_games()

    def refresh_all(self):
        self.installedGames_list.clear()
        self.ownedGames_list.clear()
        self.populate_installed_games()
        self.populate_owned_games()

    def select_all_games(self):
        self.get_current_list()[0].selectAll()

    def open_desura_page(self):
        gamelist = self.get_current_list()
        for item in gamelist[0].selectedItems():
            game = item.data(Qt.UserRole)
            game.storepage()

    def get_current_list(self):
        if self.tabWidget.currentIndex() == 0:
            return self.installedGames_list, 0
        if self.tabWidget.currentIndex() == 1:
            return self.ownedGames_list, 1

    def check_if_steam_running(self):
        if windows.steam_running():
            self.statusBar.showMessage("Steam is currently running")

            ask_close_steam = user_choice(
                "<b>Steam is currently running</b><br />Please close Steam before adding a game",
                "Close Steam before continuing",
                QMessageBox.Warning,
                acceptbutton="Close Steam")
            result = ask_close_steam.exec_()

            if result == QMessageBox.AcceptRole:
                self.logger.info("Waiting for Steam to close")
                self.statusBar.showMessage(
                    "Waiting for Steam to close.. Please wait")
                windows.close_steam()
                return True
            else:
                self.logger.error(
                    "Could not add game to Steam - Steam still running")
                self.statusBar.showMessage(
                    "Could not add game to Steam - Steam still running")
                return False
        else:
            return True

    def generate_report(self):
        if len(self.current_profileid) == 0:
            self.statusBar.showMessage("Please enter your Desura username")
            return
        self.logger.info("Generating Report")
        self.statusBar.showMessage("Generating Report")
        webbrowser.open(str(DesuraReport(self.current_profileid)))

    def action_factory(self, text, connect):
        action = QAction(text, self)
        action.activated.connect(connect)
        return action

    @staticmethod
    def qpixmap_from_url(url):
        img_data = urllib.urlopen(url).read()
        itemicon = QPixmap()
        itemicon.loadFromData(img_data)
        return itemicon
コード例 #38
0
 def showIndividualContextMenu(self, person):
     actionLookup = {}
     
     m = QMenu()
     actionLookup['Show Details'] = m.addAction('Show Details')
     # TODO: Add to / remove from path targets
     m.addSeparator()
     
     a = m.addMenu('Set A as')
     b = m.addMenu('Set B as')
     for label1 in AppState.ADDITION_ITERATOR_ORDER:
         a2 = a.addMenu(label1)
         b2 = b.addMenu(label1)
         for label2 in AppState.LEVEL_OPTION_ORDER:
             actionLookup[('Set A as',
                           self.additionIterators[label1],
                           AppState.LEVEL_OPTIONS[label2])] = a2.addAction(label2)
             actionLookup[('Set B as',
                           self.additionIterators[label1],
                           AppState.LEVEL_OPTIONS[label2])] = b2.addAction(label2)
     
     m.addSeparator()
     
     actionLookup['Trim Parents'] = m.addAction('Trim Parents')
     actionLookup['Trim Spouses'] = m.addAction('Trim Spouses')
     actionLookup['Trim Children'] = m.addAction('Trim Children')
     if not person in self.aSet and not person in self.bSet:
         actionLookup['Trim Parents'].setDisabled(True)
         actionLookup['Trim Spouses'].setDisabled(True)
         actionLookup['Trim Children'].setDisabled(True)
     
     m.addSeparator()
     
     for label1 in AppState.ADDITION_ITERATOR_ORDER:
         temp = m.addMenu('Expand '+label1)
         for label2 in AppState.LEVEL_OPTION_ORDER:
             actionLookup[('Expand',
                           self.additionIterators[label1],
                           AppState.LEVEL_OPTIONS[label2])] = temp.addAction(label2)
     
     choice = m.exec_(QCursor.pos())
     
     if choice != None:
         for menus,action in actionLookup.iteritems():
             if action == choice:
                 if menus == 'Show Details':
                     self.showIndividualDetails(person)
                 elif menus == 'Trim Parents':
                     self.snip(person, [self.ped.CHILD_TO_PARENT])
                 elif menus == 'Trim Spouses':
                     self.snip(person, [self.ped.HUSBAND_TO_WIFE,
                                        self.ped.WIFE_TO_HUSBAND])
                 elif menus == 'Trim Children':
                     self.snip(person, [self.ped.PARENT_TO_CHILD])
                 else:
                     assert isinstance(menus,tuple)
                     newSet = set(menus[1](person,level=menus[2]))
                     if menus[0] == 'Set A as':
                         historyID = self.addPedigree(newSet)
                         self.changePedigreeA(historyID)
                     elif menus[0] == 'Set B as':
                         historyID = self.addPedigree(newSet)
                         self.changePedigreeB(historyID)
                     elif menus[0] == 'Expand':
                         self.expand(person, newSet)
                 break
コード例 #39
0
class PresenceOverviewWidget(HorsePanel):
    @Slot(QModelIndex)
    def cell_entered(self, ndx):
        employee_id = self._employee_id_on_row(ndx)

        if not employee_id:
            self._show_totals_day_off(None)

        elif employee_id:
            chrono.chrono_start()

            employee = None
            for i in self.employees:
                if i.employee_id == employee_id:
                    employee = i
                    break

            self.detail_subframe.set_title(employee.fullname)
            self._show_totals_day_off(employee_id)

            d = date(
                self.base_date.year, self.base_date.month,
                min(
                    calendar.monthrange(self.base_date.year,
                                        self.base_date.month)[1],
                    max(1, ndx.column())))

            chrono.chrono_click("Retrieveing data")
            tars = dao.task_action_report_dao.get_reports_for_employee_id_on_date(
                employee_id, d)
            work_timetracks = dao.timetrack_dao.all_work_for_employee_date_manual(
                employee_id, d)
            presence_timetracks = dao.timetrack_dao.all_presence_for_employee_date_managed_by_code_full(
                employee_id, d)
            # employee = dao.employee_dao.find_by_id(employee_id)
            special_activities = dao.special_activity_dao.find_on_day(
                employee_id, d)

            chrono.chrono_click("Redrawing")
            self.time_report_view.redraw(datetime(d.year, d.month, d.day, 6,
                                                  0),
                                         tars,
                                         employee_id,
                                         work_timetracks,
                                         presence_timetracks,
                                         special_activities,
                                         view_title=_("Work on {}").format(
                                             date_to_dmy(d, full_month=True)))
            session().close(
            )  # FIXME Put his one line above; but that's tough ! SQLA doesn't help us much here !
            chrono.chrono_click("Session closed")

            # for event_type, duration in self.day_event_totals[employee_id].items():
            #     mainlog.debug("{}{}".format(event_type, duration))

        self._toggle_days_off_actions()

    def _employee_id_on_row(self, row_or_ndx):
        r = row_or_ndx
        if type(r) != int:
            r = row_or_ndx.row()

        return self._table_model.data(self._table_model.index(r, 0),
                                      Qt.UserRole)

    DAY_EVENT_PALETTE = {
        DayEventType.holidays: (Qt.GlobalColor.white, Qt.GlobalColor.red),
        DayEventType.day_off: (Qt.GlobalColor.white, Qt.GlobalColor.darkRed),
        DayEventType.unpaid_day_off:
        (Qt.GlobalColor.black, Qt.GlobalColor.magenta),
        DayEventType.free_day:
        (Qt.GlobalColor.white, Qt.GlobalColor.darkMagenta),
        DayEventType.overtime: (Qt.GlobalColor.black, Qt.GlobalColor.green),
        DayEventType.recuperation:
        (Qt.GlobalColor.white, Qt.GlobalColor.darkGreen),
        DayEventType.unemployment: (Qt.GlobalColor.white, Qt.GlobalColor.blue),
        DayEventType.unemployment_short:
        (Qt.GlobalColor.white, Qt.GlobalColor.darkBlue),
        DayEventType.work_accident: (Qt.GlobalColor.black,
                                     Qt.GlobalColor.yellow),
        DayEventType.sick_leave: (Qt.GlobalColor.white,
                                  Qt.GlobalColor.darkYellow)
    }

    MONTH_EVENT_COLUMN = 2
    YEAR_EVENT_COLUMN = 3

    def _make_total_days_off_panel(self):

        widget = QFrame()
        widget.setObjectName('HorseRegularFrame')

        widget.setFrameShape(QFrame.Panel)
        widget.setFrameShadow(QFrame.Sunken)
        layout = QVBoxLayout()

        #layout.addWidget(QLabel(_("Days off to date")))
        self.day_off_total_duration_labels = dict()
        self.day_off_month_duration_labels = dict()
        self.day_off_labels = dict()

        self._day_off_table_model = QStandardItemModel(10, 3)
        self._day_off_table_model.setHorizontalHeaderLabels(
            [None, None, _("This\nmonth"),
             _("Before")])
        self.day_off_table_view = QTableView(None)
        self.day_off_table_view.setModel(self._day_off_table_model)

        # self.day_off_table_view.setHorizontalHeader(self.headers_view)
        self.day_off_table_view.verticalHeader().hide()
        self.day_off_table_view.setAlternatingRowColors(True)
        self.day_off_table_view.setEditTriggers(
            QAbstractItemView.NoEditTriggers)

        self.day_off_table_view.hide()

        row = 0
        for det in DayEventType.symbols():
            ndx = self._day_off_table_model.index(row, 0)
            self._day_off_table_model.setData(ndx, det.description,
                                              Qt.DisplayRole)

            ndx = self._day_off_table_model.index(row, 1)
            fg, bg = self.DAY_EVENT_PALETTE[det]
            self._day_off_table_model.setData(ndx, QBrush(bg),
                                              Qt.BackgroundRole)
            self._day_off_table_model.setData(ndx, QBrush(fg),
                                              Qt.TextColorRole)
            self._day_off_table_model.setData(ndx,
                                              DayEventType.short_code(det),
                                              Qt.DisplayRole)

            row += 1

        layout.addWidget(self.day_off_table_view)

        grid = QGridLayout()
        self.days_off_layout = grid
        grid.setColumnStretch(3, 1)
        row = 0

        grid.addWidget(QLabel(_('Year')), row, self.YEAR_EVENT_COLUMN)
        grid.addWidget(QLabel(_('Month')), row, self.MONTH_EVENT_COLUMN)
        row += 1

        for det in DayEventType.symbols():
            self.day_off_total_duration_labels[det] = QLabel("-")
            self.day_off_month_duration_labels[det] = QLabel("-")
            self.day_off_labels[det] = QLabel(det.description)

            hlayout = QHBoxLayout()

            sl = QLabel()
            fg, bg = self.DAY_EVENT_PALETTE[det]

            def to_html_rgb(color):
                i = color.red() * 256 * 256 + color.green() * 256 + color.blue(
                )
                return "#{:06X}".format(i)

            p = QPalette()
            p.setColor(QPalette.Window, QColor(bg))
            p.setColor(QPalette.WindowText, QColor(fg))
            sl.setPalette(p)
            sl.setAlignment(Qt.AlignCenter)
            sl.setStyleSheet("border: 2px solid black; background: {}".format(
                to_html_rgb(QColor(bg))))

            t = DayEventType.short_code(det)
            mainlog.debug(t)
            sl.setAutoFillBackground(True)
            sl.setText(t)

            grid.addWidget(sl, row, 0)
            grid.addWidget(self.day_off_labels[det], row, 1)
            grid.addWidget(self.day_off_total_duration_labels[det], row,
                           self.YEAR_EVENT_COLUMN)
            grid.addWidget(self.day_off_month_duration_labels[det], row,
                           self.MONTH_EVENT_COLUMN)

            hlayout.addStretch()

            row += 1

        layout.addLayout(grid)
        layout.addStretch()

        self.day_off_table_view.resizeColumnsToContents()
        # self.day_off_table_view.setMinimumWidth( self.day_off_table_view.width())
        # self.day_off_table_view.resize( self.day_off_table_view.minimumWidth(),
        #                                 self.day_off_table_view.minimumHeight(),)

        widget.setLayout(layout)
        return widget

    def _show_totals_day_off(self, employee_id):

        mainlog.debug("_show_totals_day_off : {}".format(employee_id))

        def form_layout_row_set_visible(layout, row_ndx, is_visible):
            for i in range(layout.columnCount()):
                l = layout.itemAtPosition(row_ndx, i)
                if l and l.widget():
                    l.widget().setVisible(is_visible)

        det_to_show = dict()

        row = 0
        for det in DayEventType.symbols():

            yearly = 0
            if employee_id in self.all_events_in_year:
                if det in self.all_events_in_year[employee_id]:
                    yearly = nice_round(
                        self.all_events_in_year[employee_id][det])

            monthly = 0
            if employee_id in self.day_event_totals:
                if det in self.day_event_totals[employee_id]:
                    monthly = nice_round(
                        self.day_event_totals[employee_id][det])

                # ndx = self._day_off_table_model.index(row,self.YEAR_EVENT_COLUMN)
                # self._day_off_table_model.setData(ndx, v, Qt.DisplayRole)

            if yearly or monthly:
                det_to_show[det] = {'monthly': monthly, 'yearly': yearly}

        if det_to_show:
            # If there are some days spent on some counters, then we display
            # those counters *only*
            mainlog.debug("_show_totals_day_off : showing some events ".format(
                str(det_to_show)))
            row = 0
            for det in DayEventType.symbols():
                if det in det_to_show:
                    monthly = det_to_show[det]['monthly']
                    yearly = det_to_show[det]['yearly']
                    form_layout_row_set_visible(self.days_off_layout, row + 1,
                                                True)
                    self.day_off_total_duration_labels[det].setText(yearly
                                                                    or '-')
                    self.day_off_month_duration_labels[det].setText(monthly
                                                                    or '-')
                else:
                    form_layout_row_set_visible(self.days_off_layout, row + 1,
                                                False)
        else:
            # If there are no days spent on any counter, then we display
            # all counters at the 0 mark.
            mainlog.debug("_show_totals_day_off : showing no event")
            row = 0
            for det in DayEventType.symbols():
                form_layout_row_set_visible(self.days_off_layout, row + 1,
                                            True)
                row += 1

        # self.day_off_table_view.resizeColumnsToContents()

        self.days_off_panel.parent().update()

    @Slot()
    def refresh_action(self):
        global dao

        # mainlog.debug("refresh action started")
        self.hours_per_pers_subframe.set_title(date_to_my(
            self.base_date, True))

        chrono.chrono_start()
        all_events_in_month = people_admin_service.events_for_month(
            self.base_date)

        employee_with_events = [
            event.employee_id for event in all_events_in_month
        ]

        # mainlog.debug(all_events_in_month)

        self.all_events_in_year = people_admin_service.events_for_year(
            self.base_date.year)
        self.all_presences = all_presences = dao.employee_dao.presence_overview_for_month(
            self.base_date)

        all_correction_times = dict()
        for s in dao.month_time_synthesis_dao.load_all_synthesis(
                self.base_date.year, self.base_date.month):
            all_correction_times[s.employee_id] = s.correction_time

        special_activities = dao.special_activity_dao.find_on_month(
            self.base_date)

        employees = list(
            filter(
                lambda e: e.is_active or e.employee_id in all_presences or e.
                employee_id in all_correction_times or e.employee_id in
                special_activities or e.employee_id in employee_with_events,
                dao.employee_dao.list_overview()))
        self.employees = employees

        chrono.chrono_click()

        day_max = calendar.monthrange(self.base_date.year,
                                      self.base_date.month)[1]
        t_start = datetime(self.base_date.year, self.base_date.month, 1)
        t_end = datetime(self.base_date.year, self.base_date.month, day_max,
                         23, 59, 59, 999999)

        self._table_model.setRowCount(len(employees))
        self._table_model.setColumnCount(1 + day_max + 3)

        headers = QStandardItemModel(1, 1 + day_max + 3)

        headers.setHeaderData(0, Qt.Orientation.Horizontal, _("Employee"))
        for i in range(day_max):
            headers.setHeaderData(i + 1, Qt.Orientation.Horizontal,
                                  "{}".format(i + 1))
        headers.setHeaderData(day_max + 1, Qt.Orientation.Horizontal,
                              _("Correction"))
        headers.setHeaderData(day_max + 2, Qt.Orientation.Horizontal,
                              _("Total"))
        headers.setHeaderData(day_max + 3, Qt.Orientation.Horizontal,
                              _("Days off"))

        self.headers_view.setModel(
            headers)  # qt's doc : The view does *not* take ownership
        self.header_model = headers
        self.headers_view.setModel(
            self.header_model)  # qt's doc : The view does *not* take ownership

        # Compute all mondays indices
        monday = 0
        if t_start.weekday() > 0:
            monday = 7 - t_start.weekday()
        all_mondays = []

        while monday < day_max:
            all_mondays.append(monday)
            monday += 7

        today = date.today()

        # mainlog.debug("Running on employees")
        for row in range(self._table_model.rowCount()):

            # Clear the line
            for col in range(0, 32):
                ndx = self._table_model.index(row, col)
                self._table_model.setData(ndx, None, Qt.BackgroundRole)
                self._table_model.setData(ndx, QBrush(Qt.GlobalColor.black),
                                          Qt.TextColorRole)
                self._table_model.setData(ndx, None, Qt.DisplayRole)
                self._table_model.setData(ndx, None, Qt.UserRole)
                self._table_model.setData(ndx, None, Qt.UserRole + 1)
                #     else:
                #         self._table_model.setData(ndx,None,Qt.BackgroundRole)

                # else:
                #     self._table_model.setData(ndx,None,Qt.DisplayRole)
                #     self._table_model.setData(ndx,None,Qt.BackgroundRole)

            # Mark mondays
            for col in all_mondays:
                # col + 1 to account for the employee column
                self._table_model.setData(
                    self._table_model.index(row, col + 1),
                    QBrush(QColor(230, 230, 255)), Qt.BackgroundRole)

            # Mark today
            if today.month == self.base_date.month and today.year == self.base_date.year:
                self._table_model.setData(
                    self._table_model.index(row, today.day),
                    QBrush(QColor(255, 255, 128)), Qt.BackgroundRole)

        row = 0
        for employee in employees:  # employees are sorted

            self._table_model.setData(self._table_model.index(row, 0),
                                      employee.fullname,
                                      Qt.DisplayRole)  # FIXME Use a delegate
            self._table_model.setData(self._table_model.index(row, 0),
                                      employee.employee_id,
                                      Qt.UserRole)  # FIXME Use a delegate

            correction = 0
            if employee.employee_id in all_correction_times:
                correction = all_correction_times[employee.employee_id]
                self._table_model.setData(
                    self._table_model.index(row, day_max + 1),
                    duration_to_hm(correction, short_unit=True),
                    Qt.DisplayRole)
            else:
                self._table_model.setData(
                    self._table_model.index(row, day_max + 1), None,
                    Qt.DisplayRole)

            presence = 0
            if employee.employee_id in all_presences and len(
                    all_presences[employee.employee_id]) > 0:
                import functools
                presence = functools.reduce(
                    lambda acc, s: acc + s,
                    all_presences[employee.employee_id], 0)
            presence += correction

            if presence != 0:
                self._table_model.setData(ndx, QBrush(Qt.GlobalColor.black),
                                          Qt.TextColorRole)
                self._table_model.setData(
                    self._table_model.index(row, day_max + 2),
                    duration_to_hm(presence, short_unit=True), Qt.DisplayRole)
            else:
                self._table_model.setData(
                    self._table_model.index(row, day_max + 2), None,
                    Qt.DisplayRole)

            if employee.employee_id in all_presences and len(
                    all_presences[employee.employee_id]) > 0:
                for b in range(len(all_presences[employee.employee_id])):
                    ndx = self._table_model.index(row, b + 1)

                    p = all_presences[employee.employee_id][b]

                    if p > 0:
                        self._table_model.setData(
                            ndx, duration_to_hm(p, short_unit=True),
                            Qt.DisplayRole)
                        self._table_model.setData(ndx, p, Qt.UserRole)

                        if p >= 4 and p <= 8:
                            # Regular work load
                            self._table_model.setData(
                                ndx, QBrush(QColor(192, 255, 192)),
                                Qt.BackgroundRole)
                        elif p > 8 or (p < 4 and p > 0):
                            # Problematic work load
                            self._table_model.setData(
                                ndx, QBrush(QColor(255, 192, 192)),
                                Qt.BackgroundRole)

            if employee.employee_id in special_activities:
                sa_of_employee = special_activities[employee.employee_id]

                for sa in sa_of_employee:
                    start = max(t_start, sa.start_time)
                    end = min(t_end, sa.end_time)

                    for i in range(start.day, end.day + 1):
                        ndx = self._table_model.index(row, i)
                        self._table_model.setData(ndx,
                                                  QBrush(QColor(255, 128, 0)),
                                                  Qt.BackgroundRole)

                # self._table_model.setData(self._table_model.index(row,b+1),Qt.AlignRight | Qt.AlignVCenter,Qt.TextAlignmentRole)
            row += 1

        # Display day events

        employee_id_to_row = dict()  # little accelerator
        for row in range(len(employees)):
            employee_id_to_row[employees[row].employee_id] = row

        # Compute days off totals and show them

        self.day_event_totals = dict([(e.employee_id, dict())
                                      for e in employees])
        for day_event in all_events_in_month:
            # mainlog.debug("employee_id = {}".format(day_event.employee_id))
            # if day_event.employee_id not in self.day_event_totals:
            #    mainlog.debug(self.day_event_totals)

            t = self.day_event_totals[day_event.employee_id]
            if day_event.event_type not in t:
                t[day_event.event_type] = day_event.duration
            else:
                t[day_event.event_type] += day_event.duration

        for employee in employees:  # employees are sorted
            t = self.day_event_totals[employee.employee_id]
            mainlog.debug(t)
            total_off = sum(t.values())
            mainlog.debug(total_off)
            row = employee_id_to_row[employee.employee_id]
            mainlog.debug(row)
            if total_off:
                self._table_model.setData(
                    self._table_model.index(row, day_max + 3),
                    nice_round(total_off), Qt.DisplayRole)
            else:
                self._table_model.setData(
                    self._table_model.index(row, day_max + 3), None,
                    Qt.DisplayRole)

        # Show days off

        for day_event in all_events_in_month:
            row = employee_id_to_row[day_event.employee_id]
            col = day_event.date.day

            fg = bg = None
            if day_event.event_type in self.DAY_EVENT_PALETTE:
                fg, bg = self.DAY_EVENT_PALETTE[day_event.event_type]
            else:
                fg, bg = Qt.GlobalColor.red, Qt.GlobalColor.gray

            ndx = self._table_model.index(row, col)

            self._table_model.setData(ndx, day_event.day_event_id,
                                      Qt.UserRole + 1)

            # The problem here is to nicely blend the fact
            # that you can have a day event mixed with actual work
            # the very same day. Here's a poor man solution.

            active_time = self._table_model.data(ndx, Qt.UserRole)
            if not active_time:
                self._table_model.setData(
                    ndx, DayEventType.short_code(day_event.event_type),
                    Qt.DisplayRole)

                self._table_model.setData(ndx, QBrush(fg), Qt.TextColorRole)
                self._table_model.setData(ndx, QBrush(bg), Qt.BackgroundRole)
            else:
                self._table_model.setData(ndx, QBrush(fg), Qt.TextColorRole)
                self._table_model.setData(ndx, QBrush(bg), Qt.BackgroundRole)

                self._table_model.setData(
                    ndx,
                    duration_to_hm(active_time, short_unit=True) +
                    DayEventType.short_code(day_event.event_type),
                    Qt.DisplayRole)

        chrono.chrono_click()

        #for i in range(len(all_mondays)):
        self.table_view.resizeColumnsToContents()

        # mainlog.debug("Reset selection")
        ndx = self.table_view.currentIndex()

        self.table_view.selectionModel().clear()
        # self.table_view.selectionModel().clearSelection()
        # self.table_view.selectionModel().select( self.table_view.model().index(ndx.row(),ndx.column()), QItemSelectionModel.Select)
        # self.table_view.selectionModel().select( self.table_view.model().index(ndx.row(),ndx.column()), QItemSelectionModel.Select)
        self.table_view.selectionModel().setCurrentIndex(
            self.table_view.model().index(ndx.row(), ndx.column()),
            QItemSelectionModel.Select)

        self.cell_entered(self.table_view.currentIndex())

    @Slot()
    def edit_tars(self):

        employee_id = self._employee_id_on_row(self.table_view.currentIndex())

        d = date(
            self.base_date.year, self.base_date.month,
            min(
                calendar.monthrange(self.base_date.year,
                                    self.base_date.month)[1],
                max(1, ndx.column())))

        dialog = TimeReportingScannerDialog(self)
        dialog.set_data(datetime(d.year, d.month, d.day, 6, 0), employee_id)
        dialog.exec_()

        if dialog.result() == QDialog.Accepted:
            # pub.sendMessage('time_report.changed')
            self.timetrack_changed.emit()
            self.refresh_action()

    @Slot()
    def show_actions(self):
        button = self.action_menu.parent()
        p = button.mapToGlobal(QPoint(0, button.height()))
        self.action_menu.exec_(p)

    @Slot()
    def delete_holidays(self):
        ndx = self.table_view.currentIndex()
        employee_id = self._employee_id_on_row(ndx)
        d = date(self.base_date.year, self.base_date.month, ndx.column())

        if dao.special_activity_dao.delete_by_employee_and_date(
                employee_id, d):
            self.refresh_panel()

    @Slot()
    def create_holidays(self):
        employee_id = self._employee_id_on_row(self.table_view.currentIndex())

        left_col = 1000
        right_col = 0
        for ndx in self.table_view.selectionModel().selectedIndexes():
            c = ndx.column()
            left_col = min(c, left_col)
            right_col = max(c, right_col)

        d_start = date(
            self.base_date.year, self.base_date.month,
            min(
                calendar.monthrange(self.base_date.year,
                                    self.base_date.month)[1], max(1,
                                                                  left_col)))

        d_end = date(
            self.base_date.year, self.base_date.month,
            min(
                calendar.monthrange(self.base_date.year,
                                    self.base_date.month)[1],
                max(1, right_col)))

        dialog = HolidaysDialog(self)

        sa = SpecialActivity()
        sa.employee_id = employee_id
        sa.reporter_id = user_session.user_id
        sa.encoding_date = date.today()
        sa.start_time = datetime(d_start.year, d_start.month, d_start.day, 6,
                                 0)
        sa.end_time = datetime(d_end.year, d_end.month, d_end.day, 14, 0)

        dialog.setup(sa, dao.employee_dao.find_by_id(employee_id).fullname)

        # dialog.set_data(employee,self.base_date,c)
        dialog.exec_()
        if dialog.result() == QDialog.Accepted:
            dao.special_activity_dao.save(sa)
            self.refresh_action()

    @Slot()
    def edit_month_correction(self):
        employee_id = self._employee_id_on_row(self.table_view.currentIndex())

        if employee_id:
            employee = dao.employee_dao.find_by_id(employee_id)
            c = dao.month_time_synthesis_dao.load_correction_time(
                employee_id, self.base_date.year, self.base_date.month)

            dialog = MonthTimeCorrectionDialog(self)
            dialog.set_data(employee.fullname, self.base_date, c)
            dialog.exec_()
            if dialog.result() == QDialog.Accepted:
                c = dao.month_time_synthesis_dao.save(employee_id,
                                                      self.base_date.year,
                                                      self.base_date.month,
                                                      dialog.correction_time)
                self.refresh_action()

    @Slot()
    def month_today(self):
        self.base_date = date.today()
        self.refresh_action()

    @Slot()
    def month_before(self):
        m = self.base_date.month

        if m > 1:
            self.base_date = date(self.base_date.year, m - 1, 1)
        else:
            self.base_date = date(self.base_date.year - 1, 12, 1)
        self.refresh_action()

    @Slot()
    def month_after(self):
        m = self.base_date.month

        if self.base_date.year < date.today().year + 1 \
                or m < date.today().month:
            if m < 12:
                self.base_date = date(self.base_date.year, m + 1, 1)
            else:
                self.base_date = date(self.base_date.year + 1, 1, 1)
            self.refresh_action()

    @Slot()
    def edit_timetrack_no_ndx(self):
        ndx = self.table_view.currentIndex()
        if ndx.isValid() and ndx.column() >= 0 and ndx.row() >= 0:
            self.edit_timetrack(ndx)
        else:
            showWarningBox(_("Can't edit"),
                           _("You must first select a day/person."))

    timetrack_changed = Signal()

    @Slot(QModelIndex)
    def edit_timetrack(self, ndx):
        global dao
        global user_session

        if ndx.column() >= 1:
            edit_date = date(
                self.base_date.year, self.base_date.month,
                ndx.column())  # +1 already in because of employee's names
            employee_id = self._employee_id_on_row(ndx)

            tars = dao.task_action_report_dao.get_reports_for_employee_id_on_date(
                employee_id, edit_date)

            if len(tars) == 0:

                d = EditTimeTracksDialog(self, dao, edit_date)
                d.set_employee_and_date(employee_id, edit_date)
                d.exec_()
                if d.result() == QDialog.Accepted:
                    self.refresh_action()
                    self.timetrack_changed.emit()
                d.deleteLater()

            else:
                edit_date = datetime(self.base_date.year,
                                     self.base_date.month,
                                     ndx.column(),
                                     hour=6)
                from koi.TimeReportingScanner import TimeReportingScannerDialog
                d = TimeReportingScannerDialog(self)
                d.set_data(edit_date, employee_id)  # or 16
                d.exec_()
                if d.result() == QDialog.Accepted:
                    self.refresh_action()
                    self.timetrack_changed.emit()
                d.deleteLater()

    @Slot()
    def editTaskActionReports(self):
        if not user_session.has_any_roles(['TimeTrackModify']):
            return

        m = self.base_date.month
        ndx = self.table_view.currentIndex()

        if ndx.isValid() and ndx.column() >= 0 and ndx.row() >= 0:
            edit_date = date(
                self.base_date.year, m,
                ndx.column())  # +1 already in because of employee's names
            employee = self._table_model.data(
                self._table_model.index(ndx.row(), 0),
                Qt.UserRole)  # FIXME Use a delegate

            d = EditTaskActionReportsDialog(dao, self, edit_date)
            d.set_employee_date(employee, edit_date)
            d.exec_()
            if d.result() == QDialog.Accepted:
                self.refresh_action()
            d.deleteLater()
        else:
            showWarningBox(_("Can't edit"),
                           _("You must first select a day/person."))

    # @Slot(QModelIndex)
    # def timetrack_changed(self,ndx):

    #     selected_timetrack = self.controller.model.object_at(ndx)

    #     # Update the colors in the timetrack views
    #     # to show what action reports correspond to the
    #     # selected timetrack

    #     self.controller_actions.model.current_timetrack = selected_timetrack
    #     self.controller_actions.model.beginResetModel()
    #     self.controller_actions.model.endResetModel()

    #     # Make sure the first of the action reports is shown in the
    #     # table

    #     action_reports = self.controller_actions.model.objects
    #     for i in range(len(action_reports)-1,-1,-1):
    #         if action_reports[i] and action_reports[i].timetrack == selected_timetrack:
    #             self.controller_actions.view.scrollTo(self.controller_actions.model.index(i,0))
    #             break

    def _make_table_header(self):
        pass

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

        self.set_panel_title(_("Presence overview"))
        self.base_date = date.today()

        headers = QStandardItemModel(1, 31 + 3)
        self._table_model = QStandardItemModel(1, 31 + 3, None)

        self.headers_view = QHeaderView(Qt.Orientation.Horizontal, self)
        self.header_model = headers
        self.headers_view.setResizeMode(QHeaderView.ResizeToContents)
        self.headers_view.setModel(
            self.header_model)  # qt's doc : The view does *not* take ownership

        self.table_view = TableViewSignaledEvents(None)
        self.table_view.setModel(self._table_model)

        self.table_view.setHorizontalHeader(self.headers_view)
        self.table_view.verticalHeader().hide()
        self.table_view.setAlternatingRowColors(True)
        self.table_view.setEditTriggers(QAbstractItemView.NoEditTriggers)

        self.table_view.setContextMenuPolicy(Qt.CustomContextMenu)
        self.table_view.customContextMenuRequested.connect(
            self.popup_context_menu)

        self.copy_action = QAction(_("Copy order parts"), self.table_view)
        self.copy_action.triggered.connect(self.copy_slot)
        self.copy_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_C))
        self.copy_action.setShortcutContext(Qt.WidgetWithChildrenShortcut)
        self.table_view.addAction(self.copy_action)

        self.select_all_action = QAction(_("Select all"), self.table_view)
        self.select_all_action.triggered.connect(self.select_all_slot)
        self.select_all_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_A))
        self.select_all_action.setShortcutContext(
            Qt.WidgetWithChildrenShortcut)
        self.table_view.addAction(self.select_all_action)

        # self.table_view.setSelectionBehavior(QAbstractItemView.SelectItems)
        # self.table_view.setSelectionMode(QAbstractItemView.SingleSelection)

        navbar = NavBar(self, [(_("Month before"), self.month_before),
                               (_("Today"), self.month_today),
                               (_("Action"), self.show_actions),
                               (_("Month after"), self.month_after),
                               (_("Find"), find_order_action_slot)])

        self.action_menu = QMenu(navbar.buttons[2])
        navbar.buttons[2].setObjectName("specialMenuButton")
        navbar.buttons[4].setObjectName("specialMenuButton")

        self._make_days_off_menu_and_action_group()

        list_actions = [  # (_("Edit"),self.edit_tars, None, None),
            (_("Edit"), self.edit_timetrack_no_ndx, None, None),
            (_("Month correction"), self.edit_month_correction, None,
             [RoleType.modify_monthly_time_track_correction]),
            (self.days_off_menu, None), (self.copy_action, None),
            (self.select_all_action, None)
        ]

        # (_("Insert holidays"),self.create_holidays, None, None),
        # (_("Delete holidays"),self.delete_holidays, None, None) ]

        populate_menu(self.action_menu, self, list_actions)

        # mainlog.debug("tile widget")
        self.title_box = TitleWidget(_("Presence Overview"), self, navbar)
        self.vlayout = QVBoxLayout(self)
        self.vlayout.setObjectName("Vlayout")
        self.vlayout.addWidget(self.title_box)

        self.hours_per_pers_subframe = SubFrame(_("Overview"), self.table_view,
                                                self)
        self.vlayout.addWidget(self.hours_per_pers_subframe)

        self.time_report_view = TimeReportView(self)

        self.days_off_panel = self._make_total_days_off_panel()
        vbox = QVBoxLayout()
        vbox.addWidget(self.days_off_panel)
        vbox.addStretch()
        vbox.setStretch(0, 0)
        vbox.setStretch(1, 1)

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.time_report_view)
        hlayout.addLayout(vbox)
        hlayout.setStretch(0, 1)
        self.detail_subframe = SubFrame(_("Day"), hlayout, self)

        self.vlayout.addWidget(self.detail_subframe)

        self.setLayout(self.vlayout)

        # dbox = QVBoxLayout()
        # dbox.addWidget(QLabel("kjkljkj"))

        # self.total_active_hours = LabeledValue(_("Total activity"))
        # dbox.addWidget(self.total_active_hours)

        # hbox = QHBoxLayout()
        # hbox.addWidget(self.table_view)
        # hbox.addLayout(dbox)

        # self.selection_model = self.table_view.selectionModel()
        # mainlog.debug(m)
        #sm = QItemSelectionModel(self.table_view.model())
        #sm.setModel(self.table_view.model())
        # self.table_view.setSelectionModel(self.selection_model)

        self.table_view.selectionModel().currentChanged.connect(
            self.cell_entered)

        self.table_view.doubleClickedCell.connect(self.edit_timetrack)

    def _selection_to_period(self):
        left_col = 1000
        right_col = 0
        for ndx in self.table_view.selectionModel().selectedIndexes():
            c = ndx.column()
            left_col = min(c, left_col)
            right_col = max(c, right_col)

        d_start = date(
            self.base_date.year, self.base_date.month,
            min(
                calendar.monthrange(self.base_date.year,
                                    self.base_date.month)[1], max(1,
                                                                  left_col)))

        d_end = date(
            self.base_date.year, self.base_date.month,
            min(
                calendar.monthrange(self.base_date.year,
                                    self.base_date.month)[1],
                max(1, right_col)))

        return d_start, d_end

    def _toggle_days_off_actions(self):
        day_max = calendar.monthrange(self.base_date.year,
                                      self.base_date.month)[1]

        ndx = self.table_view.currentIndex()

        can_add = can_remove = False

        if ndx.column() >= 1 and ndx.column() <= day_max:

            day_event_id = ndx.data(Qt.UserRole + 1)

            can_add = True

            # if not day_event_id:
            #     day = ndx.column() - 1
            #
            #     employee_id = self._employee_id_on_row(ndx)
            #     if employee_id in self.all_presences:
            #         if not self.all_presences[employee_id][day]:
            #             can_add = True
            #         else:
            #             can_add = True
            #     else:
            #         can_add = True

            can_remove = day_event_id is not None

        self.days_off_add_submenu.setEnabled(can_add)
        for actions in self.days_off_action_group.actions():
            actions.setEnabled(can_add)

        self.day_off_remove_action.setEnabled(can_remove)

    def _add_day_off(self, action):

        if action.data() != 'Remove':

            day_event_type, day_event_duration = action.data()
            day_event_type = DayEventType.from_str(day_event_type)

            mainlog.debug("selected action {} {}".format(
                day_event_type, day_event_duration))

            ndx = self.table_view.currentIndex()
            day_event_id = ndx.data(Qt.UserRole + 1)

            # if day_event_id:
            #     showWarningBox(_("There's already a day off here"))
            #     return

            employee_id = self._employee_id_on_row(ndx)
            if employee_id in self.all_presences:
                day = ndx.column() - 1
                mainlog.debug("_add_day_off : employee_id={}, day={}".format(
                    employee_id, day))
                mainlog.debug(self.all_presences[employee_id])
                mainlog.debug(type(self.all_presences[employee_id]))

                # if self.all_presences[employee_id][day]:
                #     showWarningBox(_("One can't add day off where there is activity"))
                #     return
            else:
                mainlog.debug(
                    "_add_day_off : employee_id={} not yet known".format(
                        employee_id))

            day_event = DayEvent()
            day_event.employee_id = employee_id
            day_event.event_type = day_event_type

            day, last_day = self._selection_to_period()

            if day_event_duration in (0.5, 1):
                days_durations = [(day, day_event_duration)]
            else:
                days_durations = []
                day, last_day = self._selection_to_period()
                while day <= last_day:
                    days_durations.append(
                        (day, 1))  # One full work day on the day
                    day += timedelta(1)

            # mainlog.debug(days_durations)
            mainlog.debug("Creating day event of type {}".format(
                day_event.event_type))

            try:
                people_admin_service.set_event_on_days(day_event,
                                                       days_durations)
            except ServerException as ex:
                showErrorBox(ex.translated_message)

            self.refresh_action()

    def _remove_day_off(self):
        # Grab all the selected events

        event_ids = []
        for ndx in self.table_view.selectionModel().selectedIndexes():
            day_event_id = ndx.data(Qt.UserRole + 1)
            if day_event_id:
                mainlog.debug("Removing event: {}".format(day_event_id))
                event_ids.append(day_event_id)

        # Remove them

        if event_ids:
            people_admin_service.remove_events(event_ids)
            self.refresh_action()

    def _make_days_off_menu_and_action_group(self):
        # We use a action group to be able to use the data() of actions
        # when action is tigerred

        # Call this ONLY ONCE because there are signal/slot connections.

        self.days_off_menu = QMenu(_("Day off"))
        self.days_off_add_submenu = QMenu(_("Set day off"))
        self.days_off_action_group = QActionGroup(self)

        for det in DayEventType.symbols():
            a_one = QAction(_("Set one day"), self.days_off_action_group)
            a_one.setData((det.value, 1))

            a_half = QAction(_("Set half day"), self.days_off_action_group)
            a_half.setData((det.value, 0.5))

            a_period = QAction(_("Set period"), self.days_off_action_group)
            a_period.setData((det.value, 2))

            self.days_off_action_group.addAction(a_one)
            self.days_off_action_group.addAction(a_half)
            self.days_off_action_group.addAction(a_period)

            m = QMenu(_("Set time off for {}").format(det.description))
            m.addAction(a_one)
            m.addAction(a_half)
            m.addAction(a_period)
            self.days_off_add_submenu.addMenu(m)

        self.days_off_action_group.triggered.connect(self._add_day_off)

        self.day_off_remove_action = QAction(_("Remove day off"), self)
        self.day_off_remove_action.triggered.connect(self._remove_day_off)

        # Now we have the actions, we build the menu

        self.days_off_menu.addMenu(self.days_off_add_submenu)
        self.days_off_menu.addAction(self.day_off_remove_action)

    @Slot(QPoint)
    def popup_context_menu(self, position):
        self.days_off_menu.exec_(QCursor.pos())

    @Slot()
    def select_all_slot(self):
        m = self.table_view.model()
        all = QItemSelection(m.index(0, 0),
                             m.index(m.rowCount() - 1,
                                     m.columnCount() - 1))
        self.table_view.selectionModel().select(all,
                                                QItemSelectionModel.Select)

    @Slot()
    def copy_slot(self):

        # Collect the rows indices

        indices = self.table_view.selectedIndexes()

        if not indices:
            return

        min_row = max_row = indices[0].row()
        min_col = max_col = indices[0].column()

        def min_max(minimum, v, maximum):
            if v < minimum:
                return v, maximum
            elif v > maximum:
                return minimum, v
            else:
                return minimum, maximum

        for ndx in self.table_view.selectedIndexes():
            min_row, max_row = min_max(min_row, ndx.row(), max_row)
            min_col, max_col = min_max(min_col, ndx.column(), max_col)

        mainlog.debug("Copy from {},{} to {},{}".format(
            min_row, min_col, max_row, max_col))

        day_max = calendar.monthrange(self.base_date.year,
                                      self.base_date.month)[1]

        s = ""
        for r in range(min_row, max_row + 1):
            d = []
            for c in range(min_col, max_col + 1):
                ndx = self._table_model.item(r, c)

                if c == 0 or c > day_max:
                    d.append(ndx.data(Qt.DisplayRole) or "")
                else:
                    t = ndx.data(Qt.UserRole + 1)  # Day off
                    if t:
                        t = ndx.data(Qt.DisplayRole)
                    else:
                        hours = ndx.data(Qt.UserRole)  # Activity hours
                        if hours is not None:
                            t = str(hours).replace('.', ',')
                        else:
                            t = ""

                    d.append(t)

            s += "\t".join(d) + u"\n"

        QApplication.clipboard().setText(s)
コード例 #40
0
    def handleEvents(self, event, signals):
        att = self.axisOrder[self.findAxisIndex(event.x)]
        # context menu
        if event.contextRequested:
            contextMenu = QMenu(self)
            
            contextMenu.addAction(u'Select all')
            contextMenu.addAction(u'Select none')
            
            contextMenu.addSeparator()
            
            
            act = QAction(u'Hide Axis', self)
            contextMenu.addAction(act)
            if len(self.axisOrder) <= 1:
                act.setEnabled(False)
            
            axesMenu = QMenu(u'Show/Hide Axes', self)
            axesActions = QActionGroup(self)
            for a in self.axisOrder:
                act = QAction(a,self,checkable=True)
                if self.axes[a].visible:
                    act.toggle()
                if len(self.axisOrder) <= 1:
                    act.setEnabled(False)
                axesActions.addAction(act)
            for act in axesActions.actions():
                axesMenu.addAction(act)
            contextMenu.addMenu(axesMenu)
            
            contextMenu.addSeparator()
            
            contextMenu.addAction(u'Use as X axis')
            contextMenu.addAction(u'Use as Y axis')
            
            resultAction = contextMenu.exec_(QCursor.pos())
            
            if resultAction != None and resultAction != 0:
                # Select all
                if resultAction.text() == u'Select all':
                    self.app.intMan.newOperation(operation.ALL,att=att.dataAxis)
                
                # Select none
                if resultAction.text() == u'Select none':
                    self.app.intMan.newOperation(operation.NONE,att=att.dataAxis)
                
                # Hide axis
                if resultAction.text() == u'Hide Axis':
                    self.toggleVisible(att)
                
                # Toggle axis
                if resultAction.actionGroup() == axesActions:
                    self.toggleVisible(resultAction.text())

                # X axis
                if resultAction.text() == u'Use as X axis':
                    if self.app.currentYattribute != self.app.currentXattribute:
                        self.axes[self.app.currentXattribute].visAxis.handle.background.setAttribute('fill',self.normalHandleColor)
                        self.axes[self.app.currentXattribute].visAxis.handle.originalBackgroundColor = self.normalHandleColor
                    self.axes[att].visAxis.handle.background.setAttribute('fill',self.activeHandleColor)
                    self.axes[att].visAxis.handle.originalBackgroundColor = self.activeHandleColor
                    
                    self.app.notifyAxisChange(att,xAxis=True)
                
                # Y axis
                if resultAction.text() == u'Use as Y axis':
                    if self.app.currentXattribute != self.app.currentYattribute:
                        self.axes[self.app.currentYattribute].visAxis.handle.background.setAttribute('fill',self.normalHandleColor)
                        self.axes[self.app.currentYattribute].visAxis.handle.originalBackgroundColor = self.normalHandleColor
                    self.axes[att].visAxis.handle.background.setAttribute('fill',self.activeHandleColor)
                    self.axes[att].visAxis.handle.originalBackgroundColor = self.activeHandleColor
                    
                    self.app.notifyAxisChange(att,xAxis=False)
        
        #if linesMoved:
        #    self.highlightedLayer.refreshLines(self.app.highlightedRsNumbers)
        
        return signals
コード例 #41
0
ファイル: management.py プロジェクト: MikeyG/gevernote
 def layout_list_contextMenu(self, pos):
     menu = QMenu()
     default_action = menu.addAction(self.tr("Reset Layout"))
     default_action.triggered.connect(self.on_default_layout)
     menu.exec_(QCursor.pos())
コード例 #42
0
ファイル: Menu.py プロジェクト: cloudteampro/juma-editor
class MenuNode(object):
	_currentMenuContext = None

	"""docstring for MenuNode"""
	def __init__(self, option, parent, menubar = None):
		if isinstance(option ,(str,unicode)):
			blobs = option.split('|')
			_option={
				'label':blobs[0]
			}
			l = len(blobs)
			if l>1:	_option['shortcut'] = blobs[1]
			if l>2:	_option['help'] = blobs[2]
			option = _option

		self.qtmenubar = menubar
		self.qtaction  = None
		self.qtmenu    = None

		# self.qtaction = None
		self.owner  = None
		self.parent = parent

		signal = option.get( 'signal', None )
		self.setSignal(signal)

		self.mgr = parent and parent.mgr
		self.owner = parent and parent.owner
		
		self.children = []
		
		self.label = option.get('label', 'UNNAMED')
		self.name  = option.get('name',self.label.replace('&','').replace(' ','_'))
		self.name  = self.name.lower()

		self.shortcut = option.get( 'shortcut',     False )
		self.help     = option.get( 'help',         ''    )
		self.priority = option.get( 'priority',     0     )
		self.itemType = option.get( 'type',         False )
		self.onClick  = option.get( 'on_click',     None  )
		self.cmd      = option.get( 'command',      None  )
		self.cmdArgs  = option.get( 'command_args', None  )
		self.link     = None

		self.menuType = self.qtmenubar and 'menubar' or 'item'

		children = option.get( 'children', None )
		link     = option.get( 'link', None )

		if children or self.itemType == 'menu':
			if self.menuType != 'menubar':
				self.menuType = 'menu'
				self.itemType = False

		elif link:
			self.link = link
			if self.menuType != 'menubar':
				self.menuType = 'link'

		elif parent and parent.menuType == 'menubar':
			self.menuType = 'menu'

		if self.menuType == 'menu' :
			self.qtmenu = QMenu(self.label)

		if not parent or parent.menuType == 'root': return 

		parent.addChildControl(self)
		if self.itemType == 'check':
			checked = option.get('checked',False)
			self.setValue(checked or False)
		if children:
			for data in children:
				self.addChild(data)
		# self.mgr.addNodeIndex(self)

	def getFullName(self):
		if parent:
			return parent.getFullName()+'/'+self.name
		return self.name
		
	def addChild( self, option, owner = None ):
		if option=='----':
			if self.qtmenu:
				self.qtmenu.addSeparator()
		elif isinstance(option, list):
			output=[]
			for data in option:
				n = self.addChild(data)
				if n :
					output.append(n)
					if owner: n.owner = owner
			return output
		else:
			node = MenuNode(option, self)
			if owner: node.owner = owner
			self.children.append(node)
			return node

	def addChildControl(self, child):
		childType = child.menuType
		selfType  = self.menuType

		if selfType=='menu':
			if childType=='menu':
				child.qtaction = self.qtmenu.addMenu(child.qtmenu)

			elif child.link:
				qtmenu = child.link.qtmenu
				child.qtaction = self.qtmenu.addMenu(qtmenu)

			else:
				
				action = QtGui.QAction(child.label, None, 
					shortcut = child.shortcut,
					statusTip = child.help,
					checkable = child.itemType=='check',
					triggered = child.handleEvent
					)
				
				self.qtmenu.addAction(action)
				child.qtaction = action

		elif selfType=='menubar':
			if childType=='menu':
				self.qtmenubar.addMenu(child.qtmenu)
				child.qtaction = child.qtmenu.menuAction()
			else:
				logging.warning('attempt to add menuitem/link to a menubar')
				return
		else:
			logging.warning('menuitem has no child')	

	def setEnabled(self, enabled):
		#todo: set state of linked item
		selfType = self.menuType
		if selfType == 'menubar':
			self.qtmenubar.setEnable(enabled)
			return

		if self.qtmenu:
			self.qtmenu.setEnabled(enabled)
		else:
			self.qtaction.setEnabled(enabled)

	def remove(self):
		self.clear()
		self.parent.children.remove(self)
		selfType = self.menuType
		
		if not self.parent: return

		if selfType=='menubar':
			return

		parentType = self.parent.menuType

		if parentType == 'menu':
			self.parent.qtmenu.removeAction( self.qtaction )
		elif parentType == 'menubar':
			self.parent.qtmenubar.removeAction( self.qtaction )
		logging.info('remove menunode:' + self.name )

	def clear( self ):
		if self.menuType in [ 'menu', 'menubar' ]:
			for node in self.children[:]:
				node.remove()
		
	def findChild(self,name):
		name = name.lower()
		for c in self.children:
			if c.name==name: return c
		return None

	def getValue(self):
		if self.itemType in ('check','radio'):
			return self.qtaction.isChecked()
		return True

	def setValue(self, v):
		if self.itemType in ('check','radio'):
			self.qtaction.setChecked(v and True or False)
	
	def setSignal(self, signal):
		if isinstance(signal, (str, unicode)):
			signal = signals.get(signal)
		self.signal = signal

	def popUp( self, **option ):
		if self.qtmenu:
			context = option.get( 'context', None )
			MenuNode._currentMenuContext = context
			self.qtmenu.exec_(QtGui.QCursor.pos())

	def getContext( self ):
		return MenuNode._currentMenuContext
		
	def setOnClick(self, onClick):
		self.onClick = onClick

	def handleEvent(self):
		itemtype = self.itemType
		value    = self.getValue()
		logging.debug( 'menu event:' + self.name )
		if self.owner:
			if hasattr( self.owner, 'onMenu' ):
				self.owner.onMenu( self )

		if self.signal:
			self.signal(value)
		if self.onClick != None:			
			self.onClick(value)
		if self.cmd:
			args = self.cmdArgs or {}
			app.doCommand( self.cmd, **args )
		MenuNode._currentMenuContext = None
コード例 #43
0
 def handleInspectorMenu(self, pos):
     menu = QMenu()
     menu.addAction('Add')
     menu.addAction('Delete')
     menu.exec_(QCursor.pos())
コード例 #44
0
    def contextMenuEvent(self, event):
        """
        Handles the ``contextMenuEvent`` event for :class:`StatusBarButton`.

        :param `event`: a `QContextMenuEvent` event to be processed.
        """
        QApplication.setOverrideCursor(Qt.ArrowCursor)
        menu = QMenu(self)
        objName = self.objectName()
        themeDir = gIconDir + os.sep + '..' + os.sep + self.mainWin.getSettingsGeneralIconTheme() + os.sep
        s = "&Settings..."
        if objName == "StatusBarButtonSNAP":

            settingsSnapAction = QAction(QIcon(themeDir + "gridsnapsettings.png"), s, menu)
            settingsSnapAction.triggered.connect(self.settingsSnap)
            menu.addAction(settingsSnapAction)

        elif objName == "StatusBarButtonGRID":

            settingsGridAction = QAction(QIcon(themeDir + "gridsettings.png"), s, menu)
            settingsGridAction.triggered.connect(self.settingsGrid)
            menu.addAction(settingsGridAction)

        elif objName == "StatusBarButtonRULER":

            settingsRulerAction = QAction(QIcon(themeDir + "rulersettings.png"), s, menu)
            settingsRulerAction.triggered.connect(self.settingsRuler)
            menu.addAction(settingsRulerAction)

        elif objName == "StatusBarButtonORTHO":

            settingsOrthoAction = QAction(QIcon(themeDir + "orthosettings.png"), s, menu)
            settingsOrthoAction.triggered.connect(self.settingsOrtho)
            menu.addAction(settingsOrthoAction)

        elif objName == "StatusBarButtonPOLAR":

            settingsPolarAction = QAction(QIcon(themeDir + "polarsettings.png"), s, menu)
            settingsPolarAction.triggered.connect(self.settingsPolar)
            menu.addAction(settingsPolarAction)

        elif objName == "StatusBarButtonQSNAP":

            settingsQSnapAction = QAction(QIcon(themeDir + "qsnapsettings.png"), s, menu)
            settingsQSnapAction.triggered.connect(self.settingsQSnap)
            menu.addAction(settingsQSnapAction)

        elif objName == "StatusBarButtonQTRACK":

            settingsQTrackAction = QAction(QIcon(themeDir + "qtracksettings.png"), s, menu)
            settingsQTrackAction.triggered.connect(self.settingsQTrack)
            menu.addAction(settingsQTrackAction)

        elif objName == "StatusBarButtonLWT":

            gview = self.mainWin.activeView()
            if gview:

                enableRealAction = QAction(QIcon(themeDir + "realrender.png"), "&RealRender On", menu)
                enableRealAction.setEnabled(not gview.isRealEnabled())
                enableRealAction.triggered.connect(self.enableReal)
                menu.addAction(enableRealAction)

                disableRealAction = QAction(QIcon(themeDir + "realrender.png"), "&RealRender Off", menu)
                disableRealAction.setEnabled(gview.isRealEnabled())
                disableRealAction.triggered.connect(self.disableReal)
                menu.addAction(disableRealAction)

            settingsLwtAction = QAction(QIcon(themeDir + "lineweightsettings" + ".png"), s, menu)
            settingsLwtAction.triggered.connect(self.settingsLwt)
            menu.addAction(settingsLwtAction)

        menu.exec_(event.globalPos())
        QApplication.restoreOverrideCursor()
        self.statusbar.clearMessage()
コード例 #45
0
 def layout_list_contextMenu(self, pos):
     menu = QMenu()
     default_action = menu.addAction(self.tr("Reset Layout"))
     default_action.triggered.connect(self.on_default_layout)
     menu.exec_(QCursor.pos())
コード例 #46
0
ファイル: simulationgui.py プロジェクト: SoonSYJ/pymote2.0
 def handleInspectorMenu(self, pos):
     menu = QMenu()
     menu.addAction('Add')
     menu.addAction('Delete')
     menu.exec_(QCursor.pos())
コード例 #47
0
ファイル: list.py プロジェクト: berzjackson/everpad
 def note_context_menu(self, pos):
     menu = QMenu(self.ui.notesList)
     menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Edit'), self.edit_note)
     menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'), self.remove_note)
     menu.exec_(self.ui.notesList.mapToGlobal(pos))
コード例 #48
0
class ImageViewer(QWidget):
    """A custom widget to display an image in Gui."""

    # Inspired by :
    # https://doc.qt.io/qt-6/qtwidgets-widgets-imageviewer-example.html
    # https://code.qt.io/cgit/pyside/pyside-setup.git/tree/examples/widgets/imageviewer

    def __init__(self, parent=None):
        """Initialize Widget."""
        super().__init__(parent)
        self.setLayout(QVBoxLayout())

        self.imglabel = QLabel()
        self.imglabel.setBackgroundRole(QPalette.Base)
        self.imglabel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.imglabel.setScaledContents(True)  # Resize pixmap along with label
        self.imglabel.setAlignment(Qt.AlignCenter)
        self.imglabel.setText("(No image yet)")

        self.namelabel = QLabel()

        self.scrollarea = QScrollArea()
        self.scrollarea.setWidget(self.imglabel)
        self.scrollarea.setWidgetResizable(False)
        self.scrollarea.setAlignment(Qt.AlignCenter)

        self.layout().addWidget(self.scrollarea)
        self.layout().addWidget(self.namelabel)

        self.scale_factor = 1.0
        self._initial_size = QSize(0, 0)
        self._img_path = ""

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        # pylint: disable=no-member
        self.customContextMenuRequested.connect(self.show_context_menu)
        self.menu = QMenu()
        self.add_actions_to_menu(self.menu)

    def add_actions_to_menu(self, menu):
        """Add widget actions to a given menu.

        Args:
            menu -- the menu to add the actions (QMenu)
        """
        zoom_in_act = menu.addAction("Zoom In (25%)")
        zoom_in_act.triggered.connect(self.zoom_in)

        zoom_out_act = menu.addAction("Zoom Out (25%)")
        zoom_out_act.triggered.connect(self.zoom_out)

        zoom_normal_act = menu.addAction("Normal Size")
        zoom_normal_act.triggered.connect(self.normal_size)

        menu.addSeparator()

        copy_filename_act = menu.addAction("Copy Image to Clipboard")
        copy_filename_act.triggered.connect(self.copy_image)

        copy_filename_act = menu.addAction("Copy Filename to Clipboard")
        copy_filename_act.triggered.connect(self.copy_filename)

    def load_image(self, img_path):
        """Load an image in widget from a file.

        Args:
            img_path -- Path of image file to load (str)
        """
        img_path = str(img_path)
        pixmap = QPixmap(img_path)
        self.imglabel.setPixmap(pixmap)
        self.imglabel.resize(pixmap.size())
        self.namelabel.setText(f"File: {img_path}")
        self._img_path = img_path
        self._initial_size = pixmap.size()

    def resize_image(self, new_size=None):
        """Resize embedded image to target size.

        Args:
            new_size -- target size to resize image to (QSize)
        """
        if not new_size:
            new_size = self._initial_size
            self.scale_factor = 1.0
        new_size = QSize(new_size)
        self.imglabel.setMinimumSize(new_size)
        self.imglabel.setMaximumSize(new_size)

    def scale_image(self, factor):
        """Rescale embedded image applying a factor.

        Factor is applied relatively to current scale.

        Args:
            factor -- Factor to apply (float)
        """
        self.scale_factor *= float(factor)
        new_size = self.scale_factor * self._initial_size
        self.resize_image(new_size)

    @Slot()
    def zoom_in(self):
        """Zoom embedded image in (slot)."""
        self.scale_image(1.25)

    @Slot()
    def zoom_out(self):
        """Zoom embedded image out (slot)."""
        self.scale_image(0.8)

    @Slot()
    def normal_size(self):
        """Set embedded image scale to 1:1 (slot)."""
        self.resize_image()

    @Slot()
    def copy_filename(self):
        """Copy file name to clipboard (slot)."""
        QGuiApplication.clipboard().setText(self._img_path)

    @Slot()
    def copy_image(self):
        """Copy embedded image to clipboard (slot)."""
        QGuiApplication.clipboard().setImage(self.imglabel.pixmap().toImage())

    @Slot(QPoint)
    def show_context_menu(self, pos):
        """Show context menu."""
        self.menu.exec_(self.mapToGlobal(pos))
コード例 #49
0
    def contextMenuEvent(self, event):
        """
        Handles the ``contextMenuEvent`` event for :class:`StatusBarButton`.

        :param `event`: A `QContextMenuEvent`_ to be processed.
        """
        QApplication.setOverrideCursor(Qt.ArrowCursor)
        menu = QMenu(self)
        objName = self.objectName()
        themeDir = gIconDir + os.sep + '..' + os.sep + self.mainWin.getSettingsGeneralIconTheme(
        ) + os.sep
        s = "&Settings..."
        if objName == "StatusBarButtonSNAP":

            settingsSnapAction = QAction(
                QIcon(themeDir + "gridsnapsettings.png"), s, menu)
            settingsSnapAction.triggered.connect(self.settingsSnap)
            menu.addAction(settingsSnapAction)

        elif objName == "StatusBarButtonGRID":

            settingsGridAction = QAction(QIcon(themeDir + "gridsettings.png"),
                                         s, menu)
            settingsGridAction.triggered.connect(self.settingsGrid)
            menu.addAction(settingsGridAction)

        elif objName == "StatusBarButtonRULER":

            settingsRulerAction = QAction(
                QIcon(themeDir + "rulersettings.png"), s, menu)
            settingsRulerAction.triggered.connect(self.settingsRuler)
            menu.addAction(settingsRulerAction)

        elif objName == "StatusBarButtonORTHO":

            settingsOrthoAction = QAction(
                QIcon(themeDir + "orthosettings.png"), s, menu)
            settingsOrthoAction.triggered.connect(self.settingsOrtho)
            menu.addAction(settingsOrthoAction)

        elif objName == "StatusBarButtonPOLAR":

            settingsPolarAction = QAction(
                QIcon(themeDir + "polarsettings.png"), s, menu)
            settingsPolarAction.triggered.connect(self.settingsPolar)
            menu.addAction(settingsPolarAction)

        elif objName == "StatusBarButtonQSNAP":

            settingsQSnapAction = QAction(
                QIcon(themeDir + "qsnapsettings.png"), s, menu)
            settingsQSnapAction.triggered.connect(self.settingsQSnap)
            menu.addAction(settingsQSnapAction)

        elif objName == "StatusBarButtonQTRACK":

            settingsQTrackAction = QAction(
                QIcon(themeDir + "qtracksettings.png"), s, menu)
            settingsQTrackAction.triggered.connect(self.settingsQTrack)
            menu.addAction(settingsQTrackAction)

        elif objName == "StatusBarButtonLWT":

            gview = self.mainWin.activeView()
            if gview:

                enableRealAction = QAction(QIcon(themeDir + "realrender.png"),
                                           "&RealRender On", menu)
                enableRealAction.setEnabled(not gview.isRealEnabled())
                enableRealAction.triggered.connect(self.enableReal)
                menu.addAction(enableRealAction)

                disableRealAction = QAction(QIcon(themeDir + "realrender.png"),
                                            "&RealRender Off", menu)
                disableRealAction.setEnabled(gview.isRealEnabled())
                disableRealAction.triggered.connect(self.disableReal)
                menu.addAction(disableRealAction)

            settingsLwtAction = QAction(
                QIcon(themeDir + "lineweightsettings" + ".png"), s, menu)
            settingsLwtAction.triggered.connect(self.settingsLwt)
            menu.addAction(settingsLwtAction)

        menu.exec_(event.globalPos())
        QApplication.restoreOverrideCursor()
        self.statusbar.clearMessage()
コード例 #50
0
ファイル: simulationgui.py プロジェクト: darbula/pymote
 def handleInspectorMenu(self, pos):
     menu = QMenu()
     menu.addAction("Add")
     menu.addAction("Delete")
     menu.exec_(QCursor.pos())