예제 #1
0
 def pick_output_dir(self):
     '''
     Sets the output directory.
     '''
     dialog = QFileDialog(parent=self)
     dialog.setFileMode(QFileDialog.DirectoryOnly)
     dialog.setOption(QFileDialog.ShowDirsOnly)
     dialog.setWindowTitle(
         'Select a location to store the generated dsp config files')
     if dialog.exec():
         selected = dialog.selectedFiles()
         if len(selected) > 0:
             if os.path.abspath(selected[0]) == os.path.abspath(
                     self.__beq_dir):
                 warning = f"Output directory cannot be inside the input directory, choose a different folder"
                 QMessageBox.critical(self, '', warning, QMessageBox.Ok)
             else:
                 suffix = 'minidsp' if DspType.parse(
                     self.dspType.currentText()).is_minidsp else 'config'
                 abspath = os.path.abspath(
                     f"{selected[0]}{os.path.sep}beq_{suffix}")
                 if not os.path.exists(abspath):
                     try:
                         os.mkdir(abspath)
                     except:
                         QMessageBox.critical(
                             self, '',
                             f"Unable to create directory - {abspath}",
                             QMessageBox.Ok)
                 if os.path.exists(abspath):
                     self.outputDirectory.setText(abspath)
     self.__enable_process()
예제 #2
0
    def select_file(self):
        dial = QFileDialog()
        dial.setFileMode(QFileDialog.ExistingFile)
        dial.setAcceptMode(QFileDialog.AcceptOpen)

        if dial.exec_():
            self.first_text.setText(dial.selectedFiles()[0])
예제 #3
0
 def select_files(self):
     dial = QFileDialog(self, "Select files")
     dial.setDirectory(
         self.settings.get(
             "io.batch_directory",
             self.settings.get("io.load_image_directory",
                               str(Path.home()))))
     dial.setFileMode(QFileDialog.ExistingFiles)
     if dial.exec_():
         self.settings.set("io.batch_directory",
                           os.path.dirname(str(dial.selectedFiles()[0])))
         new_paths = sorted(
             set(map(str, dial.selectedFiles())) - self.files_to_proceed)
         for path in new_paths:
             self.selected_files.addItem(FileListItem(path))
         self.files_to_proceed.update(new_paths)
         self.file_list_changed.emit(self.files_to_proceed)
예제 #4
0
 def select_manual_output_folder(self):
     # _current_folder = self.main_window.current_folder
     dlg = QFileDialog(parent=self.main_window,
                       caption="Select or Define Output Directory")
     dlg.setFileMode(QFileDialog.Directory)
     if dlg.exec_():
         output_folder_name = str(dlg.selectedFiles()[0])
         self.main_window.autonom_ui.manual_output_folder_field.setText(output_folder_name)
예제 #5
0
 def showDefaultOutputDirectoryPicker(self):
     dialog = QFileDialog(parent=self)
     dialog.setFileMode(QFileDialog.DirectoryOnly)
     dialog.setWindowTitle(f"Select Extract Audio Output Directory")
     if dialog.exec():
         selected = dialog.selectedFiles()
         if len(selected) > 0:
             self.defaultOutputDirectory.setText(selected[0])
예제 #6
0
 def choose_data_prefix(self):
     dial = QFileDialog()
     dial.setAcceptMode(QFileDialog.AcceptOpen)
     dial.setFileMode(QFileDialog.Directory)
     dial.setDirectory(self.base_prefix.text())
     dial.setHistory(dial.history() + self.settings.get_path_history())
     if dial.exec_():
         dir_path = str(dial.selectedFiles()[0])
         self.base_prefix.setText(dir_path)
예제 #7
0
 def __select_dir(self):
     dialog = QFileDialog(parent=self)
     dialog.setFileMode(QFileDialog.DirectoryOnly)
     dialog.setWindowTitle('Select Directory')
     if dialog.exec():
         selected = dialog.selectedFiles()
         if len(selected) > 0:
             return selected[0]
     return ''
예제 #8
0
 def selectFile(self):
     self.__reinit_fields()
     dialog = QFileDialog(parent=self)
     dialog.setFileMode(QFileDialog.ExistingFile)
     dialog.setWindowTitle('Select Audio or Video File')
     if dialog.exec():
         selected = dialog.selectedFiles()
         if len(selected) > 0:
             self.inputFile.setText(selected[0])
             self.__probe_file()
