class SideView(QObject): onBeforeItemDeletion = pyqtSignal(str) onEntrySelected = pyqtSignal(str) onDirectoryChanged = pyqtSignal(str) onRemoveRequested = pyqtSignal(str) def __init__(self, dirLister, entryProvider: IEntryProvider, newEntryText: str, itemNameNormalizer: IItemNameNormalizer): super().__init__() def initListView(): self.listView = QListView() self.listView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.listView.setModel(self.model) self.listView.setMinimumWidth(200) actionRemove = QAction("Remove", None) self.listView.addAction(actionRemove) self.listView.selectionModel().currentChanged.connect( lambda selectedItem, unselectedItem: self.onEntrySelected.emit( self.itemNameNormalizer.normalizeName( self.currentDir.filePath(selectedItem.data())))) def contextMenu(position): menu = QMenu() index = self.listView.indexAt(position) entry = self.model.data(index, Qt.DisplayRole) deleteAction = None renameAction = None addAction = menu.addAction("Add") if entry is not None: deleteAction = menu.addAction("Delete") renameAction = menu.addAction("Rename") refreshAction = menu.addAction("Refresh") chosenAction = menu.exec_(self.listView.mapToGlobal(position)) if chosenAction is None: return if chosenAction == deleteAction: self.onRemoveRequested.emit(entry) elif chosenAction == renameAction: self.renameEntry(index, entry) elif chosenAction == addAction: self.onCreateNewEntry() elif chosenAction == refreshAction: self.refreshListViewEntries() self.listView.customContextMenuRequested.connect(contextMenu) self.listView.setContextMenuPolicy(Qt.CustomContextMenu) self.currentDir: QDir = None self.model = QStringListModel() self.directoryLister = dirLister self.entryProvider = entryProvider self.newEntryText = newEntryText self.itemNameNormalizer = itemNameNormalizer self.sortingParser: IEntrySorting initListView() def renameEntry(self, index, oldName): def onNewEntryCommited(editedLine: QLineEdit): self.listView.itemDelegate().commitData.disconnect( onNewEntryCommited) try: newName = editedLine.text() normalizedNameOld = self.itemNameNormalizer.normalizeName( oldName) normalizedNameNew = self.itemNameNormalizer.normalizeName( newName) self.emitOnItemDeletion(normalizedNameOld) self.entryProvider.renameEnty(normalizedNameOld, normalizedNameNew) self.sortingParser.rename(oldName, newName) self.refreshListViewEntries() except Exception: pass self.listView.itemDelegate().commitData.connect(onNewEntryCommited) self.listView.edit(index) def emitOnItemDeletion(self, normalizedName): self.onBeforeItemDeletion.emit( self.currentDir.filePath(normalizedName)) def removeEntry(self, entry): normalizedName = self.itemNameNormalizer.normalizeName(entry) self.emitOnItemDeletion(normalizedName) self.entryProvider.removeEntry(normalizedName) self.refreshListViewEntries() def setDirectory(self, dirPath: str): self.currentDir = QDir(dirPath) self.sortingParser = EntrySortingFile( self.currentDir.filePath('.sorting')) self.entryProvider.setContext(dirPath) self.refreshListViewEntries() self.onDirectoryChanged.emit(self.currentDir.absolutePath()) def refreshListViewEntries(self): if self.currentDir is None: return entries = self.directoryLister.listEntries(self.currentDir) sortedEntries = self.sortingParser.getSortedList(entries) self.model.setStringList(sortedEntries) def onCreateNewEntry(self): def onNewEntryCommited(editedLine: QLineEdit): self.listView.itemDelegate().commitData.disconnect( onNewEntryCommited) try: if editedLine.text() == self.newEntryText: raise Exception() normalizedName = self.itemNameNormalizer.normalizeName( editedLine.text()) self.entryProvider.addEntry(normalizedName) self.refreshListViewEntries() self.listView.setCurrentIndex(index) except Exception: print(f"Error adding entry {editedLine.text()}", file=sys.stderr) self.model.removeRow(self.model.rowCount() - 1) if not self.model.insertRow(self.model.rowCount()): return self.listView.itemDelegate().commitData.connect(onNewEntryCommited) index = self.model.index(self.model.rowCount() - 1, 0) self.model.setData(index, self.newEntryText) self.listView.edit(index) pass
class FITSBrowse(QMainWindow): """ The main window of this GUI.""" imdisp = None def __init__(self, parent=None): """ """ print("Skeet") super(FITSBrowse, self).__init__(parent) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setWindowTitle("FITSBrowse") self.current_directory = CurrentDirectory( "/data/lemi-archive-2016-04/20160427") self.model = FitsFileTableModel(self.current_directory) self.d_model = DirectoryListModel(self.current_directory) self.main_widget = QWidget(self) self.dir_text = "Current Directory: {0}".format( self.current_directory.cur_dir_path) self.cur_dir_label = QLabel(self.dir_text, self) self.listLabel = QLabel("&Directories") self.list_view = QListView() self.listLabel.setBuddy(self.list_view) self.list_view.setModel(self.d_model) self.list_view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) self.list_view.setMinimumWidth(self.list_view.sizeHintForColumn(0)) self.list_view.setMaximumWidth(self.list_view.sizeHintForColumn(0)) self.list_view_sm = self.list_view.selectionModel() self.list_view.doubleClicked.connect(self.change_directory) self.table_view = QTableView() self.table_view.setModel(self.model) self.table_view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) self.table_view_sm = self.table_view.selectionModel() self.table_view.doubleClicked.connect(self.display_image) list_vbox = QVBoxLayout() list_vbox.addWidget(self.listLabel) list_vbox.addWidget(self.list_view) self.list_widget = QWidget() self.list_widget.setLayout(list_vbox) #self.list_view.size main_layout = QHBoxLayout() main_layout.addWidget(self.list_widget) main_layout.addWidget(self.table_view) button_layout = QHBoxLayout() quit_button = QPushButton('Quit', self) quit_button.setToolTip('This button quits FITSBrowse') quit_button.clicked.connect(QApplication.instance().quit) button_layout.addStretch() button_layout.addWidget(quit_button) sep_line = QFrame() sep_line.setFrameShape(QFrame.HLine) super_layout = QVBoxLayout(self.main_widget) super_layout.addWidget(self.cur_dir_label) super_layout.addWidget(sep_line) super_layout.addLayout(main_layout) super_layout.addLayout(button_layout) self.setCentralWidget(self.main_widget) QtCore.QTimer.singleShot(0, self.initialLoad) x = self.table_view.frameSize() x = x.width() self.table_view.setMinimumWidth(x) self.main_widget.setMinimumHeight(500) def initialLoad(self): for column in (1, 2, 3, 4, 5, 6, 7): self.table_view.resizeColumnToContents(column) def display_image(self): indexes = self.table_view_sm.selectedIndexes() index = indexes[0] file_name = str(index.data()) if (file_name.endswith("fits") or file_name.endswith("fit")): file_with_path = os.path.join(self.current_directory.cur_dir_path, file_name) self.im_disp = ImageAnalyzer(file_with_path, parent=self) def change_directory(self): indexes = self.list_view_sm.selectedRows() if (indexes != []): index = indexes[0] new_directory = str(index.data()) current_path = self.current_directory.cur_dir_path if (new_directory == ".."): # Go up one directory if (current_path == "/"): # Do nothing. pass else: self.current_directory = CurrentDirectory( os.path.dirname(current_path)) else: # Go down into the selected directory. self.current_directory = CurrentDirectory( os.path.join(current_path, new_directory)) print("change directory, new directory is:", self.current_directory.cur_dir_path) self.model = FitsFileTableModel(self.current_directory) self.d_model = DirectoryListModel(self.current_directory) self.dir_text = "Current Directory: {0}".format( self.current_directory.cur_dir_path) self.cur_dir_label.setText(self.dir_text) self.list_view.setModel(self.d_model) self.list_view_sm = self.list_view.selectionModel() self.list_view.update() self.list_view.setMinimumWidth(self.list_view.sizeHintForColumn(0)) self.list_view.setMaximumWidth(self.list_view.sizeHintForColumn(0)) self.table_view.setModel(self.model) self.table_view_sm = self.table_view.selectionModel() self.table_view.update() QtCore.QTimer.singleShot(0, self.initialLoad) x = self.table_view.frameSize() x = x.width() self.table_view.setMinimumWidth(x) else: print("no directory selected")