Skip to content

Commit

Permalink
Additional unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rbreu committed Dec 3, 2023
1 parent fa9572d commit d3f45f2
Show file tree
Hide file tree
Showing 8 changed files with 247 additions and 161 deletions.
2 changes: 1 addition & 1 deletion beeref/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def __init__(self, app, parent=None):
self.app = app
self.parent = parent
self.settings = BeeSettings()
self.welcome_overlay = widgets.WelcomeOverlay(self)
self.welcome_overlay = widgets.welcome_overlay.WelcomeOverlay(self)

self.setBackgroundBrush(
QtGui.QBrush(QtGui.QColor(*constants.COLORS['Scene:Canvas'])))
Expand Down
137 changes: 3 additions & 134 deletions beeref/widgets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,148 +16,17 @@
import logging
import os.path

from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6 import QtCore, QtWidgets
from PyQt6.QtCore import Qt

from beeref import constants
from beeref.config import logfile_name, BeeSettings
from beeref.main_controls import MainControlsMixin
from beeref.widgets import settings # noqa: F401
from beeref.config import logfile_name
from beeref.widgets import settings, welcome_overlay # noqa: F401


logger = logging.getLogger(__name__)


class RecentFilesModel(QtCore.QAbstractListModel):
"""An entry in the 'Recent Files' list."""

def __init__(self, files):
super().__init__()
self.files = files

def rowCount(self, parent):
return len(self.files)

def data(self, index, role):
if role == QtCore.Qt.ItemDataRole.DisplayRole:
return os.path.basename(self.files[index.row()])
if role == QtCore.Qt.ItemDataRole.FontRole:
font = QtGui.QFont()
font.setUnderline(True)
return font


class RecentFilesView(QtWidgets.QListView):

def __init__(self, parent, files=None):
super().__init__(parent)
self.files = files or []
self.clicked.connect(self.on_clicked)
self.setModel(RecentFilesModel(self.files))
self.setMouseTracking(True)

def on_clicked(self, index):
self.parent().parent().open_from_file(self.files[index.row()])

def update_files(self, files):
self.files = files
self.model().files = files
self.reset()

def sizeHint(self):
size = QtCore.QSize()
height = sum(
(self.sizeHintForRow(i) + 2) for i in range(len(self.files)))
width = max(self.sizeHintForColumn(i) for i in range(len(self.files)))
size.setHeight(height)
size.setWidth(width + 2)
return size

def mouseMoveEvent(self, event):
index = self.indexAt(
QtCore.QPoint(int(event.position().x()),
int(event.position().y())))
if index.isValid():
self.setCursor(Qt.CursorShape.PointingHandCursor)
else:
self.setCursor(Qt.CursorShape.ArrowCursor)

super().mouseMoveEvent(event)


class WelcomeOverlay(MainControlsMixin, QtWidgets.QWidget):
"""Some basic info to be displayed when the scene is empty."""

txt = """<p>Paste or drop images here.</p>
<p>Right-click for more options.</p>"""

def __init__(self, parent):
super().__init__(parent)
self.control_target = parent
self.setAttribute(Qt.WidgetAttribute.WA_NoSystemBackground)
self.init_main_controls(main_window=parent.parent)

# Recent files
self.files_layout = QtWidgets.QVBoxLayout()
self.files_layout.addStretch(50)
self.files_layout.addWidget(
QtWidgets.QLabel('<h3>Recent Files</h3>', self))
self.files_view = RecentFilesView(self)
self.files_layout.addWidget(self.files_view)
self.files_layout.addStretch(50)

# Help text
self.label = QtWidgets.QLabel(self.txt, self)
self.label.setAlignment(Qt.AlignmentFlag.AlignVCenter
| Qt.AlignmentFlag.AlignCenter)
self.layout = QtWidgets.QHBoxLayout()
self.layout.addStretch(50)
self.layout.addWidget(self.label)
self.layout.addStretch(50)
self.setLayout(self.layout)

def show(self):
files = BeeSettings().get_recent_files(existing_only=True)
self.files_view.update_files(files)
if files and self.layout.indexOf(self.files_layout) < 0:
self.layout.insertLayout(0, self.files_layout)
super().show()

