diff --git a/beeref/fileio/sql.py b/beeref/fileio/sql.py index 3dd7682..0905b5e 100644 --- a/beeref/fileio/sql.py +++ b/beeref/fileio/sql.py @@ -45,7 +45,6 @@ logger = logging.getLogger(__name__) def is_bee_file(path): """Check whether the file at the given path is a bee file.""" - print(os.path.splitext(path)[1]) return os.path.splitext(path)[1] == '.bee' diff --git a/beeref/utils.py b/beeref/utils.py index 67c5a34..1ff8113 100644 --- a/beeref/utils.py +++ b/beeref/utils.py @@ -13,6 +13,8 @@ # You should have received a copy of the GNU General Public License # along with BeeRef. If not, see . +import re + from PyQt6 import QtCore, QtGui @@ -66,3 +68,13 @@ def round_to(number, base): """ return base * round(number / base) + + +def get_file_extension_from_format(formatstr): + """Extracts the first file extension from a Qt file dialog format, + e.g. 'JPEG (*.jpg *.jpeg)' yields 'jpg'. + """ + + extensions = re.match(r'.* \((.*)\)', formatstr).groups()[0] + ext = extensions.split()[0] + return ext.removeprefix('*.') diff --git a/beeref/view.py b/beeref/view.py index b21532d..c29e026 100644 --- a/beeref/view.py +++ b/beeref/view.py @@ -31,6 +31,7 @@ from beeref import widgets from beeref.items import BeePixmapItem, BeeTextItem from beeref.main_controls import MainControlsMixin from beeref.scene import BeeGraphicsScene +from beeref.utils import get_file_extension_from_format commandline_args = CommandlineArgs() @@ -366,7 +367,7 @@ class BeeGraphicsView(MainControlsMixin, self.undo_stack.setClean() def do_save(self, filename, create_new): - if not filename.endswith('.bee'): + if not fileio.is_bee_file(filename): filename = f'{filename}.bee' self.worker = fileio.ThreadedIO( fileio.save_bee, filename, self.scene, create_new=create_new) @@ -397,14 +398,20 @@ class BeeGraphicsView(MainControlsMixin, def on_action_export_scene(self): directory = os.path.dirname(self.filename) if self.filename else None - filename, f = QtWidgets.QFileDialog.getSaveFileName( + filename, formatstr = QtWidgets.QFileDialog.getSaveFileName( parent=self, caption='Export Scene to Image', directory=directory, filter=';;'.join(('Image Files (*.png *.jpg *.jpeg)', 'PNG (*.png)', 'JPEG (*.jpg *.jpeg)'))) + if filename: + name, ext = os.path.splitext(filename) + if not ext: + ext = get_file_extension_from_format(formatstr) + filename = f'{filename}.{ext}' + print(filename) logger.debug(f'Got export filename {filename}') exporter = SceneToPixmapExporter(self.scene) dialog = widgets.SceneToPixmapExporterDialog( diff --git a/tests/test_utils.py b/tests/test_utils.py index 3d69f55..48b9845 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -63,3 +63,11 @@ def test_get_rect_from_points_given_topright_bottomleft(): (3.1, 0.5, 3.0)]) def test_round_to(number, base, expected): assert utils.round_to(number, base) == expected + + +@pytest.mark.parametrize('formatstr,expected', + [('Image Files (*.png *.jpg *.jpeg)', 'png'), + ('PNG (*.png)', 'png'), + ('JPEG (*.jpg *.jpeg)', 'jpg')]) +def test_get_file_extension_from_format(formatstr, expected): + assert utils.get_file_extension_from_format(formatstr) == expected diff --git a/tests/test_view.py b/tests/test_view.py index 29b7cf1..814864f 100644 --- a/tests/test_view.py +++ b/tests/test_view.py @@ -311,6 +311,23 @@ def test_on_action_export_scene( assert img.size() == QtCore.QSize(100, 100) +@patch('beeref.widgets.SceneToPixmapExporterDialog.exec') +@patch('beeref.widgets.SceneToPixmapExporterDialog.value') +@patch('PyQt6.QtWidgets.QFileDialog.getSaveFileName') +def test_on_action_export_scene_no_file_extension( + file_mock, value_mock, exec_mock, view, tmpdir): + item = BeeTextItem('foo') + view.scene.addItem(item) + filename = os.path.join(tmpdir, 'test') + assert os.path.exists(filename) is False + file_mock.return_value = (filename, 'PNG (*.png)') + exec_mock.return_value = 1 + value_mock.return_value = QtCore.QSize(100, 100) + view.on_action_export_scene() + img = QtGui.QImage(f'{filename}.png') + assert img.size() == QtCore.QSize(100, 100) + + @patch('beeref.widgets.SceneToPixmapExporterDialog.exec') @patch('beeref.widgets.SceneToPixmapExporterDialog.value') @patch('PyQt6.QtWidgets.QFileDialog.getSaveFileName')