Beispiel #1
0
class DesktopIconWidget(QFrame):
    def __init__(self, parent):
        QFrame.__init__(self, parent)
        self.setFrameStyle(QFrame.Box | QFrame.Sunken)
        self.setStyleSheet("QListView{background:transparent;}")

        self.listView = QListView(self)
        self.setLayout(QHBoxLayout())
        self.layout().setContentsMargins(0, 0, 0, 0)
        self.layout().addWidget(self.listView)

        self.listView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.listView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.listView.setMovement(QListView.Snap)
        self.listView.setFlow(QListView.LeftToRight)
        self.listView.setResizeMode(QListView.Adjust)
        self.listView.setGridSize(QSize(self.logicalDpiX() / 96 * 70,
                                        self.logicalDpiY() / 96 * 70))
        self.listView.setViewMode(QListView.IconMode)

        self.quickDesktopModel = QuickDesktopModel(self.window().platform.databaseFile)
        self.listView.setModel(self.quickDesktopModel)
        self.createActions()
        self.makeConnections()

    def createActions(self):
        self.actionCreateComputer = QAction(self.trUtf8("我的电脑(&C)"), self)
        self.actionCreateDocuments = QAction(self.trUtf8("我的文档(&D)"), self)
        self.actionCreateMusic = QAction(self.trUtf8("我的音乐(&M)"), self)
        self.actionCreatePictures = QAction(self.trUtf8("我的图片(&P)"), self)
        self.actionCreateShortcut = QAction(self.trUtf8("创建快捷方式(&C)"), self)
        self.actionCreateShortcut.setIcon(QIcon(":/images/new.png"))
        self.actionCreateBookmark = QAction(self.trUtf8("创建网络链接(&B)"), self)
        self.actionCreateBookmark.setIcon(QIcon(":/images/insert-link.png"))
        self.actionRemoveShortcut = QAction(self.trUtf8("删除快捷方式(&R)"), self)
        self.actionRemoveShortcut.setIcon(QIcon(":/images/delete.png"))
        self.actionRenameShortcut = QAction(self.trUtf8("重命名(&N)"), self)
        self.actionRenameShortcut.setIcon(QIcon(":/images/edit-rename.png"))
        self.actionEditShortcut = QAction(self.trUtf8("编辑快捷方式(&E)"), self)
        self.actionEditShortcut.setIcon(QIcon(":/images/edit.png"))

    def makeConnections(self):
        self.listView.customContextMenuRequested.connect(self.onQuickDesktopContextMenuRequest)
        self.listView.activated.connect(self.runQuickDesktopShortcut)

        self.actionCreateComputer.triggered.connect(self.createComputerShortcut)
        self.actionCreateDocuments.triggered.connect(self.createDocumentsShortcut)
        self.actionCreateMusic.triggered.connect(self.createMusicShortcut)
        self.actionCreatePictures.triggered.connect(self.createPicturesShortcut)
        self.actionCreateShortcut.triggered.connect(self.createShortcut)
        self.actionCreateBookmark.triggered.connect(self.createBookmark)
        self.actionEditShortcut.triggered.connect(self.editShortcut)
        self.actionRemoveShortcut.triggered.connect(self.removeShortcut)
        self.actionRenameShortcut.triggered.connect(self.renameShortcut)

    def onQuickDesktopContextMenuRequest(self, pos):
        index = self.listView.indexAt(pos)
        self.listView.setCurrentIndex(index)
        menu = QMenu()
        menu.addAction(self.actionCreateShortcut)
        menu.addAction(self.actionCreateBookmark)
        menu2 = menu.addMenu(self.trUtf8("创建特殊快捷方式(&S)"))
        if os.name == "nt":
            menu2.addAction(self.actionCreateComputer)
        menu2.addAction(self.actionCreateDocuments)
        menu2.addAction(self.actionCreatePictures)
        menu2.addAction(self.actionCreateMusic)
        if index.isValid():
            menu.addAction(self.actionRemoveShortcut)
            if not self.quickDesktopModel.isSpecialShortcut(index):
                menu.addAction(self.actionEditShortcut)
            menu.addAction(self.actionRenameShortcut)
        try:
            getattr(menu, "exec")(QCursor.pos())
        except AttributeError:
            getattr(menu, "exec_")(QCursor.pos())

    def createShortcut(self):
        d = ShortcutDialog(self)
        if self.window().runDialog(d.create) == QDialog.Accepted:
            shortcut = d.getResult()
            shortcut["id"] = str(uuid.uuid4())
            self.quickDesktopModel.addShortcut(shortcut)
        d.deleteLater()

    def createBookmark(self):
        d = BookmarkDialog(self)
        if self.window().runDialog(d.create) == QDialog.Accepted:
            shortcut = {
                    "id": str(uuid.uuid4()),
                    "icon": "",
                    "openwith": "",
                    "dir": "",
            }
            shortcut.update(d.getResult())
            self.quickDesktopModel.addShortcut(shortcut)
        d.deleteLater()

    def createComputerShortcut(self):
        shortcut = {
                "id": str(uuid.uuid4()),
                "name": self.trUtf8("我的电脑"),
                "path": COMPUTER_PATH,
                "icon": "",
                "dir": "",
                "openwith": "",
        }
        self.quickDesktopModel.addShortcut(shortcut)

    def createDocumentsShortcut(self):
        shortcut = {
                "id": str(uuid.uuid4()),
                "name": self.trUtf8("我的文档"),
                "path": DOCUMENTS_PATH,
                "icon": "",
                "dir": "",
                "openwith": "",
        }
        self.quickDesktopModel.addShortcut(shortcut)

    def createPicturesShortcut(self):
        shortcut = {
                "id": str(uuid.uuid4()),
                "name": self.trUtf8("图片收藏"),
                "path": PICTURES_PATH,
                "icon": "",
                "dir": "",
                "openwith": "",
        }
        self.quickDesktopModel.addShortcut(shortcut)

    def createMusicShortcut(self):
        shortcut = {
                "id": str(uuid.uuid4()),
                "name": self.trUtf8("我的音乐"),
                "path": MUSIC_PATH,
                "icon": "",
                "dir": "",
                "openwith": "",
        }
        self.quickDesktopModel.addShortcut(shortcut)

    def renameShortcut(self):
        self.listView.edit(self.listView.currentIndex())

    def removeShortcut(self):
        self.quickDesktopModel.removeShortcut(self.listView.currentIndex())

    def editShortcut(self):
        index = self.listView.currentIndex()
        if not index.isValid():
            return
        shortcut = self.quickDesktopModel.shortcutAt(index)
        url = QUrl.fromUserInput(shortcut["path"])
        if not url.isValid():
            return
        if url.scheme() == "special":
            QMessageBox.information(self, self.trUtf8("编辑快捷方式"), self.trUtf8("不能编辑特殊图标。"))
            return
        elif url.scheme() == "file":
            d = ShortcutDialog(self)
        else:
            d = BookmarkDialog(self)
        if self.window().runDialog(d.edit, shortcut) == QDialog.Accepted:
            shortcut.update(d.getResult())
            self.quickDesktopModel.updateShortcut(shortcut, index)
        d.deleteLater()

    def runQuickDesktopShortcut(self):
        index = self.listView.currentIndex()
        if not index.isValid():
            return
        if not self.quickDesktopModel.runShortcut(index):
            QMessageBox.information(self, self.trUtf8("快捷面板"), \
                    self.trUtf8("不能运行快捷方式。请检查文件是否存在或者程序是否正确。"))
        else:
            self.window().close()