def disable_mouse_events(self):
self.files_view.setAttribute(
Qt.WidgetAttribute.WA_TransparentForMouseEvents)
self.label.setAttribute(
Qt.WidgetAttribute.WA_TransparentForMouseEvents)

def enable_mouse_events(self):
self.files_view.setAttribute(
Qt.WidgetAttribute.WA_TransparentForMouseEvents,
on=False)
self.label.setAttribute(
Qt.WidgetAttribute.WA_TransparentForMouseEvents,
on=False)

def mousePressEvent(self, event):
if self.mousePressEventMainControls(event):
return
super().mousePressEvent(event)

def mouseMoveEvent(self, event):
if self.mouseMoveEventMainControls(event):
return
super().mouseMoveEvent(event)

def mouseReleaseEvent(self, event):
if self.mouseReleaseEventMainControls(event):
return
super().mouseReleaseEvent(event)

def keyPressEvent(self, event):
if self.keyPressEventMainControls(event):
return
super().keyPressEvent(event)


class BeeProgressDialog(QtWidgets.QProgressDialog):

def __init__(self, label, worker, maximum=0, parent=None):
Expand Down
156 changes: 156 additions & 0 deletions beeref/widgets/welcome_overlay.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# This file is part of BeeRef.
#
# BeeRef is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BeeRef is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BeeRef. If not, see <https://www.gnu.org/licenses/>.

import logging
import os.path

from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6.QtCore import Qt

from beeref.config import BeeSettings
from beeref.main_controls import MainControlsMixin


logger = logging.getLogger(__name__)


class RecentFilesModel(QtCore.QAbstractListModel):
"""An entry in the 'Recent Files' list."""

def __init__(self, files):
super().__init__()
self.files = files

def rowCount(self, parent):
return len(self.files)

def data(self, index, role):
if role == QtCore.Qt.ItemDataRole.DisplayRole:
return os.path.basename(self.files[index.row()])
if role == QtCore.Qt.ItemDataRole.FontRole:
font = QtGui.QFont()
font.setUnderline(True)
return font


class RecentFilesView(QtWidgets.QListView):

def __init__(self, parent, files=None):
super().__init__(parent)
self.files = files or []
self.clicked.connect(self.on_clicked)
self.setModel(RecentFilesModel(self.files))
self.setMouseTracking(True)

def on_clicked(self, index):
self.parent().parent().open_from_file(self.files[index.row()])

def update_files(self, files):
self.files = files
self.model().files = files
self.reset()

def sizeHint(self):
size = QtCore.QSize()
height = sum(
(self.sizeHintForRow(i) + 2) for i in range(len(self.files)))
width = max(self.sizeHintForColumn(i) for i in range(len(self.files)))
size.setHeight(height)
size.setWidth(width + 2)
return size

def mouseMoveEvent(self, event):
index = self.indexAt(
QtCore.QPoint(int(event.position().x()),
int(event.position().y())))
if index.isValid():
self.setCursor(Qt.CursorShape.PointingHandCursor)
else:
self.setCursor(Qt.CursorShape.ArrowCursor)

super().mouseMoveEvent(event)


class WelcomeOverlay(MainControlsMixin, QtWidgets.QWidget):
"""Some basic info to be displayed when the scene is empty."""

txt = """<p>Paste or drop images here.</p>
<p>Right-click for more options.</p>"""

def __init__(self, parent):
super().__init__(parent)
self.control_target = parent
self.setAttribute(Qt.WidgetAttribute.WA_NoSystemBackground)
self.init_main_controls(main_window=parent.parent)

# Recent files
self.files_layout = QtWidgets.QVBoxLayout()
self.files_layout.addStretch(50)
self.files_layout.addWidget(
QtWidgets.QLabel('<h3>Recent Files</h3>', self))
self.files_view = RecentFilesView(self)
self.files_layout.addWidget(self.files_view)
self.files_layout.addStretch(50)

