Exemple #1
0
    def mapFromSource(self, index):
        """
        @see: L{mapFromSource<datafinder.gui.user.models.filter.BaseRepositoryFilter.mapFromSource>}
        Re-implemented to resolve name clash.
        """

        return QSortFilterProxyModel.mapFromSource(self, index)
Exemple #2
0
class SelectionSetsWidget(QFrame):
    """
    Widget for managing multiple stored item selections
    """
    selectionModified = Signal(bool)

    def __init__(self, parent):
        QFrame.__init__(self, parent)
        self.setContentsMargins(0, 0, 0, 0)
        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(1)
        self._setNameLineEdit = QLineEdit(self)
        layout.addWidget(self._setNameLineEdit)

        self._setListView = QListView(self)
        self._listModel = QStandardItemModel(self)
        self._proxyModel = QSortFilterProxyModel(self)
        self._proxyModel.setSourceModel(self._listModel)

        self._setListView.setModel(self._proxyModel)
        self._setListView.setItemDelegate(ListItemDelegate(self))

        self._setNameLineEdit.textChanged.connect(
            self._proxyModel.setFilterFixedString)

        self._completer = QCompleter(self._listModel, self)

        self._setNameLineEdit.setCompleter(self._completer)

        self._listModel.itemChanged.connect(self._onSetNameChange)
        layout.addWidget(self._setListView)
        buttonLayout = QHBoxLayout()

        self._addAction = QAction(
            "+", self, toolTip="Add a new sort key")
        self._updateAction = QAction(
            "Update", self, toolTip="Update/save current selection")
        self._removeAction = QAction(
            "\u2212", self, toolTip="Remove selected sort key.")

        self._addToolButton = QToolButton(self)
        self._updateToolButton = QToolButton(self)
        self._removeToolButton = QToolButton(self)
        self._updateToolButton.setSizePolicy(
                QSizePolicy.MinimumExpanding, QSizePolicy.Minimum)

        self._addToolButton.setDefaultAction(self._addAction)
        self._updateToolButton.setDefaultAction(self._updateAction)
        self._removeToolButton.setDefaultAction(self._removeAction)

        buttonLayout.addWidget(self._addToolButton)
        buttonLayout.addWidget(self._updateToolButton)
        buttonLayout.addWidget(self._removeToolButton)

        layout.addLayout(buttonLayout)
        self.setLayout(layout)

        self._addAction.triggered.connect(self.addCurrentSelection)
        self._updateAction.triggered.connect(self.updateSelectedSelection)
        self._removeAction.triggered.connect(self.removeSelectedSelection)

        self._setListView.selectionModel().selectionChanged.connect(
            self._onListViewSelectionChanged)
        self.selectionModel = None
        self._selections = []

    def sizeHint(self):
        size = QFrame.sizeHint(self)
        return QSize(size.width(), 200)

    def _onSelectionChanged(self, selected, deselected):
        self.setSelectionModified(True)

    def _onListViewSelectionChanged(self, selected, deselected):
        try:
            index = self._setListView.selectedIndexes()[0]
        except IndexError:
            return
        self.commitSelection(self._proxyModel.mapToSource(index).row())

    def _onSetNameChange(self, item):
        self.selections[item.row()].name = str(item.text())

    def _setButtonStates(self, val):
        self._updateToolButton.setEnabled(val)

    def setSelectionModel(self, selectionModel):
        if self.selectionModel:
            self.selectionModel.selectionChanged.disconnect(
                self._onSelectionChanged)
        self.selectionModel = selectionModel
        self.selectionModel.selectionChanged.connect(self._onSelectionChanged)

    def addCurrentSelection(self):
        item = self.addSelection(
            SelectionByKey(self.selectionModel.selection(),
                           name="New selection",
                           key=(1, 2, 3, 10)))
        index = self._proxyModel.mapFromSource(item.index())
        self._setListView.setCurrentIndex(index)
        self._setListView.edit(index)
        self.setSelectionModified(False)

    def removeSelectedSelection(self):
        i = self._proxyModel.mapToSource(self._setListView.currentIndex()).row()
        self._listModel.takeRow(i)
        del self.selections[i]

    def updateCurentSelection(self):
        i = self._proxyModel.mapToSource(self._setListView.selectedIndex()).row()
        self.selections[i].setSelection(self.selectionModel.selection())
        self.setSelectionModified(False)

    def addSelection(self, selection, name=""):
        self._selections.append(selection)
        item = QStandardItem(selection.name)
        item.setFlags(item.flags() ^ Qt.ItemIsDropEnabled)
        self._listModel.appendRow(item)
        self.setSelectionModified(False)
        return item

    def updateSelectedSelection(self):
        i = self._proxyModel.mapToSource(self._setListView.currentIndex()).row()
        self.selections[i].setSelection(self.selectionModel.selection())
        self.setSelectionModified(False)

    def setSelectionModified(self, val):
        self._selectionModified = val
        self._setButtonStates(val)
        self.selectionModified.emit(bool(val))

    def commitSelection(self, index):
        selection = self.selections[index]
        selection.select(self.selectionModel)

    def setSelections(self, selections):
        self._listModel.clear()
        for selection in selections:
            self.addSelection(selection)

    def selections(self):
        return self._selections

    selections = property(selections, setSelections)
