Skip to content
Snippets Groups Projects
Commit 012e0983 authored by Anders H. Rebner's avatar Anders H. Rebner
Browse files

Merge branch 'module-phonebook' into 'master'

#96 Telefonliste & Fiks til høyde på tabeller (rundt oppløsning)

See merge request !57
parents beb28931 5116537f
No related branches found
No related tags found
1 merge request!57#96 Telefonliste & Fiks til høyde på tabeller (rundt oppløsning)
Pipeline #83854 passed with stages
in 2 minutes and 33 seconds
Showing
with 639 additions and 27 deletions
soitool/media/phonetable.png

9.83 KiB

...@@ -44,9 +44,7 @@ class CodeTableBase(ModuleBase, QTableWidget, metaclass=Meta): ...@@ -44,9 +44,7 @@ class CodeTableBase(ModuleBase, QTableWidget, metaclass=Meta):
# Resize table when headline changes # Resize table when headline changes
self.cellChanged.connect( self.cellChanged.connect(
lambda: resize_table( lambda: resize_table(self, columns=False, has_headline=True,)
self, rows=False, columns=False, has_headline=True,
)
) )
# If parameters are None, launch settings-dialog and generate new table # If parameters are None, launch settings-dialog and generate new table
if size is None and data is None: if size is None and data is None:
...@@ -81,7 +79,7 @@ class CodeTableBase(ModuleBase, QTableWidget, metaclass=Meta): ...@@ -81,7 +79,7 @@ class CodeTableBase(ModuleBase, QTableWidget, metaclass=Meta):
self.insert_headline(self.start_headline) self.insert_headline(self.start_headline)
resize_table( resize_table(
self, columns=False, rows=False, has_headline=True, self, columns=False, has_headline=True,
) )
else: else:
self.code_length = data["code_length"] self.code_length = data["code_length"]
...@@ -108,7 +106,7 @@ class CodeTableBase(ModuleBase, QTableWidget, metaclass=Meta): ...@@ -108,7 +106,7 @@ class CodeTableBase(ModuleBase, QTableWidget, metaclass=Meta):
self.insert_headline(cells[0]) self.insert_headline(cells[0])
resize_table( resize_table(
self, columns=False, rows=False, has_headline=True, self, columns=False, has_headline=True,
) )
self.setFixedWidth(size["width"]) self.setFixedWidth(size["width"])
self.setFixedHeight(size["height"]) self.setFixedHeight(size["height"])
......
{
"Funksjon": true,
"Telefon": true,
"FDN": false,
"Iridium": false,
"E-post": false
}
...@@ -51,10 +51,12 @@ class TableWithSizeOfContent(QTableWidget): ...@@ -51,10 +51,12 @@ class TableWithSizeOfContent(QTableWidget):
def __init__(self, *arg, **kwargs): def __init__(self, *arg, **kwargs):
super(TableWithSizeOfContent, self).__init__(*arg, **kwargs) super(TableWithSizeOfContent, self).__init__(*arg, **kwargs)
# Makes table fit content of cells # Fixed size because resizing to contents causes size that depends on
# screen size, which we don't want..
self.verticalHeader().setSectionResizeMode( self.verticalHeader().setSectionResizeMode(
QHeaderView.ResizeMode.ResizeToContents QHeaderView.ResizeMode.Fixed
) )
# Make columns fit size of content
self.horizontalHeader().setSectionResizeMode( self.horizontalHeader().setSectionResizeMode(
QHeaderView.ResizeMode.ResizeToContents QHeaderView.ResizeMode.ResizeToContents
) )
......
...@@ -151,7 +151,7 @@ class AuthenticationBoardModule(CodeTableBase): ...@@ -151,7 +151,7 @@ class AuthenticationBoardModule(CodeTableBase):
self.resizeRowToContents(selected_row_index + 1) self.resizeRowToContents(selected_row_index + 1)
resize_table(self, columns=False, rows=False, has_headline=True) resize_table(self, columns=False, has_headline=True)
def remove_row(self, row_index): def remove_row(self, row_index):
"""Remove selected row. """Remove selected row.
...@@ -168,7 +168,7 @@ class AuthenticationBoardModule(CodeTableBase): ...@@ -168,7 +168,7 @@ class AuthenticationBoardModule(CodeTableBase):
for i in range(row_index, self.rowCount()): for i in range(row_index, self.rowCount()):
self.item(i, 0).setText(self.code_characters[i - 1]) self.item(i, 0).setText(self.code_characters[i - 1])
self.item(i, 1).setText(str(i - 1)) self.item(i, 1).setText(str(i - 1))
resize_table(self, columns=False, rows=False, has_headline=True) resize_table(self, columns=False, has_headline=True)
def generate_authentication_numbers(self): def generate_authentication_numbers(self):
"""Generate two non-equal numbers between 1 and self.code_length. """Generate two non-equal numbers between 1 and self.code_length.
......
...@@ -62,15 +62,16 @@ class ModuleBase(ABC): ...@@ -62,15 +62,16 @@ class ModuleBase(ABC):
raise NotImplementedError raise NotImplementedError
def resize_table(table, rows=True, columns=True, has_headline=False): def resize_table(table, columns=True, has_headline=False):
"""Resize a given QTableWidget. """Resize a given QTableWidget.
On purpose not resizing rows, as this causes different heights from screen
to screen.
Parameters Parameters
---------- ----------
table : QTableWidget table : QTableWidget
QTablewidget-instance to resize. QTablewidget-instance to resize.
rows : bool
Resizes rows to contents if True, by default True.
columns : bool columns : bool
Resizes columns to contents if True, by default True. Resizes columns to contents if True, by default True.
has_headline : bool has_headline : bool
...@@ -79,8 +80,6 @@ def resize_table(table, rows=True, columns=True, has_headline=False): ...@@ -79,8 +80,6 @@ def resize_table(table, rows=True, columns=True, has_headline=False):
""" """
if columns: if columns:
table.resizeColumnsToContents() table.resizeColumnsToContents()
if rows:
table.resizeRowsToContents()
# If table has a headline, make sure table is wide enough to fit it. # If table has a headline, make sure table is wide enough to fit it.
if has_headline: if has_headline:
...@@ -175,10 +174,10 @@ def event_is_ctrl_minus(event): ...@@ -175,10 +174,10 @@ def event_is_ctrl_minus(event):
bool bool
True if event is 'CTRL -'. True if event is 'CTRL -'.
""" """
# Underline is in practice minus in this situation. We don't know why # Underline is in practice minus on some computers in this situation. We
return ( # don't know why. For this reason we check both for underline and minus
event.modifiers() == Qt.ControlModifier return event.modifiers() == Qt.ControlModifier and (
and event.key() == Qt.Key_Underscore event.key() == Qt.Key_Underscore or event.key() == Qt.Key_Minus
) )
...@@ -211,8 +210,8 @@ def event_is_shift_minus(event): ...@@ -211,8 +210,8 @@ def event_is_shift_minus(event):
bool bool
True if event is 'SHIFT -'. True if event is 'SHIFT -'.
""" """
# Underline is in practice minus in this situation. We don't know why # Underline is in practice minus on some computers in this situation. We
return ( # don't know why. For this reason we check both for underline and minus
event.modifiers() == Qt.ShiftModifier return event.modifiers() == Qt.ShiftModifier and (
and event.key() == Qt.Key_Underscore event.key() == Qt.Key_Underscore or event.key() == Qt.Key_Minus
) )
...@@ -95,6 +95,9 @@ class CodePhraseModule(ModuleBase, QWidget, metaclass=Meta): ...@@ -95,6 +95,9 @@ class CodePhraseModule(ModuleBase, QWidget, metaclass=Meta):
self.table.setHorizontalHeaderItem(1, QTableWidgetItem("Frase")) self.table.setHorizontalHeaderItem(1, QTableWidgetItem("Frase"))
self.table.horizontalHeader().setStyleSheet("font-weight: bold") self.table.horizontalHeader().setStyleSheet("font-weight: bold")
# Forcing height of the header because it changes from screen to screen
self.table.horizontalHeader().setFixedHeight(30)
# To ensure table is initially larger than title # To ensure table is initially larger than title
self.table.horizontalHeader().setMinimumSectionSize(100) self.table.horizontalHeader().setMinimumSectionSize(100)
self.table.verticalHeader().hide() self.table.verticalHeader().hide()
......
"""SOI module for functions and associated contact informations."""
from json import load
from PySide2.QtWidgets import (
QWidget,
QDialog,
QLabel,
QVBoxLayout,
QTableWidget,
QPushButton,
QHBoxLayout,
QTableWidgetItem,
QCheckBox,
)
from PySide2.QtCore import Qt, QSize
from PySide2.QtGui import QBrush, QColor, QIcon
from soitool.modules.module_base import (
ModuleBase,
HEADLINE_FONT,
resize_table,
get_table_size,
TABLE_CELL_DEFAULT_FONT,
event_is_ctrl_plus,
event_is_ctrl_minus,
)
class ColumnsChoicePopup(QDialog):
"""A popup for selecting wich columns to hide/show in phonebook.
Parameters
----------
QDialog : QDialog
Parent class for popup functionality.
selected_columns : dict
Table structure for columns to show/hide.
"""
def __init__(self, selected_columns):
super().__init__()
self.selected_columns = selected_columns
self.setWindowTitle("Kolonner")
# Layout
layout = QVBoxLayout()
# Checkboxes
for header in self.selected_columns.keys():
box = QCheckBox(header)
box.setChecked(self.selected_columns[header])
layout.addWidget(box)
# Button
btn_done = QPushButton("Bruk")
btn_done.clicked.connect(lambda: self.update_selected_columns(layout))
layout.addWidget(btn_done)
self.setLayout(layout)
def update_selected_columns(self, layout):
"""Update the dict for columns to hide/show based on checkboxes.
Parameters
----------
layout : QLayout
Layout with checkboxes to loop trough.
"""
for item_index in range(layout.count()):
item = layout.itemAt(item_index).widget()
if isinstance(item, QCheckBox):
self.selected_columns[item.text()] = item.isChecked()
self.accept()
def get_selected_columns(self):
"""Getter for the table structure.
Returns
-------
dict
The table structure.
"""
return self.selected_columns
class Meta(type(ModuleBase), type(QWidget)):
"""Used as a metaclass to enable multiple inheritance."""
class PhonebookModule(ModuleBase, QWidget, metaclass=Meta):
"""SOI module for functions and associated contact informations.
# This module includes:
## Components
* Header
* Table with predefined columns
* Buttons for editing module
* Popup (ColumnsChoicePopup)
## Features
* Keybord shortcuts for editing module
* Buttons only visble when mouse in modules space
* Interface generated from config file
* Popup for editing columns
* Automatic resizing
* Able to be loaded from data parameter
Parameters
----------
data : dict
Module content, used if not None. See self.get_data()
"""
def __init__(self, data=None):
self.type = PhonebookModule.__name__
QWidget.__init__(self)
ModuleBase.__init__(self)
# Table structure
with open(
"soitool/modules/config/module_phonebook.json", "r"
) as config_file:
self.selected_columns = load(config_file)
# Header
self.header = QLabel("Telefonliste")
self.header.setFont(HEADLINE_FONT)
self.header.setFixedSize(QSize(160, 20))
# Table
self.table = self.__create_table()
self.table.cellChanged.connect(self.resize)
# Buttons
self.buttons = self.__creat_buttons()
# Layout
layout = QVBoxLayout()
layout.setAlignment(Qt.AlignTop | Qt.AlignLeft)
layout.setSpacing(0)
layout.setMargin(0)
layout.addWidget(self.header)
layout.addWidget(self.table)
layout.addWidget(self.buttons)
self.setLayout(layout)
if data:
self.load_data_to_module(data)
else:
self.set_columns()
# !!!!! CREATE MAIN COMPONENTS !!!!!!
def __create_table(self):
"""Add phonebook table.
Returns
-------
QTableWidget
The phonebook table.
"""
table = QTableWidget(2, len(self.selected_columns))
table.setFont(TABLE_CELL_DEFAULT_FONT)
table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
table.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
table.horizontalHeader().hide()
table.verticalHeader().hide()
# Headers - setup
column_index = 0
for header in self.selected_columns:
header_item = QTableWidgetItem(header)
header_item.setFont(HEADLINE_FONT)
header_item.setFlags(header_item.flags() ^ Qt.ItemIsEditable)
header_item.setBackground(QBrush(QColor("black")))
header_item.setForeground(QBrush(QColor("white")))
table.setItem(0, column_index, header_item)
column_index += 1
return table
def __creat_buttons(self):
"""Add buttons for editing phonebook table.
Returns
-------
QWidget
Widget holding a layout with buttons.
"""
# Button for editing columns
btn_components = QPushButton("Kolonner", self)
btn_components.clicked.connect(self.open_popup)
btn_components.setFixedWidth(100)
# Buttons for adding row
btn_add = QPushButton(" + ", self)
btn_add.clicked.connect(self.add_row)
btn_add.setFixedWidth(50)
# Buttons for removing row
btn_remove = QPushButton(" - ", self)
btn_remove.clicked.connect(self.remove_row)
btn_remove.setFixedWidth(50)
# Layout for structure
hbox = QHBoxLayout()
hbox.setSpacing(0)
hbox.setSpacing(0)
hbox.addWidget(btn_components)
hbox.addWidget(btn_add)
hbox.addWidget(btn_remove)
# Widget wrapping buttons
wrapper = QWidget()
wrapper.setFixedSize(QSize(230, 50))
wrapper.setLayout(hbox)
wrapper.hide()
return wrapper
# !!!!! EVENT HADNDLERS !!!!!
def enterEvent(self, event):
"""Eventhandler for showing buttons when mous enters widgets space.
Parameters
----------
event : enterEvent
Called when mouse enters widgets space.
"""
self.buttons.show()
self.resize()
QTableWidget.enterEvent(self, event)
def leaveEvent(self, event):
"""Eventhandler for hiding buttons when mouse leaves widgets space.
Parameters
----------
event : enterEvent
Called when mosue leaves widgets space.
"""
self.buttons.hide()
self.resize()
QTableWidget.enterEvent(self, event)
def keyPressEvent(self, event):
"""Keyboard shortcuts for adding/removing rows and selecting columns.
Parameters
----------
event : keyPressEvent
Called when keys are pressed.
"""
if event_is_ctrl_plus(event):
self.add_row()
elif event_is_ctrl_minus(event):
self.remove_row()
elif (
event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_R
):
self.open_popup()
else:
super().keyPressEvent(event)
# !!!!! TABLE OPERATIONS !!!!!
def add_row(self):
"""Add row to phonebook table."""
self.table.insertRow(self.table.currentRow() + 1)
self.resize()
def remove_row(self):
"""Remove selected row from phonebook table."""
if self.table.currentRow() > 0:
self.table.removeRow(self.table.currentRow())
self.resize()
def set_columns(self):
"""Update table columns visibility based on selected_columns."""
selected_item = self.table.currentItem()
for header in self.selected_columns.keys():
self.table.setColumnHidden(
self.get_column_index_by_header(header),
not (self.selected_columns[header]),
)
# Restore selected item, because the above operation sets the current
# selected item to the item in the last column of the first row.
self.table.setCurrentItem(selected_item)
self.resize()
def get_column_index_by_header(self, header):
"""Get index for column containing a spesific header.
Parameters
----------
header : string
The header to search for.
Returns
-------
int
The column index for where the header was found.
Raises
------
LookupError
Unable to find header in table headers.
"""
for column_index in range(self.table.columnCount()):
self.table.setCurrentCell(0, column_index)
if self.table.currentItem().text() == header:
return column_index
raise LookupError("'" + header + "' not in table headers.")
# !!!!! MODULE OPERATIONs !!!!!
def resize(self):
"""Resize whole module based on content."""
resize_table(self.table)
width = max(get_table_size(self.table)[0], self.header.minimumWidth())
if self.buttons.isVisible():
width = max(width, self.buttons.minimumWidth())
self.setFixedWidth(width)
height = get_table_size(self.table)[1] + self.header.minimumHeight()
if self.buttons.isVisible():
height += self.buttons.minimumHeight()
self.setFixedHeight(height)
def load_data_to_module(self, data):
"""Load module content from data.
Parameters
----------
data : dict
Module serialized as dict.
"""
for column_header in self.selected_columns.keys():
if column_header in data.keys():
self.selected_columns[column_header] = True
else:
self.selected_columns[column_header] = False
self.set_columns()
number_of_rows = len(list(data.values())[0])
self.table.setRowCount(self.table.rowCount() + number_of_rows - 1)
for column_header in data.keys():
column_index = self.get_column_index_by_header(column_header)
for row_index in range(1, number_of_rows + 1):
current_item = QTableWidgetItem(
data[column_header][row_index - 1]
)
self.table.setItem(row_index, column_index, current_item)
# To stop the last column of the first row to be selected, which looks
# strange on windows
self.table.clearSelection()
def open_popup(self):
"""Open dialog for editing columns."""
popup = ColumnsChoicePopup(self.selected_columns)
popup.exec_()
self.selected_columns = popup.get_selected_columns()
self.set_columns()
# !!!!! MODULE BASE OPERATIONS !!!!!
def get_size(self):
"""Getter for module size.
Returns
-------
tuple
Size of the module (width, height)
"""
self.resize()
return (self.minimumWidth(), self.minimumHeight())
def get_data(self):
"""Get module content as serialized data.
Returns
-------
dict
Serialized module content.
Format: {
"header1" : ["row1", "row2", "row3"],
"header2": ["row1", ..]
}
"""
data = {}
for column_index in range(self.table.columnCount()):
header = self.table.item(0, column_index).text()
if self.selected_columns[header]:
row_data = []
for row_index in range(1, self.table.rowCount()):
row_item = self.table.item(row_index, column_index)
if row_item:
row_data.append(row_item.text())
else:
row_data.append("")
data[header] = row_data
return data
@staticmethod
def get_user_friendly_name():
"""Get user-friendly name of module.
Returns
-------
string
User-friendly name.
"""
return "Telefonliste"
@staticmethod
def get_icon():
"""Get icon.
Returns
-------
QIcon
Picture of module.
"""
return QIcon("soitool/media/phonetable.png")
...@@ -507,7 +507,7 @@ class PredefinedCodesTable(QTableWidget): ...@@ -507,7 +507,7 @@ class PredefinedCodesTable(QTableWidget):
# Insert headline and resize table # Insert headline and resize table
self.insert_headline(headline) self.insert_headline(headline)
resize_table(self, rows=False, columns=False, has_headline=True) resize_table(self, columns=False, has_headline=True)
def insert_headline(self, text): def insert_headline(self, text):
"""Insert headline. """Insert headline.
......
...@@ -130,7 +130,7 @@ class SubtractorcodesModule(CodeTableBase): ...@@ -130,7 +130,7 @@ class SubtractorcodesModule(CodeTableBase):
self.setItem(selected_row_index + 1, 2, item_code) self.setItem(selected_row_index + 1, 2, item_code)
self.resizeRowToContents(selected_row_index + 1) self.resizeRowToContents(selected_row_index + 1)
resize_table(self, columns=False, rows=False, has_headline=True) resize_table(self, columns=False, has_headline=True)
def remove_row(self, row_index): def remove_row(self, row_index):
"""Remove the selected row. """Remove the selected row.
...@@ -143,7 +143,7 @@ class SubtractorcodesModule(CodeTableBase): ...@@ -143,7 +143,7 @@ class SubtractorcodesModule(CodeTableBase):
self.removeRow(row_index) self.removeRow(row_index)
self.insert_row_identifiers(has_headline=True) self.insert_row_identifiers(has_headline=True)
resize_table(self, columns=False, rows=False, has_headline=True) resize_table(self, columns=False, has_headline=True)
@staticmethod @staticmethod
def get_user_friendly_name(): def get_user_friendly_name():
......
...@@ -16,6 +16,7 @@ from soitool.modules.module_authentication_board import ( ...@@ -16,6 +16,7 @@ from soitool.modules.module_authentication_board import (
) )
from soitool.modules.module_subtractorcodes import SubtractorcodesModule from soitool.modules.module_subtractorcodes import SubtractorcodesModule
from soitool.modules.module_freetext import FreeTextModule from soitool.modules.module_freetext import FreeTextModule
from soitool.modules.module_phonebook import PhonebookModule
from soitool.modules.module_code_phrase import CodePhraseModule from soitool.modules.module_code_phrase import CodePhraseModule
from soitool.modules.module_predefined_codes import PredefinedCodesModule from soitool.modules.module_predefined_codes import PredefinedCodesModule
from soitool.accept_reject_dialog import AcceptRejectDialog from soitool.accept_reject_dialog import AcceptRejectDialog
...@@ -29,6 +30,7 @@ MODULE_CHOICES = [ ...@@ -29,6 +30,7 @@ MODULE_CHOICES = [
AuthenticationBoardModule, AuthenticationBoardModule,
SubtractorcodesModule, SubtractorcodesModule,
FreeTextModule, FreeTextModule,
PhonebookModule,
CodePhraseModule, CodePhraseModule,
PredefinedCodesModule, PredefinedCodesModule,
] ]
......
...@@ -10,6 +10,7 @@ from soitool.modules.module_authentication_board import ( ...@@ -10,6 +10,7 @@ from soitool.modules.module_authentication_board import (
) )
from soitool.modules.module_subtractorcodes import SubtractorcodesModule from soitool.modules.module_subtractorcodes import SubtractorcodesModule
from soitool.modules.module_freetext import FreeTextModule from soitool.modules.module_freetext import FreeTextModule
from soitool.modules.module_phonebook import PhonebookModule
from soitool.modules.module_predefined_codes import PredefinedCodesModule from soitool.modules.module_predefined_codes import PredefinedCodesModule
from soitool.modules.module_code_phrase import CodePhraseModule from soitool.modules.module_code_phrase import CodePhraseModule
...@@ -322,6 +323,10 @@ def construct_modules_from_serialized(serialized_modules, database): ...@@ -322,6 +323,10 @@ def construct_modules_from_serialized(serialized_modules, database):
modules.append( modules.append(
{"widget": FreeTextModule(size, data), "meta": module["meta"]} {"widget": FreeTextModule(size, data), "meta": module["meta"]}
) )
elif module_type == "PhonebookModule":
modules.append(
{"widget": PhonebookModule(data), "meta": module["meta"]}
)
elif module_type == "PredefinedCodesModule": elif module_type == "PredefinedCodesModule":
modules.append( modules.append(
{ {
......
"""Test module_phonebook.py."""
import unittest
from PySide2.QtGui import qApp, QKeySequence
from PySide2.QtCore import Qt, QTimer
from PySide2.QtTest import QTest
from PySide2.QtWidgets import (
QApplication,
QCheckBox,
QPushButton,
QTableWidgetItem,
)
from soitool.soi import SOI
from soitool.modules.module_phonebook import PhonebookModule
if isinstance(qApp, type(None)):
app = QApplication([])
else:
app = qApp
class TestPhonebookModule(unittest.TestCase):
"""TestCase for default PhonebookModule."""
def setUp(self):
"""Prepare a plane PhonebookModule."""
self.phonebook = PhonebookModule()
self.phonebook.show()
def test_header(self):
"""Test header is correct."""
self.assertEqual(self.phonebook.header.text(), "Telefonliste")
def test_resize_width(self):
"""Test able to type in table and resize to content."""
rambo_quote = "Live for nothing or die for something."
item = QTableWidgetItem(rambo_quote)
old_width = self.phonebook.minimumWidth()
self.phonebook.table.setItem(1, 0, item)
new_width = self.phonebook.minimumWidth()
self.assertGreater(new_width, old_width)
def test_popup(self):
"""Test popup is shown and i able to edit columns."""
old_column_count = visible_columns_in(self.phonebook.table)
def popup_action():
popup = app.activeModalWidget().layout()
for item_index in range(popup.count()):
current_item = popup.itemAt(item_index).widget()
if (
isinstance(current_item, QCheckBox)
and current_item.text() == "E-post"
):
current_item.setChecked(True)
elif isinstance(current_item, QPushButton):
QTest.mouseClick(current_item, Qt.LeftButton)
QTimer.singleShot(0, popup_action)
QTest.keySequence(
self.phonebook, QKeySequence(Qt.ControlModifier + Qt.Key_R)
)
new_column_count = visible_columns_in(self.phonebook.table)
self.assertEqual(new_column_count, old_column_count + 1)
def test_add_row_and_resize(self):
"""Test adding row and resizes acordingly."""
old_row_count = self.phonebook.table.rowCount()
old_height = self.phonebook.minimumHeight()
QTest.keySequence(
self.phonebook, QKeySequence(Qt.ControlModifier + Qt.Key_Plus)
)
new_row_count = self.phonebook.table.rowCount()
new_height = self.phonebook.minimumHeight()
self.assertEqual(new_row_count, old_row_count + 1)
self.assertGreater(new_height, old_height)
def test_remove_row(self):
"""Test removing row."""
self.phonebook.table.setRowCount(self.phonebook.table.rowCount() + 5)
old_row_count = self.phonebook.table.rowCount()
self.phonebook.table.setCurrentCell(1, 0)
QTest.keySequence(
self.phonebook, QKeySequence(Qt.ControlModifier + Qt.Key_Minus),
)
new_row_count = self.phonebook.table.rowCount()
self.assertEqual(new_row_count, old_row_count - 1)
def test_add_to_soi_smoke_test(self):
"""Test that can add to SOI successfully."""
soi = SOI()
test_name = "Test name"
soi.add_module(test_name, self.phonebook, False)
self.assertTrue(soi.module_name_taken(test_name))
class TestPhonebookModuleWithDataParameter(unittest.TestCase):
"""TestCase for PhoneBookModule with content preset."""
def setUp(self):
"""Prepare a phonebook with preloaded content."""
self.data = {
"Funksjon": ["Colonel Sam", "Rambo", ""],
"E-post": ["sam@usarmy.com", "muscle@guns.com", ""],
}
self.phonebook = PhonebookModule(data=self.data)
self.phonebook.show()
def test_column_count(self):
"""Test number of visible columns is correct."""
self.assertEqual(
len(self.data), visible_columns_in(self.phonebook.table)
)
def test_content(self):
"""Test content is loaded correctly."""
for column_index in range(self.phonebook.table.columnCount()):
self.phonebook.table.setCurrentCell(0, column_index)
column_header = self.phonebook.table.currentItem().text()
if not self.phonebook.table.isColumnHidden(column_index):
for row_index in range(1, self.phonebook.table.rowCount()):
self.phonebook.table.setCurrentCell(
row_index, column_index
)
current_text = self.phonebook.table.currentItem().text()
self.assertEqual(
current_text, self.data[column_header][row_index - 1]
)
def test_add_to_soi_smoketest(self):
"""Test that can add to SOI successfully."""
soi = SOI()
test_name = "Test name"
soi.add_module(test_name, self.phonebook, False)
self.assertTrue(soi.module_name_taken(test_name))
def visible_columns_in(table):
"""Count number of visible columns in a table.
Parameters
----------
table : QTableWidget
The table to count visible columns in.
Returns
-------
counter : int
Number of visible columns in table.
"""
counter = 0
for column_index in range(table.columnCount()):
if not table.isColumnHidden(column_index):
counter += 1
return counter
...@@ -109,8 +109,9 @@ class TestModulesAcrossResolutions(unittest.TestCase): ...@@ -109,8 +109,9 @@ class TestModulesAcrossResolutions(unittest.TestCase):
{"x": 664, "y": 0, "page": 1, "name": "AuthenticationBoardModule"}, {"x": 664, "y": 0, "page": 1, "name": "AuthenticationBoardModule"},
{"x": 1081.5, "y": 0, "page": 1, "name": "SubtractorcodesModule"}, {"x": 1081.5, "y": 0, "page": 1, "name": "SubtractorcodesModule"},
{"x": 1317.0, "y": 0, "page": 1, "name": "CodePhraseModule"}, {"x": 1317.0, "y": 0, "page": 1, "name": "CodePhraseModule"},
{"x": 1529.0, "y": 0, "page": 1, "name": "FreeTextModule"}, {"x": 1529.0, "y": 0, "page": 1, "name": "PhonebookModule"},
{"x": 1639.0, "y": 0, "page": 1, "name": "TableModule"}, {"x": 1771.0, "y": 0, "page": 1, "name": "FreeTextModule"},
{"x": 1881.0, "y": 0, "page": 1, "name": "TableModule"},
] ]
# For use with modules that require a database # For use with modules that require a database
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment