Example #1
0
    def on_export_theme(self, checked=None):
        """
        Export the theme to a zip file

        :param bool checked: Sent by the QAction.triggered signal. It's not used in this method.
        :rtype: None
        """
        item = self.theme_list_widget.currentItem()
        if item is None:
            critical_error_message_box(message=translate(
                'OpenLP.ThemeManager', 'You have not selected a theme.'))
            return
        theme_name = item.data(QtCore.Qt.UserRole)
        export_path, filter_used = \
            FileDialog.getSaveFileName(self.main_window,
                                       translate('OpenLP.ThemeManager',
                                                 'Save Theme - ({name})').format(name=theme_name),
                                       Settings().value(self.settings_section + '/last directory export'),
                                       translate('OpenLP.ThemeManager', 'OpenLP Themes (*.otz)'),
                                       translate('OpenLP.ThemeManager', 'OpenLP Themes (*.otz)'))
        self.application.set_busy_cursor()
        if export_path:
            Settings().setValue(
                self.settings_section + '/last directory export',
                export_path.parent)
            if self._export_theme(export_path.with_suffix('.otz'), theme_name):
                QtWidgets.QMessageBox.information(
                    self, translate('OpenLP.ThemeManager', 'Theme Exported'),
                    translate('OpenLP.ThemeManager',
                              'Your theme has been successfully exported.'))
        self.application.set_normal_cursor()
Example #2
0
    def test_get_existing_directory_param_order(self):
        """
        Test that `getExistingDirectory` passes the parameters to `QFileDialog.getExistingDirectory` in the correct
        order
        """
        # GIVEN: FileDialog
        with patch('openlp.core.widgets.dialogs.QtWidgets.QFileDialog.getExistingDirectory', return_value='') \
                as mocked_get_existing_directory:

            # WHEN: Calling the getExistingDirectory method with all parameters set
            FileDialog.getExistingDirectory('Parent', 'Caption',
                                            Path('test', 'dir'), 'Options')

            # THEN: The `QFileDialog.getExistingDirectory` should have been called with the parameters in the correct
            #       order
            mocked_get_existing_directory.assert_called_once_with(
                'Parent', 'Caption', os.path.join('test', 'dir'), 'Options')
Example #3
0
    def test_file_dialog(self):
        """
        Test that the :class:`FileDialog` instantiates correctly
        """
        # GIVEN: The FileDialog class
        # WHEN: Creating an instance
        instance = FileDialog()

        # THEN: The instance should be an instance of QFileDialog
        assert isinstance(instance, QtWidgets.QFileDialog)
Example #4
0
    def on_error_save_to_button_clicked(self):
        """
        Save the error report to a file.

        :rtype: None
        """
        file_path, filter_used = FileDialog.getSaveFileName(
            self, self.settings.value(self.plugin.settings_section + '/last directory import'))
        if file_path is None:
            return
        file_path.write_text(self.error_report_text_edit.toPlainText(), encoding='utf-8')
Example #5
0
    def on_browse_button_clicked(self):
        """
        A handler to handle a click on the browse button.

        Show the QFileDialog and process the input from the user

        :rtype: None
        """
        caption = self.dialog_caption
        path = None
        if self._path_type == PathEditType.Directories:
            if not caption:
                caption = translate('OpenLP.PathEdit', 'Select Directory')
            path = FileDialog.getExistingDirectory(self, caption, self._path, FileDialog.ShowDirsOnly)
        elif self._path_type == PathEditType.Files:
            if not caption:
                caption = self.dialog_caption = translate('OpenLP.PathEdit', 'Select File')
            path, filter_used = FileDialog.getOpenFileName(self, caption, self._path, self.filters)
        if path:
            self.on_new_path(path)
Example #6
0
    def test_get_existing_directory_user_abort(self):
        """
        Test that `getExistingDirectory` handles the case when the user cancels the dialog
        """
        # GIVEN: FileDialog with a mocked QDialog.getExistingDirectory method
        # WHEN: Calling FileDialog.getExistingDirectory and the user cancels the dialog returns a empty string
        with patch('PyQt5.QtWidgets.QFileDialog.getExistingDirectory',
                   return_value=''):
            result = FileDialog.getExistingDirectory()

            # THEN: The result should be None
            assert result is None
