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()
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)
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)
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)
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)