diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3066913..873a6a0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,6 +8,7 @@ Added * You can now add plain text notes and paste text from the clipboard * You can now open bee files from finder on MacOS (by David Andrs) +* You can now drag bee files onto an empty scene to open them Changed diff --git a/beeref/fileio/__init__.py b/beeref/fileio/__init__.py index b6f908c..be90000 100644 --- a/beeref/fileio/__init__.py +++ b/beeref/fileio/__init__.py @@ -20,11 +20,12 @@ from PyQt6 import QtCore from beeref import commands from beeref.fileio.errors import BeeFileIOError from beeref.fileio.image import load_image -from beeref.fileio.sql import SQLiteIO +from beeref.fileio.sql import SQLiteIO, is_bee_file from beeref.items import BeePixmapItem __all__ = [ + 'is_bee_file', 'load_bee', 'save_bee', 'load_images', diff --git a/beeref/fileio/sql.py b/beeref/fileio/sql.py index e78eb98..7ba62d1 100644 --- a/beeref/fileio/sql.py +++ b/beeref/fileio/sql.py @@ -42,6 +42,13 @@ from .schema import SCHEMA, USER_VERSION, MIGRATIONS, APPLICATION_ID logger = logging.getLogger(__name__) +def is_bee_file(path): + """Check wether the file at the given path is a bee file.""" + + print(os.path.splitext(path)[1]) + return os.path.splitext(path)[1] == '.bee' + + def handle_sqlite_errors(func): def wrapper(self, *args, **kwargs): try: diff --git a/beeref/view.py b/beeref/view.py index 5b1fcb9..4f7c3c2 100644 --- a/beeref/view.py +++ b/beeref/view.py @@ -676,6 +676,14 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin): pos = QtCore.QPoint(round(event.position().x()), round(event.position().y())) if mimedata.hasUrls(): + logger.debug(f'Found dropped urls: {mimedata.urls()}') + if not self.scene.items(): + # Check if we have a bee file we can open directly + path = mimedata.urls()[0] + if (path.isLocalFile() + and fileio.is_bee_file(path.toLocalFile())): + self.open_from_file(path.toLocalFile()) + return self.do_insert_images(mimedata.urls(), pos) elif mimedata.hasImage(): img = QtGui.QImage(mimedata.imageData()) diff --git a/tests/fileio/test_sql.py b/tests/fileio/test_sql.py index c8cbd88..a7e9b65 100644 --- a/tests/fileio/test_sql.py +++ b/tests/fileio/test_sql.py @@ -7,12 +7,20 @@ from unittest.mock import MagicMock, patch from PyQt6 import QtGui import pytest -from beeref.fileio import schema +from beeref.fileio import schema, is_bee_file from beeref.fileio.errors import BeeFileIOError from beeref.fileio.sql import SQLiteIO from beeref.items import BeePixmapItem, BeeTextItem +@pytest.mark.parametrize('filename,expected', + [(os.path.join('foo', 'bar.bee'), True), + (os.path.join('foo', 'bar.png'), False), + (os.path.join('foo', 'bar'), False)]) +def test_is_bee_file(filename, expected): + assert is_bee_file(filename) is expected + + def test_sqliteio_migrate_does_nothing_when_version_ok(tmpfile): io = SQLiteIO(tmpfile, MagicMock(), create_new=True) io.ex('PRAGMA user_version=%s' % schema.USER_VERSION) diff --git a/tests/test_view.py b/tests/test_view.py index 6c3ca36..8a73301 100644 --- a/tests/test_view.py +++ b/tests/test_view.py @@ -811,8 +811,7 @@ def test_drag_move(view): @patch('beeref.view.BeeGraphicsView.do_insert_images') def test_drop_when_url(insert_mock, view, imgfilename3x3): - url = QtCore.QUrl() - url.fromLocalFile(imgfilename3x3) + url = QtCore.QUrl.fromLocalFile(imgfilename3x3) mimedata = QtCore.QMimeData() mimedata.setUrls([url]) event = MagicMock() @@ -823,6 +822,39 @@ def test_drop_when_url(insert_mock, view, imgfilename3x3): insert_mock.assert_called_once_with([url], QtCore.QPoint(10, 20)) +@patch('beeref.view.BeeGraphicsView.open_from_file') +def test_drop_when_url_beefile_and_scene_empty(open_mock, view): + root = os.path.dirname(__file__) + filename = os.path.join(root, 'assets', 'test1item.bee') + url = QtCore.QUrl.fromLocalFile(filename) + mimedata = QtCore.QMimeData() + mimedata.setUrls([url]) + event = MagicMock() + event.mimeData.return_value = mimedata + event.position.return_value = QtCore.QPointF(10, 20) + + view.dropEvent(event) + open_mock.assert_called_once_with(filename) + + +@patch('beeref.view.BeeGraphicsView.do_insert_images') +@patch('beeref.view.BeeGraphicsView.open_from_file') +def test_drop_when_url_beefile_and_scene_not_empty( + open_mock, insert_mock, view, item): + view.scene.addItem(item) + root = os.path.dirname(__file__) + filename = os.path.join(root, 'assets', 'test1item.bee') + url = QtCore.QUrl.fromLocalFile(filename) + mimedata = QtCore.QMimeData() + mimedata.setUrls([url]) + event = MagicMock() + event.mimeData.return_value = mimedata + event.position.return_value = QtCore.QPointF(10, 20) + + view.dropEvent(event) + open_mock.assert_not_called() + + def test_drop_when_img(view, imgfilename3x3): mimedata = QtCore.QMimeData() mimedata.setImageData(QtGui.QImage(imgfilename3x3))