예제 #9
0
 def showBeqDirectoryPicker(self):
     ''' selects an output directory for the beq files '''
     dialog = QFileDialog(parent=self)
     dialog.setFileMode(QFileDialog.DirectoryOnly)
     dialog.setWindowTitle(f"Select BEQ Files Download Directory")
     if dialog.exec():
         selected = dialog.selectedFiles()
         if len(selected) > 0:
             self.beqFiltersDir.setText(selected[0])
             self.__count_beq_files()
예제 #10
0
 def __get_directory(self, name):
     dialog = QFileDialog(parent=self)
     dialog.setFileMode(QFileDialog.ExistingFile)
     dialog.setNameFilter(f"{name} ({name}.exe {name})")
     dialog.setWindowTitle(f"Select {name}")
     if dialog.exec():
         selected = dialog.selectedFiles()
         if len(selected) > 0:
             return selected[0]
     return None
예제 #11
0
 def choose_result_prefix(self):
     dial = QFileDialog()
     dial.setOption(QFileDialog.DontUseNativeDialog, True)
     dial.setAcceptMode(QFileDialog.AcceptOpen)
     dial.setFileMode(QFileDialog.Directory)
     dial.setDirectory(self.result_prefix.text())
     dial.setHistory(dial.history() + self.settings.get_path_history())
     if dial.exec_():
         dir_path = str(dial.selectedFiles()[0])
         self.result_prefix.setText(dir_path)
 def select_files(self):
     dial = QFileDialog(self, "Select files")
     dial.setDirectory(
         self.settings.get(
             "io.batch_directory",
             self.settings.get("io.load_image_directory",
                               str(Path.home()))))
     dial.setFileMode(QFileDialog.ExistingFiles)
     if dial.exec_():
         self.settings.set("io.batch_directory",
                           os.path.dirname(str(dial.selectedFiles()[0])))
         new_paths = sorted(
             set(map(str, dial.selectedFiles())) - self.files_to_proceed)
         for path in new_paths:
             size = os.stat(path).st_size
             size = float(size) / (1024**2)
             lwi = QListWidgetItem("{:s} ({:.2f} MB)".format(path, size))
             lwi.setTextAlignment(Qt.AlignRight)
             self.selected_files.addItem(lwi)
         self.files_to_proceed.update(new_paths)
         self.file_list_changed.emit(self.files_to_proceed)
예제 #13
0
 def mapping_dialog():
     dial = QFileDialog(self, "Select file")
     dial.setHistory(dial.history() + self.settings.get_path_history())
     base_path = str(self.base_prefix.text()).strip()
     if base_path != "":
         dial.setDirectory(base_path)
     dial.setFileMode(QFileDialog.ExistingFile)
     if dial.exec_():
         path = str(dial.selectedFiles())
         self.mask_path_list[i].setText(path)
         file_mapper: MaskFile = self.mask_mapper_list[pos]
         file_mapper.set_map_path(path)
예제 #14
0
 def showExtractCompleteSoundPicker(self):
     dialog = QFileDialog(parent=self)
     dialog.setFileMode(QFileDialog.ExistingFile)
     dialog.setNameFilter("Audio (*.wav)")
     dialog.setWindowTitle(f"Select Notification Sound")
     if dialog.exec():
         selected = dialog.selectedFiles()
         if len(selected) > 0:
             self.extractCompleteAudioFile.setText(selected[0])
         else:
             self.extractCompleteAudioFile.setText('')
     else:
         self.extractCompleteAudioFile.setText('')
예제 #15
0
 def setTargetDirectory(self):
     '''
     Sets the target directory based on the user selection.
     '''
     dialog = QFileDialog(parent=self)
     dialog.setFileMode(QFileDialog.DirectoryOnly)
     dialog.setWindowTitle(f"Select Output Directory")
     if dialog.exec():
         selected = dialog.selectedFiles()
         if len(selected) > 0:
             self.targetDir.setText(selected[0])
             if self.__executor is not None:
                 self.__executor.target_dir = selected[0]
                 self.__display_command_info()
예제 #16
0
    def stl_dialog(self):
        dialog = QFileDialog(self)
        dialog.setWindowTitle('Open STL Tool file')
        dialog.setNameFilter('(*.stl)')

        filename = None

        if dialog.exec_() == QDialog.Accepted:
            filename = dialog.selectedFiles()

        if filename:
            self.setFilename(filename[0])
        else:
            self.clearFilename()