Exemple #3
0
class WatchPointView(QTreeView):
    " Watch expression viewer widget "

    def __init__(self, parent, wpointsModel):
        QTreeView.__init__(self, parent)

        self.__model = None
        self.setModel(wpointsModel)

        self.setItemsExpandable(False)
        self.setRootIsDecorated(False)
        self.setAlternatingRowColors(True)
        self.setUniformRowHeights(True)
        self.setSelectionMode(QAbstractItemView.SingleSelection)
        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.setItemDelegate(NoOutlineHeightDelegate(4))

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.__showContextMenu)
        self.doubleClicked.connect(self.__doubleClicked)

        self.__createPopupMenus()
        return

    def setModel(self, model):
        " Sets the watch expression model "
        self.__model = model

        self.sortingModel = QSortFilterProxyModel()
        self.sortingModel.setSourceModel(self.__model)
        QTreeView.setModel(self, self.sortingModel)

        header = self.header()
        header.setSortIndicator(0, Qt.AscendingOrder)
        header.setSortIndicatorShown(True)
        header.setClickable(True)

        self.setSortingEnabled(True)
        self.__layoutDisplay()
        return

    def __layoutDisplay(self):
        " Performs the layout operation "
        self.__resizeColumns()
        self.__resort()
        return

    def __resizeColumns(self):
        " Resizes the view when items get added, edited or deleted "
        self.header().resizeSections(QHeaderView.ResizeToContents)
        self.header().setStretchLastSection(True)
        return

    def __resort(self):
        " Resorts the tree "
        self.model().sort(self.header().sortIndicatorSection(),
                          self.header().sortIndicatorOrder())
        return

    def __toSourceIndex(self, index):
        " Converts an index to a source index "
        return self.sortingModel.mapToSource(index)

    def __fromSourceIndex(self, sindex):
        " Converts a source index to an index "
        return self.sortingModel.mapFromSource(sindex)

    def __setRowSelected(self, index, selected=True):
        " Selects a row "
        if not index.isValid():
            return

        if selected:
            flags = QItemSelectionModel.SelectionFlags(
                QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows)
        else:
            flags = QItemSelectionModel.SelectionFlags(
                QItemSelectionModel.Deselect | QItemSelectionModel.Rows)
        self.selectionModel().select(index, flags)
        return

    def __createPopupMenus(self):
        """
        Private method to generate the popup menus.
        """
        self.menu = QMenu()
        self.menu.addAction(self.trUtf8("Add"), self.__addWatchPoint)
        self.menu.addAction(self.trUtf8("Edit..."), self.__editWatchPoint)
        self.menu.addSeparator()
        self.menu.addAction(self.trUtf8("Enable"), self.__enableWatchPoint)
        self.menu.addAction(self.trUtf8("Enable all"),
                            self.__enableAllWatchPoints)
        self.menu.addSeparator()
        self.menu.addAction(self.trUtf8("Disable"), self.__disableWatchPoint)
        self.menu.addAction(self.trUtf8("Disable all"),
                            self.__disableAllWatchPoints)
        self.menu.addSeparator()
        self.menu.addAction(self.trUtf8("Delete"), self.__deleteWatchPoint)
        self.menu.addAction(self.trUtf8("Delete all"),
                            self.__deleteAllWatchPoints)

        self.backMenuActions = {}
        self.backMenu = QMenu()
        self.backMenu.addAction(self.trUtf8("Add"), self.__addWatchPoint)
        self.backMenuActions["EnableAll"] = \
            self.backMenu.addAction(self.trUtf8("Enable all"),
                self.__enableAllWatchPoints)
        self.backMenuActions["DisableAll"] = \
            self.backMenu.addAction(self.trUtf8("Disable all"),
                self.__disableAllWatchPoints)
        self.backMenuActions["DeleteAll"] = \
            self.backMenu.addAction(self.trUtf8("Delete all"),
                self.__deleteAllWatchPoints)
        self.backMenu.aboutToShow.connect(self.__showBackMenu)

        self.multiMenu = QMenu()
        self.multiMenu.addAction(self.trUtf8("Add"), self.__addWatchPoint)
        self.multiMenu.addSeparator()
        self.multiMenu.addAction(self.trUtf8("Enable selected"),
                                 self.__enableSelectedWatchPoints)
        self.multiMenu.addAction(self.trUtf8("Enable all"),
                                 self.__enableAllWatchPoints)
        self.multiMenu.addSeparator()
        self.multiMenu.addAction(self.trUtf8("Disable selected"),
                                 self.__disableSelectedWatchPoints)
        self.multiMenu.addAction(self.trUtf8("Disable all"),
                                 self.__disableAllWatchPoints)
        self.multiMenu.addSeparator()
        self.multiMenu.addAction(self.trUtf8("Delete selected"),
                                 self.__deleteSelectedWatchPoints)
        self.multiMenu.addAction(self.trUtf8("Delete all"),
                                 self.__deleteAllWatchPoints)
        return

    def __showContextMenu(self, coord):
        """
        Private slot to show the context menu.

        @param coord the position of the mouse pointer (QPoint)
        """
        cnt = self.__getSelectedItemsCount()
        if cnt <= 1:
            index = self.indexAt(coord)
            if index.isValid():
                cnt = 1
                self.__setRowSelected(index)
        coord = self.mapToGlobal(coord)
        if cnt > 1:
            self.multiMenu.popup(coord)
        elif cnt == 1:
            self.menu.popup(coord)
        else:
            self.backMenu.popup(coord)

    def __findDuplicates(self,
                         cond,
                         special,
                         showMessage=False,
                         index=QModelIndex()):
        " Checks if an entry already exists "
        cond = unicode(cond)
        special = unicode(special)
        idx = self.__model.getWatchPointIndex(cond, special)
        duplicate = idx.isValid(
        ) and idx.internalPointer() != index.internalPointer()
        #        if showMessage and duplicate:
        #            if not special:
        #                msg = """<p>A watch expression '<b>%1</b>'"""
        #                                  """ already exists.</p>""".arg(Utilities.html_encode(unicode(cond)))
        #            else:
        #                msg = self.trUtf8("""<p>A watch expression '<b>%1</b>'"""
        #                                  """ for the variable <b>%2</b> already exists.</p>""")\
        #                        .arg(special)\
        #                        .arg(Utilities.html_encode(unicode(cond)))
        #            KQMessageBox.warning(None,
        #                self.trUtf8("Watch expression already exists"),
        #                msg)

        return duplicate

    def __clearSelection(self):
        " Clears the selection "
        for index in self.selectedIndexes():
            self.__setRowSelected(index, False)
        return

    def __addWatchPoint(self):
        " Adds watch expression via a context menu entry "
        #        dlg = EditWatchpointDialog( ( "", False, True, 0, "" ), self )
        #        if dlg.exec_() == QDialog.Accepted:
        #            cond, temp, enabled, ignorecount, special = dlg.getData()
        #            if not self.__findDuplicates(cond, special, True):
        #                self.__model.addWatchPoint(cond, special, (temp, enabled, ignorecount))
        #                self.__resizeColumns()
        #                self.__resort()
        return

    def __doubleClicked(self, index):
        " Handles the double clicked signal "
        if index.isValid():
            self.__doEditWatchPoint(index)
        return

    def __editWatchPoint(self):
        " Handles the edit watch expression context menu entry "
        index = self.currentIndex()
        if index.isValid():
            self.__doEditWatchPoint(index)
        return

    def __doEditWatchPoint(self, index):
        " Edits a watch expression "
        sindex = self.__toSourceIndex(index)
        if sindex.isValid():
            wp = self.__model.getWatchPointByIndex(sindex)
            if not wp:
                return

            cond, special, temp, enabled, count = wp[:5]


#            dlg = EditWatchpointDialog(
#                (cond, temp, enabled, count, special), self)
#            if dlg.exec_() == QDialog.Accepted:
#                cond, temp, enabled, count, special = dlg.getData()
#                if not self.__findDuplicates(cond, special, True, sindex):
#                    self.__model.setWatchPointByIndex(sindex,
#                        unicode(cond), unicode(special), (temp, enabled, count))
#                    self.__resizeColumns()
#                    self.__resort()
        return

    def __setWpEnabled(self, index, enabled):
        " Sets the enabled status of a watch expression "
        sindex = self.__toSourceIndex(index)
        if sindex.isValid():
            self.__model.setWatchPointEnabledByIndex(sindex, enabled)
        return

    def __enableWatchPoint(self):
        " Handles the enable watch expression context menu entry "
        index = self.currentIndex()
        self.__setWpEnabled(index, True)
        self.__resizeColumns()
        self.__resort()
        return

    def __enableAllWatchPoints(self):
        " Handles the enable all watch expressions context menu entry "
        index = self.model().index(0, 0)
        while index.isValid():
            self.__setWpEnabled(index, True)
            index = self.indexBelow(index)
        self.__resizeColumns()
        self.__resort()
        return

    def __enableSelectedWatchPoints(self):
        " Handles the enable selected watch expressions context menu entry "
        for index in self.selectedIndexes():
            if index.column() == 0:
                self.__setWpEnabled(index, True)
        self.__resizeColumns()
        self.__resort()
        return

    def __disableWatchPoint(self):
        " Handles the disable watch expression context menu entry "
        index = self.currentIndex()
        self.__setWpEnabled(index, False)
        self.__resizeColumns()
        self.__resort()
        return

    def __disableAllWatchPoints(self):
        " Handles the disable all watch expressions context menu entry "
        index = self.model().index(0, 0)
        while index.isValid():
            self.__setWpEnabled(index, False)
            index = self.indexBelow(index)
        self.__resizeColumns()
        self.__resort()
        return

    def __disableSelectedWatchPoints(self):
        " Handles the disable selected watch expressions context menu entry "
        for index in self.selectedIndexes():
            if index.column() == 0:
                self.__setWpEnabled(index, False)
        self.__resizeColumns()
        self.__resort()
        return

    def __deleteWatchPoint(self):
        " Handles the delete watch expression context menu entry "
        index = self.currentIndex()
        sindex = self.__toSourceIndex(index)
        if sindex.isValid():
            self.__model.deleteWatchPointByIndex(sindex)
        return

    def __deleteAllWatchPoints(self):
        " Handles the delete all watch expressions context menu entry "
        self.__model.deleteAll()
        return

    def __deleteSelectedWatchPoints(self):
        " Handles the delete selected watch expressions context menu entry "
        idxList = []
        for index in self.selectedIndexes():
            sindex = self.__toSourceIndex(index)
            if sindex.isValid() and index.column() == 0:
                lastrow = index.row()
                idxList.append(sindex)
        self.__model.deleteWatchPoints(idxList)
        return

    def __showBackMenu(self):
        " Handles the aboutToShow signal of the background menu "
        if self.model().rowCount() == 0:
            self.backMenuActions["EnableAll"].setEnabled(False)
            self.backMenuActions["DisableAll"].setEnabled(False)
            self.backMenuActions["DeleteAll"].setEnabled(False)
        else:
            self.backMenuActions["EnableAll"].setEnabled(True)
            self.backMenuActions["DisableAll"].setEnabled(True)
            self.backMenuActions["DeleteAll"].setEnabled(True)
        return

    def __getSelectedItemsCount(self):
        " Provides the count of items selected "
        count = len(self.selectedIndexes()) / (self.__model.columnCount() - 1)
        # column count is 1 greater than selectable
        return count