Beispiel #2
0
class SortedListWidget(QWidget):
    sortingOrderChanged = Signal()

    class _MyItemDelegate(QStyledItemDelegate):

        def __init__(self, sortingModel, parent):
            QStyledItemDelegate.__init__(self, parent)
            self.sortingModel = sortingModel

        def sizeHint(self, option, index):
            size = QStyledItemDelegate.sizeHint(self, option, index)
            return QSize(size.width(), size.height() + 4)

        def createEditor(self, parent, option, index):
            cb = QComboBox(parent)
            cb.setModel(self.sortingModel)
            cb.showPopup()
            return cb

        def setEditorData(self, editor, index):
            pass  # TODO: sensible default

        def setModelData(self, editor, model, index):
            text = editor.currentText()
            model.setData(index, text)

    def __init__(self, *args):
        QWidget.__init__(self, *args)
        self.setContentsMargins(0, 0, 0, 0)
        gridLayout = QGridLayout()
        gridLayout.setContentsMargins(0, 0, 0, 0)
        gridLayout.setSpacing(1)

        model = QStandardItemModel(self)
        model.rowsInserted.connect(self.__changed)
        model.rowsRemoved.connect(self.__changed)
        model.dataChanged.connect(self.__changed)

        self._listView = QListView(self)
        self._listView.setModel(model)