예제 #17
0
def showSelectProjectDialog(parent: QWidget = None) -> Optional[Path]:
    dialog = QFileDialog(parent, Qt.Dialog)
    dialog.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.Dialog)
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setLabelText(QFileDialog.LookIn, "Select project folder")
    dialog.setFileMode(QFileDialog.Directory)
    dialog.setOption(QFileDialog.ShowDirsOnly, True)
    dialog.setViewMode(QFileDialog.Detail)
    dialog.setDirectory(QDir.homePath())

    if dialog.exec_():
        paths = dialog.selectedFiles()
        assert len(paths) == 1
        path = Path(paths[0])
        return path
예제 #18
0
 def file_dialog(self, *args, **kwargs):
     dialog = QFileDialog(self)
     if not self._is_file_dialog_opened:
         # set the initial directory to HOME
         dialog.setDirectory(os.path.expanduser("~"))
         self._is_file_dialog_opened = True
     dialog.setWindowTitle('Open .edi Files...')
     dialog.setNameFilter('.edi files (*.edi)')
     dialog.setFileMode(QFileDialog.ExistingFiles)
     if dialog.exec_() == QDialog.Accepted:
         file_list = dialog.selectedFiles()
         self._progress_bar.setMaximumValue(len(file_list))
         self._progress_bar.onStart()
         self._add_files(file_list, DEFAULT_GROUP_NAME)
         self._update_tree_view()
         self._progress_bar.onFinished()
예제 #19
0
def open_exe_name_dialog(parent, appname):
    options = QFileDialog.Options()
    options |= QDir.AllEntries
    options |= QDir.Hidden

    file_dialog = QFileDialog()
    file_dialog.setFilter(QDir.AllEntries | QDir.Hidden)
    file_dialog.setFileMode(QFileDialog.ExistingFile)
    file_dialog.setWindowTitle(
        f"{appname} could not be found. Please locate in"
        "manually")
    if file_dialog.exec():
        file_name = file_dialog.selectedFiles()
        print(file_name[0])
        return file_name[0]
    else:
        print("No file is selected. guiscrcpy is likely to fail")
예제 #20
0
def parse_file(filter, title, parsers):
    '''
    Presents a file dialog to the user so they can choose something to load.
    :return: a 2 entry tuple with the file name and loaded thing (if anything was loaded)
    '''
    dialog = QFileDialog()
    dialog.setFileMode(QFileDialog.ExistingFile)
    dialog.setNameFilter(filter)
    dialog.setWindowTitle(title)
    if dialog.exec():
        selected = dialog.selectedFiles()
        if len(selected) > 0:
            file_name = selected[0]
            for k, v in parsers.items():
                if file_name.endswith(k):
                    return v(file_name)
    return None, None
예제 #21
0
def load_filter(parent, status_bar=None):
    '''
    Presents a file dialog to the user so they can choose a filter to load.
    :return: the loaded filter, if any.
    '''
    dialog = QFileDialog(parent=parent)
    dialog.setFileMode(QFileDialog.ExistingFile)
    dialog.setNameFilter(f"*.filter")
    dialog.setWindowTitle(f"Load Filter")
    if dialog.exec():
        selected = dialog.selectedFiles()
        if len(selected) > 0:
            with open(selected[0], 'r') as infile:
                input = json.load(infile)
                if status_bar is not None:
                    status_bar.showMessage(f"Loaded filter from {infile.name}")
                return input
    return None
예제 #22
0
 def pick_user_source_dir(self):
     '''
     Sets the user source directory.
     '''
     dialog = QFileDialog(parent=self)
     dialog.setFileMode(QFileDialog.DirectoryOnly)
     dialog.setOption(QFileDialog.ShowDirsOnly)
     dialog.setWindowTitle('Choose a directory which holds your own BEQ files')
     if dialog.exec():
         selected = dialog.selectedFiles()
         if len(selected) > 0:
             if os.path.abspath(selected[0]) == os.path.abspath(self.__beq_dir):
                 QMessageBox.critical(self, '',
                                      f"User directory cannot be inside the input directory, choose a different folder",
                                      QMessageBox.Ok)
             else:
                 self.userSourceDir.setText(selected[0])
                 self.update_beq_count()