Exemple #4
0
class SelectionSetsWidget(QFrame):
    """
    Widget for managing multiple stored item selections
    """
    selectionModified = Signal(bool)

    def __init__(self, parent):
        QFrame.__init__(self, parent)
        self.setContentsMargins(0, 0, 0, 0)
        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(1)
        self._setNameLineEdit = QLineEdit(self)
        layout.addWidget(self._setNameLineEdit)

        self._setListView = QListView(self)
        self._listModel = QStandardItemModel(self)
        self._proxyModel = QSortFilterProxyModel(self)
        self._proxyModel.setSourceModel(self._listModel)

        self._setListView.setModel(self._proxyModel)
        self._setListView.setItemDelegate(ListItemDelegate(self))

        self._setNameLineEdit.textChanged.connect(
            self._proxyModel.setFilterFixedString)

        self._completer = QCompleter(self._listModel, self)

        self._setNameLineEdit.setCompleter(self._completer)

        self._listModel.itemChanged.connect(self._onSetNameChange)
        layout.addWidget(self._setListView)
        buttonLayout = QHBoxLayout()

        self._addAction = QAction("+", self, toolTip="Add a new sort key")
        self._updateAction = QAction("Update",
                                     self,
                                     toolTip="Update/save current selection")
        self._removeAction = QAction("\u2212",
                                     self,
                                     toolTip="Remove selected sort key.")

        self._addToolButton = QToolButton(self)
        self._updateToolButton = QToolButton(self)
        self._removeToolButton = QToolButton(self)
        self._updateToolButton.setSizePolicy(QSizePolicy.MinimumExpanding,
                                             QSizePolicy.Minimum)

        self._addToolButton.setDefaultAction(self._addAction)
        self._updateToolButton.setDefaultAction(self._updateAction)
        self._removeToolButton.setDefaultAction(self._removeAction)

        buttonLayout.addWidget(self._addToolButton)
        buttonLayout.addWidget(self._updateToolButton)
        buttonLayout.addWidget(self._removeToolButton)

        layout.addLayout(buttonLayout)
        self.setLayout(layout)

        self._addAction.triggered.connect(self.addCurrentSelection)
        self._updateAction.triggered.connect(self.updateSelectedSelection)
        self._removeAction.triggered.connect(self.removeSelectedSelection)

        self._setListView.selectionModel().selectionChanged.connect(
            self._onListViewSelectionChanged)
        self.selectionModel = None
        self._selections = []

    def sizeHint(self):
        size = QFrame.sizeHint(self)
        return QSize(size.width(), 150)

    def _onSelectionChanged(self, selected, deselected):
        self.setSelectionModified(True)

    def _onListViewSelectionChanged(self, selected, deselected):
        try:
            index = self._setListView.selectedIndexes()[0]
        except IndexError:
            return
        self.commitSelection(self._proxyModel.mapToSource(index).row())

    def _onSetNameChange(self, item):
        self.selections[item.row()].name = str(item.text())

    def _setButtonStates(self, val):
        self._updateToolButton.setEnabled(val)

    def setSelectionModel(self, selectionModel):
        if self.selectionModel:
            self.selectionModel.selectionChanged.disconnect(
                self._onSelectionChanged)
        self.selectionModel = selectionModel
        self.selectionModel.selectionChanged.connect(self._onSelectionChanged)

    def addCurrentSelection(self):
        item = self.addSelection(
            SelectionByKey(self.selectionModel.selection(),
                           name="New selection",
                           key=(1, 2, 3, 10)))
        index = self._proxyModel.mapFromSource(item.index())
        self._setListView.setCurrentIndex(index)
        self._setListView.edit(index)
        self.setSelectionModified(False)

    def removeSelectedSelection(self):
        i = self._proxyModel.mapToSource(
            self._setListView.currentIndex()).row()
        self._listModel.takeRow(i)
        del self.selections[i]

    def updateCurentSelection(self):
        i = self._proxyModel.mapToSource(
            self._setListView.selectedIndex()).row()
        self.selections[i].setSelection(self.selectionModel.selection())
        self.setSelectionModified(False)

    def addSelection(self, selection, name=""):
        self._selections.append(selection)
        item = QStandardItem(selection.name)
        item.setFlags(item.flags() ^ Qt.ItemIsDropEnabled)
        self._listModel.appendRow(item)
        self.setSelectionModified(False)
        return item

    def updateSelectedSelection(self):
        i = self._proxyModel.mapToSource(
            self._setListView.currentIndex()).row()
        self.selections[i].setSelection(self.selectionModel.selection())
        self.setSelectionModified(False)

    def setSelectionModified(self, val):
        self._selectionModified = val
        self._setButtonStates(val)
        self.selectionModified.emit(bool(val))

    def commitSelection(self, index):
        selection = self.selections[index]
        selection.select(self.selectionModel)

    def setSelections(self, selections):
        self._listModel.clear()
        for selection in selections:
            self.addSelection(selection)

    def selections(self):
        return self._selections

    selections = property(selections, setSelections)