Example #7
0
 def on_attach_file_button_clicked(self):
     """
     Attach files to the bug report e-mail.
     """
     file_path, filter_used = \
         FileDialog.getOpenFileName(self,
                                    translate('ImagePlugin.ExceptionDialog', 'Select Attachment'),
                                    Settings().value(self.settings_section + '/last directory'),
                                    '{text} (*)'.format(text=UiStrings().AllFiles))
     log.info('New files {file_path}'.format(file_path=file_path))
     if file_path:
         self.file_attachment = str(file_path)
Example #8
0
    def test_get_open_file_name_selected_filter(self):
        """
        Test that `getOpenFileName` does not modify the selectedFilter as returned by `QFileDialog.getOpenFileName`
        """
        # GIVEN: FileDialog with a mocked QDialog.get_save_file_name method
        # WHEN: Calling FileDialog.getOpenFileName, and `QFileDialog.getOpenFileName` returns a known `selectedFilter`
        with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName',
                   return_value=('', 'selected filter')):
            result = FileDialog.getOpenFileName()

            # THEN: getOpenFileName() should return a tuple with the second value set to a the selected filter
            assert result[1] == 'selected filter'
Example #9
0
    def test_get_existing_directory_user_accepts(self):
        """
        Test that `getExistingDirectory` handles the case when the user accepts the dialog
        """
        # GIVEN: FileDialog with a mocked QDialog.getExistingDirectory method
        # WHEN: Calling FileDialog.getExistingDirectory, the user chooses a file and accepts the dialog (it returns a
        #       string pointing to the directory)
        with patch('PyQt5.QtWidgets.QFileDialog.getExistingDirectory',
                   return_value=os.path.join('test', 'dir')):
            result = FileDialog.getExistingDirectory()

            # THEN: getExistingDirectory() should return a Path object pointing to the chosen file
            assert result == Path('test', 'dir')
Example #10
0
 def on_file_click(self):
     """
     Add a file to the list widget to make it available for showing
     """
     file_paths, selected_filter = FileDialog.getOpenFileNames(
         self, self.on_new_prompt,
         Settings().value(self.settings_section + '/last directory'),
         self.on_new_file_masks)
     log.info('New file(s) {file_paths}'.format(file_paths=file_paths))
     if file_paths:
         self.application.set_busy_cursor()
         self.validate_and_load(file_paths)
     self.application.set_normal_cursor()
Example #11
0
    def test_get_open_file_name_user_abort(self):
        """
        Test that `getOpenFileName` handles the case when the user cancels the dialog
        """
        # GIVEN: FileDialog with a mocked QDialog.getOpenFileName method
        # WHEN: Calling FileDialog.getOpenFileName and the user cancels the dialog (it returns a tuple with the first
        #       value set as an empty string)
        with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName',
                   return_value=('', '')):
            result = FileDialog.getOpenFileName()

            # THEN: First value should be None
            assert result[0] is None
Example #12
0
    def test_get_open_file_name_user_accepts(self):
        """
        Test that `getOpenFileName` handles the case when the user accepts the dialog
        """
        # GIVEN: FileDialog with a mocked QDialog.getOpenFileName method
        # WHEN: Calling FileDialog.getOpenFileName, the user chooses a file and accepts the dialog (it returns a
        #       tuple with the first value set as an string pointing to the file)
        with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName',
                   return_value=(os.path.join('test', 'chosen.file'), '')):
            result = FileDialog.getOpenFileName()

            # THEN: getOpenFileName() should return a tuple with the first value set to a Path object pointing to the
            #       chosen file
            assert result[0] == Path('test', 'chosen.file')
Example #13
0
    def get_folder(self, title, editbox, setting_name):
        """
        Opens a FileDialog and saves the selected folder to the given editbox.

        :param str title: The title of the dialog.
        :param QtWidgets.QLineEdit editbox: An QLineEditbox.
        :param str setting_name: The place where to save the last opened directory.
        :rtype: None
        """
        folder_path = FileDialog.getExistingDirectory(
            self, title, Settings().value(self.plugin.settings_section + '/' + setting_name),
            FileDialog.ShowDirsOnly)
        if folder_path:
            editbox.setText(str(folder_path))
            Settings().setValue(self.plugin.settings_section + '/' + setting_name, folder_path)
