Module soitool.codebook_row_adder

Includes functionality for inserting rows into database-table CodeBook.

Expand source code
"""Includes functionality for inserting rows into database-table CodeBook."""
from sqlite3 import IntegrityError
from PySide2.QtWidgets import (
    QHBoxLayout,
    QVBoxLayout,
    QLabel,
    QLineEdit,
    QComboBox,
    QPushButton,
    QWidget,
)
from PySide2.QtCore import Qt
from soitool.codebook_model_view import CodebookTableModel, CodebookTableView


class CodebookRowAdder(QWidget):
    """Widget for adding rows to database-table CodeBook.

    This class can be used alone, or alongside a soitool.CodeBookTableView.
    If used with a CodeBookTableView, this class will tell the view to
    update/refresh when new rows are inserted.

    Parameters
    ----------
    codebook_view : soitool.CodeBookTableView or None (default)
        Reference to view if it is used alongside this class, None otherwise.
        The view's model (CodeBookTableModel) has an exclusive lock on the
        database. Therefore, this reference is needed to be able to
        insert new rows, but it is also used to refresh the view when
        the row is inserted.
    database : soitool.database.Database
        Database to use.

    Raises
    ------
    ValueError
        If argument codebook_view is not
        None (default) or CodeBookTableView.
    """

    def __init__(self, database, codebook_view=None):
        super().__init__()

        # Raise error if argument is invalid
        if codebook_view is not None and not isinstance(
            codebook_view, CodebookTableView
        ):
            raise ValueError(
                "Invalid value for argument 'codebook_view': "
                + "'{}'".format(codebook_view)
            )

        self.database = database
        self.codebook_view = codebook_view

        self.create_widgets()
        self.set_widget_widths()
        self.create_and_set_layout()
        self.set_size()

    def create_widgets(self):
        """Create labels, input-widgets and button needed to insert rows."""
        # Create labels
        self.label_word = QLabel("Ord/Uttrykk")
        self.label_category = QLabel("Kategori")
        self.label_type = QLabel("Type")
        self.label_feedback = QLabel("")

        # Create input-widgets
        self.text_field_category = QLineEdit()
        self.text_field_word = QLineEdit()
        self.combo_type = QComboBox()
        self.combo_type.addItem("Stor")
        self.combo_type.addItem("Liten")

        # Create button
        self.button = QPushButton("Legg til", self)
        self.button.setFixedHeight(22)
        self.button.clicked.connect(self.insert_row)

    def set_widget_widths(self):
        """Set width of widgets."""
        # Match width of widgets to columnwidths of the view if it is used
        if self.codebook_view is not None:
            self.text_field_word.setFixedWidth(
                self.codebook_view.columnWidth(0) - 12
            )
            self.text_field_category.setFixedWidth(
                self.codebook_view.columnWidth(1) - 10
            )
            self.combo_type.setFixedWidth(
                self.codebook_view.columnWidth(2) - 5
            )
            self.button.setFixedWidth(self.codebook_view.columnWidth(3) - 5)
        # Set standard witdh of widgets if a view is not used
        else:
            self.text_field_word.setFixedWidth(140)
            self.text_field_category.setFixedWidth(120)
            self.combo_type.setFixedWidth(80)
            self.button.setFixedWidth(80)

    def create_and_set_layout(self):
        """Create layouts, add them to main layout and set main layout."""
        # Create layout for word
        vbox_word = QVBoxLayout()
        vbox_word.addWidget(self.label_word)
        vbox_word.addWidget(self.text_field_word)
        vbox_word.setAlignment(self.label_word, Qt.AlignHCenter)

        # Create layout for category
        vbox_category = QVBoxLayout()
        vbox_category.addWidget(self.label_category)
        vbox_category.addWidget(self.text_field_category)
        vbox_category.setAlignment(self.label_category, Qt.AlignHCenter)

        # Create layout for type
        vbox_type = QVBoxLayout()
        vbox_type.addWidget(self.label_type, Qt.AlignHCenter)
        vbox_type.addWidget(self.combo_type)
        vbox_type.setAlignment(self.label_type, Qt.AlignHCenter)

        # Create layout for button
        vbox_button = QVBoxLayout()
        vbox_button.addSpacing(25)
        vbox_button.addWidget(self.button)

        # Create layout to add layouts next to eachother
        hbox = QHBoxLayout()
        hbox.addLayout(vbox_word)
        hbox.addLayout(vbox_category)
        hbox.addLayout(vbox_type)
        hbox.addLayout(vbox_button)

        # Create layout to place feedback at the bottom
        vbox = QVBoxLayout()
        vbox.addLayout(hbox)
        vbox.addWidget(self.label_feedback)

        self.setLayout(vbox)

    def set_size(self):
        """Set standard size or size based on the view's size."""
        # Set own width equal to the sum of the view's columnwidths
        if self.codebook_view is not None:
            codebook_view_width = 0
            for i in range(self.codebook_view.model().columnCount()):
                codebook_view_width += self.codebook_view.columnWidth(i)
            self.setFixedSize(codebook_view_width, 80)
        # Set standard size
        else:
            self.setFixedSize(465, 80)

    def insert_row(self):
        """Read input and insert row to database.

        Give feedback if word (Primary key) is empty or already exists.
        """
        # Reset feedback-label
        self.label_feedback.setText("")

        # Read input
        word_input = self.text_field_word.text()
        category_input = self.text_field_category.text()
        type_input = self.combo_type.currentText()

        # If word is not empty
        if len(word_input) > 0:

            # Uppercase first character of word and category (if not empty)
            word_input = word_input[0].upper() + word_input[1:]
            if len(category_input) > 0:
                category_input = category_input[0].upper() + category_input[1:]

            try:
                # If a view is used, remove its model temporarily
                if self.codebook_view is not None:
                    self.codebook_view.setModel(None)

                # Try to add row to database
                stmt = (
                    "INSERT INTO CodeBook(Word, Category, Type)"
                    + "VALUES(?, ?, ?)"
                )
                self.database.conn.execute(
                    stmt, (word_input, category_input, type_input,)
                )

                # Add unique code to row and commit changes
                self.database.add_code_to(word_input)
                self.database.conn.commit()

                # Give feedback and reset input
                self.label_feedback.setText("Ord/Uttrykk lagt til.")
                self.text_field_word.setText("")
                self.text_field_category.setText("")
                self.combo_type.setCurrentIndex(0)

            except IntegrityError:
                self.label_feedback.setText("Ord/uttrykk eksisterer allerede.")
        else:
            self.label_feedback.setText("Ord/Uttrykk er ikke fylt inn.")

        # If a view is used, create and set a new, updated model
        if self.codebook_view is not None:
            self.codebook_view.setModel(CodebookTableModel())