class CurrentPlaylistForm(QWidget, auxilia.Actions, CurrentListForm):
    '''List and controls for the currently loaded playlist'''
    editing = 0
    def __init__(self, modelManager, view, app, config):
        QWidget.__init__(self)
        self.app = app
        self.view = view
        self.config = config
        self._temp = {}
        self.playQueue = modelManager.playQueue
        self.playerState = modelManager.playerState
        self.modelManager = modelManager
        self.playQueueDelegate = PlayQueueDelegate(self.config)
        self.setupUi(self)

        self.connect(self.playerState, SIGNAL('repeatChanged'), self.repeatButton.setChecked)
        self.connect(self.playerState, SIGNAL('randomChanged'), self.randomButton.setChecked)
        self.connect(self.playerState, SIGNAL('xFadeChanged'), self.crossFade.setValue)
        self.connect(self.crossFade, SIGNAL('valueChanged(int)'), self.playerState.setXFade)
        self.connect(self.repeatButton, SIGNAL('toggled(bool)'), self.playerState.setRepeat)
        self.connect(self.randomButton, SIGNAL('toggled(bool)'), self.playerState.setRandom)

        self.playQueueProxy = QSortFilterProxyModel()
        self.playQueueProxy.setSourceModel(self.playQueue)
        self.playQueueProxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.playQueueProxy.setDynamicSortFilter(True)
        self.playQueueProxy.setFilterRole(Qt.AccessibleTextRole)
        self.currentList.setModel(self.playQueueProxy)
        self.currentList.setItemDelegateForColumn(0, self.playQueueDelegate)
        self.currentList.horizontalHeader().setResizeMode(1)

        if config.oneLinePlaylist:
            self.oneLinePlaylist.setChecked(True)
        self.keepPlayingVisible.setChecked(self.config.keepPlayingVisible)
        self._togglePlaylistTools(self.config.playlistControls)
        self.connect(self.playQueue, SIGNAL('aboutToUpdate'), self.prepareForUpdate)
        self.connect(self.playQueue, SIGNAL('updated'), self.updated)
        self.connect(self.playQueue, SIGNAL('currentSongChanged'), self._ensurePlayingVisable)


        # Connect to the view for double click action.
        self.connect(self.currentList, SIGNAL('doubleClicked(const QModelIndex &)'), self._playSong)

        self.connect(self.currentFilter,SIGNAL('textEdited(QString)'),self.playQueueProxy.setFilterFixedString)

        self.connect(self.currentRemove,SIGNAL('clicked()'),self._removeSelected)
        self.connect(self.currentClear,SIGNAL('clicked()'),self.playQueue.clear)
        self.connect(self.currentSave,SIGNAL('clicked()'),self._saveCurrent)
        self.connect(self.addStream,SIGNAL('clicked()'),self._addStream)

        self.connect(self.currentBottom, SIGNAL('clicked()'), self._togglePlaylistTools)
        self.connect(self.currentList,SIGNAL('selectionChanged()'),self._setEditing)
        self.connect(self.currentList.verticalScrollBar(), SIGNAL('valueChanged(int)'), self._setEditing)
        self.connect(self.keepPlayingVisible,SIGNAL('toggled(bool)'),self._toggleKeepPlayingVisible)
        self.connect(self.oneLinePlaylist,SIGNAL('toggled(bool)'),self._setOneLinePlaylist)
        self.connect(self.showNumbers,SIGNAL('toggled(bool)'),self._setNumbers)
        self.showNumbers.setChecked(self.config.showNumbers)

        # Menu for current playlist.
        # Create actions.
        self.currentMenuPlay = self.action(self.currentList, self._playSong,
                icon="media-playback-start", text='play', tooltip='Start playing the selected song.')
        self.currentMenuRemove = self.action(self.currentList, self._removeSelected,
                icon="list-remove", text='Remove', tooltip="Remove the selected songs from the playlist.")
        self.currentMenuClear = self.action(self.currentList, self.playQueue.clear,
                icon="document-new", text='Clear', tooltip="Remove all songs from the playlist.")
        self.currentMenuSave = self.action(self.currentList, self._saveCurrent,
                icon="document-save-as", text='Save', tooltip="Save the current playlist.")
        self.currentMenuCrop = self.action(self.currentList, self._cropCurrent,
                icon="project-development-close", text='Crop', tooltip="Remove all but the selected songs.")
        self.currentMenuShuffle = self.action(self.currentList, self.playQueue.shuffle,
                icon="media-playlist-shuffle", text='Shuffle', tooltip="Shuffle the songs in the playlist.")

        # Set the Off icon for the repeat and random buttons.
        icon = self.randomButton.icon()
        icon.addPixmap(
                icon.pixmap(32,32,QIcon.Normal),
                QIcon.Normal,
                QIcon.On)
        icon.addPixmap(
                icon.pixmap(32,32,QIcon.Disabled),
                QIcon.Normal,
                QIcon.Off)
        self.randomButton.setIcon(icon)
        icon = self.repeatButton.icon()
        icon.addPixmap(
                icon.pixmap(32,32,QIcon.Normal),
                QIcon.Normal,
                QIcon.On)
        icon.addPixmap(
                icon.pixmap(32,32,QIcon.Disabled),
                QIcon.Normal,
                QIcon.Off)
        self.repeatButton.setIcon(icon)

    def prepareForUpdate(self):
        '''Save some state prior to applying changes to the play queue.'''
        self._temp['oldLength'] = len(self.playQueue)
        scrollBar = self.currentList.verticalScrollBar()
        oldScroll = scrollBar.value()
        self._temp['setBottom'] = oldScroll == scrollBar.maximum()
        self._temp['oldScroll'] = oldScroll

    def updated(self):
        self._setEditing()
        self.view.numSongsLabel.setText(str(len(self.playQueue))+' Songs')
        self._setPlayTime(self.playQueue.totalTime())
        self._resize()
        self.app.processEvents()
        scrollBar = self.currentList.verticalScrollBar()
        if self._temp.get('oldLength') == 0:
            self._ensurePlayingVisable(force=True)
        elif self._temp.get('setBottom'):
            scrollBar.setValue(scrollBar.maximum())
        else:
            scrollBar.setValue(self._temp.get('oldScroll', 0))
        try:
            del self._temp['oldLength']
            del self._temp['setBottom']
            del self._temp['oldScroll']
        except KeyError:
            pass

    def keyPressEvent(self, event):
        if event.matches(QKeySequence.Delete):
            self._removeSelected()
        elif event.key() == Qt.Key_Escape:
            self.currentList.reset()
        else:
            QListView.keyPressEvent(self.currentList, event)

    def _getSelectedRows(self):
        return (self.playQueueProxy.mapToSource(index).row() for index in self.currentList.selectedIndexes())

    def _ensurePlayingVisable(self, force=False):
        if time() - self.playQueue.lastEdit <= 5 and not force == True:
            return
        if self.playQueue.playing is None:
            return
        playing = self.playQueue.id_index(self.playQueue.playing)
        if self.currentList.isRowHidden(playing):
            return
        playing = self.playQueueProxy.mapFromSource(self.playQueue.createIndex(playing, 0))
        self.currentList.scrollTo(playing, 1) # PositionAtTop
        height = self.currentList.viewport().height()
        scrollBar = self.currentList.verticalScrollBar()
        correction = (height / 8) - self.currentList.rowViewportPosition(playing.row())
        new_pos = scrollBar.value() - correction
        scrollBar.setValue(new_pos)

    def _saveCurrent(self):
        '''Save the current playlist'''
        playlistModel = self.modelManager.playlists
        (name, ok) = QInputDialog.getItem(self,
                'Save Playlist',
                'Enter or select the playlist name',
                [name for name in playlistModel],
                0,
                True)
        if ok == True:
            playlistModel.saveCurrent(name)

    def _removeSelected(self):
        '''Remove the selected item(s) from the current playlist'''
        self._removeSongs(self._getSelectedRows())
        self.currentList.reset()

    def _cropCurrent(self):
        selection = set(self._getSelectedRows())
        rows = set(xrange(len(self.playQueue)))
        self._removeSongs(list(rows - selection))

    def _removeSongs(self, rowList):
        start = rowList.next()
        end = start + 1
        for row in rowList:
            if row != end:
                del self.playQueue[start:end]
                start = row
            end = row + 1
        del self.playQueue[start:end]

    def _playSong(self, index=None):
        try:
            row = self._getSelectedRows().next()
        except StopIteration:
            return
        self.playerState.currentSong = row
        self.playerState.play()


    def _setPlayTime(self, playTime=0):
        self.view.playTimeLabel.setText('Total play time: %s' % mpdlibrary.Time(playTime).human)

    def _setNumbers(self, value):
        self.config.showNumbers = value
        self.currentList.verticalHeader().setVisible(value)

    def _toggleKeepPlayingVisible(self, value):
        self.config.keepPlayingVisible = value
        if value:
            self._ensurePlayingVisable(force=True)

    def _setOneLinePlaylist(self, value):
        self.config.oneLinePlaylist = value
        self.playQueueDelegate.setOneLine(value)
        self._resize()

    def _resize(self):
        metrics = QFontMetrics(QFont())
        length = 0
        for song in self.playQueue:
            artist = metrics.width(song.artist)
            title = metrics.width(song.title)
            if self.config.oneLinePlaylist:
                length = max(artist + title, length)
            else:
                length = max(artist, title, length)
        width = length + self.playQueueDelegate.height + 4
        header = self.currentList.horizontalHeader()
        header.setMinimumSectionSize(width)
        self.currentList.verticalHeader().setDefaultSectionSize(self.playQueueDelegate.height)

    def _togglePlaylistTools(self, value=None):
        text = ('Show Playlist Tools', 'Hide Playlist Tools')
        if value == None:
            value = not self.playlistTools.isVisible()
        scrollBar = self.currentList.verticalScrollBar()
        scrollValue = scrollBar.value()
        scrollMax = scrollBar.maximum()
        self.playlistTools.setVisible(value)
        self.currentBottom.setArrowType(int(value)+1)
        self.currentBottom.setText(text[value])
        self.config.playlistControls = bool(self.playlistTools.isVisible())
        if scrollValue == scrollMax:
            scrollBar.setValue(scrollBar.maximum())

    def _addStream(self):
        '''Ask the user for the url of the stream to add.'''
        (url,ok) = QInputDialog.getText(self
                , 'Add Stream'
                , 'Please enter the url of the stream you like to add to the playlist.'
                , 0
                , 'Add Stream')
        url = str(url)
        if ok == True and url:
            try:
                streamList = streamTools.getStreamList(url)
            except streamTools.ParseError:
                print 'error: Could not parse stream address.'
                return
            self.playQueue.extend(streamList)

    def _setEditing(self):
        self.playQueue.lastEdit = time()