예제 #23
0
class FileLineEdit(QLineEdit):
    def __init__(self,
                 check_exists: bool = False,
                 parent: Optional[QWidget] = None):
        super(FileLineEdit, self).__init__(parent)

        browse_action_icon = self.window().style().standardIcon(
            QStyle.SP_DirOpenIcon)
        self._browse_action = self.addAction(browse_action_icon,
                                             QLineEdit.LeadingPosition)

        self._file_dialog = QFileDialog(self)
        self._file_dialog.setOption(QFileDialog.DontUseNativeDialog)

        # noinspection PyUnusedLocal
        # noinspection PyUnresolvedReferences
        @self._browse_action.triggered.connect
        def on_browse_action_triggered(checked=False):
            path = self.path
            if path is not None:
                if path.parent.is_dir():
                    self._file_dialog.setDirectory(str(path.parent))
                if path.exists():
                    self._file_dialog.selectFile(str(path))
            if self._file_dialog.exec() == QFileDialog.Accepted:
                selected_files = self._file_dialog.selectedFiles()
                self.setText(selected_files[0])

        if check_exists:
            # noinspection PyUnresolvedReferences
            @self.textChanged.connect
            def on_text_changed(text):
                if not text or Path(text).exists():
                    self.setStyleSheet('')
                else:
                    self.setStyleSheet('background-color: #88ff0000')

    @property
    def file_dialog(self) -> QFileDialog:
        return self._file_dialog

    @property
    def path(self) -> Optional[Path]:
        return Path(self.text()) if self.text() else None
예제 #24
0
    def _export_shape_file(self, *args, **kwargs):
        # show files
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Information)
        msg.setText("You are about to create shape files.")
        msg.setInformativeText(
            "Please select an output directory after click \"OK\"\n"
            "For the list of .edi files (stations) included in the creation, please click \"Show Details\""
        )
        msg.setWindowTitle("Note")
        msg.setDetailedText("\n".join([
            "{station} ({fn})".format(
                station=station, fn=self._file_handler.station2ref(station))
            for station in self._station_viewer.selected_stations
        ]))
        msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)

        if msg.exec_() == QMessageBox.Ok:
            dialog = QFileDialog(self)
            dir_name = None
            dialog.setWindowTitle("Selecting Output Directory ...")
            dialog.setFileMode(QFileDialog.DirectoryOnly)
            while dir_name is None:
                if dialog.exec_() == QDialog.Accepted:
                    dir_name = dialog.selectedFiles()[0]
                    dir_name = str(dir_name)
                    if not os.path.isdir(dir_name):
                        QMessageBox.information(
                            self, "NOTE",
                            "Please select a directory to save the created shape files."
                        )
                        dir_name = None  # will read again
                else:
                    break
            if dir_name is not None:
                collect = EdiCollection(mt_objs=[
                    self._file_handler.get_MT_obj(
                        self._file_handler.station2ref(station))
                    for station in self._station_viewer.selected_stations
                ])
                collect.create_mt_station_gdf(dir_name)
                QMessageBox.information(self, "Creation Completed",
                                        "Output written to %s" % dir_name)
                webbrowser.open(dir_name)
예제 #25
0
 def export_plans(self):
     choose = ExportDialog(self.settings.batch_plans, PlanPreview)
     if not choose.exec_():
         return
     dial = QFileDialog(self, "Export calculation plans")
     dial.setFileMode(QFileDialog.AnyFile)
     dial.setAcceptMode(QFileDialog.AcceptSave)
     dial.setDirectory(dial.setDirectory(self.settings.get("io.batch_plan_directory", str(Path.home()))))
     dial.setNameFilter("Calculation plans (*.json)")
     dial.setDefaultSuffix("json")
     dial.selectFile("calculation_plans.json")
     dial.setHistory(dial.history() + self.settings.get_path_history())
     if dial.exec_():
         file_path = str(dial.selectedFiles()[0])
         self.settings.set("io.batch_plan_directory", os.path.dirname(file_path))
         self.settings.add_path_history(os.path.dirname(file_path))
         data = {x: self.settings.batch_plans[x] for x in choose.get_export_list()}
         with open(file_path, "w") as ff:
             json.dump(data, ff, cls=self.settings.json_encoder_class, indent=2)
예제 #26
0
 def import_plans(self):
     dial = QFileDialog(self, "Import calculation plans")
     dial.setFileMode(QFileDialog.ExistingFile)
     dial.setAcceptMode(QFileDialog.AcceptOpen)
     dial.setDirectory(self.settings.get("io.open_directory", str(Path.home())))
     dial.setNameFilter("Calculation plans (*.json)")
     dial.setDefaultSuffix("json")
     dial.setHistory(dial.history() + self.settings.get_path_history())
     if dial.exec_():
         file_path = dial.selectedFiles()[0]
         plans, err = self.settings.load_part(file_path)
         self.settings.set("io.batch_plan_directory", os.path.dirname(file_path))
         self.settings.add_path_history(os.path.dirname(file_path))
         if err:
             QMessageBox.warning(self, "Import error", "error during importing, part of data were filtered.")
         choose = ImportDialog(plans, self.settings.batch_plans, PlanPreview)
         if choose.exec_():
             for original_name, final_name in choose.get_import_list():
                 self.settings.batch_plans[final_name] = plans[original_name]
             self.update_plan_list()