Example #14
0
    def test_get_open_file_names_user_accepts(self):
        """
        Test that `getOpenFileNames` handles the case when the user accepts the dialog
        """
        # GIVEN: FileDialog with a mocked QDialog.getOpenFileNames method
        # WHEN: Calling FileDialog.getOpenFileNames, the user chooses some files and accepts the dialog (it returns a
        #       tuple with the first value set as a list of strings pointing to the file)
        with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileNames',
                   return_value=([
                       os.path.join('test', 'chosen.file1'),
                       os.path.join('test', 'chosen.file2')
                   ], '')):
            result = FileDialog.getOpenFileNames()

            # THEN: getOpenFileNames() should return a tuple with the first value set to a list of Path objects pointing
            #       to the chosen file
            assert result[0] == [
                Path('test', 'chosen.file1'),
                Path('test', 'chosen.file2')
            ]
Example #15
0
    def get_file_name(self, title, editbox, setting_name, filters=''):
        """
        Opens a FileDialog and saves the filename to the given editbox.

        :param str title: The title of the dialog.
        :param QtWidgets.QLineEdit editbox:  An QLineEdit.
        :param str setting_name: The place where to save the last opened directory.
        :param str filters: The file extension filters. It should contain the file description
            as well as the file extension. For example::

                'OpenLP 2 Databases (*.sqlite)'
        :rtype: None
        """
        if filters:
            filters += ';;'
        filters += '%s (*)' % UiStrings().AllFiles
        file_path, filter_used = FileDialog.getOpenFileName(
            self, title, Settings().value(self.plugin.settings_section + '/' + setting_name), filters)
        if file_path:
            editbox.setText(str(file_path))
            Settings().setValue(self.plugin.settings_section + '/' + setting_name, file_path.parent)
Example #16
0
    def on_import_theme(self, checked=None):
        """
        Opens a file dialog to select the theme file(s) to import before attempting to extract OpenLP themes from
        those files. This process will only load version 2 themes.

        :param bool checked: Sent by the QAction.triggered signal. It's not used in this method.
        :rtype: None
        """
        file_paths, filter_used = FileDialog.getOpenFileNames(
            self,
            translate('OpenLP.ThemeManager', 'Select Theme Import File'),
            Settings().value(self.settings_section + '/last directory import'),
            translate('OpenLP.ThemeManager', 'OpenLP Themes (*.otz)'))
        self.log_info('New Themes {file_paths}'.format(file_paths=file_paths))
        if not file_paths:
            return
        self.application.set_busy_cursor()
        for file_path in file_paths:
            self.unzip_theme(file_path, self.theme_path)
        Settings().setValue(self.settings_section + '/last directory import', file_path.parent)
        self.load_themes()
        self.application.set_normal_cursor()
Example #17
0
    def get_files(self, title, listbox, filters=''):
        """
        Opens a QFileDialog and writes the filenames to the given listbox.

        :param title: The title of the dialog (str).
        :param listbox: A listbox (QListWidget).
        :param filters: The file extension filters. It should contain the file descriptions as well as the file
            extensions. For example::

                'SongBeamer Files (*.sng)'
        """
        if filters:
            filters += ';;'
        filters += '{text} (*)'.format(text=UiStrings().AllFiles)
        file_paths, filter_used = FileDialog.getOpenFileNames(
            self, title,
            self.settings.value(self.plugin.settings_section + '/last directory import'), filters)
        for file_path in file_paths:
            list_item = QtWidgets.QListWidgetItem(str(file_path))
            list_item.setData(QtCore.Qt.UserRole, file_path)
            listbox.addItem(list_item)
        if file_paths:
            self.settings.setValue(self.plugin.settings_section + '/last directory import', file_paths[0].parent)
Example #18
0
 def on_save_report_button_clicked(self):
     """
     Saving exception log and system information to a file.
     """
     file_path, filter_used = FileDialog.getSaveFileName(
         self, translate('OpenLP.ExceptionForm', 'Save Crash Report'),
         Settings().value(self.settings_section + '/last directory'),
         translate('OpenLP.ExceptionForm',
                   'Text files (*.txt *.log *.text)'))
     if file_path:
         Settings().setValue(self.settings_section + '/last directory',
                             file_path.parent)
         opts = self._create_report()
         report_text = self.report_text.format(
             version=opts['version'],
             description=opts['description'],
             traceback=opts['traceback'],
             libs=opts['libs'],
             system=opts['system'])
         try:
             with file_path.open('w') as report_file:
                 report_file.write(report_text)
         except OSError:
             log.exception('Failed to write crash report')