Exemple #6
0
class BreakPointView( QTreeView ):
    " Breakpoint viewer widget "

    def __init__( self, parent, bpointsModel ):
        QTreeView.__init__( self, parent )

        self.__model = None
        self.setModel( bpointsModel )

        self.setItemsExpandable( False )
        self.setRootIsDecorated( False )
        self.setAlternatingRowColors( True )
        self.setUniformRowHeights( True )
        self.setSelectionMode( QAbstractItemView.SingleSelection )
        self.setSelectionBehavior( QAbstractItemView.SelectRows )
        self.setItemDelegate( NoOutlineHeightDelegate( 4 ) )

        self.setContextMenuPolicy( Qt.CustomContextMenu )
        self.customContextMenuRequested.connect( self.__showContextMenu )
        self.doubleClicked.connect( self.__doubleClicked )

        self.__createPopupMenus()
        return

    def setModel( self, model ):
        " Sets the breakpoint model "
        self.__model = model

        self.sortingModel = QSortFilterProxyModel()
        self.sortingModel.setSourceModel( self.__model )
        QTreeView.setModel( self, self.sortingModel )

        header = self.header()
        header.setSortIndicator( 0, Qt.AscendingOrder )
        header.setSortIndicatorShown( True )
        header.setClickable( True )

        self.setSortingEnabled( True )
        self.layoutDisplay()
        return

    def layoutDisplay( self ):
        " Performs the layout operation "
        self.__resizeColumns()
        self.__resort()
        return

    def __resizeColumns( self ):
        " Resizes the view when items get added, edited or deleted "
        self.header().resizeSections( QHeaderView.ResizeToContents )
        self.header().setStretchLastSection( True )
        return

    def __resort( self ):
        " Resorts the tree "
        self.model().sort( self.header().sortIndicatorSection(),
                           self.header().sortIndicatorOrder() )
        return

    def toSourceIndex( self, index ):
        " Converts an index to a source index "
        return self.sortingModel.mapToSource( index )

    def __fromSourceIndex( self, sindex ):
        " Convert a source index to an index "
        return self.sortingModel.mapFromSource( sindex )

    def __setRowSelected( self, index, selected = True ):
        " Selects a row "
        if not index.isValid():
            return

        if selected:
            flags = QItemSelectionModel.SelectionFlags(
                QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows )
        else:
            flags = QItemSelectionModel.SelectionFlags(
                QItemSelectionModel.Deselect | QItemSelectionModel.Rows )
        self.selectionModel().select( index, flags )
        return

    def __createPopupMenus( self ):
        " Generate the popup menu "
        self.menu = QMenu()
        self.__editAct = self.menu.addAction(
                                PixmapCache().getIcon( 'bpprops.png' ),
                                "Edit...", self.__editBreak )
        self.__jumpToCodeAct = self.menu.addAction(
                                PixmapCache().getIcon( 'gotoline.png' ),
                                "Jump to code", self.__showSource )
        self.menu.addSeparator()
        self.__enableAct = self.menu.addAction(
                                PixmapCache().getIcon( 'bpenable.png' ),
                                "Enable", self.enableBreak )
        self.__enableAllAct = self.menu.addAction(
                                PixmapCache().getIcon( 'bpenableall.png' ),
                                "Enable all", self.enableAllBreaks )
        self.menu.addSeparator()
        self.__disableAct = self.menu.addAction(
                                PixmapCache().getIcon( 'bpdisable.png' ),
                                "Disable", self.disableBreak )
        self.__disableAllAct = self.menu.addAction(
                                PixmapCache().getIcon( 'bpdisableall.png' ),
                                "Disable all", self.disableAllBreaks )
        self.menu.addSeparator()
        self.__delAct = self.menu.addAction(
                                PixmapCache().getIcon( 'bpdel.png' ),
                                "Delete", self.deleteBreak )
        self.__delAllAct = self.menu.addAction(
                                PixmapCache().getIcon( 'bpdelall.png' ),
                                "Delete all", self.deleteAllBreaks )
        return

    def __showContextMenu( self, coord ):
        " Shows the context menu "
        index = self.currentIndex()
        if not index.isValid():
            return
        sindex = self.toSourceIndex( index )
        if not sindex.isValid():
            return
        bp = self.__model.getBreakPointByIndex( sindex )
        if not bp:
            return

        enableCount, disableCount = self.__model.getCounts()

        self.__editAct.setEnabled( True )
        self.__enableAct.setEnabled( not bp.isEnabled() )
        self.__disableAct.setEnabled( bp.isEnabled() )
        self.__jumpToCodeAct.setEnabled( True )
        self.__delAct.setEnabled( True )
        self.__enableAllAct.setEnabled( disableCount > 0 )
        self.__disableAllAct.setEnabled( enableCount > 0 )
        self.__delAllAct.setEnabled( enableCount + disableCount > 0 )

        self.menu.popup( QCursor.pos() )
        return

    def __doubleClicked( self, index ):
        " Handles the double clicked signal "
        if not index.isValid():
            return

        sindex = self.toSourceIndex( index )
        if not sindex.isValid():
            return

        # Jump to the code
        bpoint = self.__model.getBreakPointByIndex( sindex )
        fileName = bpoint.getAbsoluteFileName()
        line = bpoint.getLineNumber()
        self.jumpToCode( fileName, line )
        return

    def jumpToCode( self, fileName, line ):
        " Jumps to the source code "
        editorsManager = GlobalData().mainWindow.editorsManager()
        editorsManager.openFile( fileName, line )
        editor = editorsManager.currentWidget().getEditor()
        editor.gotoLine( line )
        editorsManager.currentWidget().setFocus()
        return

    def __editBreak( self ):
        " Handle the edit breakpoint context menu entry "
        index = self.currentIndex()
        if index.isValid():
            self.__editBreakpoint( index )
        return

    def __editBreakpoint( self, index ):
        " Edits a breakpoint "
        sindex = self.toSourceIndex( index )
        if sindex.isValid():
            bp = self.__model.getBreakPointByIndex( sindex )
            if not bp:
                return

            dlg = BreakpointEditDialog( bp )
            if dlg.exec_() == QDialog.Accepted:
                newBpoint = dlg.getData()
                if newBpoint == bp:
                    return
                self.__model.setBreakPointByIndex( sindex, newBpoint )
                self.layoutDisplay()
        return

    def __setBpEnabled( self, index, enabled ):
        " Sets the enabled status of a breakpoint "
        sindex = self.toSourceIndex( index )
        if sindex.isValid():
            self.__model.setBreakPointEnabledByIndex( sindex, enabled )
        return

    def enableBreak( self ):
        " Handles the enable breakpoint context menu entry "
        index = self.currentIndex()
        self.__setBpEnabled( index, True )
        self.__resizeColumns()
        self.__resort()
        return

    def enableAllBreaks( self ):
        " Handles the enable all breakpoints context menu entry "
        index = self.model().index( 0, 0 )
        while index.isValid():
            self.__setBpEnabled( index, True )
            index = self.indexBelow( index )
        self.__resizeColumns()
        self.__resort()
        return

    def disableBreak( self ):
        " Handles the disable breakpoint context menu entry "
        index = self.currentIndex()
        self.__setBpEnabled( index, False )
        self.__resizeColumns()
        self.__resort()
        return

    def disableAllBreaks( self ):
        " Handles the disable all breakpoints context menu entry "
        index = self.model().index( 0, 0 )
        while index.isValid():
            self.__setBpEnabled( index, False )
            index = self.indexBelow( index )
        self.__resizeColumns()
        self.__resort()
        return

    def deleteBreak( self ):
        " Handles the delete breakpoint context menu entry "
        index = self.currentIndex()
        sindex = self.toSourceIndex( index )
        if sindex.isValid():
            self.__model.deleteBreakPointByIndex( sindex )
        return

    def deleteAllBreaks( self ):
        " Handles the delete all breakpoints context menu entry "
        self.__model.deleteAll()
        return

    def __showSource( self ):
        " Handles the goto context menu entry "
        index = self.currentIndex()
        self.__doubleClicked( index )
        return

    def highlightBreakpoint( self, fn, lineno ):
        " Handles the clientLine signal "
        sindex = self.__model.getBreakPointIndex( fn, lineno )
        if sindex.isValid():
            return

        index = self.__fromSourceIndex( sindex )
        if index.isValid():
            self.__clearSelection()
            self.__setRowSelected( index, True )
        return

    def __getSelectedItemsCount( self ):
        " Provides the count of items selected "
        count = len( self.selectedIndexes() ) / ( self.__model.columnCount() - 1 )
        # column count is 1 greater than selectable
        return count

    def selectionChanged( self, selected, deselected ):
        " The slot is called when the selection has changed "
        if selected.indexes():
            self.emit( SIGNAL( 'selectionChanged' ),
                       selected.indexes()[ 0 ] )
        else:
            self.emit( SIGNAL( 'selectionChanged' ), None )
        QTreeView.selectionChanged( self, selected, deselected )
        return