예제 #27
0
 def import_measurement_profiles(self):
     dial = QFileDialog(self, "Import settings profiles")
     dial.setDirectory(self.settings.get("io.export_directory", ""))
     dial.setFileMode(QFileDialog.ExistingFile)
     dial.setNameFilter("measurement profile (*.json)")
     if dial.exec_():
         file_path = str(dial.selectedFiles()[0])
         self.settings.set("io.export_directory", file_path)
         stat, err = self.settings.load_part(file_path)
         if err:
             QMessageBox.warning(
                 self, "Import error",
                 "error during importing, part of data were filtered.")
         measurement_dict = self.settings.measurement_profiles
         imp = ImportDialog(stat, measurement_dict, StringViewer)
         if not imp.exec_():
             return
         for original_name, final_name in imp.get_import_list():
             measurement_dict[final_name] = stat[original_name]
         self.profile_list.clear()
         self.profile_list.addItems(list(sorted(measurement_dict.keys())))
         self.settings.dump()
예제 #28
0
 def import_pipeline(self):
     dial = QFileDialog(self, "Import pipeline segment")
     dial.setFileMode(QFileDialog.ExistingFile)
     dial.setAcceptMode(QFileDialog.AcceptOpen)
     dial.setDirectory(self._settings.get("io.save_directory", ""))
     dial.setNameFilter("Segment pipeline (*.json)")
     dial.setHistory(dial.history() + self._settings.get_path_history())
     if dial.exec_():
         file_path = dial.selectedFiles()[0]
         self._settings.set("io.save_directory", os.path.dirname(file_path))
         self._settings.add_path_history(os.path.dirname(file_path))
         profs, err = self._settings.load_part(file_path)
         if err:
             QMessageBox.warning(
                 self, "Import error",
                 "error during importing, part of data were filtered.")
         profiles_dict = self._settings.segmentation_pipelines
         imp = ImportDialog(profs, profiles_dict, ProfileDictViewer)
         if not imp.exec_():
             return
         for original_name, final_name in imp.get_import_list():
             profiles_dict[final_name] = profs[original_name]
         self._settings.dump()
         self.update_profile_list()
예제 #29
0
 def openDirDialog(self):
     dialog = QFileDialog(self)
     dialog.setFileMode(QFileDialog.DirectoryOnly)
     if dialog.exec_():
         directory = dialog.selectedFiles()[0]
         self.openDir(directory)