Classes

class CodebookRowAdder (database, codebook_view=None)

Widget for adding rows to database-table CodeBook.

This class can be used alone, or alongside a soitool.CodeBookTableView. If used with a CodeBookTableView, this class will tell the view to update/refresh when new rows are inserted.

Parameters

codebook_view : soitool.CodeBookTableView or None (default)
Reference to view if it is used alongside this class, None otherwise. The view's model (CodeBookTableModel) has an exclusive lock on the database. Therefore, this reference is needed to be able to insert new rows, but it is also used to refresh the view when the row is inserted.
database : Database
Database to use.

Raises

ValueError
If argument codebook_view is not None (default) or CodeBookTableView.
Expand source code
class CodebookRowAdder(QWidget):
    """Widget for adding rows to database-table CodeBook.

    This class can be used alone, or alongside a soitool.CodeBookTableView.
    If used with a CodeBookTableView, this class will tell the view to
    update/refresh when new rows are inserted.

    Parameters
    ----------
    codebook_view : soitool.CodeBookTableView or None (default)
        Reference to view if it is used alongside this class, None otherwise.
        The view's model (CodeBookTableModel) has an exclusive lock on the
        database. Therefore, this reference is needed to be able to
        insert new rows, but it is also used to refresh the view when
        the row is inserted.
    database : soitool.database.Database
        Database to use.

    Raises
    ------
    ValueError
        If argument codebook_view is not
        None (default) or CodeBookTableView.
    """

    def __init__(self, database, codebook_view=None):
        super().__init__()

        # Raise error if argument is invalid
        if codebook_view is not None and not isinstance(
            codebook_view, CodebookTableView
        ):
            raise ValueError(
                "Invalid value for argument 'codebook_view': "
                + "'{}'".format(codebook_view)
            )

        self.database = database
        self.codebook_view = codebook_view

        self.create_widgets()
        self.set_widget_widths()
        self.create_and_set_layout()
        self.set_size()

    def create_widgets(self):
        """Create labels, input-widgets and button needed to insert rows."""
        # Create labels
        self.label_word = QLabel("Ord/Uttrykk")
        self.label_category = QLabel("Kategori")
        self.label_type = QLabel("Type")
        self.label_feedback = QLabel("")

        # Create input-widgets
        self.text_field_category = QLineEdit()
        self.text_field_word = QLineEdit()
        self.combo_type = QComboBox()
        self.combo_type.addItem("Stor")
        self.combo_type.addItem("Liten")

        # Create button
        self.button = QPushButton("Legg til", self)
        self.button.setFixedHeight(22)
        self.button.clicked.connect(self.insert_row)

    def set_widget_widths(self):
        """Set width of widgets."""
        # Match width of widgets to columnwidths of the view if it is used
        if self.codebook_view is not None:
            self.text_field_word.setFixedWidth(
                self.codebook_view.columnWidth(0) - 12
            )
            self.text_field_category.setFixedWidth(
                self.codebook_view.columnWidth(1) - 10
            )
            self.combo_type.setFixedWidth(
                self.codebook_view.columnWidth(2) - 5
            )
            self.button.setFixedWidth(self.codebook_view.columnWidth(3) - 5)
        # Set standard witdh of widgets if a view is not used
        else:
            self.text_field_word.setFixedWidth(140)
            self.text_field_category.setFixedWidth(120)
            self.combo_type.setFixedWidth(80)
            self.button.setFixedWidth(80)

    def create_and_set_layout(self):
        """Create layouts, add them to main layout and set main layout."""
        # Create layout for word
        vbox_word = QVBoxLayout()
        vbox_word.addWidget(self.label_word)
        vbox_word.addWidget(self.text_field_word)
        vbox_word.setAlignment(self.label_word, Qt.AlignHCenter)

        # Create layout for category
        vbox_category = QVBoxLayout()
        vbox_category.addWidget(self.label_category)
        vbox_category.addWidget(self.text_field_category)
        vbox_category.setAlignment(self.label_category, Qt.AlignHCenter)

        # Create layout for type
        vbox_type = QVBoxLayout()
        vbox_type.addWidget(self.label_type, Qt.AlignHCenter)
        vbox_type.addWidget(self.combo_type)
        vbox_type.setAlignment(self.label_type, Qt.AlignHCenter)

        # Create layout for button
        vbox_button = QVBoxLayout()
        vbox_button.addSpacing(25)
        vbox_button.addWidget(self.button)

        # Create layout to add layouts next to eachother
        hbox = QHBoxLayout()
        hbox.addLayout(vbox_word)
        hbox.addLayout(vbox_category)
        hbox.addLayout(vbox_type)
        hbox.addLayout(vbox_button)

        # Create layout to place feedback at the bottom
        vbox = QVBoxLayout()
        vbox.addLayout(hbox)
        vbox.addWidget(self.label_feedback)

        self.setLayout(vbox)

    def set_size(self):
        """Set standard size or size based on the view's size."""
        # Set own width equal to the sum of the view's columnwidths
        if self.codebook_view is not None:
            codebook_view_width = 0
            for i in range(self.codebook_view.model().columnCount()):
                codebook_view_width += self.codebook_view.columnWidth(i)
            self.setFixedSize(codebook_view_width, 80)
        # Set standard size
        else:
            self.setFixedSize(465, 80)

    def insert_row(self):
        """Read input and insert row to database.

        Give feedback if word (Primary key) is empty or already exists.
        """
        # Reset feedback-label
        self.label_feedback.setText("")

        # Read input
        word_input = self.text_field_word.text()
        category_input = self.text_field_category.text()
        type_input = self.combo_type.currentText()

        # If word is not empty
        if len(word_input) > 0:

            # Uppercase first character of word and category (if not empty)
            word_input = word_input[0].upper() + word_input[1:]
            if len(category_input) > 0:
                category_input = category_input[0].upper() + category_input[1:]

            try:
                # If a view is used, remove its model temporarily
                if self.codebook_view is not None:
                    self.codebook_view.setModel(None)

                # Try to add row to database
                stmt = (
                    "INSERT INTO CodeBook(Word, Category, Type)"
                    + "VALUES(?, ?, ?)"
                )
                self.database.conn.execute(
                    stmt, (word_input, category_input, type_input,)
                )

                # Add unique code to row and commit changes
                self.database.add_code_to(word_input)
                self.database.conn.commit()

                # Give feedback and reset input
                self.label_feedback.setText("Ord/Uttrykk lagt til.")
                self.text_field_word.setText("")
                self.text_field_category.setText("")
                self.combo_type.setCurrentIndex(0)

            except IntegrityError:
                self.label_feedback.setText("Ord/uttrykk eksisterer allerede.")
        else:
            self.label_feedback.setText("Ord/Uttrykk er ikke fylt inn.")

        # If a view is used, create and set a new, updated model
        if self.codebook_view is not None:
            self.codebook_view.setModel(CodebookTableModel())