Example #19
0
 def on_save_report_button_clicked(self):
     """
     Saving exception log and system information to a file.
     """
     while True:
         file_path, filter_used = FileDialog.getSaveFileName(
             self, translate('OpenLP.ExceptionForm', 'Save Crash Report'),
             Settings().value(self.settings_section + '/last directory'),
             translate('OpenLP.ExceptionForm',
                       'Text files (*.txt *.log *.text)'))
         if file_path is None:
             break
         Settings().setValue(self.settings_section + '/last directory',
                             file_path.parent)
         opts = self._create_report()
         report_text = self.report_text.format(
             version=opts['version'],
             description=opts['description'],
             traceback=opts['traceback'],
             libs=opts['libs'],
             system=opts['system'])
         try:
             with file_path.open('w') as report_file:
                 report_file.write(report_text)
                 break
         except OSError as e:
             log.exception('Failed to write crash report')
             QtWidgets.QMessageBox.warning(
                 self,
                 translate('OpenLP.ExceptionDialog',
                           'Failed to Save Report'),
                 translate(
                     'OpenLP.ExceptionDialog',
                     'The following error occurred when saving the report.\n\n'
                     '{exception}').format(file_name=file_path,
                                           exception=e))
Example #20
0
def report_song_list():
    """
    Export the song list as a CSV file.
    :return: Nothing
    """
    main_window = Registry().get('main_window')
    plugin = Registry().get('songs').plugin
    report_file_path, filter_used = FileDialog.getSaveFileName(
        main_window, translate('SongPlugin.ReportSongList', 'Save File'),
        Path(translate('SongPlugin.ReportSongList', 'song_extract.csv')),
        translate('SongPlugin.ReportSongList', 'CSV format (*.csv)'))

    if report_file_path is None:
        main_window.error_message(
            translate('SongPlugin.ReportSongList', 'Output Path Not Selected'),
            translate(
                'SongPlugin.ReportSongList',
                'You have not set a valid output location for your report. \n'
                'Please select an existing path on your computer.'))
        return
    report_file_path.with_suffix('.csv')
    Registry().get('application').set_busy_cursor()
    try:
        with report_file_path.open('wt') as export_file:
            fieldnames = ('Title', 'Alternative Title', 'Copyright',
                          'Author(s)', 'Song Book', 'Topic')
            writer = csv.DictWriter(export_file,
                                    fieldnames=fieldnames,
                                    quoting=csv.QUOTE_ALL)
            headers = dict((n, n) for n in fieldnames)
            writer.writerow(headers)
            song_list = plugin.manager.get_all_objects(Song)
            for song in song_list:
                author_list = []
                for author_song in song.authors_songs:
                    author_list.append(author_song.author.display_name)
                author_string = ' | '.join(author_list)
                book_list = []
                for book_song in song.songbook_entries:
                    if hasattr(book_song, 'entry') and book_song.entry:
                        book_list.append('{name} #{entry}'.format(
                            name=book_song.songbook.name,
                            entry=book_song.entry))
                book_string = ' | '.join(book_list)
                topic_list = []
                for topic_song in song.topics:
                    if hasattr(topic_song, 'name'):
                        topic_list.append(topic_song.name)
                topic_string = ' | '.join(topic_list)
                writer.writerow({
                    'Title': song.title,
                    'Alternative Title': song.alternate_title,
                    'Copyright': song.copyright,
                    'Author(s)': author_string,
                    'Song Book': book_string,
                    'Topic': topic_string
                })
            Registry().get('application').set_normal_cursor()
            main_window.information_message(
                translate('SongPlugin.ReportSongList', 'Report Creation'),
                translate('SongPlugin.ReportSongList',
                          'Report \n{name} \nhas been successfully created. ').
                format(name=report_file_path))
    except OSError as ose:
        Registry().get('application').set_normal_cursor()
        log.exception('Failed to write out song usage records')
        critical_error_message_box(
            translate('SongPlugin.ReportSongList', 'Song Extraction Failed'),
            translate('SongPlugin.ReportSongList',
                      'An error occurred while extracting: {error}').format(
                          error=ose.strerror))