Skip to content
Snippets Groups Projects
Commit e4fecc8c authored by Thomas Holene Løkkeborg's avatar Thomas Holene Løkkeborg
Browse files

Merge branch 'autentiseringstavle-testelement-linje' into 'master'

#105 Autentiseringstavle viser elementnr for autentisering

See merge request !62
parents 1363c2bd 00e3d78e
No related branches found
No related tags found
1 merge request!62#105 Autentiseringstavle viser elementnr for autentisering
Pipeline #80794 passed
......@@ -48,35 +48,48 @@ class CodeTableBase(ModuleBase, QTableWidget, metaclass=Meta):
# Resize table when headline changes
self.cellChanged.connect(
lambda: resize_table(
self,
resize_rows=False,
resize_columns=False,
has_headline=True,
self, rows=False, columns=False, has_headline=True,
)
)
# If parameters are None, generate new table
if size is None and data is None:
self.generate_table()
self.resizeColumnsToContents()
self.insert_headline(self.headline)
self.resizeRowsToContents()
self.insert_headline(self.start_headline)
# Resize height of rows and set size of window
resize_table(self, resize_columns=False, has_headline=True)
resize_table(
self, columns=False, rows=False, has_headline=True,
)
else:
self.setColumnCount(len(data[1]))
self.setRowCount(len(data) - 1) # - 1 to skip headline
self.code_length = data["code_length"]
self.space_interval = data["space_interval"]
self.space_amount = data["space_amount"]
self.code_character_type = data["code_character_type"]
cells = data["cells"]
self.setColumnCount(len(cells[1]))
self.setRowCount(len(cells) - 1) # - 1 to skip headline
# Set cell-items
for i in range(self.rowCount()):
for j in range(self.columnCount()):
item = QTableWidgetItem(data[i + 1][j]) # +1 skip headline
item.setTextAlignment(Qt.AlignCenter)
item = QTableWidgetItem(
cells[i + 1][j]
) # +1 skip headline
if j == 2 and self.type == AUTHENTICATIONBOARD_MODULE:
item.setTextAlignment(Qt.AlignLeft | Qt.AlignVCenter)
else:
item.setTextAlignment(Qt.AlignCenter)
self.setItem(i, j, item)
self.resizeColumnsToContents()
self.insert_headline(data[0])
self.resizeRowsToContents()
self.insert_headline(cells[0])
resize_table(self, resize_columns=False, has_headline=True)
resize_table(
self, columns=False, rows=False, has_headline=True,
)
self.setFixedWidth(size["width"])
self.setFixedHeight(size["height"])
......@@ -112,13 +125,13 @@ class CodeTableBase(ModuleBase, QTableWidget, metaclass=Meta):
Parameters
----------
text : string, optional
The headline text, self.headline is used if None,
The headline text, self.start_headline is used if None,
by default None.
"""
headline = self.headline if text is None else text
headline = self.start_headline if text is None else text
item_headline = QTableWidgetItem(headline)
item_headline.setTextAlignment(Qt.AlignHCenter)
item_headline.setTextAlignment(Qt.AlignCenter)
item_headline.setFont(HEADLINE_FONT)
self.insertRow(0)
......@@ -200,16 +213,26 @@ class CodeTableBase(ModuleBase, QTableWidget, metaclass=Meta):
List[0] contains headline,
list[x][y] represents value of row x, column y.
"""
data = []
cells = []
item_headline = self.item(0, 0)
if item_headline is not None:
data.append(item_headline.text())
cells.append(item_headline.text())
else:
cells.append("")
for i in range(1, self.rowCount()):
row = []
for j in range(self.columnCount()):
row.append(self.item(i, j).text())
data.append(row)
cells.append(row)
data = {
"cells": cells,
"code_length": self.code_length,
"space_interval": self.space_interval,
"space_amount": self.space_amount,
"code_character_type": self.code_character_type,
}
return data
......
"""Module containing SOI-module 'Autentiseringstavle'."""
import string
from secrets import choice
from PySide2.QtWidgets import QTableWidgetItem
from PySide2 import QtGui
from PySide2.QtCore import Qt
......@@ -39,14 +40,16 @@ class AuthenticationBoardModule(CodeTableBase):
If parameters are given, the widget initializes accordingly:
'size' is a dict: {"width": int, "height": int},
'data' is a 2D list where data[0] is the headline,
and data[x][y] represents the value in row x, column y.
'data' is a dict with keys "cells", "code_length", "space_interval",
"space_amount" and "code_character_type". "cells" is a 2D list where
cells[0] is the headline and cells[x][y] represents the value in row x,
column y. The other keys contain an integer.
The widget does not use more room than needed, and resizes dynamically.
It has shortcuts for adding and removing rows.
Codes are not horizontally centered for readability because 'BGD' is wider
than 'III' (example) in certain fonts.
Codes are not horizontally centered for readability concerns because 'BGD'
is wider than 'III' (example) in certain fonts.
"""
def __init__(self, size=None, data=None):
......@@ -63,12 +66,23 @@ class AuthenticationBoardModule(CodeTableBase):
"Invalid value for CONSTANT 'CODE_CHARACTER_TYPE': "
"'{}'".format(CODE_CHARACTER_TYPE)
)
self.start_no_of_codes = START_NO_OF_CODES
self.code_length = CODE_LENGTH
self.space_interval = SPACE_INTERVAL
self.space_amount = SPACE_AMOUNT
self.code_character_type = CODE_CHARACTER_TYPE
self.headline = HEADLINE_TEXT
# Set default values for table to be generated
if size is None and data is None:
self.start_no_of_codes = START_NO_OF_CODES
self.code_length = CODE_LENGTH
self.space_interval = SPACE_INTERVAL
self.space_amount = SPACE_AMOUNT
self.code_character_type = CODE_CHARACTER_TYPE
numbers = self.generate_authentication_numbers()
self.start_headline = (
HEADLINE_TEXT
+ " ("
+ str(numbers[0])
+ " & "
+ str(numbers[1])
+ ")"
)
CodeTableBase.__init__(self, size, data)
......@@ -123,7 +137,9 @@ class AuthenticationBoardModule(CodeTableBase):
# Resize code-column in case it got wider
# Example: 'BGD' is wider than 'III' (depending on font)
self.resizeColumnToContents(2)
resize_table(self, resize_columns=False, has_headline=True)
self.resizeRowToContents(selected_row_index + 1)
resize_table(self, columns=False, rows=False, has_headline=True)
def remove_row(self, row_index):
"""Remove selected row.
......@@ -140,7 +156,28 @@ class AuthenticationBoardModule(CodeTableBase):
for i in range(row_index, self.rowCount()):
self.item(i, 0).setText(self.code_characters[i - 1])
self.item(i, 1).setText(str(i - 1))
resize_table(self, resize_columns=False, has_headline=True)
resize_table(self, columns=False, rows=False, has_headline=True)
def generate_authentication_numbers(self):
"""Generate two non-equal numbers between 1 and self.code_length.
Returns
-------
list
Containing two integers, sorted in ascending order.
"""
available_numbers = list(range(1, self.code_length + 1))
numbers = []
numbers.append(choice(available_numbers))
numbers.append(choice(available_numbers))
while numbers[0] == numbers[1]:
numbers[1] = choice(available_numbers)
numbers.sort()
return numbers
@staticmethod
def get_user_friendly_name():
......
......@@ -38,26 +38,24 @@ class ModuleBase(ABC):
raise NotImplementedError
def resize_table(
table, resize_rows=True, resize_columns=True, has_headline=False
):
def resize_table(table, rows=True, columns=True, has_headline=False):
"""Resize a given QTableWidget.
Parameters
----------
table : QTableWidget
QTablewidget-instance to resize.
resize_rows : bool
rows : bool
Resizes rows to contents if True, by default True.
resize_columns : bool
columns : bool
Resizes columns to contents if True, by default True.
has_headline : bool
True if the table has a headline, by default False.
Last column is widened if headline is wider than table.
"""
if resize_columns:
if columns:
table.resizeColumnsToContents()
if resize_rows:
if rows:
table.resizeRowsToContents()
# If table has a headline, make sure table is wide enough to fit it.
......
......@@ -33,8 +33,10 @@ class SubtractorcodesModule(CodeTableBase):
If parameters are given, the widget initializes accordingly:
'size' is a dict: {"width": int, "height": int},
'data' is a 2D list where data[0] is the headline,
and data[x][y] represents the value in row x, column y.
'data' is a dict with keys "cells", "code_length", "space_interval",
"space_amount" and "code_character_type". "cells" is a 2D list where
cells[0] is the headline and cells[x][y] represents the value in row x,
column y. The other keys contain an integer.
The widget does not use more room than needed, and resizes dynamically.
It has shortcuts for adding and removing rows.
......@@ -48,7 +50,7 @@ class SubtractorcodesModule(CodeTableBase):
"Invalid value for CONSTANT 'START_NO_OF_CODES': "
"'{}'".format(START_NO_OF_CODES)
)
self.headline = HEADLINE_TEXT
self.start_headline = HEADLINE_TEXT
self.code_length = CODE_LENGTH
self.start_no_of_codes = START_NO_OF_CODES
self.space_interval = SPACE_INTERVAL
......@@ -115,7 +117,8 @@ class SubtractorcodesModule(CodeTableBase):
item_code.setFlags(item_code.flags() ^ Qt.ItemIsEditable)
self.setItem(selected_row_index + 1, 2, item_code)
resize_table(self, resize_columns=False, has_headline=True)
self.resizeRowToContents(selected_row_index + 1)
resize_table(self, columns=False, rows=False, has_headline=True)
def remove_row(self, row_index):
"""Remove the selected row.
......@@ -128,7 +131,7 @@ class SubtractorcodesModule(CodeTableBase):
self.removeRow(row_index)
self.insert_row_identifiers(has_headline=True)
resize_table(self, resize_columns=False, has_headline=True)
resize_table(self, columns=False, rows=False, has_headline=True)
@staticmethod
def get_user_friendly_name():
......
......@@ -50,7 +50,7 @@ class TableModule(ModuleBase, QTableWidget, metaclass=Meta):
self.setRowCount(START_ROWS)
# Resize width and height of rows, columns and window
resize_table(self, resize_rows=True, resize_columns=True)
resize_table(self)
# Set header-items
for i in range(self.columnCount()):
......@@ -74,9 +74,7 @@ class TableModule(ModuleBase, QTableWidget, metaclass=Meta):
self.setFixedWidth(size["width"])
self.setFixedHeight(size["height"])
self.cellChanged.connect(
lambda: resize_table(self, resize_rows=True, resize_columns=True)
)
self.cellChanged.connect(lambda: resize_table(self))
def keyPressEvent(self, event):
"""Launch actions when specific combinations of keys are pressed.
......@@ -131,24 +129,24 @@ class TableModule(ModuleBase, QTableWidget, metaclass=Meta):
"""Add column to the right of selected column."""
self.insertColumn(self.currentColumn() + 1)
self.set_header_item(self.currentColumn() + 1, "")
resize_table(self, resize_rows=True, resize_columns=True)
resize_table(self)
def remove_column(self):
"""Remove selected column if two or more columns exist."""
if self.columnCount() > 1:
self.removeColumn(self.currentColumn())
resize_table(self, resize_rows=True, resize_columns=True)
resize_table(self)
def add_row(self):
"""Add row below selected row."""
self.insertRow(self.currentRow() + 1)
resize_table(self, resize_rows=True, resize_columns=True)
resize_table(self)
def remove_row(self):
"""Remove selected row if two or more rows exist (including header)."""
if self.rowCount() > 2 and self.currentRow() != 0:
self.removeRow(self.currentRow())
resize_table(self, resize_rows=True, resize_columns=True)
resize_table(self)
def get_size(self):
"""Return size of widget."""
......
......@@ -45,8 +45,9 @@ class TestDefaultAuthenticationBoardAndSubtractorcodesModule(
def test_default_module(self):
"""Test that module is initialized properly."""
# Assert correct headline
self.assertEqual(
self.authentication.item(0, 0).text(), HEADLINE_TEXT_AUTHENTICATION
self.assertTrue(
HEADLINE_TEXT_AUTHENTICATION
in self.authentication.item(0, 0).text()
)
self.assertEqual(
self.subtractor.item(0, 0).text(), HEADLINE_TEXT_SUBTRACTOR
......@@ -224,11 +225,17 @@ class TestAuthenticationBoardModuleFromData(unittest.TestCase):
def test_create_from_data(self):
"""Test creating AuthenticationBoardModule from data."""
test_data = [
"Headline text",
["A", "0", "TEST CODE ONE"],
["B", "1", "TEST CODE TWO"],
]
test_data = {
"cells": [
"Headline text",
["A", "0", "TEST CODE ONE"],
["B", "1", "TEST CODE TWO"],
],
"code_length": 11,
"space_interval": 4,
"space_amount": 1,
"code_character_type": "ascii",
}
test_size = {"width": 100, "height": 100}
module = AuthenticationBoardModule(size=test_size, data=test_data)
......
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