import sys import os from typing import Hashable from PyQt5.QtWidgets import QFileDialog, QFrame, QLabel, QListWidget, QMainWindow, QMenuBar, QStackedLayout, QToolBar, QAction, QStatusBar, QVBoxLayout, QWidget, QGridLayout, QSpacerItem, QSizePolicy from PyQt5.QtGui import QIcon, QPixmap, QKeySequence from PyQt5.QtCore import Qt, QSize, QSettings from numpy import unique from file_handler import FileHandler import constants as cnst class NixView(QMainWindow): def __init__(self, *args, **kwargs): super(NixView, self).__init__(*args, **kwargs) self.setWindowTitle("NixView") self.setWindowIcon(QIcon('./icons/nixview.icns')) self._file_handler = FileHandler() self.setStatusBar(QStatusBar(self)) self.setMenuBar(QMenuBar(self)) self.create_actions() self._cw = CentralWidget(self) self.setCentralWidget(self._cw) self.show() def create_actions(self): self._file_open_action = QAction(QIcon("./icons/nix_open.png"), "Open", self) self._file_open_action.setStatusTip("Open nix file") self._file_open_action.setShortcut(QKeySequence("Ctrl+o")) self._file_open_action.triggered.connect(self.on_file_open) self._file_close_action = QAction(QIcon("./icons/nix_close.png"), "Close", self) self._file_close_action.setStatusTip("Close current nix file") self._file_close_action.setShortcut(QKeySequence("Ctrl+w")) self._file_close_action.setEnabled(False) self._file_close_action.triggered.connect(self.on_file_close) self._quit_action = QAction(QIcon("./icons/quit.png"), "Quit", self) self._quit_action.setStatusTip("Close current file and quit") self._quit_action.triggered.connect(self.on_quit) self.create_toolbar() self.create_menu() def create_toolbar(self): self._toolbar = QToolBar("My main toolbar") self._toolbar.setIconSize(QSize(32, 32)) self._toolbar.addAction(self._file_open_action) self._toolbar.addAction(self._file_close_action) self._toolbar.addAction(self._quit_action) self.addToolBar(self._toolbar) def create_menu(self): menu = self.menuBar() file_menu = menu.addMenu("&File") file_menu.addAction(self._file_open_action) file_menu.addAction(self._file_close_action) file_menu.addAction(self._quit_action) self.setMenuBar(menu) def _update_recent_files(self, filename): settings = QSettings(cnst.organization, cnst.application) recent_file_max_count = settings.value(cnst.settings_recent_file_max_count_key, 10, type=int) filenames = settings.value(cnst.settings_recent_files_key, []) new_filenames = [filename] if len(filenames) < recent_file_max_count: new_filenames.extend(filenames) else: new_filenames.extend(filenames[:-1]) new_filenames = list(unique(new_filenames)) settings.setValue(cnst.settings_recent_files_key, new_filenames) del settings def on_file_open(self, s): dlg = QFileDialog(self, 'Open nix data file', '', "NIX files (*.h5 *.nix)") dlg.setFileMode(QFileDialog.ExistingFile) filenames = None if dlg.exec_(): filenames = dlg.selectedFiles() success, msg = self._file_handler.open(filenames[0]) self.statusBar().showMessage(msg, 5000) if success: self._file_close_action.setEnabled(success) self._cw.show_file_content() self._update_recent_files(filenames[0]) def on_file_close(self, s): self._file_handler.close() self._cw.reset() self._file_close_action.setEnabled(False) self.statusBar().showMessage("Successfully closed current file", 1000) def on_quit(self, s): self._file_handler.close() sys.exit() class CentralWidget(QWidget): def __init__(self, parent=None) -> None: super().__init__(parent=parent) splash = SplashScreen() self._file_view = FileView(self) self._stack = QStackedLayout(self) self._stack.addWidget(splash) self._stack.addWidget(self._file_view) self.setLayout(self._stack) self.setStyleSheet("background-color: white;") def show_file_content(self): self._stack.setCurrentIndex(1) def reset(self): self._file_view.reset() self._stack.setCurrentIndex(0) class FileView(QWidget): def __init__(self, parent=None) -> None: super().__init__(parent=parent) self.setLayout(QVBoxLayout()) self.layout().addWidget(QLabel("FileView")) self._file_handler = FileHandler() def reset(self): print("FileView ", self._file_handler.is_valid) pass class SplashScreen(QWidget): def __init__(self, parent=None) -> None: super().__init__(parent=parent) layout = QGridLayout() self.setLayout(layout) self.setStyleSheet("background-color: white;") label = QLabel() label.setPixmap(QPixmap("./icons/nixview256.png")) label.setAlignment(Qt.AlignCenter) layout.addWidget(label, 1, 1) verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) verticalSpacer2 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) hSpacer = QSpacerItem(400, 20, QSizePolicy.Maximum, QSizePolicy.Expanding) hSpacer2 = QSpacerItem(400, 20, QSizePolicy.Maximum, QSizePolicy.Expanding) layout.addItem(verticalSpacer, 0, 1) layout.addItem(verticalSpacer2, 2, 1) layout.addItem(hSpacer, 1, 0) layout.addItem(hSpacer2, 1, 2) frame = QFrame() l = QVBoxLayout() l.addWidget(QLabel("Recently opened files:")) self._file_list = QListWidget(self) self._file_list.itemClicked.connect(self._on_file_clicked) self._file_list.itemDoubleClicked.connect(self._on_file_clicked) l.addWidget(self._file_list) frame.setLayout(l) layout.addWidget(frame, 3, 1) self._file_map = {} self._read_recent_files() def _create_short_filename(original, max_len=40): short = original parts = original.split(os.sep) print(parts) return short def _read_recent_files(self): settings = QSettings(cnst.organization, cnst.application) filenames = settings.value(cnst.settings_recent_files_key, []) del settings for f in filenames: shortname = _create_short_filename(f, max_len=40) self._file_map[f] =shortname self._file_list.addItem(self._file_map[f]) def _on_file_clicked(self, s): print(s)