Data File Reference Module

import tkinter
import tkinter.messagebox

import raconverter
import raconverter.entry_fields
from raconverter.constants import *


class DataFileReference:
    """
    Create an entry form with data file reference entry fields.
    Valid entry fields are stored in an instance attribute.

    :param top_level: The top level window
    """

    def __init__(self, top_level):
        self.top_level = top_level
        self._data_file_references = []

        # Instantiate classes
        self.entry_fields = raconverter.entry_fields.EntryFields()
        self.misc = raconverter.Misc()

        # Add content
        self.top_level.title(REFERENCE_FORM_TITLE)
        self.entry_field_objects = self.create_entry_fields(self.top_level)
        self.add_entry_fields_tooltips(self.entry_field_objects)
        self.add_buttons(self.top_level, self.entry_field_objects)

        # Set focus
        focus_widget = self.entry_field_objects[DATA_FILE_NAME]
        focus_widget.focus_force()

        # Fix the windows size and center on screen
        self.top_level.resizable(RESIZE_X, RESIZE_Y)
        self.misc.center_window_on_screen(self.top_level)

    @property
    def data_file_references(self):
        """
        Get internal list with valid data file reference(s).

        :return: An empty list | A list with valid entry text (sublist for each data file reference)
        """
        return self._data_file_references

    @data_file_references.setter
    def data_file_references(self, valid_entry_text):
        """
        Append valid entry text to a list.

        :param valid_entry_text: A list with valid entry text (sublist for each data file reference)
        """
        self._data_file_references.append(valid_entry_text)

    def create_entry_fields(self, top_level):
        """
        Create entry frames with entry label and field.

        :param top_level: The top level window
        :return: A dictionary with the entry fields
        """
        data_file_name = self.add_data_file_name(top_level)
        variable_other = self.add_variable_other(top_level)
        variable_this = self.add_variable_this(top_level)

        entry_fields = {DATA_FILE_NAME: data_file_name, VARIABLE_OTHER: variable_other, VARIABLE_THIS: variable_this}

        return entry_fields

    def add_data_file_name(self, top_level):
        """
        Add entry field.

        :param top_level: The top level window
        :return: Entry field with data file name
        """
        data_file_name = self.entry_fields.entry_data_file_name(top_level, LABEL_WIDTH21, ENTRY_WIDTH36, DATA_FILE_NAME)

        return data_file_name

    def add_variable_other(self, top_level):
        """
        Add entry field.

        :param top_level: The top level window
        :return: Entry field with variable(s) other data file
        """
        variable_other = self.entry_fields.entry_variable_name(top_level, LABEL_WIDTH21, ENTRY_WIDTH36, VARIABLE_OTHER)

        return variable_other

    def add_variable_this(self, top_level):
        """
        Add entry field.

        :param top_level: The top level window
        :return: Entry field with variable(s) this data file
        """
        variable_this = self.entry_fields.entry_variable_name(top_level, LABEL_WIDTH21, ENTRY_WIDTH36, VARIABLE_THIS)

        return variable_this

    def add_entry_fields_tooltips(self, entry_fields):
        """
        Add entry tooltips.

        :param entry_fields: A dictionary with the entry fields
        """
        self.entry_fields.add_tooltip(entry_fields[DATA_FILE_NAME], DATA_FILE_NAME_TOOLTIP)
        self.entry_fields.add_tooltip(entry_fields[VARIABLE_OTHER], VARIABLE_OTHER_TOOLTIP)
        self.entry_fields.add_tooltip(entry_fields[VARIABLE_THIS], VARIABLE_THIS_TOOLTIP)

    def add_buttons(self, top_level, entry_fields):
        """
        Add buttons.

        :param top_level: The top level window
        :param entry_fields: A dictionary with the entry fields
        """
        button_frame = tkinter.Frame(top_level)
        button_frame.pack(side=SIDE_TOP, padx=BUTTON_FRAME_PADX7, pady=BUTTON_FRAME_PADY10, fill=FILL_X,
                          expand=EXPAND_YES)
        # Button add
        button_add = tkinter.Button(button_frame, font=FONT, height=BUTTON_HEIGHT1, text=BUTTON_ADD)
        button_add.config(command=lambda: self.button_add(top_level, entry_fields))
        button_add.pack(side=SIDE_LEFT, anchor=ANCHOR_EAST, padx=BUTTON_PADX3, fill=FILL_X, expand=EXPAND_YES)
        # Button quit
        button_quit = tkinter.Button(button_frame, font=FONT, height=BUTTON_HEIGHT1, text=BUTTON_QUIT)
        button_quit.config(command=lambda: self.button_quit(top_level))
        button_quit.pack(side=SIDE_RIGHT, anchor=ANCHOR_EAST, padx=BUTTON_PADX3, fill=FILL_X, expand=EXPAND_YES)

    def button_add(self, top_level, entry_fields):
        """
        Add valid data file reference to a list.
        Destroy the top level window.

        :param top_level: The top level window
        :param entry_fields: A dictionary with the entry fields
        """
        # Get entry text
        valid_entry_text = self.get_valid_entry_text(entry_fields)

        # If valid entry text
        if valid_entry_text:
            # Append data file reference to a list
            self.data_file_references = valid_entry_text
            # Ask another data file reference (yes/no)
            if not tkinter.messagebox.askyesno(DATA_FILE_REFERENCE, ADD_DATA_FILE_REFERENCE_MESSAGE):
                top_level.destroy()

    @staticmethod
    def button_quit(top_level):
        """
        Destroy the top level window.

        :param top_level: The top level window
        """
        top_level.destroy()

    def get_valid_entry_text(self, entry_fields):
        """
        Get valid entry text from the entry fields.

        :param entry_fields: A dictionary with the entry fields
        :return: An empty list | A list with valid entry text
        """
        valid_entry_text = []

        # Get the entry text
        data_file_name = entry_fields[DATA_FILE_NAME].get()
        variable_other = entry_fields[VARIABLE_OTHER].get()
        variable_this = entry_fields[VARIABLE_THIS].get()

        # Validate the entry text
        valid_data_file_name = self.entry_fields.validate_data_file_name(entry_fields[DATA_FILE_NAME])
        valid_variable_other_data_file = self.entry_fields.validate_variable_name(entry_fields[VARIABLE_OTHER])
        valid_variable_this_data_file = self.entry_fields.validate_variable_name(entry_fields[VARIABLE_THIS])

        # If valid entry text
        if valid_data_file_name and valid_variable_other_data_file and valid_variable_this_data_file:
            # Reject empty entry text
            if not data_file_name:
                tkinter.messagebox.showwarning(INVALID_NAME, INVALID_DATA_FILE_NAME_MESSAGE)
                entry_fields[DATA_FILE_NAME].focus_force()
            elif not variable_other:
                tkinter.messagebox.showwarning(INVALID_NAME, INVALID_VARIABLE_NAME_MESSAGE)
                entry_fields[VARIABLE_OTHER].focus_force()
            elif not variable_this:
                tkinter.messagebox.showwarning(INVALID_NAME, INVALID_VARIABLE_NAME_MESSAGE)
                entry_fields[VARIABLE_THIS].focus_force()
            else:
                # Append valid entry text to list
                valid_entry_text = [data_file_name, variable_other, variable_this]
                # Strip leading, trailing, and multiple spaces in entry text
                valid_entry_text = [' '.join(x.split()) for x in valid_entry_text]

                # Reset entry text
                for key, entry_field in entry_fields.items():
                    entry_field.delete(INDEX_START0, INDEX_END)

                # Set focus
                entry_fields[DATA_FILE_NAME].focus_force()

        return valid_entry_text

Leave a Reply

Your email address will not be published.