Ancestors

  • PySide2.QtWidgets.QWidget
  • PySide2.QtCore.QObject
  • PySide2.QtGui.QPaintDevice
  • Shiboken.Object

Class variables

var staticMetaObject

Methods

def create_and_set_layout(self)

Create layouts, add them to main layout and set main layout.

Expand source code
def create_and_set_layout(self):
    """Create layouts, add them to main layout and set main layout."""
    # Create layout for word
    vbox_word = QVBoxLayout()
    vbox_word.addWidget(self.label_word)
    vbox_word.addWidget(self.text_field_word)
    vbox_word.setAlignment(self.label_word, Qt.AlignHCenter)

    # Create layout for category
    vbox_category = QVBoxLayout()
    vbox_category.addWidget(self.label_category)
    vbox_category.addWidget(self.text_field_category)
    vbox_category.setAlignment(self.label_category, Qt.AlignHCenter)

    # Create layout for type
    vbox_type = QVBoxLayout()
    vbox_type.addWidget(self.label_type, Qt.AlignHCenter)
    vbox_type.addWidget(self.combo_type)
    vbox_type.setAlignment(self.label_type, Qt.AlignHCenter)

    # Create layout for button
    vbox_button = QVBoxLayout()
    vbox_button.addSpacing(25)
    vbox_button.addWidget(self.button)

    # Create layout to add layouts next to eachother
    hbox = QHBoxLayout()
    hbox.addLayout(vbox_word)
    hbox.addLayout(vbox_category)
    hbox.addLayout(vbox_type)
    hbox.addLayout(vbox_button)

    # Create layout to place feedback at the bottom
    vbox = QVBoxLayout()
    vbox.addLayout(hbox)
    vbox.addWidget(self.label_feedback)

    self.setLayout(vbox)
