def __init__(self, parent, itemsTableTool): super(ItemsTableGui, self).__init__(parent) self.ui = Ui_ItemsTableGui() self.ui.setupUi(self) self._itemsTableView = UnivTableView(self) self.ui.tableViewContainer.addWidget(self._itemsTableView) self.__itemsTableTool = itemsTableTool #Widgets for text queries self.ui.lineEdit_query = TextEdit(self, one_line=True) tmp = QtGui.QHBoxLayout(self.ui.widget_lineEdit_query) tmp.addWidget(self.ui.lineEdit_query) self.connect(self.ui.pushButton_query_exec, QtCore.SIGNAL("clicked()"), self.query_exec) self.connect(self.ui.lineEdit_query, QtCore.SIGNAL("returnPressed()"), self.ui.pushButton_query_exec.click) self.connect(self.ui.pushButton_query_reset, QtCore.SIGNAL("clicked()"), self.query_reset) self.connect(self._itemsTableView, QtCore.SIGNAL("doubleClicked(const QModelIndex&)"), self.__onTableDoubleClicked) #TODO limit page function sometimes works not correct!!! It sometimes shows less items, than specified in limit spinbox! #Initialization of limit and page spinboxes self.ui.spinBox_limit.setValue( int(UserConfig().get("spinBox_limit.value", 0))) self.ui.spinBox_limit.setSingleStep( int(UserConfig().get("spinBox_limit.step", 5))) self.connect(self.ui.spinBox_limit, QtCore.SIGNAL("valueChanged(int)"), self.query_exec) self.connect( self.ui.spinBox_limit, QtCore.SIGNAL("valueChanged(int)"), lambda: UserConfig().store("spinBox_limit.value", self.ui.spinBox_limit.value())) self.connect(self.ui.spinBox_limit, QtCore.SIGNAL("valueChanged(int)"), lambda val: self.ui.spinBox_page.setEnabled(val > 0)) self.connect(self.ui.spinBox_page, QtCore.SIGNAL("valueChanged(int)"), self.query_exec) self.ui.spinBox_page.setEnabled(self.ui.spinBox_limit.value() > 0) self._itemsTableView.setSortingEnabled(True) self.__table_model = None self.__context_menu = None self.__initContextMenu()
def __init__(self, parent, itemsTableTool): super(ItemsTableGui, self).__init__(parent) self.ui = Ui_ItemsTableGui() self.ui.setupUi(self) self._itemsTableView = UnivTableView(self) self.ui.tableViewContainer.addWidget(self._itemsTableView) self.__itemsTableTool = itemsTableTool #Widgets for text queries self.ui.lineEdit_query = TextEdit(self, one_line=True) tmp = QtGui.QHBoxLayout(self.ui.widget_lineEdit_query) tmp.addWidget(self.ui.lineEdit_query) self.connect(self.ui.pushButton_query_exec, QtCore.SIGNAL("clicked()"), self.query_exec) self.connect(self.ui.lineEdit_query, QtCore.SIGNAL("returnPressed()"), self.ui.pushButton_query_exec.click) self.connect(self.ui.pushButton_query_reset, QtCore.SIGNAL("clicked()"), self.query_reset) self.connect(self._itemsTableView, QtCore.SIGNAL("doubleClicked(const QModelIndex&)"), self.__onTableDoubleClicked) #TODO limit page function sometimes works not correct!!! It sometimes shows less items, than specified in limit spinbox! #Initialization of limit and page spinboxes self.ui.spinBox_limit.setValue(int(UserConfig().get("spinBox_limit.value", 0))) self.ui.spinBox_limit.setSingleStep(int(UserConfig().get("spinBox_limit.step", 5))) self.connect(self.ui.spinBox_limit, QtCore.SIGNAL("valueChanged(int)"), self.query_exec) self.connect(self.ui.spinBox_limit, QtCore.SIGNAL("valueChanged(int)"), lambda: UserConfig().store("spinBox_limit.value", self.ui.spinBox_limit.value())) self.connect(self.ui.spinBox_limit, QtCore.SIGNAL("valueChanged(int)"), lambda val: self.ui.spinBox_page.setEnabled(val > 0)) self.connect(self.ui.spinBox_page, QtCore.SIGNAL("valueChanged(int)"), self.query_exec) self.ui.spinBox_page.setEnabled(self.ui.spinBox_limit.value() > 0) self._itemsTableView.setSortingEnabled(True) self.__table_model = None self.__context_menu = None self.__initContextMenu()
class ItemsTableGui(ToolGui): def __init__(self, parent, itemsTableTool): super(ItemsTableGui, self).__init__(parent) self.ui = Ui_ItemsTableGui() self.ui.setupUi(self) self._itemsTableView = UnivTableView(self) self.ui.tableViewContainer.addWidget(self._itemsTableView) self.__itemsTableTool = itemsTableTool #Widgets for text queries self.ui.lineEdit_query = TextEdit(self, one_line=True) tmp = QtGui.QHBoxLayout(self.ui.widget_lineEdit_query) tmp.addWidget(self.ui.lineEdit_query) self.connect(self.ui.pushButton_query_exec, QtCore.SIGNAL("clicked()"), self.query_exec) self.connect(self.ui.lineEdit_query, QtCore.SIGNAL("returnPressed()"), self.ui.pushButton_query_exec.click) self.connect(self.ui.pushButton_query_reset, QtCore.SIGNAL("clicked()"), self.query_reset) self.connect(self._itemsTableView, QtCore.SIGNAL("doubleClicked(const QModelIndex&)"), self.__onTableDoubleClicked) #TODO limit page function sometimes works not correct!!! It sometimes shows less items, than specified in limit spinbox! #Initialization of limit and page spinboxes self.ui.spinBox_limit.setValue(int(UserConfig().get("spinBox_limit.value", 0))) self.ui.spinBox_limit.setSingleStep(int(UserConfig().get("spinBox_limit.step", 5))) self.connect(self.ui.spinBox_limit, QtCore.SIGNAL("valueChanged(int)"), self.query_exec) self.connect(self.ui.spinBox_limit, QtCore.SIGNAL("valueChanged(int)"), lambda: UserConfig().store("spinBox_limit.value", self.ui.spinBox_limit.value())) self.connect(self.ui.spinBox_limit, QtCore.SIGNAL("valueChanged(int)"), lambda val: self.ui.spinBox_page.setEnabled(val > 0)) self.connect(self.ui.spinBox_page, QtCore.SIGNAL("valueChanged(int)"), self.query_exec) self.ui.spinBox_page.setEnabled(self.ui.spinBox_limit.value() > 0) self._itemsTableView.setSortingEnabled(True) self.__table_model = None self.__context_menu = None self.__initContextMenu() def __getTableModel(self): return self.__table_model def __setTableModel(self, model): self.__table_model = model self._itemsTableView.setModel(model) if model is not None: self.connect(model, QtCore.SIGNAL("modelReset()"), self._itemsTableView.resizeRowsToContents) self.connect(model, QtCore.SIGNAL("dataChanged(const QModelIndex&, const QModelIndex&)"), self._resize_row_to_contents) itemsTableModel = property(fget=__getTableModel, fset=__setTableModel) def update(self): self.query_exec() def query_exec(self): try: if self.__table_model is None: raise errors.MsgException(self.tr("Items Table Widget has no Model.")) query_text = self.query_text() limit = self.query_limit() page = self.query_page() self.__table_model.query(query_text, limit, page) self.resize_rows_to_contents() stats.sendEvent("items_table.query_exec") except Exception as ex: logger.warning(str(ex)) helpers.show_exc_info(self, ex) def query_reset(self): if self.__table_model is not None: self.__table_model.query("") self.query_text_reset() self.emit(QtCore.SIGNAL("queryTextResetted")) stats.sendEvent("items_table.query_reset") def query_text(self): return self.ui.lineEdit_query.text() def query_text_reset(self): self.ui.lineEdit_query.setText("") def set_tag_completer(self, completer): self.ui.lineEdit_query.set_completer(completer) def query_limit(self): return self.ui.spinBox_limit.value() def query_page(self): return self.ui.spinBox_page.value() def selectedRows(self): #We use set, because selectedIndexes() may return duplicates rows = set() for index in self._itemsTableView.selectionModel().selectedIndexes(): rows.add(index.row()) return rows def selectedItemIds(self): #We use set, because selectedIndexes() may return duplicates item_ids = set() for index in self._itemsTableView.selectionModel().selectedIndexes(): item_ids.add(self.__table_model.objAtRow(index.row()).id) return item_ids def itemAtRow(self, row): return self.__table_model.objAtRow(row) def rowCount(self): return self.__table_model.rowCount() def resetSingleRow(self, row): self.__table_model.resetRowRange(row, row) def resetRowRange(self, topRow, bottomRow): self.__table_model.resetRowRange(topRow, bottomRow) def selectedKeywordAll(self): self.ui.lineEdit_query.setText("ALL") self.query_exec() def selected_tags_changed(self, tags, not_tags): text = "" for tag in tags: text = text + tag + " " for tag in not_tags: text = text + query_tokens.NOT_OPERATOR + " " + tag + " " self.ui.lineEdit_query.setText(text) self.query_exec() def _resize_row_to_contents(self, top_left, bottom_right): if top_left.row() == bottom_right.row(): self._itemsTableView.resizeRowToContents(top_left.row()) elif top_left.row() < bottom_right.row(): for row in range(top_left.row(), bottom_right.row()): self._itemsTableView.resizeRowToContents(row) def resize_rows_to_contents(self): self._itemsTableView.resizeRowsToContents() def restoreColumnsWidth(self): self._itemsTableView.restoreColumnsWidth("items_table") def restoreColumnsVisibility(self): self._itemsTableView.restoreColumnsVisibility("items_table") def saveColumnsWidth(self): self._itemsTableView.saveColumnsWidth("items_table") def saveColumnsVisibility(self): self._itemsTableView.saveColumnsVisibility("items_table") def buildActions(self): if len(self.actions) > 0: logger.info("Actions already built") return self.actions['addItems'] = self._createAction(self.tr("Add items")) self.actions['editItem'] = self._createAction(self.tr("Edit item")) self.actions['rebuildItemsThumbnail'] = self._createAction(self.tr("Rebuild item's thumbnail")) self.actions['deleteItem'] = self._createAction(self.tr("Delete item")) self.actions['openItem'] = self._createAction(self.tr("Open item")) self.actions['openItemWithBuiltinImageViewer'] = self._createAction(self.tr("Open item with built-in Image Viewer")) self.actions['createM3uAndOpenIt'] = self._createAction(self.tr("Create m3u playlist and open it")) self.actions['openItemWithExternalFileManager'] = self._createAction(self.tr("Open containing directory")) self.actions['exportItems'] = self._createAction(self.tr("Export items")) self.actions['exportItemsFiles'] = self._createAction(self.tr("Export items' files")) self.actions['exportItemsFilePaths'] = self._createAction(self.tr("Export items' file paths")) self.actions['checkItemsIntegrity'] = self._createAction(self.tr("Check Item integrity")) self.actions['fixFileNotFoundTryFind'] = self._createAction(self.tr("Try find file")) self.actions['fixFileNotFoundRemoveDataRef'] = self._createAction(self.tr("Remove Item's reference to file")) self.actions['fixHashMismatchTryFind'] = self._createAction(self.tr("Try find file")) self.actions['fixHashMismatchUpdateHash'] = self._createAction(self.tr("Update file hash")) self.actions['itemsTableSettings'] = self._createAction(self.tr("Settings")) def buildMainMenu(self): assert len(self.actions) > 0, "Actions should be already built" if self._mainMenu is not None: logger.info("Main Menu of this Tool already built") return self._mainMenu = self._createMenu(self.tr("Items Table"), self) menu = self._mainMenu menu.addAction(self.actions['addItems']) menu.addSeparator() menu.addAction(self.actions['editItem']) menu.addAction(self.actions['rebuildItemsThumbnail']) menu.addSeparator() menu.addAction(self.actions['deleteItem']) menu.addSeparator() menu.addAction(self.actions['openItem']) menu.addAction(self.actions['openItemWithBuiltinImageViewer']) menu.addAction(self.actions['createM3uAndOpenIt']) menu.addAction(self.actions['openItemWithExternalFileManager']) menu.addSeparator() subMenuExport = self._createAndAddSubMenu(self.tr("Export"), self, menu) subMenuExport.addAction(self.actions['exportItems']) subMenuExport.addAction(self.actions['exportItemsFiles']) subMenuExport.addAction(self.actions['exportItemsFilePaths']) menu.addSeparator() menu.addAction(self.actions['checkItemsIntegrity']) subMenuFixFileNotFoundError = self._createAndAddSubMenu(self.tr("Fix File Not Found Error"), self, menu) subMenuFixFileNotFoundError.addAction(self.actions['fixFileNotFoundTryFind']) subMenuFixFileNotFoundError.addAction(self.actions['fixFileNotFoundRemoveDataRef']) subMenuFixHashMismatchError = self._createAndAddSubMenu(self.tr("Fix File Hash Mismatch Error"), self, menu) subMenuFixHashMismatchError.addAction(self.actions['fixHashMismatchTryFind']) subMenuFixHashMismatchError.addAction(self.actions['fixHashMismatchUpdateHash']) menu.addSeparator() menu.addAction(self.actions['itemsTableSettings']) def __buildContextMenu(self): if self.__context_menu is not None: logger.info("Context menu of this Tool already built") return self.__context_menu = self._createMenu(menuTitle=None, menuParent=self) menu = self.__context_menu menu.addAction(self.actions['openItem']) menu.addAction(self.actions['openItemWithBuiltinImageViewer']) menu.addAction(self.actions['createM3uAndOpenIt']) menu.addAction(self.actions['openItemWithExternalFileManager']) menu.addSeparator() menu.addAction(self.actions['editItem']) menu.addAction(self.actions['rebuildItemsThumbnail']) menu.addSeparator() menu.addAction(self.actions['deleteItem']) menu.addSeparator() subMenuExport = self._createAndAddSubMenu(self.tr("Export"), self, menu) subMenuExport.addAction(self.actions['exportItems']) subMenuExport.addAction(self.actions['exportItemsFiles']) subMenuExport.addAction(self.actions['exportItemsFilePaths']) menu.addSeparator() menu.addAction(self.actions['checkItemsIntegrity']) subMenuFixFileNotFoundError = self._createAndAddSubMenu(self.tr("Fix File Not Found Error"), self, menu) subMenuFixFileNotFoundError.addAction(self.actions['fixFileNotFoundTryFind']) subMenuFixFileNotFoundError.addAction(self.actions['fixFileNotFoundRemoveDataRef']) subMenuFixHashMismatchError = self._createAndAddSubMenu(self.tr("Fix File Hash Mismatch Error"), self, menu) subMenuFixHashMismatchError.addAction(self.actions['fixHashMismatchTryFind']) subMenuFixHashMismatchError.addAction(self.actions['fixHashMismatchUpdateHash']) def __initContextMenu(self): self.buildActions() self.__buildContextMenu() self.__addContextMenu() def __addContextMenu(self): assert self.__context_menu is not None, "Context menu is not built" self._itemsTableView.setContextMenuPolicy(Qt.CustomContextMenu) self.connect(self._itemsTableView, QtCore.SIGNAL("customContextMenuRequested(const QPoint &)"), self.showContextMenu) def showContextMenu(self, pos): self.__context_menu.exec_(self._itemsTableView.mapToGlobal(pos)) def dragEnterEvent(self, event): if event.mimeData().hasUrls: event.accept() else: event.ignore() def dropEvent(self, event): if not event.mimeData().hasUrls: event.ignore() return files = [] for url in event.mimeData().urls(): files.append(url.toLocalFile()) if len(files) <= 0: event.ignore() return event.accept() self.__itemsTableTool.acceptDropOfFilesAndDirs(files) def __onTableDoubleClicked(self, index): if not self.__table_model.isOpenItemActionAllowed(index): return action = self.actions['openItem'] action.trigger()
class ItemsTableGui(ToolGui): def __init__(self, parent, itemsTableTool): super(ItemsTableGui, self).__init__(parent) self.ui = Ui_ItemsTableGui() self.ui.setupUi(self) self._itemsTableView = UnivTableView(self) self.ui.tableViewContainer.addWidget(self._itemsTableView) self.__itemsTableTool = itemsTableTool #Widgets for text queries self.ui.lineEdit_query = TextEdit(self, one_line=True) tmp = QtGui.QHBoxLayout(self.ui.widget_lineEdit_query) tmp.addWidget(self.ui.lineEdit_query) self.connect(self.ui.pushButton_query_exec, QtCore.SIGNAL("clicked()"), self.query_exec) self.connect(self.ui.lineEdit_query, QtCore.SIGNAL("returnPressed()"), self.ui.pushButton_query_exec.click) self.connect(self.ui.pushButton_query_reset, QtCore.SIGNAL("clicked()"), self.query_reset) self.connect(self._itemsTableView, QtCore.SIGNAL("doubleClicked(const QModelIndex&)"), self.__onTableDoubleClicked) #TODO limit page function sometimes works not correct!!! It sometimes shows less items, than specified in limit spinbox! #Initialization of limit and page spinboxes self.ui.spinBox_limit.setValue( int(UserConfig().get("spinBox_limit.value", 0))) self.ui.spinBox_limit.setSingleStep( int(UserConfig().get("spinBox_limit.step", 5))) self.connect(self.ui.spinBox_limit, QtCore.SIGNAL("valueChanged(int)"), self.query_exec) self.connect( self.ui.spinBox_limit, QtCore.SIGNAL("valueChanged(int)"), lambda: UserConfig().store("spinBox_limit.value", self.ui.spinBox_limit.value())) self.connect(self.ui.spinBox_limit, QtCore.SIGNAL("valueChanged(int)"), lambda val: self.ui.spinBox_page.setEnabled(val > 0)) self.connect(self.ui.spinBox_page, QtCore.SIGNAL("valueChanged(int)"), self.query_exec) self.ui.spinBox_page.setEnabled(self.ui.spinBox_limit.value() > 0) self._itemsTableView.setSortingEnabled(True) self.__table_model = None self.__context_menu = None self.__initContextMenu() def __getTableModel(self): return self.__table_model def __setTableModel(self, model): self.__table_model = model self._itemsTableView.setModel(model) if model is not None: self.connect(model, QtCore.SIGNAL("modelReset()"), self._itemsTableView.resizeRowsToContents) self.connect( model, QtCore.SIGNAL( "dataChanged(const QModelIndex&, const QModelIndex&)"), self._resize_row_to_contents) itemsTableModel = property(fget=__getTableModel, fset=__setTableModel) def update(self): self.query_exec() def query_exec(self): try: if self.__table_model is None: raise errors.MsgException( self.tr("Items Table Widget has no Model.")) query_text = self.query_text() limit = self.query_limit() page = self.query_page() self.__table_model.query(query_text, limit, page) self.resize_rows_to_contents() stats.sendEvent("items_table.query_exec") except Exception as ex: logger.warning(str(ex)) helpers.show_exc_info(self, ex) def query_reset(self): if self.__table_model is not None: self.__table_model.query("") self.query_text_reset() self.emit(QtCore.SIGNAL("queryTextResetted")) stats.sendEvent("items_table.query_reset") def query_text(self): return self.ui.lineEdit_query.text() def query_text_reset(self): self.ui.lineEdit_query.setText("") def set_tag_completer(self, completer): self.ui.lineEdit_query.set_completer(completer) def query_limit(self): return self.ui.spinBox_limit.value() def query_page(self): return self.ui.spinBox_page.value() def selectedRows(self): #We use set, because selectedIndexes() may return duplicates rows = set() for index in self._itemsTableView.selectionModel().selectedIndexes(): rows.add(index.row()) return rows def selectedItemIds(self): #We use set, because selectedIndexes() may return duplicates item_ids = set() for index in self._itemsTableView.selectionModel().selectedIndexes(): item_ids.add(self.__table_model.objAtRow(index.row()).id) return item_ids def itemAtRow(self, row): return self.__table_model.objAtRow(row) def rowCount(self): return self.__table_model.rowCount() def resetSingleRow(self, row): self.__table_model.resetRowRange(row, row) def resetRowRange(self, topRow, bottomRow): self.__table_model.resetRowRange(topRow, bottomRow) def selectedKeywordAll(self): self.ui.lineEdit_query.setText("ALL") self.query_exec() def selected_tags_changed(self, tags, not_tags): text = "" for tag in tags: text = text + tag + " " for tag in not_tags: text = text + query_tokens.NOT_OPERATOR + " " + tag + " " self.ui.lineEdit_query.setText(text) self.query_exec() def _resize_row_to_contents(self, top_left, bottom_right): if top_left.row() == bottom_right.row(): self._itemsTableView.resizeRowToContents(top_left.row()) elif top_left.row() < bottom_right.row(): for row in range(top_left.row(), bottom_right.row()): self._itemsTableView.resizeRowToContents(row) def resize_rows_to_contents(self): self._itemsTableView.resizeRowsToContents() def restoreColumnsWidth(self): self._itemsTableView.restoreColumnsWidth("items_table") def restoreColumnsVisibility(self): self._itemsTableView.restoreColumnsVisibility("items_table") def saveColumnsWidth(self): self._itemsTableView.saveColumnsWidth("items_table") def saveColumnsVisibility(self): self._itemsTableView.saveColumnsVisibility("items_table") def buildActions(self): if len(self.actions) > 0: logger.info("Actions already built") return self.actions['addItems'] = self._createAction(self.tr("Add items")) self.actions['editItem'] = self._createAction(self.tr("Edit item")) self.actions['rebuildItemsThumbnail'] = self._createAction( self.tr("Rebuild item's thumbnail")) self.actions['deleteItem'] = self._createAction(self.tr("Delete item")) self.actions['openItem'] = self._createAction(self.tr("Open item")) self.actions['openItemWithBuiltinImageViewer'] = self._createAction( self.tr("Open item with built-in Image Viewer")) self.actions['createM3uAndOpenIt'] = self._createAction( self.tr("Create m3u playlist and open it")) self.actions['openItemWithExternalFileManager'] = self._createAction( self.tr("Open containing directory")) self.actions['exportItems'] = self._createAction( self.tr("Export items")) self.actions['exportItemsFiles'] = self._createAction( self.tr("Export items' files")) self.actions['exportItemsFilePaths'] = self._createAction( self.tr("Export items' file paths")) self.actions['checkItemsIntegrity'] = self._createAction( self.tr("Check Item integrity")) self.actions['fixFileNotFoundTryFind'] = self._createAction( self.tr("Try find file")) self.actions['fixFileNotFoundRemoveDataRef'] = self._createAction( self.tr("Remove Item's reference to file")) self.actions['fixHashMismatchTryFind'] = self._createAction( self.tr("Try find file")) self.actions['fixHashMismatchUpdateHash'] = self._createAction( self.tr("Update file hash")) self.actions['itemsTableSettings'] = self._createAction( self.tr("Settings")) def buildMainMenu(self): assert len(self.actions) > 0, "Actions should be already built" if self._mainMenu is not None: logger.info("Main Menu of this Tool already built") return self._mainMenu = self._createMenu(self.tr("Items Table"), self) menu = self._mainMenu menu.addAction(self.actions['addItems']) menu.addSeparator() menu.addAction(self.actions['editItem']) menu.addAction(self.actions['rebuildItemsThumbnail']) menu.addSeparator() menu.addAction(self.actions['deleteItem']) menu.addSeparator() menu.addAction(self.actions['openItem']) menu.addAction(self.actions['openItemWithBuiltinImageViewer']) menu.addAction(self.actions['createM3uAndOpenIt']) menu.addAction(self.actions['openItemWithExternalFileManager']) menu.addSeparator() subMenuExport = self._createAndAddSubMenu(self.tr("Export"), self, menu) subMenuExport.addAction(self.actions['exportItems']) subMenuExport.addAction(self.actions['exportItemsFiles']) subMenuExport.addAction(self.actions['exportItemsFilePaths']) menu.addSeparator() menu.addAction(self.actions['checkItemsIntegrity']) subMenuFixFileNotFoundError = self._createAndAddSubMenu( self.tr("Fix File Not Found Error"), self, menu) subMenuFixFileNotFoundError.addAction( self.actions['fixFileNotFoundTryFind']) subMenuFixFileNotFoundError.addAction( self.actions['fixFileNotFoundRemoveDataRef']) subMenuFixHashMismatchError = self._createAndAddSubMenu( self.tr("Fix File Hash Mismatch Error"), self, menu) subMenuFixHashMismatchError.addAction( self.actions['fixHashMismatchTryFind']) subMenuFixHashMismatchError.addAction( self.actions['fixHashMismatchUpdateHash']) menu.addSeparator() menu.addAction(self.actions['itemsTableSettings']) def __buildContextMenu(self): if self.__context_menu is not None: logger.info("Context menu of this Tool already built") return self.__context_menu = self._createMenu(menuTitle=None, menuParent=self) menu = self.__context_menu menu.addAction(self.actions['openItem']) menu.addAction(self.actions['openItemWithBuiltinImageViewer']) menu.addAction(self.actions['createM3uAndOpenIt']) menu.addAction(self.actions['openItemWithExternalFileManager']) menu.addSeparator() menu.addAction(self.actions['editItem']) menu.addAction(self.actions['rebuildItemsThumbnail']) menu.addSeparator() menu.addAction(self.actions['deleteItem']) menu.addSeparator() subMenuExport = self._createAndAddSubMenu(self.tr("Export"), self, menu) subMenuExport.addAction(self.actions['exportItems']) subMenuExport.addAction(self.actions['exportItemsFiles']) subMenuExport.addAction(self.actions['exportItemsFilePaths']) menu.addSeparator() menu.addAction(self.actions['checkItemsIntegrity']) subMenuFixFileNotFoundError = self._createAndAddSubMenu( self.tr("Fix File Not Found Error"), self, menu) subMenuFixFileNotFoundError.addAction( self.actions['fixFileNotFoundTryFind']) subMenuFixFileNotFoundError.addAction( self.actions['fixFileNotFoundRemoveDataRef']) subMenuFixHashMismatchError = self._createAndAddSubMenu( self.tr("Fix File Hash Mismatch Error"), self, menu) subMenuFixHashMismatchError.addAction( self.actions['fixHashMismatchTryFind']) subMenuFixHashMismatchError.addAction( self.actions['fixHashMismatchUpdateHash']) def __initContextMenu(self): self.buildActions() self.__buildContextMenu() self.__addContextMenu() def __addContextMenu(self): assert self.__context_menu is not None, "Context menu is not built" self._itemsTableView.setContextMenuPolicy(Qt.CustomContextMenu) self.connect( self._itemsTableView, QtCore.SIGNAL("customContextMenuRequested(const QPoint &)"), self.showContextMenu) def showContextMenu(self, pos): self.__context_menu.exec_(self._itemsTableView.mapToGlobal(pos)) def dragEnterEvent(self, event): if event.mimeData().hasUrls: event.accept() else: event.ignore() def dropEvent(self, event): if not event.mimeData().hasUrls: event.ignore() return files = [] for url in event.mimeData().urls(): files.append(url.toLocalFile()) if len(files) <= 0: event.ignore() return event.accept() self.__itemsTableTool.acceptDropOfFilesAndDirs(files) def __onTableDoubleClicked(self, index): if not self.__table_model.isOpenItemActionAllowed(index): return action = self.actions['openItem'] action.trigger()