#        self._listView.setDragEnabled(True)
        self._listView.setDropIndicatorShown(True)
        self._listView.setDragDropMode(QListView.InternalMove)
        self._listView.viewport().setAcceptDrops(True)
        self._listView.setMinimumHeight(100)

        gridLayout.addWidget(self._listView, 0, 0, 2, 2)

        vButtonLayout = QVBoxLayout()

        self._upAction = QAction(
            "\u2191", self, toolTip="Move up")

        self._upButton = QToolButton(self)
        self._upButton.setDefaultAction(self._upAction)
        self._upButton.setSizePolicy(
            QSizePolicy.Fixed, QSizePolicy.MinimumExpanding)

        self._downAction = QAction(
            "\u2193", self, toolTip="Move down")

        self._downButton = QToolButton(self)
        self._downButton.setDefaultAction(self._downAction)
        self._downButton.setSizePolicy(
            QSizePolicy.Fixed, QSizePolicy.MinimumExpanding)

        vButtonLayout.addWidget(self._upButton)
        vButtonLayout.addWidget(self._downButton)

        gridLayout.addLayout(vButtonLayout, 0, 2, 2, 1)

        hButtonLayout = QHBoxLayout()

        self._addAction = QAction("+", self)
        self._addButton = QToolButton(self)
        self._addButton.setDefaultAction(self._addAction)

        self._removeAction = QAction("-", self)
        self._removeButton = QToolButton(self)
        self._removeButton.setDefaultAction(self._removeAction)
        hButtonLayout.addWidget(self._addButton)
        hButtonLayout.addWidget(self._removeButton)
        hButtonLayout.addStretch(10)
        gridLayout.addLayout(hButtonLayout, 2, 0, 1, 2)

        self.setLayout(gridLayout)
        self._addAction.triggered.connect(self._onAddAction)
        self._removeAction.triggered.connect(self._onRemoveAction)
        self._upAction.triggered.connect(self._onUpAction)
        self._downAction.triggered.connect(self._onDownAction)

    def sizeHint(self):
        size = QWidget.sizeHint(self)
        return QSize(size.width(), 100)

    def _onAddAction(self):
        item = QStandardItem("")
        item.setFlags(item.flags() ^ Qt.ItemIsDropEnabled)
        self._listView.model().appendRow(item)
        self._listView.setCurrentIndex(item.index())
        self._listView.edit(item.index())

    def _onRemoveAction(self):
        current = self._listView.currentIndex()
        self._listView.model().takeRow(current.row())

    def _onUpAction(self):
        row = self._listView.currentIndex().row()
        model = self._listView.model()
        if row > 0:
            items = model.takeRow(row)
            model.insertRow(row - 1, items)
            self._listView.setCurrentIndex(model.index(row - 1, 0))

    def _onDownAction(self):
        row = self._listView.currentIndex().row()
        model = self._listView.model()
        if row < model.rowCount() and row >= 0:
            items = model.takeRow(row)
            if row == model.rowCount():
                model.appendRow(items)
            else:
                model.insertRow(row + 1, items)
            self._listView.setCurrentIndex(model.index(row + 1, 0))

    def setModel(self, model):
        """ Set a model to select items from
        """
        self._model = model
        self._listView.setItemDelegate(self._MyItemDelegate(self._model, self))

    def addItem(self, *args):
        """ Add a new entry in the list
        """
        item = QStandardItem(*args)
        item.setFlags(item.flags() ^ Qt.ItemIsDropEnabled)
        self._listView.model().appendRow(item)

    def setItems(self, items):
        self._listView.model().clear()
        for item in items:
            self.addItem(item)

    def items(self):
        order = []
        for row in range(self._listView.model().rowCount()):
            order.append(str(self._listView.model().item(row, 0).text()))
        return order

    def __changed(self):
        self.sortingOrderChanged.emit()

    sortingOrder = property(items, setItems)