class WatchPointView(QTreeView):
    " Watch expression viewer widget "

    def __init__(self, parent, wpointsModel):
        QTreeView.__init__(self, parent)

        self.__model = None
        self.setModel(wpointsModel)

        self.setItemsExpandable(False)
        self.setRootIsDecorated(False)
        self.setAlternatingRowColors(True)
        self.setUniformRowHeights(True)
        self.setSelectionMode(QAbstractItemView.SingleSelection)
        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.setItemDelegate(NoOutlineHeightDelegate(4))

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.__showContextMenu)
        self.doubleClicked.connect(self.__doubleClicked)

        self.__createPopupMenus()
        return

    def setModel(self, model):
        " Sets the watch expression model "
        self.__model = model

        self.sortingModel = QSortFilterProxyModel()
        self.sortingModel.setSourceModel(self.__model)
        QTreeView.setModel(self, self.sortingModel)

        header = self.header()
        header.setSortIndicator(0, Qt.AscendingOrder)
        header.setSortIndicatorShown(True)
        header.setClickable(True)

        self.setSortingEnabled(True)
        self.__layoutDisplay()
        return

    def __layoutDisplay(self):
        " Performs the layout operation "
        self.__resizeColumns()
        self.__resort()
        return

    def __resizeColumns(self):
        " Resizes the view when items get added, edited or deleted "
        self.header().resizeSections(QHeaderView.ResizeToContents)
        self.header().setStretchLastSection(True)
        return

    def __resort(self):
        " Resorts the tree "
        self.model().sort(self.header().sortIndicatorSection(), self.header().sortIndicatorOrder())
        return

    def __toSourceIndex(self, index):
        " Converts an index to a source index "
        return self.sortingModel.mapToSource(index)

    def __fromSourceIndex(self, sindex):
        " Converts a source index to an index "
        return self.sortingModel.mapFromSource(sindex)

    def __setRowSelected(self, index, selected=True):
        " Selects a row "
        if not index.isValid():
            return

        if selected:
            flags = QItemSelectionModel.SelectionFlags(QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows)
        else:
            flags = QItemSelectionModel.SelectionFlags(QItemSelectionModel.Deselect | QItemSelectionModel.Rows)
        self.selectionModel().select(index, flags)
        return

    def __createPopupMenus(self):
        """
        Private method to generate the popup menus.
        """
        self.menu = QMenu()
        self.menu.addAction(self.trUtf8("Add"), self.__addWatchPoint)
        self.menu.addAction(self.trUtf8("Edit..."), self.__editWatchPoint)
        self.menu.addSeparator()
        self.menu.addAction(self.trUtf8("Enable"), self.__enableWatchPoint)
        self.menu.addAction(self.trUtf8("Enable all"), self.__enableAllWatchPoints)
        self.menu.addSeparator()
        self.menu.addAction(self.trUtf8("Disable"), self.__disableWatchPoint)
        self.menu.addAction(self.trUtf8("Disable all"), self.__disableAllWatchPoints)
        self.menu.addSeparator()
        self.menu.addAction(self.trUtf8("Delete"), self.__deleteWatchPoint)
        self.menu.addAction(self.trUtf8("Delete all"), self.__deleteAllWatchPoints)

        self.backMenuActions = {}
        self.backMenu = QMenu()
        self.backMenu.addAction(self.trUtf8("Add"), self.__addWatchPoint)
        self.backMenuActions["EnableAll"] = self.backMenu.addAction(
            self.trUtf8("Enable all"), self.__enableAllWatchPoints
        )
        self.backMenuActions["DisableAll"] = self.backMenu.addAction(
            self.trUtf8("Disable all"), self.__disableAllWatchPoints
        )
        self.backMenuActions["DeleteAll"] = self.backMenu.addAction(
            self.trUtf8("Delete all"), self.__deleteAllWatchPoints
        )
        self.backMenu.aboutToShow.connect(self.__showBackMenu)

        self.multiMenu = QMenu()
        self.multiMenu.addAction(self.trUtf8("Add"), self.__addWatchPoint)
        self.multiMenu.addSeparator()
        self.multiMenu.addAction(self.trUtf8("Enable selected"), self.__enableSelectedWatchPoints)
        self.multiMenu.addAction(self.trUtf8("Enable all"), self.__enableAllWatchPoints)
        self.multiMenu.addSeparator()
        self.multiMenu.addAction(self.trUtf8("Disable selected"), self.__disableSelectedWatchPoints)
        self.multiMenu.addAction(self.trUtf8("Disable all"), self.__disableAllWatchPoints)
        self.multiMenu.addSeparator()
        self.multiMenu.addAction(self.trUtf8("Delete selected"), self.__deleteSelectedWatchPoints)
        self.multiMenu.addAction(self.trUtf8("Delete all"), self.__deleteAllWatchPoints)
        return

    def __showContextMenu(self, coord):
        """
        Private slot to show the context menu.

        @param coord the position of the mouse pointer (QPoint)
        """
        cnt = self.__getSelectedItemsCount()
        if cnt <= 1:
            index = self.indexAt(coord)
            if index.isValid():
                cnt = 1
                self.__setRowSelected(index)
        coord = self.mapToGlobal(coord)
        if cnt > 1:
            self.multiMenu.popup(coord)
        elif cnt == 1:
            self.menu.popup(coord)
        else:
            self.backMenu.popup(coord)

    def __findDuplicates(self, cond, special, showMessage=False, index=QModelIndex()):
        " Checks if an entry already exists "
        cond = unicode(cond)
        special = unicode(special)
        idx = self.__model.getWatchPointIndex(cond, special)
        duplicate = idx.isValid() and idx.internalPointer() != index.internalPointer()
        #        if showMessage and duplicate:
        #            if not special:
        #                msg = """<p>A watch expression '<b>%1</b>'"""
        #                                  """ already exists.</p>""".arg(Utilities.html_encode(unicode(cond)))
        #            else:
        #                msg = self.trUtf8("""<p>A watch expression '<b>%1</b>'"""
        #                                  """ for the variable <b>%2</b> already exists.</p>""")\
        #                        .arg(special)\
        #                        .arg(Utilities.html_encode(unicode(cond)))
        #            KQMessageBox.warning(None,
        #                self.trUtf8("Watch expression already exists"),
        #                msg)

        return duplicate

    def __clearSelection(self):
        " Clears the selection "
        for index in self.selectedIndexes():
            self.__setRowSelected(index, False)
        return

    def __addWatchPoint(self):
        " Adds watch expression via a context menu entry "
        #        dlg = EditWatchpointDialog( ( "", False, True, 0, "" ), self )
        #        if dlg.exec_() == QDialog.Accepted:
        #            cond, temp, enabled, ignorecount, special = dlg.getData()
        #            if not self.__findDuplicates(cond, special, True):
        #                self.__model.addWatchPoint(cond, special, (temp, enabled, ignorecount))
        #                self.__resizeColumns()
        #                self.__resort()
        return

    def __doubleClicked(self, index):
        " Handles the double clicked signal "
        if index.isValid():
            self.__doEditWatchPoint(index)
        return

    def __editWatchPoint(self):
        " Handles the edit watch expression context menu entry "
        index = self.currentIndex()
        if index.isValid():
            self.__doEditWatchPoint(index)
        return

    def __doEditWatchPoint(self, index):
        " Edits a watch expression "
        sindex = self.__toSourceIndex(index)
        if sindex.isValid():
            wp = self.__model.getWatchPointByIndex(sindex)
            if not wp:
                return

            cond, special, temp, enabled, count = wp[:5]

        #            dlg = EditWatchpointDialog(
        #                (cond, temp, enabled, count, special), self)
        #            if dlg.exec_() == QDialog.Accepted:
        #                cond, temp, enabled, count, special = dlg.getData()
        #                if not self.__findDuplicates(cond, special, True, sindex):
        #                    self.__model.setWatchPointByIndex(sindex,
        #                        unicode(cond), unicode(special), (temp, enabled, count))
        #                    self.__resizeColumns()
        #                    self.__resort()
        return

    def __setWpEnabled(self, index, enabled):
        " Sets the enabled status of a watch expression "
        sindex = self.__toSourceIndex(index)
        if sindex.isValid():
            self.__model.setWatchPointEnabledByIndex(sindex, enabled)
        return

    def __enableWatchPoint(self):
        " Handles the enable watch expression context menu entry "
        index = self.currentIndex()
        self.__setWpEnabled(index, True)
        self.__resizeColumns()
        self.__resort()
        return

    def __enableAllWatchPoints(self):
        " Handles the enable all watch expressions context menu entry "
        index = self.model().index(0, 0)
        while index.isValid():
            self.__setWpEnabled(index, True)
            index = self.indexBelow(index)
        self.__resizeColumns()
        self.__resort()
        return

    def __enableSelectedWatchPoints(self):
        " Handles the enable selected watch expressions context menu entry "
        for index in self.selectedIndexes():
            if index.column() == 0:
                self.__setWpEnabled(index, True)
        self.__resizeColumns()
        self.__resort()
        return

    def __disableWatchPoint(self):
        " Handles the disable watch expression context menu entry "
        index = self.currentIndex()
        self.__setWpEnabled(index, False)
        self.__resizeColumns()
        self.__resort()
        return

    def __disableAllWatchPoints(self):
        " Handles the disable all watch expressions context menu entry "
        index = self.model().index(0, 0)
        while index.isValid():
            self.__setWpEnabled(index, False)
            index = self.indexBelow(index)
        self.__resizeColumns()
        self.__resort()
        return

    def __disableSelectedWatchPoints(self):
        " Handles the disable selected watch expressions context menu entry "
        for index in self.selectedIndexes():
            if index.column() == 0:
                self.__setWpEnabled(index, False)
        self.__resizeColumns()
        self.__resort()
        return

    def __deleteWatchPoint(self):
        " Handles the delete watch expression context menu entry "
        index = self.currentIndex()
        sindex = self.__toSourceIndex(index)
        if sindex.isValid():
            self.__model.deleteWatchPointByIndex(sindex)
        return

    def __deleteAllWatchPoints(self):
        " Handles the delete all watch expressions context menu entry "
        self.__model.deleteAll()
        return

    def __deleteSelectedWatchPoints(self):
        " Handles the delete selected watch expressions context menu entry "
        idxList = []
        for index in self.selectedIndexes():
            sindex = self.__toSourceIndex(index)
            if sindex.isValid() and index.column() == 0:
                lastrow = index.row()
                idxList.append(sindex)
        self.__model.deleteWatchPoints(idxList)
        return

    def __showBackMenu(self):
        " Handles the aboutToShow signal of the background menu "
        if self.model().rowCount() == 0:
            self.backMenuActions["EnableAll"].setEnabled(False)
            self.backMenuActions["DisableAll"].setEnabled(False)
            self.backMenuActions["DeleteAll"].setEnabled(False)
        else:
            self.backMenuActions["EnableAll"].setEnabled(True)
            self.backMenuActions["DisableAll"].setEnabled(True)
            self.backMenuActions["DeleteAll"].setEnabled(True)
        return

    def __getSelectedItemsCount(self):
        " Provides the count of items selected "
        count = len(self.selectedIndexes()) / (self.__model.columnCount() - 1)
        # column count is 1 greater than selectable
        return count
