Fit view when pasting/loading images into empty scene

This commit is contained in:
Rebecca Breu 2021-09-04 15:50:26 +02:00
parent 3ee5f65407
commit e08f043361
3 changed files with 57 additions and 9 deletions

View file

@ -8,8 +8,8 @@ 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
* Dragging bee files onto an empty scene will now open them
* Adding the first image(s) to a new scene centers the view
Changed
-------

View file

@ -13,6 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with BeeRef. If not, see <https://www.gnu.org/licenses/>.
from functools import partial
import logging
import os
import os.path
@ -380,7 +381,14 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin):
def on_action_debuglog(self):
gui.DebugLogDialog(self)
def on_insert_images_finished(self, filename, errors):
def on_insert_images_finished(self, new_scene, filename, errors):
"""Callback for when loading of images is finished.
:param new_scene: True if the scene was empty before, else False
:param filename: Not used, for compability only
:param errors: List of filenames that couldn't be loaded
"""
logger.debug('Insert images finished')
if errors:
errornames = [
@ -396,6 +404,8 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin):
self.scene.add_queued_items()
self.scene.arrange_optimal()
self.undo_stack.endMacro()
if new_scene:
self.on_action_fit_scene()
def do_insert_images(self, filenames, pos=None):
if not pos:
@ -408,7 +418,9 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin):
self.mapToScene(pos),
self.scene)
self.worker.progress.connect(self.on_items_loaded)
self.worker.finished.connect(self.on_insert_images_finished)
self.worker.finished.connect(
partial(self.on_insert_images_finished,
not self.scene.items()))
self.progress = gui.BeeProgressDialog(
'Loading images',
worker=self.worker,
@ -464,6 +476,9 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin):
if not img.isNull():
item = BeePixmapItem(img)
self.undo_stack.push(commands.InsertItems(self.scene, [item], pos))
if len(self.scene.items()) == 1:
# This is the first image in the scene
self.on_action_fit_scene()
return
text = clipboard.text()
if text:

View file

@ -291,7 +291,7 @@ def test_on_action_debuglog(show_mock, view):
@patch('beeref.scene.BeeGraphicsScene.clearSelection')
@patch('PyQt6.QtWidgets.QFileDialog.getOpenFileNames')
def test_on_action_insert_images(
def test_on_action_insert_images_new_scene(
dialog_mock, clear_mock, view, imgfilename3x3, qtbot):
dialog_mock.return_value = ([imgfilename3x3], None)
view.on_insert_images_finished = MagicMock()
@ -302,7 +302,24 @@ def test_on_action_insert_images(
assert item.isSelected() is True
assert item.pixmap()
clear_mock.assert_called_once_with()
view.on_insert_images_finished.assert_called_once_with('', [])
view.on_insert_images_finished.assert_called_once_with(True, '', [])
@patch('beeref.scene.BeeGraphicsScene.clearSelection')
@patch('PyQt6.QtWidgets.QFileDialog.getOpenFileNames')
def test_on_action_insert_images_existing_scene(
dialog_mock, clear_mock, view, imgfilename3x3, qtbot, item):
view.scene.addItem(item)
dialog_mock.return_value = ([imgfilename3x3], None)
view.on_insert_images_finished = MagicMock()
view.on_action_insert_images()
qtbot.waitUntil(lambda: view.on_insert_images_finished.called is True)
assert len(view.scene.items()) == 2
item = view.scene.items()[0]
assert item.isSelected() is True
assert item.pixmap()
clear_mock.assert_called_once_with()
view.on_insert_images_finished.assert_called_once_with(False, '', [])
@patch('beeref.scene.BeeGraphicsScene.clearSelection')
@ -319,7 +336,7 @@ def test_on_action_insert_images_when_error(
assert item.pixmap()
clear_mock.assert_called_once_with()
view.on_insert_images_finished.assert_called_once_with(
'', ['iaeiae', 'trntrn'])
True, '', ['iaeiae', 'trntrn'])
@patch('beeref.scene.BeeGraphicsScene.clearSelection')
@ -360,14 +377,30 @@ def test_on_action_copy_text(clipboard_mock, view, imgfilename3x3):
assert mimedata.data('beeref/items') == b'1'
@patch('beeref.view.BeeGraphicsView.on_action_fit_scene')
@patch('beeref.scene.BeeGraphicsScene.clearSelection')
@patch('PyQt6.QtGui.QClipboard.image')
def test_on_action_paste_external(
clipboard_mock, clear_mock, view, imgfilename3x3):
def test_on_action_paste_external_new_scene(
clipboard_mock, clear_mock, fit_mock, view, imgfilename3x3):
clipboard_mock.return_value = QtGui.QImage(imgfilename3x3)
view.on_action_paste()
assert len(view.scene.items()) == 1
assert view.scene.items()[0].isSelected() is True
fit_mock.assert_called_once_with()
@patch('beeref.view.BeeGraphicsView.on_action_fit_scene')
@patch('beeref.scene.BeeGraphicsScene.clearSelection')
@patch('PyQt6.QtGui.QClipboard.image')
def test_on_action_paste_external_existing_scene(
clipboard_mock, clear_mock, fit_mock, view, item, imgfilename3x3):
view.scene.addItem(item)
clipboard_mock.return_value = QtGui.QImage(imgfilename3x3)
view.on_action_paste()
assert len(view.scene.items()) == 2
assert view.scene.items()[0].isSelected() is True
assert view.scene.items()[1].isSelected() is False
fit_mock.assert_not_called()
@patch('beeref.scene.BeeGraphicsScene.clearSelection')