Beispiel #3
0
class SortedListWidget(QWidget):
    sortingOrderChanged = Signal()

    class _MyItemDelegate(QStyledItemDelegate):
        def __init__(self, sortingModel, parent):
            QStyledItemDelegate.__init__(self, parent)
            self.sortingModel = sortingModel

        def sizeHint(self, option, index):
            size = QStyledItemDelegate.sizeHint(self, option, index)
            return QSize(size.width(), size.height() + 4)

        def createEditor(self, parent, option, index):
            cb = QComboBox(parent)
            cb.setModel(self.sortingModel)
            cb.showPopup()
            return cb

        def setEditorData(self, editor, index):
            pass  # TODO: sensible default

        def setModelData(self, editor, model, index):
            text = editor.currentText()
            model.setData(index, text)

    def __init__(self, *args):
        QWidget.__init__(self, *args)
        self.setContentsMargins(0, 0, 0, 0)
        gridLayout = QGridLayout()
        gridLayout.setContentsMargins(0, 0, 0, 0)
        gridLayout.setSpacing(1)

        model = QStandardItemModel(self)
        model.rowsInserted.connect(self.__changed)
        model.rowsRemoved.connect(self.__changed)
        model.dataChanged.connect(self.__changed)

        self._listView = QListView(self)
        self._listView.setModel(model)
        #        self._listView.setDragEnabled(True)
        self._listView.setDropIndicatorShown(True)
        self._listView.setDragDropMode(QListView.InternalMove)
        self._listView.viewport().setAcceptDrops(True)
        self._listView.setMinimumHeight(100)

        gridLayout.addWidget(self._listView, 0, 0, 2, 2)

        vButtonLayout = QVBoxLayout()

        self._upAction = QAction("\u2191", self, toolTip="Move up")

        self._upButton = QToolButton(self)
        self._upButton.setDefaultAction(self._upAction)
        self._upButton.setSizePolicy(QSizePolicy.Fixed,
                                     QSizePolicy.MinimumExpanding)

        self._downAction = QAction("\u2193", self, toolTip="Move down")

        self._downButton = QToolButton(self)
        self._downButton.setDefaultAction(self._downAction)
        self._downButton.setSizePolicy(QSizePolicy.Fixed,
                                       QSizePolicy.MinimumExpanding)

        vButtonLayout.addWidget(self._upButton)
        vButtonLayout.addWidget(self._downButton)

        gridLayout.addLayout(vButtonLayout, 0, 2, 2, 1)

        hButtonLayout = QHBoxLayout()

        self._addAction = QAction("+", self)
        self._addButton = QToolButton(self)
        self._addButton.setDefaultAction(self._addAction)

        self._removeAction = QAction("-", self)
        self._removeButton = QToolButton(self)
        self._removeButton.setDefaultAction(self._removeAction)
        hButtonLayout.addWidget(self._addButton)
        hButtonLayout.addWidget(self._removeButton)
        hButtonLayout.addStretch(10)
        gridLayout.addLayout(hButtonLayout, 2, 0, 1, 2)

        self.setLayout(gridLayout)
        self._addAction.triggered.connect(self._onAddAction)
        self._removeAction.triggered.connect(self._onRemoveAction)
        self._upAction.triggered.connect(self._onUpAction)
        self._downAction.triggered.connect(self._onDownAction)

    def sizeHint(self):
        size = QWidget.sizeHint(self)
        return QSize(size.width(), 100)

    def _onAddAction(self):
        item = QStandardItem("")
        item.setFlags(item.flags() ^ Qt.ItemIsDropEnabled)
        self._listView.model().appendRow(item)
        self._listView.setCurrentIndex(item.index())
        self._listView.edit(item.index())

    def _onRemoveAction(self):
        current = self._listView.currentIndex()
        self._listView.model().takeRow(current.row())

    def _onUpAction(self):
        row = self._listView.currentIndex().row()
        model = self._listView.model()
        if row > 0:
            items = model.takeRow(row)
            model.insertRow(row - 1, items)
            self._listView.setCurrentIndex(model.index(row - 1, 0))

    def _onDownAction(self):
        row = self._listView.currentIndex().row()
        model = self._listView.model()
        if row < model.rowCount() and row >= 0:
            items = model.takeRow(row)
            if row == model.rowCount():
                model.appendRow(items)
            else:
                model.insertRow(row + 1, items)
            self._listView.setCurrentIndex(model.index(row + 1, 0))

    def setModel(self, model):
        """ Set a model to select items from
        """
        self._model = model
        self._listView.setItemDelegate(self._MyItemDelegate(self._model, self))

    def addItem(self, *args):
        """ Add a new entry in the list
        """
        item = QStandardItem(*args)
        item.setFlags(item.flags() ^ Qt.ItemIsDropEnabled)
        self._listView.model().appendRow(item)

    def setItems(self, items):
        self._listView.model().clear()
        for item in items:
            self.addItem(item)

    def items(self):
        order = []
        for row in range(self._listView.model().rowCount()):
            order.append(str(self._listView.model().item(row, 0).text()))
        return order

    def __changed(self):
        self.sortingOrderChanged.emit()

    sortingOrder = property(items, setItems)
Beispiel #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(), 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)
Beispiel #5
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)