def create_widgets(self)

Create labels, input-widgets and button needed to insert rows.

Expand source code
def create_widgets(self):
    """Create labels, input-widgets and button needed to insert rows."""
    # Create labels
    self.label_word = QLabel("Ord/Uttrykk")
    self.label_category = QLabel("Kategori")
    self.label_type = QLabel("Type")
    self.label_feedback = QLabel("")

    # Create input-widgets
    self.text_field_category = QLineEdit()
    self.text_field_word = QLineEdit()
    self.combo_type = QComboBox()
    self.combo_type.addItem("Stor")
    self.combo_type.addItem("Liten")

    # Create button
    self.button = QPushButton("Legg til", self)
    self.button.setFixedHeight(22)
    self.button.clicked.connect(self.insert_row)
def insert_row(self)

Read input and insert row to database.

Give feedback if word (Primary key) is empty or already exists.

Expand source code
def insert_row(self):
    """Read input and insert row to database.

    Give feedback if word (Primary key) is empty or already exists.
    """
    # Reset feedback-label
    self.label_feedback.setText("")

    # Read input
    word_input = self.text_field_word.text()
    category_input = self.text_field_category.text()
    type_input = self.combo_type.currentText()

    # If word is not empty
    if len(word_input) > 0:

        # Uppercase first character of word and category (if not empty)
        word_input = word_input[0].upper() + word_input[1:]
        if len(category_input) > 0:
            category_input = category_input[0].upper() + category_input[1:]

        try:
            # If a view is used, remove its model temporarily
            if self.codebook_view is not None:
                self.codebook_view.setModel(None)

            # Try to add row to database
            stmt = (
                "INSERT INTO CodeBook(Word, Category, Type)"
                + "VALUES(?, ?, ?)"
            )
            self.database.conn.execute(
                stmt, (word_input, category_input, type_input,)
            )

            # Add unique code to row and commit changes
            self.database.add_code_to(word_input)
            self.database.conn.commit()

            # Give feedback and reset input
            self.label_feedback.setText("Ord/Uttrykk lagt til.")
            self.text_field_word.setText("")
            self.text_field_category.setText("")
            self.combo_type.setCurrentIndex(0)

        except IntegrityError:
            self.label_feedback.setText("Ord/uttrykk eksisterer allerede.")
    else:
        self.label_feedback.setText("Ord/Uttrykk er ikke fylt inn.")

    # If a view is used, create and set a new, updated model
    if self.codebook_view is not None:
        self.codebook_view.setModel(CodebookTableModel())
