# Source code for enaml.widgets.file_dialog_ex

    #------------------------------------------------------------------------------
    # Copyright (c) 2013-2025, Nucleic Development Team.
    #
    # Distributed under the terms of the Modified BSD License.
    #
    # The full license is in the file LICENSE, distributed with this software.
    #------------------------------------------------------------------------------
    from atom.api import Bool, Enum, List, Str, Typed, ForwardTyped

    from enaml.core.declarative import d_, observe

    from .toolkit_dialog import ToolkitDialog, ProxyToolkitDialog

    class ProxyFileDialogEx(ProxyToolkitDialog):
        """ The abstract definition of a proxy FileDialogEx object.

        """
        #: A reference to the FileDialog declaration.
        declaration = ForwardTyped(lambda: FileDialogEx)

        def set_accept_mode(self, accept_mode):
            raise NotImplementedError

        def set_file_mode(self, file_mode):
            raise NotImplementedError

        def set_show_dirs_only(self, show):
            raise NotImplementedError

        def set_current_path(self, path):
            raise NotImplementedError

        def set_name_filters(self, filters):
            raise NotImplementedError

        def set_selected_name_filter(self, selected):
            raise NotImplementedError

        def exec_native(self):
            raise NotImplementedError

    class FileDialogEx(ToolkitDialog):
        """ A toolkit dialog for getting file and directory names.

        This dialog supercedes the FileDialog class. New code you should
        use this dialog in lieu of the older version.

        """
        #: The accept mode of the dialog.
        accept_mode = d_(Enum('open', 'save'))

        #: The file mode of the dialog.
        file_mode = d_(Enum(
            'any_file', 'existing_file', 'existing_files', 'directory'))

        #: Whether or not to only show directories. This is only valid when
        #: the file_mode is set to 'directory'.
        show_dirs_only = d_(Bool(False))

        #: The currently selected path in the dialog.
        current_path = d_(Str())

        #: The paths selected by the user when the dialog is accepted.
        #: This value is output only.
        selected_paths = List(Str())

        #: The name filters used to restrict the available files.
        name_filters = d_(List(Str()))

        #: The selected name filter from the list of name filters.
        selected_name_filter = d_(Str())

        #: A reference to the ProxyFileDialog object.
        proxy = Typed(ProxyFileDialogEx)

        @staticmethod
        def get_existing_directory(parent=None, **kwargs):
            """ Get an existing directory on the filesystem.

            Parameters
            ----------
            parent : ToolkitObject or None
                The parent toolkit object for this dialog.

            **kwargs
                Additional data to pass to the dialog constructor.

            Returns
            -------
            result : unicode
                The user selected directory path. This will be an empty
                string if no directory was selected.

            """
            kwargs['accept_mode'] = 'open'
            kwargs['file_mode'] = 'directory'
            kwargs['show_dirs_only'] = True
            dialog = FileDialogEx(parent, **kwargs)
            if dialog.exec_native():
                if dialog.selected_paths:
                    return dialog.selected_paths[0]
            return ''

        @staticmethod
        def get_open_file_name(parent=None, **kwargs):
            """ Get the file name for an open file dialog.

            Parameters
            ----------
            parent : ToolkitObject or None
                The parent toolkit object for this dialog.

            **kwargs
                Additional data to pass to the dialog constructor.

            Returns
            -------
            result : unicode
                The user selected file name. This will be an empty
                string if no file name was selected.

            """
            kwargs['accept_mode'] = 'open'
            kwargs['file_mode'] = 'existing_file'
            dialog = FileDialogEx(parent, **kwargs)
            if dialog.exec_native():
                if dialog.selected_paths:
                    return dialog.selected_paths[0]
            return ''

        @staticmethod
        def get_open_file_names(parent=None, **kwargs):
            """ Get the file names for an open files dialog.

            Parameters
            ----------
            parent : ToolkitObject or None
                The parent toolkit object for this dialog.

            **kwargs
                Additional data to pass to the dialog constructor.

            Returns
            -------
            result : list
                The user selected file names. This will be an empty
                list if no file names were selected.

            """
            kwargs['accept_mode'] = 'open'
            kwargs['file_mode'] = 'existing_files'
            dialog = FileDialogEx(parent, **kwargs)
            if dialog.exec_native():
                return dialog.selected_paths
            return []

        @staticmethod
        def get_save_file_name(parent=None, **kwargs):
            """ Get the file name for a save file dialog.

            Parameters
            ----------
            parent : ToolkitObject or None
                The parent toolkit object for this dialog.

            **kwargs
                Additional data to pass to the dialog constructor.

            Returns
            -------
            result : unicode
                The user selected file name. This will be an empty
                string if no file name was selected.

            """
            kwargs['accept_mode'] = 'save'
            kwargs['file_mode'] = 'any_file'
            dialog = FileDialogEx(parent, **kwargs)
            if dialog.exec_native():
                if dialog.selected_paths:
                    return dialog.selected_paths[0]
            return ''

        def exec_native(self):
            """ Open the dialog using a native OS dialog if available.

            Returns
            -------
            result : bool
                Whether or not the dialog was accepted.

            """
            if not self.is_initialized:
                self.initialize()
            if not self.proxy_is_active:
                self.activate_proxy()
            self._prepare()
            self.proxy.exec_native()
            return self.result

        #--------------------------------------------------------------------------
        # Observers
        #--------------------------------------------------------------------------
        @observe('accept_mode', 'file_mode', 'show_dirs_only', 'current_path',
            'name_filters', 'selected_name_filter')
        def _update_proxy(self, change):
            """ An observer which updates the proxy when the data changes.

            """
            # The superclass implementation is sufficient.
            super(FileDialogEx, self)._update_proxy(change)

        #--------------------------------------------------------------------------
        # Utility Methods
        #--------------------------------------------------------------------------
        def _prepare(self):
            """ A reimplemented preparation method.

            This method resets the selected paths and filters.

            """
            super(FileDialogEx, self)._prepare()
            self.selected_paths = []
            self.selected_name_filter = ''