# Help text
self.label = QtWidgets.QLabel(self.txt, self)
self.label.setAlignment(Qt.AlignmentFlag.AlignVCenter
| Qt.AlignmentFlag.AlignCenter)
self.layout = QtWidgets.QHBoxLayout()
self.layout.addStretch(50)
self.layout.addWidget(self.label)
self.layout.addStretch(50)
self.setLayout(self.layout)

def show(self):
files = BeeSettings().get_recent_files(existing_only=True)
self.files_view.update_files(files)
if files and self.layout.indexOf(self.files_layout) < 0:
self.layout.insertLayout(0, self.files_layout)
super().show()

def disable_mouse_events(self):
self.files_view.setAttribute(
Qt.WidgetAttribute.WA_TransparentForMouseEvents)
self.label.setAttribute(
Qt.WidgetAttribute.WA_TransparentForMouseEvents)

def enable_mouse_events(self):
self.files_view.setAttribute(
Qt.WidgetAttribute.WA_TransparentForMouseEvents,
on=False)
self.label.setAttribute(
Qt.WidgetAttribute.WA_TransparentForMouseEvents,
on=False)

def mousePressEvent(self, event):
if self.mousePressEventMainControls(event):
return
super().mousePressEvent(event)

def mouseMoveEvent(self, event):
if self.mouseMoveEventMainControls(event):
return
super().mouseMoveEvent(event)

def mouseReleaseEvent(self, event):
if self.mouseReleaseEventMainControls(event):
return
super().mouseReleaseEvent(event)

def keyPressEvent(self, event):
if self.keyPressEventMainControls(event):
return
super().keyPressEvent(event)
14 changes: 14 additions & 0 deletions tests/items/test_textitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,20 @@ def test_key_press_event_enter(exit_mock, key_press_mock, view):
exit_mock.assert_called_once_with()


@patch('PyQt6.QtWidgets.QGraphicsTextItem.keyPressEvent')
@patch('beeref.items.BeeTextItem.exit_edit_mode')
def test_key_press_event_escape(exit_mock, key_press_mock, view):
item = BeeTextItem('foo bar')
view.scene.addItem(item)
view.scene.edit_item = item
event = MagicMock()
event.key.return_value = Qt.Key.Key_Escape
event.modifiers.return_value = Qt.KeyboardModifier.NoModifier
item.keyPressEvent(event)
key_press_mock.assert_not_called()
exit_mock.assert_called_once_with(commit=False)


def test_item_to_clipboard(qapp):
clipboard = QtWidgets.QApplication.clipboard()
item = BeeTextItem('foo bar')
Expand Down
6 changes: 3 additions & 3 deletions tests/test_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def test_init_with_filename(open_file_mock, view, qapp, commandline_args):
del view


@patch('beeref.widgets.WelcomeOverlay.hide')
@patch('beeref.widgets.welcome_overlay.WelcomeOverlay.hide')
def test_on_scene_changed_when_items(hide_mock, view):
item = BeePixmapItem(QtGui.QImage())
view.scene.addItem(item)
Expand All @@ -51,7 +51,7 @@ def test_on_scene_changed_when_items(hide_mock, view):
assert view.get_scale() == 2


@patch('beeref.widgets.WelcomeOverlay.show')
@patch('beeref.widgets.welcome_overlay.WelcomeOverlay.show')
def test_on_scene_changed_when_no_items(show_mock, view):
view.scale(2, 2)
with patch('beeref.view.BeeGraphicsView.recalc_scene_rect') as r:
Expand Down Expand Up @@ -600,7 +600,7 @@ def test_on_action_show_titlebar_unchecked(
create_mock.assert_called_once()


@patch('beeref.widgets.WelcomeOverlay.cursor')
@patch('beeref.widgets.welcome_overlay.WelcomeOverlay.cursor')
def test_on_action_move_window_when_welcome_overlay(cursor_mock, view):
cursor_mock.return_value = MagicMock(
pos=MagicMock(return_value=QtCore.QPointF(10.0, 20.0)))
Expand Down
Loading

0 comments on commit d3f45f2

Please sign in to comment.