Exemple #8
0
class BreakPointView(QTreeView):
    " Breakpoint viewer widget "

    def __init__(self, parent, bpointsModel):
        QTreeView.__init__(self, parent)

        self.__model = None
        self.setModel(bpointsModel)

        self.setItemsExpandable(False)
        self.setRootIsDecorated(False)
        self.setAlternatingRowColors(True)
        self.setUniformRowHeights(True)
        self.setSelectionMode(QAbstractItemView.SingleSelection)
        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.setItemDelegate(NoOutlineHeightDelegate(4))

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.__showContextMenu)
        self.doubleClicked.connect(self.__doubleClicked)

        self.__createPopupMenus()
        return

    def setModel(self, model):
        " Sets the breakpoint model "
        self.__model = model

        self.sortingModel = QSortFilterProxyModel()
        self.sortingModel.setSourceModel(self.__model)
        QTreeView.setModel(self, self.sortingModel)

        header = self.header()
        header.setSortIndicator(0, Qt.AscendingOrder)
        header.setSortIndicatorShown(True)
        header.setClickable(True)

        self.setSortingEnabled(True)
        self.layoutDisplay()
        return

    def layoutDisplay(self):
        " Performs the layout operation "
        self.__resizeColumns()
        self.__resort()
        return

    def __resizeColumns(self):
        " Resizes the view when items get added, edited or deleted "
        self.header().resizeSections(QHeaderView.ResizeToContents)
        self.header().setStretchLastSection(True)
        return

    def __resort(self):
        " Resorts the tree "
        self.model().sort(self.header().sortIndicatorSection(),
                          self.header().sortIndicatorOrder())
        return

    def toSourceIndex(self, index):
        " Converts an index to a source index "
        return self.sortingModel.mapToSource(index)

    def __fromSourceIndex(self, sindex):
        " Convert a source index to an index "
        return self.sortingModel.mapFromSource(sindex)

    def __setRowSelected(self, index, selected=True):
        " Selects a row "
        if not index.isValid():
            return

        if selected:
            flags = QItemSelectionModel.SelectionFlags(
                QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows)
        else:
            flags = QItemSelectionModel.SelectionFlags(
                QItemSelectionModel.Deselect | QItemSelectionModel.Rows)
        self.selectionModel().select(index, flags)
        return

    def __createPopupMenus(self):
        " Generate the popup menu "
        self.menu = QMenu()
        self.__editAct = self.menu.addAction(
            PixmapCache().getIcon('bpprops.png'), "Edit...", self.__editBreak)
        self.__jumpToCodeAct = self.menu.addAction(
            PixmapCache().getIcon('gotoline.png'), "Jump to code",
            self.__showSource)
        self.menu.addSeparator()
        self.__enableAct = self.menu.addAction(
            PixmapCache().getIcon('bpenable.png'), "Enable", self.enableBreak)
        self.__enableAllAct = self.menu.addAction(
            PixmapCache().getIcon('bpenableall.png'), "Enable all",
            self.enableAllBreaks)
        self.menu.addSeparator()
        self.__disableAct = self.menu.addAction(
            PixmapCache().getIcon('bpdisable.png'), "Disable",
            self.disableBreak)
        self.__disableAllAct = self.menu.addAction(
            PixmapCache().getIcon('bpdisableall.png'), "Disable all",
            self.disableAllBreaks)
        self.menu.addSeparator()
        self.__delAct = self.menu.addAction(PixmapCache().getIcon('bpdel.png'),
                                            "Delete", self.deleteBreak)
        self.__delAllAct = self.menu.addAction(
            PixmapCache().getIcon('bpdelall.png'), "Delete all",
            self.deleteAllBreaks)
        return

    def __showContextMenu(self, coord):
        " Shows the context menu "
        index = self.currentIndex()
        if not index.isValid():
            return
        sindex = self.toSourceIndex(index)
        if not sindex.isValid():
            return
        bp = self.__model.getBreakPointByIndex(sindex)
        if not bp:
            return

        enableCount, disableCount = self.__model.getCounts()

        self.__editAct.setEnabled(True)
        self.__enableAct.setEnabled(not bp.isEnabled())
        self.__disableAct.setEnabled(bp.isEnabled())
        self.__jumpToCodeAct.setEnabled(True)
        self.__delAct.setEnabled(True)
        self.__enableAllAct.setEnabled(disableCount > 0)
        self.__disableAllAct.setEnabled(enableCount > 0)
        self.__delAllAct.setEnabled(enableCount + disableCount > 0)

        self.menu.popup(QCursor.pos())
        return

    def __doubleClicked(self, index):
        " Handles the double clicked signal "
        if not index.isValid():
            return

        sindex = self.toSourceIndex(index)
        if not sindex.isValid():
            return

        # Jump to the code
        bpoint = self.__model.getBreakPointByIndex(sindex)
        fileName = bpoint.getAbsoluteFileName()
        line = bpoint.getLineNumber()
        self.jumpToCode(fileName, line)
        return

    def jumpToCode(self, fileName, line):
        " Jumps to the source code "
        editorsManager = GlobalData().mainWindow.editorsManager()
        editorsManager.openFile(fileName, line)
        editor = editorsManager.currentWidget().getEditor()
        editor.gotoLine(line)
        editorsManager.currentWidget().setFocus()
        return

    def __editBreak(self):
        " Handle the edit breakpoint context menu entry "
        index = self.currentIndex()
        if index.isValid():
            self.__editBreakpoint(index)
        return

    def __editBreakpoint(self, index):
        " Edits a breakpoint "
        sindex = self.toSourceIndex(index)
        if sindex.isValid():
            bp = self.__model.getBreakPointByIndex(sindex)
            if not bp:
                return

            dlg = BreakpointEditDialog(bp)
            if dlg.exec_() == QDialog.Accepted:
                newBpoint = dlg.getData()
                if newBpoint == bp:
                    return
                self.__model.setBreakPointByIndex(sindex, newBpoint)
                self.layoutDisplay()
        return

    def __setBpEnabled(self, index, enabled):
        " Sets the enabled status of a breakpoint "
        sindex = self.toSourceIndex(index)
        if sindex.isValid():
            self.__model.setBreakPointEnabledByIndex(sindex, enabled)
        return

    def enableBreak(self):
        " Handles the enable breakpoint context menu entry "
        index = self.currentIndex()
        self.__setBpEnabled(index, True)
        self.__resizeColumns()
        self.__resort()
        return

    def enableAllBreaks(self):
        " Handles the enable all breakpoints context menu entry "
        index = self.model().index(0, 0)
        while index.isValid():
            self.__setBpEnabled(index, True)
            index = self.indexBelow(index)
        self.__resizeColumns()
        self.__resort()
        return

    def disableBreak(self):
        " Handles the disable breakpoint context menu entry "
        index = self.currentIndex()
        self.__setBpEnabled(index, False)
        self.__resizeColumns()
        self.__resort()
        return

    def disableAllBreaks(self):
        " Handles the disable all breakpoints context menu entry "
        index = self.model().index(0, 0)
        while index.isValid():
            self.__setBpEnabled(index, False)
            index = self.indexBelow(index)
        self.__resizeColumns()
        self.__resort()
        return

    def deleteBreak(self):
        " Handles the delete breakpoint context menu entry "
        index = self.currentIndex()
        sindex = self.toSourceIndex(index)
        if sindex.isValid():
            self.__model.deleteBreakPointByIndex(sindex)
        return

    def deleteAllBreaks(self):
        " Handles the delete all breakpoints context menu entry "
        self.__model.deleteAll()
        return

    def __showSource(self):
        " Handles the goto context menu entry "
        index = self.currentIndex()
        self.__doubleClicked(index)
        return

    def highlightBreakpoint(self, fn, lineno):
        " Handles the clientLine signal "
        sindex = self.__model.getBreakPointIndex(fn, lineno)
        if sindex.isValid():
            return

        index = self.__fromSourceIndex(sindex)
        if index.isValid():
            self.__clearSelection()
            self.__setRowSelected(index, True)
        return

    def __getSelectedItemsCount(self):
        " Provides the count of items selected "
        count = len(self.selectedIndexes()) / (self.__model.columnCount() - 1)
        # column count is 1 greater than selectable
        return count

    def selectionChanged(self, selected, deselected):
        " The slot is called when the selection has changed "
        if selected.indexes():
            self.emit(SIGNAL('selectionChanged'), selected.indexes()[0])
        else:
            self.emit(SIGNAL('selectionChanged'), None)
        QTreeView.selectionChanged(self, selected, deselected)
        return