예제 #30
0
    def run_opensbml(self,
                     filenames=None,
                     goto=None,
                     word='',
                     editorwindow=None,
                     processevents=True):
        """Prompt the user to load a SBML file, translate to antimony, and 
        display in a new window"""
        editor = self.main.editor
        editor0 = editor.get_current_editor()
        if editor0 is not None:
            position0 = editor0.get_position('cursor')
            filename0 = editor.get_current_filename()
        else:
            position0, filename0 = None, None
        if not filenames:
            # Recent files action
            action = editor.sender()
            if isinstance(action, QAction):
                filenames = from_qvariant(action.data(), to_text_string)
        if not filenames:
            basedir = getcwd()
            if editor.edit_filetypes is None:
                editor.edit_filetypes = get_edit_filetypes()
            if editor.edit_filters is None:
                editor.edit_filters = get_edit_filters()

            c_fname = editor.get_current_filename()
            if c_fname is not None and c_fname != editor.TEMPFILE_PATH:
                basedir = os.path.dirname(c_fname)
            editor.redirect_stdio.emit(False)
            parent_widget = editor.get_current_editorstack()
            if filename0 is not None:
                selectedfilter = get_filter(editor.edit_filetypes,
                                            os.path.splitext(filename0)[1])
            else:
                selectedfilter = ''
            if not running_under_pytest():
                customfilters = 'SBML files (*.sbml *.xml);;All files (*.*)'
                filenames, _sf = getopenfilenames(
                    parent_widget,
                    _("Open SBML file"),
                    basedir,
                    customfilters,
                    selectedfilter=selectedfilter,
                    options=QFileDialog.HideNameFilterDetails)
            else:
                # Use a Qt (i.e. scriptable) dialog for pytest
                dialog = QFileDialog(parent_widget,
                                     _("Open SBML file"),
                                     options=QFileDialog.DontUseNativeDialog)
                if dialog.exec_():
                    filenames = dialog.selectedFiles()
            editor.redirect_stdio.emit(True)
            if filenames:
                filenames = [os.path.normpath(fname) for fname in filenames]
            else:
                return

        focus_widget = QApplication.focusWidget()
        if editor.dockwidget and\
           (not editor.dockwidget.isAncestorOf(focus_widget)\
            and not isinstance(focus_widget, CodeEditor)):
            editor.dockwidget.setVisible(True)
            editor.dockwidget.setFocus()
            editor.dockwidget.raise_()

        def _convert(fname):
            fname = os.path.abspath(encoding.to_unicode_from_fs(fname))
            if os.name == 'nt' and len(fname) >= 2 and fname[1] == ':':
                fname = fname[0].upper() + fname[1:]
            return fname

        if hasattr(filenames, 'replaceInStrings'):
            # This is a QStringList instance (PyQt API #1), converting to list:
            filenames = list(filenames)
        if not isinstance(filenames, list):
            filenames = [_convert(filenames)]
        else:
            filenames = [_convert(fname) for fname in list(filenames)]

        if isinstance(goto, int):
            goto = [goto]
        elif goto is not None and len(goto) != len(filenames):
            goto = None

        for index, filename in enumerate(filenames):
            p = re.compile('(.xml$|.sbml$)')
            pythonfile = p.sub('_antimony.py', filename)
            if (pythonfile == filename):
                pythonfile = filename + "_antimony.py"
            # -- Do not open an already opened file
            current_editor = editor.set_current_filename(
                pythonfile, editorwindow)
            if current_editor is None:
                # -- Not a valid filename:
                if not os.path.isfile(filename):
                    continue
                # --
                current_es = editor.get_current_editorstack(editorwindow)

                # Creating the editor widget in the first editorstack (the one
                # that can't be destroyed), then cloning this editor widget in
                # all other editorstacks:
                finfo, newname = self.load_and_translate(
                    filename, pythonfile, editor)
                finfo.path = editor.main.get_spyder_pythonpath()
                editor._clone_file_everywhere(finfo)
                current_editor = current_es.set_current_filename(newname)

                current_es.analyze_script()
            if goto is not None:  # 'word' is assumed to be None as well
                current_editor.go_to_line(goto[index], word=word)
                position = current_editor.get_position('cursor')
                editor.cursor_moved(filename0, position0, filename, position)
            if (current_editor is not None):
                current_editor.clearFocus()
                current_editor.setFocus()
                current_editor.window().raise_()
            if processevents:
                QApplication.processEvents()