def set_size(self)

Set standard size or size based on the view's size.

Expand source code
def set_size(self):
    """Set standard size or size based on the view's size."""
    # Set own width equal to the sum of the view's columnwidths
    if self.codebook_view is not None:
        codebook_view_width = 0
        for i in range(self.codebook_view.model().columnCount()):
            codebook_view_width += self.codebook_view.columnWidth(i)
        self.setFixedSize(codebook_view_width, 80)
    # Set standard size
    else:
        self.setFixedSize(465, 80)
def set_widget_widths(self)

Set width of widgets.

Expand source code
def set_widget_widths(self):
    """Set width of widgets."""
    # Match width of widgets to columnwidths of the view if it is used
    if self.codebook_view is not None:
        self.text_field_word.setFixedWidth(
            self.codebook_view.columnWidth(0) - 12
        )
        self.text_field_category.setFixedWidth(
            self.codebook_view.columnWidth(1) - 10
        )
        self.combo_type.setFixedWidth(
            self.codebook_view.columnWidth(2) - 5
        )
        self.button.setFixedWidth(self.codebook_view.columnWidth(3) - 5)
    # Set standard witdh of widgets if a view is not used
    else:
        self.text_field_word.setFixedWidth(140)
        self.text_field_category.setFixedWidth(120)
        self.combo_type.setFixedWidth(80)
        self.button.setFixedWidth(80)