Example #1
0
class SelectFileDialog(QDialog, BaseUI):
    """
    A dialog allowing the user to select a file. Files can be
    selected via drag-and-drop, or by browsing with the file
    explorer.
    """
    def __init__(self):
        self.file: str = None
        self.combo_recent: QComboBox = None
        self.settings = Settings()
        super().__init__()

    def setup_ui(self):
        uic.loadUi(resources.get("layout:dialog_select_file.ui"), self)
        self.setup_drops()
        self.setup_recent_files()

        self.btn_browse.clicked.connect(self.browse_for_file)
        self.btn_use_recent.clicked.connect(self.use_recent_file)

        QTimer.singleShot(500, self.check_args)

    def get_result(self) -> str:
        """
        Shows the dialog and returns the path to the file chosen by the user.
        """
        self.exec()
        self.settings.add_recent_file(self.file)
        return self.get_file_path()

    def check_args(self):
        """
        Check the commandline arguments in case there is
        a pre-selected file.
        """
        file = args.args_file()
        if file:
            self.file = resources.get(file)
            self.accept()  # Close dialog.

    def setup_drops(self):
        """Sets up the label to accept drag-and-drop."""
        drop_target = self.lbl_drag_drop
        drop_target.setAcceptDrops(True)
        drop_target.set_drop_callback(self.on_drop)

    def browse_for_file(self):
        """Opens a file browser dialog for selecting a file."""
        dialog = QFileDialog()
        dialog.setFileMode(QFileDialog.AnyFile)

        if dialog.exec():
            filenames = dialog.selectedFiles()
            self.file = filenames[0]
            self.lbl_drag_drop.show_selected_file(self.file)

            if self.file:
                self.disable_recent_files()

    def setup_recent_files(self):
        files = self.settings.get_recent_files()
        if files:
            self.combo_recent.addItems(files)
        else:
            self.disable_recent_files()

    def use_recent_file(self):
        file = self.combo_recent.currentText()
        self.file = file
        self.accept()  # Close the dialog.

    def on_drop(self, file: str):
        if not file:
            raise Exception(
                "Cannot load file: ''. This may be an issue specific to your OS."
            )

        self.disable_recent_files()
        self.file = file

    def disable_recent_files(self):
        """
        Disables the UI for selecting a recent file, since it may cause users to erroneously
        use a recent file instead of the file chosen in the GUI.
        """
        self.btn_use_recent.setDisabled(True)
        self.combo_recent.setDisabled(True)

    def get_file_path(self):
        """Gets the file path for the selected file."""
        return resources.path_from_file_string(self.file)
Example #2
0
class SelectFileDialog(QDialog, BaseUI):
    """
    A dialog allowing the user to select a file. Files can be
    selected via drag-and-drop, or by browsing with the file
    explorer.
    """
    def __init__(self):
        self.file: str = None
        self.settings = Settings()

        self.combo_recent: QComboBox = None
        self.buttonBox: QDialogButtonBox = None

        super().__init__()
        self.use_shortcut = UseShortcutComponent(self, self.use_recent_file)

    def setup_ui(self):
        uic.loadUi(resources.get("layout:dialog_select_file.ui"), self)
        self.setup_drops()
        self.setup_recent_files()

        self.btn_browse.clicked.connect(self.browse_for_file)
        self.btn_use_recent.clicked.connect(self.use_recent_file)

        self.set_ok_enabled(False)

        QTimer.singleShot(500, self.check_args)

    def get_result(self) -> str:
        """
        Shows the dialog and returns the path to the file chosen by the user.
        """
        self.exec()
        self.settings.add_recent_file(self.file)
        return self.get_file_path()

    def check_args(self):
        """
        Check the commandline arguments in case there is
        a pre-selected file.
        """
        file = args.args_file()
        if file:
            self.file = resources.get(file)
            self.accept()  # Close dialog.

    def setup_drops(self):
        """Sets up the label to accept drag-and-drop."""
        drop_target = self.lbl_drag_drop
        drop_target.setAcceptDrops(True)
        drop_target.set_drop_callback(self.on_drop)

    def browse_for_file(self):
        """Opens a file browser dialog for selecting a file."""
        dialog = QFileDialog()
        dialog.setFileMode(QFileDialog.AnyFile)

        folder = self.settings.get_last_opened_directory()
        if not folder:
            folder = join(os.getcwd(), "res", "data")

        dialog.setDirectory(folder)

        if dialog.exec():
            filepath = dialog.selectedFiles()[0]

            directory, filename = os.path.split(filepath)
            self.settings.set_last_opened_directory(directory)

            self.set_file(filepath)
            self.lbl_drag_drop.show_selected_file(self.file)

            if self.file:
                self.disable_recent_files()

    def setup_recent_files(self):
        files = self.settings.get_recent_files()
        if files:
            self.combo_recent.addItems(files)
        else:
            self.disable_recent_files()

    def use_recent_file(self):
        file = self.combo_recent.currentText()
        self.file = file
        self.accept()  # Close the dialog.

    def on_drop(self, file: str):
        if not file:
            raise Exception(
                f"Cannot load file: '{file}'. This may be an issue specific to drag-and-drop on your OS."
            )

        self.disable_recent_files()
        self.set_file(file)

    def set_file(self, file: str) -> None:
        self.file = file
        self.set_ok_enabled(bool(file))

    def disable_recent_files(self):
        """
        Disables the UI for selecting a recent file, since it may cause users to erroneously
        use a recent file instead of the file chosen in the GUI.
        """
        self.btn_use_recent.setDisabled(True)
        self.combo_recent.setDisabled(True)

    def set_ok_enabled(self, enabled: bool) -> None:
        """
        Sets the "ok" button in the dialog as enabled or disabled.

        :param enabled: whether to set the button as enabled, not disabled
        """
        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled)

    def get_file_path(self):
        """Gets the file path for the selected file."""
        return resources.path_from_file_string(self.file)