예제 #31
0
class ExportDialog(QDialog):
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        self.ui = Ui_Dialog_Export()
        self.ui.setupUi(self)
        self._fig = None

        # setup file types
        for frmt in IMAGE_FORMATS:
            self.ui.comboBox_fileType.addItem("{0[1]} (.{0[0]})".format(frmt))

        self._file_name_changed()  # select the default format

        # setup directory and dir dialog
        self._dir_dialog = QFileDialog(self)
        # self._dir_dialog.setDirectory(os.path.expanduser("~"))
        self._dir_dialog.setFileMode(QFileDialog.DirectoryOnly)
        self._dir_dialog.setWindowTitle("Save to ...")
        self.ui.comboBox_directory.addItem(os.path.expanduser("~"))
        self.ui.pushButton_browse.clicked.connect(self._browse)

        self._dir_validator = DirectoryValidator()
        self.ui.comboBox_directory.lineEdit().setValidator(self._dir_validator)

        # file name
        self.ui.comboBox_fileName.currentIndexChanged.connect(
            self._file_name_changed)

        # file type
        self.ui.comboBox_fileType.currentIndexChanged.connect(
            self._file_type_changed)

        # cancel button
        self.ui.pushButton_cancel.clicked.connect(self._cancel_button_clicked)
        # export button
        self.ui.pushButton_export.clicked.connect(self._export_button_clicked)
        # preview button
        self.ui.pushButton_preview.clicked.connect(
            self._preview_button_clicked)

        # dpi
        self.ui.spinBox_dpi.valueChanged.connect(self._dpi_changed)
        # inches
        self.ui.doubleSpinBox_width_inches.valueChanged.connect(
            self._width_inches_changed)
        self.ui.doubleSpinBox_height_inches.valueChanged.connect(
            self._height_inches_changed)
        # pixels
        self.ui.spinBox_width_pixels.valueChanged.connect(
            self._width_pixels_changed)
        self.ui.spinBox_height_pixels.valueChanged.connect(
            self._height_pixels_changed)

        # message box for when the file already exist
        self._msg_box = QMessageBox(self)
        self._msg_box.setWindowTitle("Export...")
        self._msg_box_button_overwrite = self._msg_box.addButton(
            self.tr("Overwrite"), QMessageBox.AcceptRole)
        self._msg_box_button_save_as = self._msg_box.addButton(
            self.tr("Save As"), QMessageBox.ActionRole)
        self._msg_box_button_cancel = self._msg_box.addButton(
            QMessageBox.Cancel)
        self._msg_box.setDefaultButton(self._msg_box_button_save_as)

    _orientation = ['portrait', 'landscape']

    _no_alpha_channel_formats = ('jpg', 'jpeg')  # ("png", "gif", "psd")

    def _dpi_changed(self, dpi):
        self.ui.doubleSpinBox_height_inches.blockSignals(True)
        self.ui.doubleSpinBox_width_inches.blockSignals(True)
        self.ui.spinBox_height_pixels.setValue(
            self.ui.doubleSpinBox_height_inches.value() * dpi)
        self.ui.spinBox_width_pixels.setValue(
            self.ui.doubleSpinBox_width_inches.value() * dpi)
        self.ui.doubleSpinBox_height_inches.blockSignals(False)
        self.ui.doubleSpinBox_width_inches.blockSignals(False)

    def _width_pixels_changed(self, width):
        self.ui.doubleSpinBox_width_inches.blockSignals(True)
        new_width_inches = width / float(self.ui.spinBox_dpi.value())
        self.ui.doubleSpinBox_width_inches.setValue(new_width_inches)
        self.ui.doubleSpinBox_width_inches.blockSignals(False)

    def _height_pixels_changed(self, height):
        self.ui.doubleSpinBox_height_inches.blockSignals(True)
        new_height_inches = height / float(self.ui.spinBox_dpi.value())
        self.ui.doubleSpinBox_height_inches.setValue(new_height_inches)
        self.ui.doubleSpinBox_height_inches.blockSignals(False)

    def _width_inches_changed(self, width):
        self.ui.spinBox_width_pixels.blockSignals(True)
        self.ui.spinBox_width_pixels.setValue(width *
                                              self.ui.spinBox_dpi.value())
        self.ui.spinBox_width_pixels.blockSignals(False)

    def _height_inches_changed(self, height):
        self.ui.spinBox_height_pixels.blockSignals(True)
        self.ui.spinBox_height_pixels.setValue(height *
                                               self.ui.spinBox_dpi.value())
        self.ui.spinBox_height_pixels.blockSignals(False)

    def _cancel_button_clicked(self, b):
        self.reject()

    def _export_button_clicked(self, b):
        self.accept()

    def _preview_button_clicked(self):
        if self._fig:
            # set figures
            self._fig.set_size_inches(self.get_size_inches_width(),
                                      self.get_size_inches_height())
            params = self.get_savefig_params()
            self._fig.set_dpi(params['dpi'])
            self._fig.set_tight_layout(True if params['bbox_inches'] ==
                                       'tight' else False)

            canvas = FigureCanvas(self._fig)
            canvas.show()

            # dialog
            preview_dialog = PreviewDialog(self, self._fig)
            preview_dialog.exec_()

    def _file_type_changed(self, *args, **kwargs):
        index = self.ui.comboBox_fileType.currentIndex()
        ext, _ = IMAGE_FORMATS[index]
        filename = str(self.ui.comboBox_fileName.currentText())
        filename, _ = os.path.splitext(filename)

        if ext in self._no_alpha_channel_formats:  # enable transparent if the format supports
            self.ui.checkBox_transparent.setEnabled(False)
        else:
            self.ui.checkBox_transparent.setEnabled(True)

        # update file name
        filename = "%s.%s" % (filename, ext)
        index = self.ui.comboBox_fileName.findText(filename)
        if index == -1:
            self.ui.comboBox_fileName.addItem(filename)
        self.ui.comboBox_fileName.setCurrentIndex(
            index if index >= 0 else self.ui.comboBox_fileName.
            findText(filename))

    def _file_name_changed(self, *args, **kwargs):
        filename = str(self.ui.comboBox_fileName.currentText())
        filename, extension = os.path.splitext(filename)
        extension = extension[1:]  # get ride of .
        # check if the extension is supported
        index = [
            i for i, (ext, dsc) in enumerate(IMAGE_FORMATS) if ext == extension
        ]
        if index:
            self.ui.comboBox_fileType.setCurrentIndex(index[0])
        elif extension:
            # no extension
            pass
        else:
            # extension not supported:
            pass

    def _browse(self, *args, **kwargs):
        if self._dir_dialog.exec_() == QDialog.Accepted:
            dirs = self._dir_dialog.selectedFiles(
            )  # behave differently in pyqt4 and pyqt5
            directory = str(dirs[0] if dirs else self._dir_dialog.directory().
                            absolutePath())  # this makes the behave the same
            # update directory
            index = self.ui.comboBox_directory.findText(directory)
            if index == -1:
                self.ui.comboBox_directory.addItem(directory)
            self.ui.comboBox_directory.setCurrentIndex(
                index if index >= 0 else self.ui.comboBox_directory.
                findText(directory))

    def export_to_file(self, fig):
        self._fig = fig
        respawn = True
        while respawn:
            respawn = False
            self.ui.spinBox_dpi.setValue(fig.get_dpi())
            self.ui.doubleSpinBox_width_inches.setValue(fig.get_figwidth())
            self.ui.doubleSpinBox_height_inches.setValue(fig.get_figheight())
            response = self.exec_()
            if response == QDialog.Accepted:
                # saving files
                fname = self.get_save_file_name()

                if os.path.exists(fname):
                    new_name = generate_unique_file_name(fname)
                    self._show_file_exist_message(fname, new_name)
                    if self._msg_box.clickedButton(
                    ) == self._msg_box_button_cancel:
                        respawn = True
                        continue
                    elif self._msg_box.clickedButton(
                    ) == self._msg_box_button_save_as:
                        fname = new_name  # save_as
                    else:
                        pass  # use the original name to overwrite

                params = self.get_savefig_params()
                # change size
                fig.set_size_inches(self.get_size_inches_width(),
                                    self.get_size_inches_height())
                try:
                    fig.savefig(fname, **params)
                except IOError as err:
                    if 'RGBA' in err.message:
                        # if the problem is RGBA as the alpha channel is not supported in the selected format
                        # save to png then save as
                        basename = os.path.basename(fname)
                        tmp_dir = tempfile.gettempdir()
                        filename, ext = os.path.splitext(basename)
                        png_file = filename + ".png"
                        final_format = params['format']
                        params['format'] = 'png'
                        new_fname = os.path.join(tmp_dir, png_file)
                        fig.savefig(new_fname, **params)
                        with Image.open(new_fname) as im:
                            rgb_im = im.convert('RGB')
                            # make sure the fname is ended with the right extension
                            fname, _ = os.path.splitext(fname)
                            fname += "." + final_format
                            rgb_im.save(fname)
                    else:
                        raise err

                if self.ui.checkBox_open_after_export.isChecked():
                    # open with the system default application, this should work on all platforms
                    webbrowser.open(fname)
                return fname
                # elif response == QtGu

    def get_size_inches_width(self):
        return self.ui.doubleSpinBox_width_inches.value()

    def get_size_inches_height(self):
        return self.ui.doubleSpinBox_height_inches.value()

    def _show_file_exist_message(self, fname, new_name):
        self._msg_box.setText(
            "<p>File \"{0}\" already exists. Do you want to overwrite the existing, or save to \"{1}\" instead?<\p>"
            .format(fname, new_name))
        self._msg_box.exec_()

    def get_save_file_name(self):
        name = os.path.join(str(self.ui.comboBox_directory.currentText()),
                            str(self.ui.comboBox_fileName.currentText()))
        return os.path.normpath(name)

    def get_savefig_params(self):
        params = {
            'dpi': self.ui.spinBox_dpi.value(),
            'orientation': self.get_orientation(),
            'format': self.get_file_format()[0],
            'transparent': self.get_transparent(),
            'bbox_inches': self.get_bbox_inches()
        }
        return params

    def get_transparent(self):
        return self.ui.checkBox_transparent.isEnabled(
        ) and self.ui.checkBox_transparent.isChecked()

    def get_file_format(self):
        return IMAGE_FORMATS[self.ui.comboBox_fileType.currentIndex()]

    def get_bbox_inches(self):
        return 'tight' if self.ui.checkBox_tightBbox.isChecked() else None

    def get_orientation(self):
        return self._orientation[self.ui.comboBox_orientation.currentIndex()]

    def keyPressEvent(self, event):
        """Capture and ignore all key press events.

        This is used so that return key event does not trigger any button
        from the dialog. We need to allow the return key to be used in filters
        in the widget."""
        if event.key() == QtCore.Qt.Key_Escape:
            # call reject if Escape is pressed.
            self.reject()
        pass