diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c0621c1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,224 @@ +# ---> Python +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# ---> Qt +# C++ objects and libs +*.slo +*.lo +*.o +*.a +*.la +*.lai +*.so +*.so.* +*.dll +*.dylib + +# Qt-es +object_script.*.Release +object_script.*.Debug +*_plugin_import.cpp +/.qmake.cache +/.qmake.stash +*.pro.user +*.pro.user.* +*.qbs.user +*.qbs.user.* +*.moc +moc_*.cpp +moc_*.h +qrc_*.cpp +ui_*.h +*.qmlc +*.jsc +Makefile* +*build-* +*.qm +*.prl + +# Qt unit tests +target_wrapper.* + +# QtCreator +*.autosave + +# QtCreator Qml +*.qmlproject.user +*.qmlproject.user.* + +# QtCreator CMake +CMakeLists.txt.user* + +# QtCreator 4.8< compilation database +compile_commands.json + +# QtCreator local machine specific files for imported projects +*creator.user* + +*_qmlcache.qrc + + +.history +depend +output/output/LOGtoJSON.exe + +.pytest_cache \ No newline at end of file diff --git a/.trunk/.gitignore b/.trunk/.gitignore new file mode 100644 index 0000000..15966d0 --- /dev/null +++ b/.trunk/.gitignore @@ -0,0 +1,9 @@ +*out +*logs +*actions +*notifications +*tools +plugins +user_trunk.yaml +user.yaml +tmp diff --git a/.trunk/configs/.flake8 b/.trunk/configs/.flake8 new file mode 100644 index 0000000..d84bb77 --- /dev/null +++ b/.trunk/configs/.flake8 @@ -0,0 +1,10 @@ +# Autoformatter friendly flake8 config (all formatting rules disabled) +[flake8] +extend-ignore = D1, D2, E1, E2, E3, E501, W1, W2, W3, W5 +exclude = + .history + .vscode + .git + .venv + __pycache__ + diff --git a/.trunk/configs/.isort.cfg b/.trunk/configs/.isort.cfg new file mode 100644 index 0000000..b9fb3f3 --- /dev/null +++ b/.trunk/configs/.isort.cfg @@ -0,0 +1,2 @@ +[settings] +profile=black diff --git a/.trunk/configs/.markdownlint.yaml b/.trunk/configs/.markdownlint.yaml new file mode 100644 index 0000000..fb94039 --- /dev/null +++ b/.trunk/configs/.markdownlint.yaml @@ -0,0 +1,10 @@ +# Autoformatter friendly markdownlint config (all formatting rules disabled) +default: true +blank_lines: false +bullet: false +html: false +indentation: false +line_length: false +spaces: false +url: false +whitespace: false diff --git a/.trunk/configs/.sqlfluff b/.trunk/configs/.sqlfluff new file mode 100644 index 0000000..5d2192c --- /dev/null +++ b/.trunk/configs/.sqlfluff @@ -0,0 +1,2 @@ +[sqlfluff] +dialect = ansi diff --git a/.trunk/configs/.yamllint.yaml b/.trunk/configs/.yamllint.yaml new file mode 100644 index 0000000..4d44466 --- /dev/null +++ b/.trunk/configs/.yamllint.yaml @@ -0,0 +1,10 @@ +rules: + quoted-strings: + required: only-when-needed + extra-allowed: ["{|}"] + empty-values: + forbid-in-block-mappings: true + forbid-in-flow-mappings: true + key-duplicates: {} + octal-values: + forbid-implicit-octal: true diff --git a/.trunk/configs/ruff.toml b/.trunk/configs/ruff.toml new file mode 100644 index 0000000..2bac1c8 --- /dev/null +++ b/.trunk/configs/ruff.toml @@ -0,0 +1,22 @@ +# Generic, formatter-friendly config. +select = ["B", "D3", "D4", "E", "F"] + +# Never enforce `E501` (line length violations). This should be handled by formatters. +ignore = ["E501","F401"] +exclude = [ + ".trunk", + ".git", + ".github", + "build", + "dist", + "docs", + "examples", + "tests", + ".history", + ".vscode", + "venv", + ".venv", + "__pycache__", +] +line-length = 88 +indent-width = 4 diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml new file mode 100644 index 0000000..d0c9a1e --- /dev/null +++ b/.trunk/trunk.yaml @@ -0,0 +1,59 @@ +# This file controls the behavior of Trunk: https://docs.trunk.io/cli +# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml +version: 0.1 +cli: + version: 1.19.0 +plugins: + sources: + - id: trunk + ref: v1.4.2 + uri: https://github.com/trunk-io/plugins +runtimes: + enabled: + - node@18.12.1 + - python@3.10.8 +lint: + disabled: + - flake8 + - taplo + - pylint + - mypy + - git-diff-check + - checkov + - oxipng + - prettier + - trivy + - trufflehog + enabled: + - osv-scanner@1.6.1 + - sql-formatter@15.1.2 + - sqlfluff@2.3.5 + - isort@5.13.2 + - ruff@0.1.14 + - bandit@1.7.7 + - markdownlint@0.38.0 + - yamllint@1.33.0 + - black@23.12.1 +actions: + disabled: + - trunk-fmt-pre-commit + enabled: + - trunk-announce + - trunk-check-pre-push + - trunk-upgrade-available +#ignore the following folders +# .history +# .vscode +# .idea +# .git +# .github +# .trunk# .vscode +# node_modules +# .DS_Store +# .pytest_cache +# .mypy_cache +# build +# dist +# __pycache__ +# .venv +# .ipynb_checkpoints diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..df88aea --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,30 @@ +{ + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/Thumbs.db": true, + "**/.trunk/*actions/": true, + "**/.trunk/*logs/": true, + "**/.trunk/*notifications/": true, + "**/.trunk/*out/": true, + "**/.trunk/*plugins/": true, + "**/.history": true, + "**/.pytest_cache": true, + ".pytest_cache": true, + "**/__pycache__": true, + "__pycache__": true + }, + "explorerExclude.backup": {}, + "python.testing.unittestEnabled": false, + "python.testing.unittestArgs": [ + "-v", + "-s", + "./test", + "-p", + "*_test.py" + ], + "python.testing.pytestEnabled": true, +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..279c350 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,14 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Compile UI", + "type": "shell", + "command": "pyuic6 ${file} -o ${fileDirname}/${fileBasenameNoExtension}_ui.py", + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} diff --git a/LICENSE b/LICENSE index 33f39c8..664d8c4 100644 --- a/LICENSE +++ b/LICENSE @@ -2,20 +2,8 @@ MIT License Copyright (c) 2024 WorldTeacher -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 1a3d6ea..27a67a7 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ -# SemesterapparatsManager -A software created to manage media +# Semesterapparate + +this repo will be used to create a GUI application to manage the semesterapparate of the PH Freiburg. \ No newline at end of file diff --git a/__main__.py b/__main__.py new file mode 100644 index 0000000..e69de29 diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..0814e23 --- /dev/null +++ b/config.yaml @@ -0,0 +1,79 @@ +default_apps: true +save_path: C:\Users\aky547\Desktop\testfolder\ +custom_applications: +- name: Text files + extensions: + - txt + - md + - rst + application: Notepad +- name: CSV files + extensions: + - csv + application: Excel +- name: pdf files + extensions: + - pdf + application: Firefox +- name: Word files + extensions: + - docx + - doc + application: Word +- name: Excel files + extensions: + - xlsx + - xls + application: Excel +database: + name: database.db + path: C:\Users\aky547\Desktop\semap\db\ +subjects: +- name: Biologie + aliases: null +- name: Chemie + aliases: null +- name: Deutsch + aliases: null +- name: Englisch + aliases: null +- name: Erziehungswissenschaft + aliases: null +- name: Französisch + aliases: null +- name: Geographie + aliases: null +- name: Geschichte + aliases: null +- name: Gesundheitspädagogik + aliases: null +- name: Haushalt / Textil + aliases: null +- name: Kunst + aliases: null +- name: Mathematik / Informatik + aliases: null +- name: Medien in der Bildung + aliases: null +- name: Musik + aliases: null +- name: Philosophie + aliases: null +- name: Physik + aliases: null +- name: Politikwissenschaft + aliases: null +- name: Prorektorat Lehre und Studium + aliases: null +- name: Psychologie + aliases: null +- name: Soziologie + aliases: null +- name: Sport + aliases: null +- name: Technik + aliases: null +- name: Theologie + aliases: null +- name: Wirtschaftslehre + aliases: null diff --git a/database_testing.py b/database_testing.py new file mode 100644 index 0000000..b02ec3a --- /dev/null +++ b/database_testing.py @@ -0,0 +1,19 @@ +from src.backend.database import Database +from src.logic.dataclass import ApparatData + +apparat = ApparatData() +apparat.appname = "testapparat123" +apparat.appnr = 155 +apparat.dauerapp = True +apparat.profname = "Mustermanns, Max" +apparat.subject = "Physik" +apparat.semester = "SoSe 2021" + + +files = {"name": "test.png", "type": "png", + "path": r"C:\Users\aky547\Desktop\test.png"} +db = Database() +# print(db.recreate_file("testfile.pdf",files,3)) +# db.insert_file(files,3) +# recreate_file("test.pdf",files,1))#insert_file(files,1)) +db.get_apparats_name(70) \ No newline at end of file diff --git a/db_testing.py b/db_testing.py new file mode 100644 index 0000000..627e487 --- /dev/null +++ b/db_testing.py @@ -0,0 +1,46 @@ +from omegaconf import OmegaConf + +from codebase import Database +from codebase.pickles import load_pickle, make_pickle +from webrequest import BibTextTransformer, WebRequest + +config = OmegaConf.load("config.yaml") +db = Database() +# # # f = db.get_media(1, 1) +# # # dataclass_objects = [] + +# # # for dataclass_str in f: +# # # print(f"dataclass {dataclass_str}") +# # # # dataclass_obj = ast.literal_eval(dataclass_str[0]) +# # # dataclass_objects.append(dataclass_str) + +# # # cla = BookData().from_string(dataclass_objects[0]) +# # # print(type(cla)) +# # book = ( +# # BibTextTransformer("ARRAY") +# # .get_data(WebRequest().get_ppn("ST 250 U42 (15)").get_data()) +# # .return_data() +# # ) +# # print(book) + +# # bpickle = make_pickle(book) +# # print(bpickle) + +# # print(load_pickle(bpickle)) + + +# # # print(pickle.dumps(book), type(pickle.dumps(book))) + +# # # db.add_medium(book, "2", "1") +# # # db.get_app_data("1", "Testapparat") + +# # books = db.get_media(1, 1, 0) + +# # print(len(books)) +# book = db.get_specific_book(16) + +# print(book) + + +if __name__ == "__main__": + print(db.get_media(15, 2)) diff --git a/log.py b/log.py new file mode 100644 index 0000000..c8051a9 --- /dev/null +++ b/log.py @@ -0,0 +1,65 @@ +import logging +import os + +if not os.path.exists("logs"): + os.mkdir("logs") +with open("logs/application.log", "w") as f: + pass + +# Create a common file handler for all loggers +common_file_handler = logging.FileHandler("logs/application.log") +common_file_handler.setLevel(logging.DEBUG) +formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") +common_file_handler.setFormatter(formatter) + + +class MyLogger: + def __init__(self, logger_name): + self.logger = logging.getLogger(logger_name) + self.logger.setLevel(logging.DEBUG) + self.logger.addHandler(common_file_handler) + self.encoding = "utf-8" + + def log_info(self, message: str): + # ensure that the message is encoded in utf-8 + self.logger.info(message.encode(self.encoding)) + + def log_debug(self, message: str): + self.logger.debug(message.encode(self.encoding)) + + def log_warning(self, message: str): + self.logger.warning(message.encode(self.encoding)) + + def log_error(self, message: str): + self.logger.error(message.encode(self.encoding)) + + def log_critical(self, message: str): + self.logger.critical(message.encode(self.encoding)) + + def log_exception(self, message: str): + self.logger.exception(message) + + +# Usage example: +if __name__ == "__main__": + logger1 = MyLogger("Logger1") + logger2 = MyLogger("Logger2") + + logger1.log_info("This is an info message from Logger1") + logger1.log_debug("This is a debug message from Logger1") + logger1.log_warning("This is a warning message from Logger1") + logger1.log_error("This is an error message from Logger1") + logger1.log_critical("This is a critical message from Logger1") + + logger2.log_info("This is an info message from Logger2") + logger2.log_debug("This is a debug message from Logger2") + logger2.log_warning("This is a warning message from Logger2") + logger2.log_error("This is an error message from Logger2") + logger2.log_critical("This is a critical message from Logger2") + + try: + # Simulate an exception + raise Exception("An exception occurred") + except Exception as e: + logger1.log_exception("An exception occurred in Logger1") + logger2.log_exception("An exception occurred in Logger2") diff --git a/main.py b/main.py new file mode 100644 index 0000000..90d21cd --- /dev/null +++ b/main.py @@ -0,0 +1,8 @@ +from src.logic import userInterface + + + + + +if __name__ == '__main__': + userInterface.launch_gui() \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e3da720 Binary files /dev/null and b/requirements.txt differ diff --git a/sap.db b/sap.db new file mode 100644 index 0000000..54d1ca2 Binary files /dev/null and b/sap.db differ diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/backend/__init__.py b/src/backend/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/backend/admin_console.py b/src/backend/admin_console.py new file mode 100644 index 0000000..379103f --- /dev/null +++ b/src/backend/admin_console.py @@ -0,0 +1,52 @@ +import hashlib +import random + +from src.backend.database import Database + + +# change passwords for apparats, change passwords for users, list users, create and delete users etc +# create a class that has all commands. for each command, create a function that does the thing +class AdminCommands: + def __init__(self): + self.db = Database() + + def create_password(self, password): + salt = self.create_salt() + hashed_password = self.hash_password(password) + return (hashed_password,salt) + def create_salt(self): + return "".join( + random.choices( + "abcdefghijklmnopqrstuvwxyzQWERTZUIOPLKJHGFDSAYXCVBNM0123456789", k=16 + ) + ) + + def create_admin(self): + salt = self.create_salt() + hashed_password = self.hash_password("admin") + self.db.create_user("admin", salt+hashed_password, "admin", salt) + + def hash_password(self, password): + hashed = hashlib.sha256((password).encode("utf-8")).hexdigest() + return hashed + + def list_users(self): + return self.db.get_users() + + def delete_user(self, username): + self.db.delete_user(username) + + def change_password(self, username, password): + hashed_password = self.hash_password(password) + self.db.change_password(username, hashed_password) + + +if __name__ == "__main__": + c = AdminCommands() + c.create_user("test", "test", "user") + c.create_user("admin", "admin", "admin") + print(c.list_users()) + c.delete_user("test") + print(c.list_users()) + c.change_password("admin", "nopass") + print(c.list_users()) diff --git a/src/backend/database.py b/src/backend/database.py new file mode 100644 index 0000000..21bea2b --- /dev/null +++ b/src/backend/database.py @@ -0,0 +1,748 @@ +import datetime +import os +import re +import shutil +import sqlite3 as sql3 +import tempfile +from typing import Any + +from omegaconf import OmegaConf + +from src.backend.db import main as template +# from src.data import pickles +import pickle +from src.logic.constants import SEMAP_MEDIA_ACCOUNTS +from src.logic.dataclass import ApparatData, BookData +from log import MyLogger +from icecream import ic +config = OmegaConf.load("config.yaml") + +logger = MyLogger("Database") + + +class Database: + logger.log_info("Database imported") + + def __init__(self) -> None: + # TODO: change path later on to a variable based on the settings + self.database_path = f"{config.database.path}{config.database.name}" + ic(self.database_path) + # self.database_path = "sap.db" + logger.log_info("Connecting to database") + self.database = sql3.connect(self.database_path) + self.cur = self.database.cursor() + + pass + def create_database(self): + #create database from template + template(self.database_path) + subjects = config.subjects + for subject in subjects: + self.cur.execute(f"INSERT INTO subjects (name) VALUES ('{subject}')") + self.database.commit() + + def create_blob(self, file): + with open(file, "rb") as f: + blob = f.read() + return blob + + def recreate_file(self, filename, app_id: int): + blob = self.get_blob(filename, app_id) + # write the blob to the file and save it to a preset destination + # with open(filename, "wb") as f: + # f.write(blob) + #use tempfile to create a temporary file + if not os.path.exists(config.database.tempdir): + os.mkdir(config.database.tempdir) + tempfile.NamedTemporaryFile(filename=filename,delete=False,dir=config.database.tempdir,mode="wb").write(blob) + + # user = os.getlogin() + # home = os.path.expanduser("~") + + # # check if the folder exists, if not, create it + # if not os.path.exists(f"{home}/Desktop/SemApp/{user}"): + # os.mkdir(f"{home}/Desktop/SemApp/{user}") + # shutil.move(filename, f"{home}/Desktop/SemApp/{user}") + + def get_blob(self, filename: str, app_id: int): + query = f"SELECT fileblob FROM files WHERE filename='{filename}' AND app_id={app_id}" + logger.log_info(f"Retrieving blob for {filename}, Appid {app_id} from database") + result = self.cur.execute(query).fetchone() + return result[0] + + def get_kto_no(self, app_id: int): + query = f"SELECT konto FROM semesterapparat WHERE id={app_id}" + result = self.cur.execute(query).fetchone() + return result[0] + + def insert_file(self, file: list[dict], app_id: int, prof_id): + for f in file: + filename = f["name"] + path = f["path"] + filetyp = f["type"] + print(f"filename: {filename}, path: {path}, filetyp: {filetyp}") + if path == "Database": + continue + blob = self.create_blob(path) + + query = "INSERT OR IGNORE INTO files (filename, fileblob, app_id, filetyp,prof_id) VALUES (?, ?, ?, ?,?)" + params = (filename, blob, app_id, filetyp, prof_id) + self.cur.execute(query, params) + logger.log_info( + f"Inserted {len(file)} file(s) of Apparat {app_id} into database" + ) + self.database.commit() + + def get_files(self, app_id: int, prof_id: int): + query = f"SELECT filename, filetyp FROM files WHERE app_id={app_id} AND prof_id={prof_id}" + result: list[tuple] = self.cur.execute(query).fetchall() + return result + + def get_prof_name_by_id(self, id, add_title: bool = False): + if add_title is True: + query = f"SELECT titel, fname, lname FROM prof WHERE id={id}" + result = self.cur.execute(query).fetchone() + name = " ".join(result[0:3]) + return name + else: + query = f"SELECT fullname FROM prof WHERE id={id}" + print(query) + result = self.cur.execute(query).fetchone() + name = result[0] + return name + + def get_prof_id(self, profname: str): + query = f"SELECT id FROM prof WHERE fullname='{profname.replace(',', '')}'" + result = self.cur.execute(query).fetchone() + if result is None: + return None + return self.cur.execute(query).fetchone()[0] + + def get_app_id(self, appname: str): + query = f"SELECT id FROM semesterapparat WHERE name='{appname}'" + result = self.cur.execute(query).fetchone() + if result is None: + return None + return self.cur.execute(query).fetchone()[0] + + def get_profs(self): + query = "select * from prof" + return self.cur.execute(query).fetchall() + + def app_exists(self, appnr: str) -> bool: + query = f"SELECT appnr FROM semesterapparat WHERE appnr='{appnr}'" + result = self.cur.execute(query).fetchone() + if result is None: + return False + return True + + def get_prof_data(self, profname: str = None, id: int = None) -> dict[str, str]: + if profname is not None: + profname = profname.replace(",", "") + profname = re.sub(r"\s+", " ", profname).strip() + if id: + query = "Select prof_id FROM semesterapparat WHERE appnr=?" + params = (id,) + result = self.cur.execute(query, params).fetchone() + id = result[0] + query = ( + f"SELECT * FROM prof WHERE fullname='{profname}'" + if id is None + else f"SELECT * FROM prof WHERE id={id}" + ) + result = self.cur.execute(query).fetchone() + return_data = { + "prof_title": result[1], + "profname": f"{result[3], result[2]}", + "prof_mail": result[5], + "prof_tel": result[6], + "id": result[0], + } + print(return_data) + # select the entry that contains the first name + return return_data + + def set_new_sem_date(self, appnr, new_sem_date, dauerapp=False): + # Todo: use extend_semester in new release + date = datetime.datetime.now().strftime("%Y-%m-%d") + + query = f"UPDATE semesterapparat SET verlängert_am='{date}', verlängerung_bis='{new_sem_date}' WHERE appnr='{appnr}'" + if dauerapp is not False: + query = f"UPDATE semesterapparat SET verlängert_am='{date}', verlängerung_bis='{new_sem_date}', dauerapp='{dauerapp} WHERE appnr='{appnr}'" + self.cur.execute(query) + + self.database.commit() + + def create_apparat(self, ApparatData: ApparatData): + prof_id = self.get_prof_id(ApparatData.profname) + app_id = self.get_app_id(ApparatData.appname) + if app_id is None: + if prof_id is None: + self.create_prof(ApparatData.get_prof_details()) + prof_id = self.get_prof_id(ApparatData.profname) + + query = f"INSERT OR IGNORE INTO semesterapparat (appnr, name, erstellsemester, dauer, prof_id, fach,deletion_status,konto) VALUES ('{ApparatData.appnr}', '{ApparatData.appname}', '{ApparatData.semester}', '{ApparatData.dauerapp}', {prof_id}, '{ApparatData.app_fach}', '{ApparatData.deleted}', '{SEMAP_MEDIA_ACCOUNTS[ApparatData.appnr]}')" + print(query) + self.cur.execute(query) + self.database.commit() + logger.log_info(f"Created new apparat {ApparatData.appname}") + app_id = self.get_app_id(ApparatData.appname) + # if ApparatData.media_list is not None: #! Deprecated + # for media in ApparatData.media_list: + # self.insert_file(media, app_id) + # self.database.commit() + return app_id + + def create_prof(self, prof_details: dict): + prof_title = prof_details["prof_title"] + prof_fname = prof_details["profname"].split(",")[1] + prof_fname = prof_fname.strip() + prof_lname = prof_details["profname"].split(",")[0] + prof_lname = prof_lname.strip() + prof_fullname = prof_details["profname"].replace(",", "") + prof_mail = prof_details["prof_mail"] + prof_tel = prof_details["prof_tel"] + + query = f'INSERT OR IGNORE INTO prof (titel, fname, lname, fullname, mail, telnr) VALUES ("{prof_title}", "{prof_fname}", "{prof_lname}", "{prof_fullname}", "{prof_mail}", "{prof_tel}")' + self.cur.execute(query) + self.database.commit() + pass + + def get_apparat_nrs(self) -> list: + try: + self.cur.execute( + "SELECT appnr FROM semesterapparat Where deletion_status=0" + ) + except sql3.OperationalError: + return [] + return [i[0] for i in self.cur.fetchall()] + + def get_all_apparts(self, deleted=0): + + self.cur.execute( + f"SELECT * FROM semesterapparat WHERE deletion_status={deleted}" + ) + return self.cur.fetchall() + + # + def get_app_data(self, appnr, appname) -> ApparatData: + result = self.cur.execute( + f"SELECT * FROM semesterapparat WHERE appnr='{appnr}' AND name='{appname}'" + ).fetchone() + print(f"result: {result}") + # app_id=result[0] + data = ApparatData() + data.appnr = appnr + data.app_fach = result[3] + data.appname = result[1] + profname = self.get_prof_name_by_id(result[2]) + # set profname to lastname, firstname + profname = f"{profname.split(' ')[0]}, {profname.split(' ')[1]}" + data.profname = profname + prof_data = self.get_prof_data(data.profname) + data.prof_mail = prof_data["prof_mail"] + data.prof_tel = prof_data["prof_tel"] + data.prof_title = prof_data["prof_title"] + data.erstellsemester = result[5] + data.semester = result[8] + data.deleted = result[9] + data.apparat_adis_id = result[12] + data.prof_adis_id = None + + print(data) + # data.media_list=self.get_media(app_id) + + return data + + def add_medium(self, bookdata: BookData, app_id: str, prof_id: str, *args): + # insert the bookdata into the media table + # try to retrieve the bookdata from the media table, check if the to be inserted bookdata is already in the table for the corresponding apparat + # if yes, do not insert the bookdata + # if no, insert the bookdata + t_query = ( + f"SELECT bookdata FROM media WHERE app_id={app_id} AND prof_id={prof_id}" + ) + # print(t_query) + result = self.cur.execute(t_query).fetchall() + result = [pickle.loads(i[0]) for i in result] + if bookdata in result: + print("Bookdata already in database") + # check if the book was deleted in the apparat + query = ( + "SELECT deleted FROM media WHERE app_id=? AND prof_id=? AND bookdata=?" + ) + params = (app_id, prof_id, pickle.dumps(bookdata)) + result = self.cur.execute(query, params).fetchone() + if result[0] == 1: + print("Book was deleted, updating bookdata") + query = "UPDATE media SET deleted=0 WHERE app_id=? AND prof_id=? AND bookdata=?" + params = (app_id, prof_id, pickle.dumps(bookdata)) + self.cur.execute(query, params) + self.database.commit() + return + + query = ( + "INSERT INTO media (bookdata, app_id, prof_id,deleted) VALUES (?, ?, ?,?)" + ) + converted = pickle.dumps(bookdata) + params = (converted, app_id, prof_id, 0) + self.cur.execute(query, params) + self.database.commit() + + def request_medium(self, app_id, prof_id, signature) -> int: + query = "SELECT bookdata, id FROM media WHERE app_id=? AND prof_id=?" + params = (app_id, prof_id) + result = self.cur.execute(query, params).fetchall() + books = [(i[1], pickle.loads(i[0])) for i in result] + print(books) + book = [i[0] for i in books if i[1].signature == signature] + return book[0] + + def add_message(self, message: dict, user, appnr): + def __get_user_id(user): + query = "SELECT id FROM user WHERE username=?" + params = (user,) + result = self.cur.execute(query, params).fetchone() + return result[0] + + user_id = __get_user_id(user) + query = "INSERT INTO messages (message, user_id, remind_at) VALUES (?, ?, ?)" + params = (message["message"], user_id, message["remind_at"]) + self.cur.execute(query, params) + self.database.commit() + + def get_messages(self, date: str): + def __get_user_name(id): + query = "SELECT username FROM user WHERE id=?" + params = (id,) + result = self.cur.execute(query, params).fetchone() + return result[0] + + query = f"SELECT * FROM messages WHERE remind_at='{date}'" + result = self.cur.execute(query).fetchall() + ret = [ + { + "message": i[2], + "user": __get_user_name(i[4]), + "apparatnr": i[5], + "id": i[0], + } + for i in result + ] + return ret + + def get_apparat_id(self, appname): + query = f"SELECT appnr FROM semesterapparat WHERE name='{appname}'" + result = self.cur.execute(query).fetchone() + return result[0] + + + def get_apparats_by_semester(self, semester: str): + query = f"SELECT * FROM semesterapparat WHERE erstellsemester='{semester}'" + result = self.cur.execute(query).fetchall() + return result + + def get_semester(self) -> list[str]: + query = "SELECT DISTINCT erstellsemester FROM semesterapparat" + result = self.cur.execute(query).fetchall() + return [i for i in result] + + def is_eternal(self, id): + query = f"SELECT dauer FROM semesterapparat WHERE id={id}" + result = self.cur.execute(query).fetchone() + return result[0] + + def statistic_request(self, **kwargs: Any): + def __query(query): + result = self.cur.execute(query).fetchall() + for result_a in result: + orig_value = result_a + prof_name = self.get_prof_name_by_id(result_a[2]) + # replace the prof_id with the prof_name + result_a = list(result_a) + result_a[2] = prof_name + result_a = tuple(result_a) + result[result.index(orig_value)] = result_a + + return result + + if "deletable" in kwargs.keys(): + query = f"SELECT * FROM semesterapparat WHERE deletion_status=0 AND dauer=0 AND (erstellsemester!='{kwargs['deletesemester']}' OR verlängerung_bis!='{kwargs['deletesemester']}')" + return __query(query) + + if "dauer" in kwargs.keys(): + kwargs["dauer"] = kwargs["dauer"].replace("Ja", "1").replace("Nein", "0") + query = "SELECT * FROM semesterapparat WHERE " + for key, value in kwargs.items() if kwargs.items() is not None else {}: + print(key, value) + query += f"{key}='{value}' AND " + print(query) + # remove deletesemester part from normal query, as this will be added to the database upon deleting the apparat + if "deletesemester" in kwargs.keys(): + query = query.replace( + f"deletesemester='{kwargs['deletesemester']}' AND ", "" + ) + if "endsemester" in kwargs.keys(): + if "erstellsemester" in kwargs.keys(): + query = query.replace(f"endsemester='{kwargs['endsemester']}' AND ", "") + query = query.replace( + f"erstellsemester='{kwargs['erstellsemester']} AND ", "xyz" + ) + else: + query = query.replace( + f"endsemester='{kwargs['endsemester']}' AND ", "xyz" + ) + print("replaced") + query = query.replace( + "xyz", + f"(erstellsemester='{kwargs['endsemester']}' OR verlängerung_bis='{kwargs['endsemester']}') AND ", + ) + #remove all x="" parts from the query where x is a key in kwargs + + query = query[:-5] + print(query) + return __query(query) + + def get_app_count_by_semester(self) -> tuple[list[str], list[int]]: + """get the apparats created and deleted in the distinct semesters""" + + # get unique semesters + query = "SELECT DISTINCT erstellsemester FROM semesterapparat" + result = self.cur.execute(query).fetchall() + semesters = [i[0] for i in result] + created = [] + deleted = [] + for semester in semesters: + query = f"SELECT COUNT(*) FROM semesterapparat WHERE erstellsemester='{semester}'" + result = self.cur.execute(query).fetchone() + created.append(result[0]) + query = f"SELECT COUNT(*) FROM semesterapparat WHERE deletion_status=1 AND deleted_date='{semester}'" + result = self.cur.execute(query).fetchone() + deleted.append(result[0]) + # store data in a tuple + ret = [] + e_tuple = () + for sem in semesters: + e_tuple = ( + sem, + created[semesters.index(sem)], + deleted[semesters.index(sem)], + ) + ret.append(e_tuple) + return ret + # get the count of apparats created in the semesters + + def apparats_by_semester(self, semester: str): + """Get a list of all created and deleted apparats in the given semester""" + # get a list of apparats created and in the given semester + query = f"SELECT name,prof_id FROM semesterapparat WHERE erstellsemester='{semester}'" + result = self.cur.execute(query).fetchall() + c_tmp = [] + for i in result: + c_tmp.append((i[0], self.get_prof_name_by_id(i[1]))) + query = ( + f"SELECT name,prof_id FROM semesterapparat WHERE deleted_date='{semester}'" + ) + result = self.cur.execute(query).fetchall() + d_tmp = [] + for i in result: + d_tmp.append((i[0], self.get_prof_name_by_id(i[1]))) + # group the apparats by prof + c_ret = {} + for i in c_tmp: + if i[1] not in c_ret.keys(): + c_ret[i[1]] = [i[0]] + else: + c_ret[i[1]].append(i[0]) + d_ret = {} + for i in d_tmp: + if i[1] not in d_ret.keys(): + d_ret[i[1]] = [i[0]] + else: + d_ret[i[1]].append(i[0]) + return {"created": c_ret, "deleted": d_ret} + + def delete_message(self, message_id): + query = "DELETE FROM messages WHERE id=?" + params = (message_id,) + self.cur.execute(query, params) + self.database.commit() + + def delete_medium(self, title_id): + # delete the bookdata from the media table + query = "UPDATE media SET deleted=1 WHERE id=?" + params = (title_id,) + self.cur.execute(query, params) + self.database.commit() + pass + + def update_bookdata(self, bookdata: BookData, title_id): + query = "UPDATE media SET bookdata=? WHERE id=?" + converted = pickle.dumps(bookdata) + params = (converted, title_id) + self.cur.execute(query, params) + self.database.commit() + + def get_specific_book(self, book_id): + query = "SELECT bookdata FROM media WHERE id=?" + params = (book_id,) + result = self.cur.execute(query, params).fetchone() + return pickle.loads(result[0]) + + def get_media(self, app_id, prof_id, del_state=0) -> list[dict[int, BookData, int]]: + """request media from database and return result as list. + + Args: + ---- + - app_id (int): ID of the apparat + - prof_id (int): ID of the prof + - del_state (int, optional): If deleted books should be requested as well. 1 = yes 0 = no. Defaults to 0. + + Returns: + ------- + - list[dict[int,BookData,int]]: Returns a list of dictionaries containing the bookdata, the id and the availability of the book in the following format: + ------- + {"id": int, + "bookdata": BookData, + "available": int} + """ + query = f"SELECT id,bookdata,available FROM media WHERE (app_id={app_id} AND prof_id={prof_id}) AND (deleted={del_state if del_state == 0 else '1 OR deleted=0'})" + logger.log_info(f"Requesting media from database with query: {query}") + result = self.cur.execute(query).fetchall() + ret_result = [] + for result_a in result: + ic(result_a) + data = {"id": int, "bookdata": BookData, "available": int} + data["id"] = result_a[0] + data["bookdata"] = pickle.loads(result_a[1]) + data["available"] = result_a[2] + ret_result.append(data) + return ret_result + + def get_subjects_and_aliases(self): + query = "SELECT subjects.name, aliases.name FROM subjects LEFT JOIN aliases ON subjects.id = aliases.subject_id" + return self.cur.execute(query).fetchall() + + def get_subjects(self): + query = "SELECT id,name FROM subjects" + return self.cur.execute(query).fetchall() + + def get_aliases(self,subject_id): + query = f"SELECT name FROM aliases WHERE subject_id={subject_id}" + return self.cur.execute(query).fetchall() + + def add_subject(self,subject_name): + query = f"INSERT INTO subjects (name) VALUES ('{subject_name}')" + self.cur.execute(query) + self.database.commit() + + def get_apparats_by_prof(self,prof_id): + query = f"SELECT * FROM semesterapparat WHERE prof_id={prof_id}" + return self.cur.execute(query).fetchall() + def add_alias(self,alias_name,subject): + query = f"SELECT id FROM subjects WHERE name='{subject}'" + subject_id = self.cur.execute(query).fetchone()[0] + query = f"INSERT INTO aliases (name,subject_id) VALUES ('{alias_name}',{subject_id})" + self.cur.execute(query) + self.database.commit() + + def update_apparat(self, apparat_data: ApparatData): + data = apparat_data + query = f"UPDATE semesterapparat SET name = ?, fach = ?, dauer = ?, prof_id = ? WHERE appnr = ?" + params = ( + data.appname, + data.app_fach, + data.dauerapp, + self.get_prof_id(data.profname), + data.appnr, + ) + print(query) + self.cur.execute(query, params) + self.database.commit() + + def delete_apparat(self, appnr: str, semester: str): + # update the deletion status to 1 and the deleted_state to semester for the given apparat + query = f"UPDATE semesterapparat SET deletion_status=1, deleted_date='{semester}' WHERE appnr='{appnr}'" + self.cur.execute(query) + self.database.commit() + + def get_book_id(self, bookdata: BookData, app_id: int, prof_id: int): + query = "SELECT id FROM media WHERE bookdata=? AND app_id=? AND prof_id=?" + params = (pickle.loads(bookdata), app_id, prof_id) + result = self.cur.execute(query, params).fetchone() + return result + + + + def set_availability(self, book_id, available): + query = "UPDATE media SET available=? WHERE id=?" + params = (available, book_id) + self.cur.execute(query, params) + self.database.commit() + + def get_latest_book_id(self): + query = "SELECT id FROM media ORDER BY id DESC LIMIT 1" + result = self.cur.execute(query).fetchone() + return result[0] + + def close(self): + self.database.close() + + def login(self, username, hashed_password) -> bool: + # check if the user and password exist in the database + # if yes, return True + # if no, return False + query = "SELECT salt FROM user WHERE username=?" + params = (username,) + result = self.cur.execute(query, params).fetchone() + + if result is None: + return False + salt = result[0] + print(salt) + query = "SELECT password FROM user WHERE username=?" + params = (str(username),) + result = self.cur.execute(query, params).fetchone() + password = result[0] + if password == f"{salt}{hashed_password}": + return True + else: + return False + + # admin stuff below here + def get_users(self): + query = "SELECT * FROM user" + return self.cur.execute(query).fetchall() + + def get_apparats(self) -> list[tuple]: + query = "SELECT * FROM semesterapparat" + return self.cur.execute(query).fetchall() + + def change_password(self, user, password): + saltq = "SELECT salt FROM user WHERE username=?" + params = (user,) + salt = self.cur.execute(saltq, params).fetchone()[0] + password = f"{salt}{password}" + query = "UPDATE user SET password=? WHERE username=?" + params = (password, user) + self.cur.execute(query, params) + self.database.commit() + + def get_role(self, username): + query = "SELECT role FROM user WHERE username=?" + params = (username,) + result = self.cur.execute(query,params).fetchone() + return result[0] + + def get_roles(self): + query = "SELECT role FROM user" + return self.cur.execute(query).fetchall() + + def create_user(self, username, password, role, salt): + """Create a user based on passed data. + + Args: + ---- + - username (str): Username to be used + - password (str): the salted password + - role (str): Role of the user + - salt (str): a random salt for the user + """ + query = "INSERT OR IGNORE INTO user (username, password, role, salt) VALUES (?, ?, ?, ?)" + params = (username, password, role, salt) + self.cur.execute(query, params) + self.database.commit() + + def delete_user(self, user): + query = "DELETE FROM user WHERE username=?" + params = (user,) + self.cur.execute(query, params) + self.database.commit() + + def get_faculty_members(self,name:str=None): + query = "SELECT titel, fname,lname,mail,telnr,fullname FROM prof" + if name: + query = query.replace(",fullname", "") + query += f" WHERE fullname='{name}'" + return self.cur.execute(query).fetchall() + + def update_faculty_member(self,data,oldlname,oldfname): + placeholders = ', '.join(f"{k} = :{k}" for k in data.keys()) + sql = f"UPDATE prof SET {placeholders} WHERE lname = :oldlname AND fname = :oldfname" + data["oldlname"] = oldlname + data["oldfname"] = oldfname + print(sql, data) + self.cur.execute(sql, data) + self.database.commit() + + def faculty_data(self,name): + query = f"SELECT * FROM prof WHERE fullname='{name}'" + result = self.cur.execute(query).fetchone() + return result + + def update_user(self,username, data:dict[str,str]): + + query = "UPDATE user SET " + for key,value in data.items(): + if key == "username": + continue + query += f"{key}='{value}'," + query = query[:-1] + query += " WHERE username=?" + params = (username,) + + self.cur.execute(query,params) + self.database.commit() + + def check_username(self,username): + query = "SELECT username FROM user WHERE username=?" + params = (username,) + result = self.cur.execute(query,params).fetchone() + if result is None: + return False + return True + def get_apparats_name(self, app_id,prof_id): + query = f"SELECT name FROM semesterapparat WHERE appnr={app_id} AND prof_id={prof_id}" + ic(query) + result = self.cur.execute(query).fetchone() + return result[0] + + def search_book(self, data:dict[str,str])->list[tuple[BookData,int]]: + query = "SELECT * FROM media " + result = self.database.execute(query).fetchall() + ret = [] + #get length of data dict + length = len(data) + mode = 0 + if length == 1: + if "signature" in data.keys(): + mode = 1 + elif "title" in data.keys(): + mode = 2 + elif length == 2: + mode = 3 + else: + return None + print(len(result)) + for res in result: + bookdata = pickle.loads(res[1]) + app_id = res[2] + prof_id = res[3] + #if signature and title present in dict: + #if signature present in dict: + if mode == 1: + if data["signature"] in bookdata.signature: + ret.append((bookdata,app_id,prof_id)) + #if title present in dict: + elif mode == 2: + if data["title"] in bookdata.title: + ret.append((bookdata,app_id,prof_id)) + elif mode == 3: + if data["signature"] in bookdata.signature and data["title"] in bookdata.title: + ret.append((bookdata,app_id,prof_id)) + return ret + + +if __name__ == "__main__": + db = Database() + print(db.login("kirchner", "loginpass")) diff --git a/src/backend/db.py b/src/backend/db.py new file mode 100644 index 0000000..8fb0e02 --- /dev/null +++ b/src/backend/db.py @@ -0,0 +1,130 @@ +import sqlite3 +from omegaconf import OmegaConf +config = OmegaConf.load("config.yaml") +subjects = config.subjects + +# Connect to the database +def main(database): + conn = sqlite3.connect(database) + conn.execute( + """CREATE TABLE app_kontos ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + app_id INTEGER, + konto INTEGER, + passwort TEXT, + FOREIGN KEY (app_id) REFERENCES semesterapparat (id) + )""" + ) + + conn.execute( + """CREATE TABLE files ( + id INTEGER PRIMARY KEY, + filename TEXT, + fileblob BLOB, + app_id INTEGER, + filetyp TEXT, + prof_id INTEGER REFERENCES prof (id), + FOREIGN KEY (app_id) REFERENCES semesterapparat (id) + )""" + ) + + conn.execute( + """CREATE TABLE media ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + bookdata BLOB, + app_id INTEGER, + prof_id INTEGER, + deleted INTEGER DEFAULT (0), + available BOOLEAN, + reservation BOOLEAN, + FOREIGN KEY (prof_id) REFERENCES prof (id), + FOREIGN KEY (app_id) REFERENCES semesterapparat (id) + )""" + ) + + conn.execute( + """CREATE TABLE messages ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + created_at date NOT NULL DEFAULT CURRENT_TIMESTAMP, + message TEXT NOT NULL, + remind_at date NOT NULL DEFAULT CURRENT_TIMESTAMP, + user_id INTEGER NOT NULL, + appnr INTEGER, + FOREIGN KEY (user_id) REFERENCES user (id) + )""" + ) + + conn.execute( + """CREATE TABLE prof ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + titel TEXT, + fname TEXT, + lname TEXT, + fullname TEXT NOT NULL UNIQUE, + mail TEXT, + telnr TEXT + )""" + ) + + conn.execute( + """CREATE TABLE semesterapparat ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + name TEXT, + prof_id INTEGER, + fach TEXT, + appnr INTEGER, + erstellsemester TEXT, + verlängert_am TEXT, + dauer BOOLEAN, + verlängerung_bis TEXT, + deletion_status INTEGER, + deleted_date TEXT, + apparat_id_adis INTEGER, + prof_id_adis INTEGER, + konto INTEGER REFERENCES app_kontos (id), + FOREIGN KEY (prof_id) REFERENCES prof (id) + )""" + ) + + conn.execute( + """CREATE TABLE user ( + id integer NOT NULL PRIMARY KEY AUTOINCREMENT, + created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + username TEXT NOT NULL UNIQUE, + password TEXT NOT NULL, + salt TEXT NOT NULL, + role TEXT NOT NULL, + email TEXT UNIQUE, + name TEXT + )""" + ) + conn.execute( + """ +CREATE TABLE subjects ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + name TEXT NOT NULL UNIQUE +) +""" + ) + + conn.execute( + """ + CREATE TABLE aliases ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + name TEXT NOT NULL UNIQUE, + subject_id INTEGER, + FOREIGN KEY (subject_id) REFERENCES subjects (id) +) +""" + ) + + # Commit the changes and close the connection + conn.commit() + #insert subjects + + + conn.close() + + +if __name__ == "__main__": + main() diff --git a/src/backend/pickles.py b/src/backend/pickles.py new file mode 100644 index 0000000..5b4e104 --- /dev/null +++ b/src/backend/pickles.py @@ -0,0 +1,9 @@ +import pickle +from typing import ByteString, Any + +def make_pickle(data:Any): + return pickle.dumps(data) + + +def load_pickle(data:ByteString): + return pickle.loads(data) diff --git a/src/backend/settings.py b/src/backend/settings.py new file mode 100644 index 0000000..1390d78 --- /dev/null +++ b/src/backend/settings.py @@ -0,0 +1,26 @@ +from dataclasses import dataclass, field + +import yaml + + +@dataclass +class Settings: + """Settings for the app.""" + + save_path: str + database_name: str + database_path: str + bib_id: str + default_apps: bool = True + custom_applications: list[dict] = field(default_factory=list) + + def save_settings(self): + """Save the settings to the config file.""" + with open("config.yaml", "w") as f: + yaml.dump(self.__dict__, f) + + def load_settings(self): + """Load the settings from the config file.""" + with open("config.yaml", "r") as f: + data = yaml.safe_load(f) + return data diff --git a/src/logic/__init__.py b/src/logic/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/logic/c_sort.py b/src/logic/c_sort.py new file mode 100644 index 0000000..3a27726 --- /dev/null +++ b/src/logic/c_sort.py @@ -0,0 +1,59 @@ +from typing import List, Tuple + +from natsort import natsorted + + +def custom_sort(unsorted: List[Tuple[str, int, int]]) -> List[Tuple[str, int, int]]: + """Sort a list of semesters in the format "SoSe n" and "WiSe n/n+1" in the correct order. + Where n == year in 2 digit format + + Args: + ---- + unsorted (list[tuple]): List of semesters in the format "SoSe n" and "WiSe n/n+1" + + Returns: + ------- + ret (list[tuple]): Sorted list in correct order of WiSe n/n+1 and SoSe n + """ + summer = natsorted([i for i in unsorted if "SoSe" in i[0]]) + winter = natsorted([i for i in unsorted if "WiSe" in i[0]]) + summer = natsorted(summer, key=lambda x: x[0]) + winter = natsorted(winter, key=lambda x: x[0]) + + # Merge the lists + ret = [] + i = 0 + j = 0 + while i < len(summer) and j < len(winter): + if summer[i][0][5:] <= winter[j][0][5:]: + ret.append(summer[i]) + i += 1 + else: + ret.append(winter[j]) + j += 1 + + # Append the remaining items + while i < len(summer): + ret.append(summer[i]) + i += 1 + while j < len(winter): + ret.append(winter[j]) + j += 1 + + return ret + + # Test the function + + pass + + +if __name__ == "__main__": + unsorted = [ + ("WiSe 23/24", 7, 5), + ("SoSe 23", 5, 0), + ("SoSe 22", 1, 0), + ("WiSe 22/23", 1, 0), + ("SoSe 15", 1, 0), + ] + + print(custom_sort(unsorted)) diff --git a/src/logic/constants.py b/src/logic/constants.py new file mode 100644 index 0000000..9ed0a78 --- /dev/null +++ b/src/logic/constants.py @@ -0,0 +1,221 @@ +APP_NRS = [i for i in range(1, 181)] + +PROF_TITLES = [ + "Dr. mult.", + "Dr. paed.", + "Dr. rer. pol.", + "Dr. sc. techn.", + "Drs.", + "Dr. agr.", + "Dr. habil.", + "Dr. oec.", + "Dr. med.", + "Dr. e. h.", + "Dr. oec. publ.", + "Dr. -Ing.", + "Dr. theol.", + "Dr. med. vet.", + "Dr. ing.", + "Dr. rer. nat.", + "Dr. des.", + "Dr. sc. mus.", + "Dr. h. c.", + "Dr. pharm.", + "Dr. med. dent.", + "Dr. phil. nat.", + "Dr. phil.", + "Dr. iur.", + "Dr.", + "Kein Titel", +] +SEMAP_MEDIA_ACCOUNT_PREFIX = "10080" +semaps = { + "1": "0005", + "2": "0018", + "3": "0021", + "4": "0034", + "5": "0047", + "6": "0050", + "7": "0063", + "8": "0076", + "9": "0089", + "10": "0092", + "11": "0104", + "12": "0117", + "13": "0120", + "14": "0133", + "15": "0146", + "16": "0159", + "17": "0162", + "18": "0175", + "19": "0188", + "20": "0191", + "21": "0203", + "22": "0216", + "23": "0229", + "24": "0232", + "25": "0245", + "26": "0258", + "27": "0261", + "28": "0274", + "29": "0287", + "30": "0290", + "31": "0302", + "32": "0315", + "33": "0328", + "34": "0331", + "35": "0344", + "36": "0357", + "37": "0360", + "38": "0373", + "39": "0386", + "40": "0399", + "41": "0401", + "42": "0414", + "43": "0427", + "44": "0430", + "45": "0443", + "46": "0456", + "47": "0469", + "48": "0472", + "49": "0485", + "50": "0498", + "51": "0500", + "52": "0513", + "53": "0526", + "54": "0539", + "55": "0542", + "56": "0555", + "57": "0568", + "58": "0571", + "59": "0584", + "60": "0597", + "61": "0609", + "62": "0612", + "63": "0625", + "64": "0638", + "65": "0641", + "66": "0654", + "67": "0667", + "68": "0670", + "69": "0683", + "70": "0696", + "71": "0708", + "72": "0711", + "73": "0724", + "74": "0737", + "75": "0740", + "76": "0753", + "77": "0766", + "78": "0779", + "79": "0782", + "80": "0795", + "81": "0807", + "82": "0810", + "83": "0823", + "84": "0836", + "85": "0849", + "86": "0852", + "87": "0865", + "88": "0878", + "89": "0881", + "90": "0894", + "91": "0906", + "92": "0919", + "93": "0922", + "94": "0935", + "95": "0948", + "96": "0951", + "97": "0964", + "98": "0977", + "99": "0980", + "100": "0993", + "101": "1002", + "102": "1015", + "103": "1028", + "104": "1031", + "105": "1044", + "106": "1057", + "107": "1060", + "108": "1073", + "109": "1086", + "110": "1099", + "111": "1101", + "112": "1114", + "113": "1127", + "114": "1130", + "115": "1143", + "116": "1156", + "117": "1169", + "118": "1172", + "119": "1185", + "120": "1198", + "121": "1200", + "122": "1213", + "123": "1226", + "124": "1239", + "125": "1242", + "126": "1255", + "127": "1268", + "128": "1271", + "129": "1284", + "130": "1297", + "131": "1309", + "132": "1312", + "133": "1325", + "134": "1338", + "135": "1341", + "136": "1354", + "137": "1367", + "138": "1370", + "139": "1383", + "140": "1396", + "141": "1408", + "142": "1411", + "143": "1424", + "144": "1437", + "145": "1440", + "146": "1453", + "147": "1466", + "148": "1479", + "149": "1482", + "150": "1495", + "151": "1507", + "152": "1510", + "153": "1523", + "154": "1536", + "155": "1549", + "156": "1552", + "157": "1565", + "158": "1578", + "159": "1581", + "160": "1594", + "161": "1606", + "162": "1619", + "163": "1622", + "164": "1635", + "165": "1648", + "166": "1651", + "167": "1664", + "168": "1677", + "169": "1680", + "170": "1693", + "171": "1705", + "172": "1718", + "173": "1721", + "174": "1734", + "175": "1747", + "176": "1750", + "177": "1763", + "178": "1776", + "179": "1789", + "180": "1792", +} +# take the semaps dict and add the prefix to the values +for key, value in semaps.items(): + semaps[key] = f"{SEMAP_MEDIA_ACCOUNT_PREFIX}{value}{value[-1]}" +SEMAP_MEDIA_ACCOUNTS = semaps + +# for s in SEMAP_MEDIA_ACCOUNTS: +# assert len(SEMAP_MEDIA_ACCOUNTS[s]) == 10, f"semap {s} has wrong length" +# print(f"{SEMAP_MEDIA_ACCOUNTS[s]}") diff --git a/src/logic/csvparser.py b/src/logic/csvparser.py new file mode 100644 index 0000000..821b461 --- /dev/null +++ b/src/logic/csvparser.py @@ -0,0 +1,27 @@ +import csv + +import pandas as pdf + + +def csv_to_list(path: str) -> list[str]: + """ + Extracts the data from a csv file and returns it as a pandas dataframe + """ + with open(path, newline='') as csvfile: + reader = csv.reader(csvfile, delimiter=';', quotechar='|') + data = [] + for row in reader: + for i in range(len(row)): + row[i] = row[i].replace('"', "") + data.append(row) + ret= [] + for i in data: + ret.append(i[0]) + return ret + + + +if __name__ == "__main__": + text = csv_to_list("C:/Users/aky547/Desktop/semap/71.csv") + #remove linebreaks + print(text) \ No newline at end of file diff --git a/src/logic/dataclass.py b/src/logic/dataclass.py new file mode 100644 index 0000000..796b1a1 --- /dev/null +++ b/src/logic/dataclass.py @@ -0,0 +1,76 @@ +import re +from dataclasses import dataclass, field + + +@dataclass +class ApparatData: + prof_title: str | None = None + profname: str | None = None + dauerapp: bool = False + appnr: int | None = None + appname: str | None = None + app_fach: str | None = None + semester: str | None = None + erstellsemester: str | None = None + prof_mail: str | None = None + prof_tel: int | None = None + deleted: int = 0 + prof_adis_id: int | None = None + apparat_adis_id: int | None = None + + def get_prof_details(self) -> dict: + return { + "prof_title": self.prof_title, + "profname": self.profname, + "prof_mail": self.prof_mail, + "prof_tel": self.prof_tel, + "fullname": self.profname, + } + + +@dataclass +class BookData: + ppn: str | None = None + title: str | None = None + signature: str | None = None + edition: str | None = None + link: str | None = None + isbn: str | list | None = field(default_factory=list) + author: str | None = None + language: str | list | None = field(default_factory=list) + publisher: str | None = None + year: str | None = None + pages: str | None = None + # avaliability: dict | None = field(default_factory=dict) + # def assign(self, field,value): + # self.__setattr__(field,value) + + def from_dict(self, data: dict): + for key, value in data.items(): + setattr(self, key, value) + + def to_dict(self): + return self.__dict__ + + def from_dataclass(self, dataclass): + for key, value in dataclass.__dict__.items(): + setattr(self, key, value) + + def from_string(self, data: str): + if not data.startswith("BookData"): + raise ValueError("No valid BookData string") + else: + pattern = r"(\w+)='([^']*)'" + data_dict = dict(re.findall(pattern, data)) + print(data_dict) + for key, value in data_dict.items(): + setattr(self, key, value) + return self + + +@dataclass +class MailData: + subject: str | None = None + body: str | None = None + mailto: str | None = None + prof: str | None = None diff --git a/src/logic/fileparser.py b/src/logic/fileparser.py new file mode 100644 index 0000000..d527daa --- /dev/null +++ b/src/logic/fileparser.py @@ -0,0 +1,45 @@ +import csv + +import pandas as pd +from docx import Document + + +def csv_to_list(path: str) -> list[str]: + """ + Extracts the data from a csv file and returns it as a pandas dataframe + """ + with open(path, newline="") as csvfile: + reader = csv.reader(csvfile, delimiter=";", quotechar="|") + data = [] + for row in reader: + for i in range(len(row)): + row[i] = row[i].replace('"', "") + data.append(row) + ret = [] + for i in data: + ret.append(i[0]) + return ret + + +def word_docx_to_csv(path) -> pd.DataFrame: + doc = Document(path) + tables = doc.tables + + m_data = [] + for table in tables: + data = [] + for row in table.rows: + row_data = [] + for cell in row.cells: + text = cell.text + text = text.replace("\n", "") + row_data.append(text) + data.append(row_data) + df = pd.DataFrame(data) + df.columns = df.iloc[0] + df = df.iloc[1:] + + m_data.append(df) + + df = m_data[2] + return df diff --git a/src/logic/get_msword_content.py b/src/logic/get_msword_content.py new file mode 100644 index 0000000..1f44218 --- /dev/null +++ b/src/logic/get_msword_content.py @@ -0,0 +1,31 @@ +from docx import Document + +data={} +wordDoc = Document('files/Semesterapparat - Anmeldung.docx') +paragraphs = wordDoc.tables +for table in paragraphs: + for column in table.columns: + cellcount=0 + for cell in column.cells: + if cellcount<12: + cellcount+=1 + print(f'cell:{cell.text}') + + + # print(f'paragraphs[{i}]: {paragraphs[i]}') + # data[i] = paragraphs[i] + +# for i in range(0, len(paragraphs)): +# for i in range(2, len(paragraphs)): +# data[i] = paragraphs[i] + +print(data) + +# for table in wordDoc.tables: +# for row in table.rows: +# print('---') +# for cell in row.cells: +# print(f'cell:{cell.text}') + + + diff --git a/src/logic/get_pdf_content.py b/src/logic/get_pdf_content.py new file mode 100644 index 0000000..2a3d6ed --- /dev/null +++ b/src/logic/get_pdf_content.py @@ -0,0 +1,11 @@ +import tabula + + +file="files/Semesterapparat - Anmeldung.pdf" + +def extract_book_data(file): + tables=tabula.read_pdf(file,pages="all",encoding="utf-8",multiple_tables=True) + tabula.convert_into(file, file.replace(".pdf"), output_format="csv", pages="all") + with open("files/Semesterapparat - Anmeldung.csv", "r") as f: + content=f.read() + diff --git a/src/logic/mail.py b/src/logic/mail.py new file mode 100644 index 0000000..e69de29 diff --git a/src/logic/pdfparser.py b/src/logic/pdfparser.py new file mode 100644 index 0000000..5c0482e --- /dev/null +++ b/src/logic/pdfparser.py @@ -0,0 +1,30 @@ +# add depend path to system path +import os +import sys + +import pandas as pd +from pdfquery import PDFQuery + + +def pdf_to_csv(path: str) -> pd.DataFrame: + """ + Extracts the data from a pdf file and returns it as a pandas dataframe + """ + file = PDFQuery(path) + file.load() + #get the text from the pdf file + text_elems = file.extract([ + ('with_formatter', 'text'), + ('all_text', '*') + ]) + extracted_text = text_elems['all_text'] + + return extracted_text + + +if __name__ == "__main__": + text = pdf_to_csv("54_pdf.pdf") + #remove linebreaks + text = text.replace("\n", "") + print(text) + diff --git a/src/logic/settings.py b/src/logic/settings.py new file mode 100644 index 0000000..3e7cda3 --- /dev/null +++ b/src/logic/settings.py @@ -0,0 +1,20 @@ +import yaml +from dataclasses import dataclass, field + +@dataclass +class Settings: + """Settings for the app.""" + save_path: str + database_name: str + database_path: str + default_apps:bool = True + custom_applications: list[dict] = field(default_factory=list) + def save_settings(self): + """Save the settings to the config file.""" + with open("config.yaml", "w") as f: + yaml.dump(self.__dict__, f) + +#open the config file and load the settings +with open("config.yaml", "r") as f: + data = yaml.safe_load(f) + diff --git a/src/logic/threads.py b/src/logic/threads.py new file mode 100644 index 0000000..7cc7e99 --- /dev/null +++ b/src/logic/threads.py @@ -0,0 +1,195 @@ +import threading +import time + +from PyQt6.QtCore import QThread, pyqtSignal + +from src.backend.database import Database +from log import MyLogger +from src.transformers import RDS_AVAIL_DATA +from src.logic.webrequest import BibTextTransformer, WebRequest +import sqlite3 + +class BookGrabber(QThread): + updateSignal = pyqtSignal(int, int) + + def __init__( + self, + mode: str = None, + data: list = None, + app_id: int = None, + prof_id: int = None, + parent=None, + ): + super().__init__(parent) + self.logger = MyLogger("Worker") + self.logger.log_info("Starting worker thread") + self.logger.log_info("Worker thread started") + self.app_id = app_id + self.prof_id = prof_id + self.mode = mode + self.data = data + self.book_id = None + self.db_lock = threading.Lock() + + def run(self): + self.db = Database() + item = 0 + for entry in self.data: + signature = str(entry) + self.logger.log_info("Processing entry: " + signature) + + webdata = WebRequest().get_ppn(entry).get_data() + if webdata == "error": + continue + bd = BibTextTransformer(self.mode).get_data(webdata).return_data() + transformer = BibTextTransformer("RDS") + rds = transformer.get_data(webdata).return_data("rds_availability") + bd.signature = entry + with self.db_lock: + #confirm lock is acquired + print("lock acquired, adding book to database") + self.db.add_medium(bd, self.app_id, self.prof_id) + # get latest book id + self.book_id = self.db.get_latest_book_id() + self.logger.log_info("Added book to database") + state = 0 + for rds_item in rds.items: + sign = rds_item.superlocation + loc = rds_item.location + # print(item.location) + if self.app_id in sign or self.app_id in loc: + state = 1 + book_id = None + # for book in self.books: + # if book["bookdata"].signature == entry: + # book_id = book["id"] + # break + self.logger.log_info(f"State of {signature}: {state}") + with self.db_lock: + print( + "lock acquired, updating availability of " + + str(book_id) + + " to " + + str(state) + ) + try: + self.db.set_availability(self.book_id, state) + except sqlite3.OperationalError as e: + self.logger.log_error(f"Failed to update availability: {e}") + break + + # time.sleep(5) + item += 1 + self.updateSignal.emit(item, len(self.data)) + self.logger.log_info("Worker thread finished") + # teminate thread + + self.quit() + + +class AvailChecker(QThread): + updateSignal = pyqtSignal(str, int) + + def __init__( + self, links: list = [], appnumber: int = None, parent=None, books=list[dict] + ): + if links is None: + links = [] + super().__init__(parent) + self.logger = MyLogger("AvailChecker") + self.logger.log_info("Starting worker thread") + self.logger.log_info( + "Checking availability for " + + str(links) + + " with appnumber " + + str(appnumber) + + "..." + ) + self.links = links + self.appnumber = appnumber + self.books = books + self.db_lock = threading.Lock() + + def run(self): + self.db = Database() + state = 0 + + for link in self.links: + self.logger.log_info("Processing entry: " + str(link)) + data = WebRequest().get_ppn(link).get_data() + transformer = BibTextTransformer("RDS") + rds = transformer.get_data(data).return_data("rds_availability") + print(rds) + for item in rds.items: + sign = item.superlocation + loc = item.location + # print(item.location) + if self.appnumber in sign or self.appnumber in loc: + state = 1 + book_id = None + for book in self.books: + if book["bookdata"].signature == link: + book_id = book["id"] + break + self.logger.log_info(f"State of {link}: " + str(state)) + with self.db_lock: + print( + "lock acquired, updating availability of " + + str(book_id) + + " to " + + str(state) + ) + self.db.set_availability(book_id, state) + break + self.updateSignal.emit(item.callnumber, state) + + self.logger.log_info("Worker thread finished") + # teminate thread + + self.quit() + + +class AutoAdder(QThread): + updateSignal = pyqtSignal(int) + + setTextSignal = pyqtSignal(int) + progress = pyqtSignal(int) + + def __init__(self, data=None, app_id=None, prof_id=None, parent=None): + super().__init__(parent) + self.logger = MyLogger("AutoAdder") + self.data = data + self.app_id = app_id + self.prof_id = prof_id + + print("Launched AutoAdder") + print(self.data, self.app_id, self.prof_id) + + def run(self): + self.db = Database() + # show the dialog, start the thread to gather data and dynamically update progressbar and listwidget + self.logger.log_info("Starting worker thread") + item = 0 + for entry in self.data: + try: + # webdata = WebRequest().get_ppn(entry).get_data() + # bd = BibTextTransformer("ARRAY").get_data(webdata).return_data() + # bd.signature = entry + self.updateSignal.emit(item) + self.setTextSignal.emit(entry) + # qsleep + item += 1 + self.progress.emit(item) + print(item, len(self.data)) + time.sleep(1) + + except Exception as e: + print(e) + self.logger.log_exception( + f"The query failed with message {e} for signature {entry}" + ) + continue + if item == len(self.data): + self.logger.log_info("Worker thread finished") + # teminate thread + self.finished.emit() diff --git a/src/logic/userInterface.py b/src/logic/userInterface.py new file mode 100644 index 0000000..a24622a --- /dev/null +++ b/src/logic/userInterface.py @@ -0,0 +1,1974 @@ +# encoding: utf-8 +import atexit +import os + +# import re +import sys +import tempfile +import time +from pathlib import Path + +from natsort import natsorted +from omegaconf import OmegaConf +from PyQt6 import QtCore, QtGui, QtWidgets +from PyQt6.QtCore import QDate, QThread, pyqtSignal +from PyQt6.QtGui import QColor, QRegularExpressionValidator + +from src.logic import c_sort +from src.backend.database import Database +from src.logic.constants import APP_NRS, PROF_TITLES +from src.logic.dataclass import ApparatData, BookData, MailData +from log import MyLogger +from src.logic.threads import BookGrabber,AvailChecker +from src.ui import ( + App_Ext_Dialog, + FilePicker, + GraphWidget, + Mail_Dialog, + Message_Widget, + Settings, + StatusWidget, + Ui_Semesterapparat, + edit_bookdata_ui, + fileparser_ui, + login_ui, + medienadder_ui, + parsed_titles_ui, + popus_confirm, + reminder_ui, + settings_ui, + new_subject_ui, +) +# from src.logic.webrequest import BibTextTransformer, WebRequest +from src.backend.admin_console import AdminCommands +from src.logic.csvparser import csv_to_list +from src.logic.wordparser import word_docx_to_csv +from icecream import ic +config = OmegaConf.load("config.yaml") + + +class Medien(medienadder_ui): + def __init__(self) -> None: + self.logger = MyLogger("Medien") + super().__init__() + self.mode = "" + self.data = [] + + def get_list_data(self) -> list: + signatures = self.listWidget.findItems("*", QtCore.Qt.MatchFlag.MatchWildcard) + return [signature.text() for signature in signatures] + + def get_mode(self) -> str: + return self.comboBox.currentText() + + +# class Setup(SetupWizard): +# def __init__(self, MainWindow): +# super().__init__() +# self.setupUi(MainWindow) +# self.settings = Settings() +# self.setWindowTitle("Semesterapparatsmanagement Setup") +# self.btn_save_path_select.clicked.connect(self.select_save_path) +# # self.setWindowIcon(QtGui.QIcon("ui\icon.png")) + +# def select_save_path(self) -> None: +# # open a dialog to select a save path +# dialog = QtWidgets.QFileDialog() +# dialog.setFileMode(QtWidgets.QFileDialog.FileMode.Directory) +# dialog.setOption(QtWidgets.QFileDialog.Option.ShowDirsOnly) +# dialog.exec() +# self.settings.save_path = dialog.selectedFiles()[0] +# self.save_path.setText(self.settings.save_path) +# self.settings.save_settings() +class MyComboBox(QtWidgets.QComboBox): + + def __init__(self, parent=None): + super().__init__(parent) + +valid_input = (0, 0, 0, 0, 0, 0) + + +class MessageCalendar(QtWidgets.QCalendarWidget): + #Widget for MessageCalendar + def __init__(self, parent=None): + super().__init__(parent) + self.messages = {} # Dictionary to store dates with messages + + def setMessages(self, messages): + for message in messages: + print(message) + # Convert the date string to a QDate object + date = QDate.fromString(message["remind_at"], "yyyy-MM-dd") + # Store the message for the date + self.messages[date] = message["message"] + self.updateCells() + + def updateCells(self): + self.repaint() + + def paintCell(self, painter, rect, date): + super().paintCell(painter, rect, date) + + # Check if there is a message for the current date + if date in self.messages: + # If there is a message, color the cell background + painter.fillRect(rect, QColor("#a7e681")) + + def change_stylesheet_cell(self, date: QDate, color: str): + # change the stylesheet of a cell + self.setStyleSheet( + f"QCalendarWidget QTableView QTableCornerButton::section {{background-color: {color};}}" + ) + + +class Ui(Ui_Semesterapparat): + # use the Ui_MainWindow class from mainwindow.py + def __init__(self, MainWindow, username: str) -> None: + self.logger = MyLogger("Ui") + self.logger.log_info("Starting Semesterapparatsmanagement") + super().__init__() + self.active_user = username + self.setupUi(MainWindow) + self.MainWindow = MainWindow + # set the window title + MainWindow.setWindowTitle("Semesterapparatsmanagement") + + self.db = Database() + # self.show() + # self.setWindowTitle("Semesterapparatsmanagement") + # self.setWindowIcon(QIcon("ui\icon.png")) + # self.sem_sommer.clicked.connect(self.buttonClicked) + self.btn_add_document.clicked.connect(self.add_document) + self.check_file.clicked.connect( + self.btn_check_file_threaded + ) # default: self.add_media_from_file) + self.create_new_app.clicked.connect(self.btn_create_new_apparat) + # self.load_app.clicked.connect(self.btn_load_apparat) + self.btn_apparat_save.clicked.connect(self.btn_save_apparat) + self.btn_apparat_apply.clicked.connect(self.update_apparat) + self.btn_open_document.clicked.connect(self.open_document) + self.add_medium.clicked.connect(self.btn_add_medium) + self.btn_copy_adis_command.clicked.connect(self.text_to_clipboard) + self.btn_reserve.clicked.connect(self.check_availability) + self.calendarWidget = MessageCalendar(self.frame_2) + self.calendarWidget.setGeometry(QtCore.QRect(0, 0, 291, 191)) + self.calendarWidget.setGridVisible(True) + self.calendarWidget.setVerticalHeaderFormat( + QtWidgets.QCalendarWidget.VerticalHeaderFormat.NoVerticalHeader + ) + self.calendarWidget.setObjectName("MessageCalendar") + self.calendarWidget.clicked.connect(self.open_reminder) + self.tableWidget_apparat_media.horizontalHeader().setSectionResizeMode( + QtWidgets.QHeaderView.ResizeMode.Stretch + ) + self.tableWidget_apparate.horizontalHeader().setSectionResizeMode( + QtWidgets.QHeaderView.ResizeMode.Stretch + ) + self.tableWidget_apparate.setSortingEnabled(True) + # self.tableWidget_apparate.text + self.actionEinstellungen.triggered.connect(self.open_settings) + # set validators + self.sem_year.setValidator(QtGui.QIntValidator()) + self.sem_year.setText(str(QtCore.QDate.currentDate().year())) + self.prof_mail.setValidator( + QRegularExpressionValidator( + QtCore.QRegularExpression( + r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}" + ) + ) + ) + self.prof_tel_nr.setValidator(QtGui.QIntValidator()) + # set the validator for the app name, allow all letters and umlauts + self.app_fach.setValidator( + QtGui.QRegularExpressionValidator( + QtCore.QRegularExpression(r"[a-zA-Z\s\W]+") + ) + ) + + # allow only letters, numbers, whitespaces, symbols for the apparat name + self.app_name.setValidator( + QtGui.QRegularExpressionValidator( + QtCore.QRegularExpression(r"[a-zA-Z0-9\s\W]+") + ) + ) + self.tableWidget_apparate.addScrollBarWidget( + QtWidgets.QScrollBar(), QtCore.Qt.AlignmentFlag.AlignRight + ) + # connect contextmenuevent to tablewidget + self.tableWidget_apparate.setContextMenuPolicy( + QtCore.Qt.ContextMenuPolicy.CustomContextMenu + ) + self.tableWidget_apparate.customContextMenuRequested.connect( + self.open_context_menu + ) + self.tableWidget_apparat_media.setContextMenuPolicy( + QtCore.Qt.ContextMenuPolicy.CustomContextMenu + ) + self.tableWidget_apparat_media.customContextMenuRequested.connect( + self.media_context_menu + ) + #enable automatic resizing of columns for book_search_result + self.book_search_result.horizontalHeader().setSectionResizeMode( + QtWidgets.QHeaderView.ResizeMode.Stretch + ) + self.tableWidget_apparate.doubleClicked.connect(self.load_app_data) + self.load_app.hide() + print(f"user:{self.active_user}") + userrole = self.db.get_role(self.active_user) + if userrole == "admin": + self.tabWidget.setTabVisible(2, True) + else: + self.tabWidget.setTabVisible(2, False) + # self.update_app_media_list() + self.populate_prof_dropdown() + self.frame.setEnabled(False) + # if the focus is changed from the prof name dropdown, set the prof data if the prof exists in the database, otherwise show a message + self.drpdwn_prof_name.currentIndexChanged.connect(self.set_prof_data) + self.cancel_active_selection.clicked.connect(self.btn_cancel_active_selection) + self.check_eternal_app.stateChanged.connect(self.set_state) + # validate inputs + self.prof_mail.textChanged.connect(self.validate_prof_mail) + self.drpdwn_prof_name.editTextChanged.connect(self.validate_prof_name) + self.prof_tel_nr.textChanged.connect(self.validate_prof_tel) + self.app_name.textChanged.connect(self.validate_app_name) + self.app_fach.currentTextChanged.connect(self.validate_app_fach) + self.sem_year.textChanged.connect(self.validate_semester) + self.check_eternal_app.stateChanged.connect(self.validate_semester) + self.chkbx_show_del_media.setEnabled(False) + self.chkbx_show_del_media.stateChanged.connect(self.update_app_media_list) + self.label_info.hide() + self.progress_label.setText("Bitte warten...") + self.line_2.hide() + self.progress_label.hide() + self.message_frame.hide() + self.btn_reserve.hide() + self.check_deletable.stateChanged.connect(self.gridchange) + self.tableWidget.horizontalHeader().setSectionResizeMode( + QtWidgets.QHeaderView.ResizeMode.Stretch + ) + self.btn_del_select_apparats.setEnabled(False) + self.btn_del_select_apparats.clicked.connect(self.delete_selected_apparats) + self.statistics_table.doubleClicked.connect(self.display_detailed_data) + self.tabWidget_2.currentChanged.connect(self.tabW2_changed) + self.tabWidget.currentChanged.connect(self.tabW1_changed) + self.tableWidget.resizeColumnsToContents() + self.tableWidget.resizeRowsToContents() + # set self.app_fach viable inputs to be + + # create a thread, that continually checks the validity of the inputs + self.grabbers = [] + self.thread = QThread() + self.validate_thread = QThread() + self.validate_thread.started.connect(self.thread_check) + self.validate_thread.start() + + # get all current apparats and cache them in a list + self.apparats = self.db.get_all_apparts(deleted=0) + print(self.apparats) + self.apparats = natsorted(self.apparats, key=lambda x: x[4], reverse=True) + + for apparat in self.apparats: + self.insert_apparat_into_table(apparat) + + self.old_apparats = self.apparats #create a clone to compare against later + # if length of apparats changes, update box_apparats + # if tab is changed, gather data needed + self.tabWidget.currentChanged.connect(self.tab_changed) + self.btn_search.clicked.connect(self.statistics) + # self.thread_check() + + ### Admin interface ### + #!admin - create user + #!admin - delete user + #!admin - change user + #TODO:admin - change faculty + self.select_action_box.addItem("") + self.select_action_box.setCurrentText("") + self.hide_all() + self.select_action_box.currentTextChanged.connect(self.admin_action_changed) + self.edit_faculty_member_select_member.currentTextChanged.connect(self.edit_faculty_member_set_data) + self.book_search.clicked.connect(self.search_book) + + #enable click functionality for the combobox to allow selection of roles + + #admin buttons + self.user_frame_addUser.clicked.connect(self.add_user) + self.pushButton.clicked.connect(self.delete_user) + self.update_user.clicked.connect(self.update_user_data) + self.update_faculty_member.clicked.connect(self.edit_faculty_member_action) + + + def tabW1_changed(self): + if self.tabWidget.currentIndex() == 1: + # self.tabWidget.setCurrentIndex(1) + self.tabWidget_2.setCurrentIndex(1) + self.tabWidget_2.setCurrentIndex(0) + + + def search_book(self): + self.book_search_result.setRowCount(0) + signature = self.seach_by_signature.text() + title = self.search_by_title.text() + params = { + "signature": signature if signature != "" else None, + "title": title if title != "" else None + } + params = {key: value for key, value in params.items() if value is not None} + ic(params) + retdata = self.db.search_book(params) + + for book in retdata: + ic(book) + self.book_search_result.insertRow(0) + self.book_search_result.setItem(0,0,QtWidgets.QTableWidgetItem(book[0].title)) + self.book_search_result.setItem(0,1,QtWidgets.QTableWidgetItem(book[0].signature)) + print(book[1]) + self.book_search_result.setItem(0,2,QtWidgets.QTableWidgetItem(self.db.get_apparats_name(book[1],book[2]))) + + + def edit_faculty_member_set_data(self): + #get the selected member + name = self.edit_faculty_member_select_member.currentText() + fullname = name.replace(",","") + print(fullname,name) + #get the data for the selected member + data = self.db.faculty_data(fullname) + #set the data + print(data) + if data == None: + self.edit_faculty_member_title.setText("") + self.faculty_member_old_telnr.setText("") + self.faculty_member_oldmail.setText("") + self.edit_faculty_member_title.setText("") + else: + self.edit_faculty_member_title.setText(data[1]) + self.faculty_member_old_telnr.setText(data[6]) + self.faculty_member_oldmail.setText(data[5]) + self.edit_faculty_member_title.setText(data[1]) if data[1] != None else self.edit_faculty_member_title.setText("") + + + # self.edit_faculty_member_name.setText(f"{data[3]} {data[2]}") + # self.edit_faculty_member_title.setCurrentText(data[1]) + # self.edit_faculty_member_mail.setText(data[4]) + # self.edit_faculty_member_tel.setText(data[5]) + # self.edit_faculty_member_adis_id.setText(str(data[0])) + # self.edit_faculty_member_id.setText(str(data[6])) + + def add_user(self): + username = self.user_create_frame_username.text() + password = self.user_create_frame_password.text() + role = self.user_frame_userrole.currentText() + if self.db.check_username(username): + ic("username already exists") + # self.user_create_frame_error.setText("Der Nutzername ist bereits vergeben")#TODO: implement error message + return + userdata = AdminCommands().create_password(password) + self.db.create_user(username=username, password=f"{userdata[1]}{userdata[0]}", salt=userdata[1], role=role) + self.user_create_frame_username.clear() + self.user_create_frame_password.clear() + self.user_frame_userrole.setCurrentText("") + self.admin_action_changed() + + def delete_user(self): + if self.user_delete_confirm.isChecked(): + username = self.user_delete_frame_user_select.currentText() + self.db.delete_user(username) + self.user_delete_frame_user_select.removeItem(self.user_delete_frame_user_select.currentIndex()) + self.user_delete_confirm.setChecked(False) + else: + # self.user_delete_err_message.setText("Bitte bestätigen Sie die Löschung des Nutzers") # TODO: implement error message + ic("please confirm the deletion of the user") + + def update_user_data(self): + username = self.user_edit_frame_user_select.currentText() + password = self.user_edit_frame_new_password.text() if self.user_edit_frame_new_password.text() != "" else None + role = self.user_edit_frame_role_select.currentText() if self.user_edit_frame_role_select.currentText() != "" else None + + userdata = AdminCommands().create_password(password) + data = { + "password": f"{userdata[1]}{userdata[0]}", + "salt": userdata[1], + "role": role + } + data = {key: value for key, value in data.items() if value is not None} + print(data) + self.db.update_user(username=username,data = data) + self.user_edit_frame_user_select.setCurrentText("") + self.user_edit_frame_new_password.clear() + self.user_edit_frame_role_select.setCurrentText("") + + def edit_faculty_member_action(self): + def __gen_fullname(fname,lname,data): + if fname == "" and lname == "": + return data[3] + if fname == ""and lname != "": + return f"{lname} {data[1]}" + if fname != "" and lname == "": + return f"{data[2]} {fname}" + if fname != "" and lname != "": + return f"{lname} {fname}" + #get the data and use new value if it is not none and does not mach the old value + if self.edit_faculty_member_select_member.currentText(""): + return + olddata = self.db.get_faculty_members(self.edit_faculty_member_select_member.currentText()) + + data = olddata[0] + oldlname = data[2] + oldfname = data[1] + #take data except first and last entry + + titel = self.edit_faculty_member_new_title.currentText() if self.edit_faculty_member_new_title.currentText() != "Kein Titel" else None + fname = self.edit_faculty_member_new_surname.text() if self.edit_faculty_member_new_surname.text() != "" else self.edit_faculty_member_select_member.currentText().split(" ")[1].strip() + lname = self.user_faculty_member_new_name.text() if self.user_faculty_member_new_name.text() != "" else self.edit_faculty_member_select_member.currentText().split(" ")[0].strip() + fullname = __gen_fullname(fname,lname,data) + mail = self.user_faculty_member_new_telnr.text() + telnr = self.user_faculty_member_new_mail.text() + new_data = { + "titel":titel, + "fname":fname, + "lname":lname, + "fullname":fullname, + "mail":mail, + "telnr":telnr, + } + new_data = {key: value for key, value in new_data.items() if value != ""} + self.db.update_faculty_member(data = new_data,oldlname=oldlname,oldfname=oldfname) + self.add_faculty_member_data() + self.edit_faculty_member_new_title.setCurrentText("") + self.edit_faculty_member_new_surname.clear() + self.user_faculty_member_new_name.clear() + self.user_faculty_member_new_telnr.clear() + self.user_faculty_member_new_mail.clear() + + def hide_all(self): + self.user_create_frame.hide() + self.user_edit_frame.hide() + self.user_delete_frame.hide() + self.edit_faculty_member.hide() + + def admin_action_changed(self): + action = self.select_action_box.currentText() + roles = self.db.get_roles() + roles = [role[0] for role in roles] + #remove duplicates + roles = list(dict.fromkeys(roles)) + users = self.db.get_users() + users = [user[2] for user in users] + users.remove(self.active_user) + if "admin" in users: + users.remove("admin") + if action == "Nutzer anlegen": + self.hide_all() + self.user_create_frame.show() + self.user_frame_userrole.addItems(roles) + elif action == "Nutzer aktualisieren": + self.hide_all() + self.user_edit_frame.show() + self.user_edit_frame_role_select.addItems(roles) + self.user_edit_frame_user_select.addItems(users) + elif action == "Nutzer löschen": + self.hide_all() + self.user_delete_frame.show() + self.user_delete_frame_user_select.addItems(users) + self.user_delete_frame_user_select.setCurrentText("") + self.user_delete_frame_user_select.addItems(users) + + elif action == "Lehrperson bearbeiten": + self.hide_all() + self.edit_faculty_member.show() + self.add_faculty_member_data() + self.edit_faculty_member_new_title.addItems(PROF_TITLES) + + + else: + self.hide_all() + return + + def add_faculty_member_data(self): + faculty_members = self.db.get_faculty_members() + names = [f"{member[5]}" for member in faculty_members] + self.edit_faculty_member_select_member.clear() + self.edit_faculty_member_select_member.addItems(names) + self.edit_faculty_member_select_member.addItem("") + self.edit_faculty_member_select_member.setCurrentText("") + + def tabW2_changed(self): + + if self.tabWidget_2.currentIndex() == 0: + self.stackedWidget_4.setCurrentIndex(0) + else: + self.stackedWidget_4.setCurrentIndex(1) + + def generateSemester(self, today=False): + """Generates the current semester. + + Args: + ----- + today (bool, optional): If True, the current semester is generated. Defaults to False. + Returns: + -------- + str: The current semester + """ + if today: + currentYear = QDate.currentDate().year() + currentYear = int(str(currentYear)[-2:]) + month = QDate.currentDate().month() + if month >= 4 and month <= 9: + return "SoSe " + str(currentYear) + else: + return f"WiSe {currentYear}/{currentYear+1}" + currentYear = self.sem_year.text() + currentYear = int(currentYear[-2:]) + + semester = ( + self.sem_sommer.text() + if self.sem_sommer.isChecked() + else self.sem_winter.text() + ) + if semester == "Sommer": + return "SoSe " + str(currentYear) + else: + return f"WiSe {currentYear}/{currentYear+1}" + + def display_detailed_data(self): + selected_semester = self.statistics_table.item( + self.statistics_table.currentRow(), 0 + ).text() + # get all apparats from the selected semester + data = self.db.apparats_by_semester(selected_semester) + # replace keys for german names + # split to two lists + created = {"Erstellt": data["created"]} + deleted = {"Gelöscht": data["deleted"]} + created_status = StatusWidget(created, selected_semester) + deleted_status = StatusWidget(deleted, selected_semester) + created_status.setSizePolicy( + QtWidgets.QSizePolicy.Policy.Expanding, + QtWidgets.QSizePolicy.Policy.Expanding, + ) + deleted_status.setSizePolicy( + QtWidgets.QSizePolicy.Policy.Expanding, + QtWidgets.QSizePolicy.Policy.Expanding, + ) + + # add them to the gridLayout_4 + self.gridLayout_4.addWidget(created_status, 1, 0) + self.gridLayout_4.addWidget(deleted_status, 1, 1) + created_status.person_double_clicked.connect(self.open_apparat) + deleted_status.person_double_clicked.connect(self.open_apparat) + + def open_apparat(self, header:str, apparat:str, parent_depth:int): + print(header) + if header == "deleted" and parent_depth == 2: + #TODO: warn message here + print("warning") + if parent_depth == 1: + print(apparat) + #person selected case - open all apparats from this person in the tableWidget + self.tableWidget.setRowCount(0) + prof_id = self.db.get_prof_id(apparat.split("(")[0].strip()) + apparats = self.db.get_apparats_by_prof(prof_id) + for app in apparats: + print(app) + #set the items 0 = clickable checkbox, 1 = appname, 2 = profname, 3 = fach + #insert new row + self.tableWidget.insertRow(0) + self.tableWidget.setItem(0,0, QtWidgets.QTableWidgetItem("")) + self.tableWidget.setItem(0, 1, QtWidgets.QTableWidgetItem(app[1])) + self.tableWidget.setItem( + 0, 2, QtWidgets.QTableWidgetItem(str(app[4])) + ) + self.tableWidget.setItem(0, 3, QtWidgets.QTableWidgetItem(app[2])) + self.tableWidget.setItem(0, 4, QtWidgets.QTableWidgetItem(app[3])) + # replace the 0 with a checkbox + checkbox = QtWidgets.QCheckBox() + checkbox.setChecked(False) + self.tableWidget.setCellWidget(0, 0, checkbox) + # if i[9] is 1, set the background of the row to red + if int(app[9]) == 1: + for j in range(5): + self.tableWidget.item(0, j).setBackground(QtGui.QColor(235, 74, 71)) + # disable the checkbox + self.tableWidget.cellWidget(0, 0).setEnabled(False) + # set the tooltip + self.tableWidget.cellWidget(0, 0).setToolTip( + "Dieser Semesterapparat kann nicht gelöscht werden, da er bereits gelöscht wurde" + ) + elif parent_depth == 2: + #apparat selected case - open the apparat in the frame + self.load_app_data(apparat) + #change tab focus to tab 0 + self.tabWidget.setCurrentIndex(0) + return + + def gridchange(self): + if self.check_deletable.isChecked(): + self.box_semester.setEnabled(False) + self.box_semester.clear() + self.box_appnrs.setEnabled(False) + self.box_appnrs.clear() + self.box_person.setEnabled(False) + self.box_person.clear() + self.box_fach.setEnabled(False) + self.box_fach.clear() + self.box_erstellsemester.setEnabled(False) + self.box_erstellsemester.clear() + self.box_dauerapp.setEnabled(False) + self.box_dauerapp.clear() + else: + self.box_semester.setEnabled(True) + self.box_appnrs.setEnabled(True) + self.box_person.setEnabled(True) + self.box_fach.setEnabled(True) + self.box_erstellsemester.setEnabled(True) + self.box_dauerapp.setEnabled(True) + self.tab_changed() + + def populate_tab(self): + #add default values to the dropdowns + self.box_appnrs.clear() + self.box_appnrs.addItem("") + self.box_appnrs.setCurrentText("") + self.box_person.clear() + self.box_person.addItem("") + self.box_person.setCurrentText("") + self.box_fach.clear() + self.box_fach.addItem("") + self.box_fach.setCurrentText("") + self.box_erstellsemester.clear() + self.box_erstellsemester.addItem("") + self.box_erstellsemester.setCurrentText("") + self.box_semester.clear() + self.box_semester.addItem("") + self.box_semester.setCurrentText("") + self.box_dauerapp.clear() + self.box_dauerapp.addItems(["Ja", "Nein", ""]) + self.box_dauerapp.setCurrentText("") + #add custom vaules + appnrs = self.db.get_apparat_nrs() + apparats = natsorted(appnrs) + apparats = [str(apparat) for apparat in apparats] + self.box_appnrs.addItems(apparats) + persons = self.db.get_profs() + self.box_person.addItems( + [f"{person[3]}, {person[2]}" for person in persons] + ) + self.box_fach.addItems(subject[1] for subject in self.db.get_subjects()) + semester = self.db.get_semester() + self.box_erstellsemester.addItems([sem[0] for sem in semester]) + self.statistics_table.setRowCount(0) + + #set data for table and graph in tab 2 tableWidget_3 + data = self.db.get_app_count_by_semester() + data = c_sort.custom_sort(data) + # self.tabWidget_3.clear() + self.tabWidget_3.removeTab(1) + self.statistics_table.setRowCount(len(data)) + for i in range(len(data)): + self.statistics_table.setItem( + i, 0, QtWidgets.QTableWidgetItem(data[i][0]) + ) + self.statistics_table.setItem( + i, 1, QtWidgets.QTableWidgetItem(str(data[i][1])) + ) + self.statistics_table.setItem( + i, 2, QtWidgets.QTableWidgetItem(str(data[i][2])) + ) + self.statistics_table.resizeColumnsToContents() + self.statistics_table.resizeRowsToContents() + # create graph + + graph_data = { + "x": [i[0] for i in data], + "y": [i[1] for i in data], + "y2": [i[2] for i in data], + } + graph = GraphWidget(data=graph_data, legend_labels=["Erstellt", "Gelöscht"]) + + # place the graph into tabWidget_3 + self.tabWidget_3.addTab(graph, "Erstellte und gelöschte Semesterapparate") + self.tabWidget_3.setCurrentIndex(0) + + def tab_changed(self): + curr_tab = self.tabWidget.currentIndex() + if curr_tab == 0: # create tab + return + elif curr_tab == 1: # statistics tab + self.populate_tab() + elif curr_tab == 2: #admin tab + self.populate_admin_tab() + + def populate_admin_tab(self): + pass + + def populate_dropdown(self, box, data): + box.clear() + box.addItem("") + box.setCurrentText("") + box.addItems(data) + + def delete_selected_apparats(self): + # get all selected apparats + selected_apparats = [] + for i in range(self.tableWidget.rowCount()): + if self.tableWidget.cellWidget(i, 0).isChecked(): + selected_apparats.append(self.tableWidget.item(i, 2).text()) + # delete all selected apparats + print(selected_apparats) + for apparat in selected_apparats: + self.db.delete_apparat(apparat, self.generateSemester(today=True)) + # refresh the table + self.tab_changed() + self.btn_del_select_apparats.setEnabled(False) + + def statistics(self): + """Generate the statistics based on the selected filters.""" + self.db_err_message.setText("") + self.btn_del_select_apparats.setEnabled(True) + params = { + "appnr": self.box_appnrs.currentText() + if self.box_appnrs.currentText() != "" + else None, + "prof_id": self.db.get_prof_id(self.box_person.currentText()) + if self.box_person.currentText() != "" + else None, + "fach": self.box_fach.currentText() + if self.box_fach.currentText() != "" + else None, + "erstellsemester": self.box_erstellsemester.currentText() + if self.box_erstellsemester.currentText() != "" + else None, + "dauer": "1" + if self.box_dauerapp.currentText() == "Ja" + else "0" + if self.box_dauerapp.currentText() == "Nein" + else None, + "endsemester": self.box_semester.currentText() + if self.box_semester.currentText() != "" + else None, + "deletable": "True" if self.check_deletable.isChecked() else None, + "deletesemester": self.generateSemester(today=True), + } + params = {key: value for key, value in params.items() if value is not None} #remove empty lines to prevent errors + print(params) + params = {key: value for key, value in params.items() if value != "Alle"} #remove empty lines to prevent errors + print(params) + result = self.db.statistic_request(**params) + # add QTableWidgetItems to the table + self.tableWidget.setRowCount(len(result)) + if len(result) == 0: + self.db_err_message.setText("Keine Ergebnisse gefunden") + return + for i in range(len(result)): + print(result[i]) + # set the items 0 = clickable checkbox, 1 = appname, 2 = profname, 3 = fach + self.tableWidget.setItem(i, 0, QtWidgets.QTableWidgetItem("")) + self.tableWidget.setItem(i, 1, QtWidgets.QTableWidgetItem(result[i][1])) + self.tableWidget.setItem( + i, 2, QtWidgets.QTableWidgetItem(str(result[i][4])) + ) + self.tableWidget.setItem(i, 3, QtWidgets.QTableWidgetItem(result[i][2])) + self.tableWidget.setItem(i, 4, QtWidgets.QTableWidgetItem(result[i][3])) + # replace the 0 with a checkbox + checkbox = QtWidgets.QCheckBox() + checkbox.setChecked(False) + self.tableWidget.setCellWidget(i, 0, checkbox) + # if i[9] is 1, set the background of the row to red + if int(result[i][9]) == 1: + for j in range(5): + self.tableWidget.item(i, j).setBackground(QtGui.QColor(235, 74, 71)) + # disable the checkbox + self.tableWidget.cellWidget(i, 0).setEnabled(False) + # set the tooltip + self.tableWidget.cellWidget(i, 0).setToolTip( + "Dieser Semesterapparat kann nicht gelöscht werden, da er bereits gelöscht wurde" + ) + + + + def populate_frame(self, appdata: ApparatData): + # populate the frame with the data from the database + self.drpdwn_app_nr.setCurrentText(str(appdata.appnr)) + self.drpdwn_prof_title.setCurrentText(appdata.prof_title) + self.drpdwn_prof_name.setCurrentText(appdata.profname) + self.prof_mail.setText(appdata.prof_mail) + self.prof_tel_nr.setText(appdata.prof_tel) + self.app_name.setText(appdata.appname) + self.app_fach.setCurrentText(appdata.app_fach) + if appdata.semester is not None: + self.sem_sommer.setChecked( + True if appdata.semester.split(" ")[0] == "SoSe" else False + ) + self.sem_winter.setChecked( + True if appdata.semester.split(" ")[0] == "WiSe" else False + ) + self.sem_year.setText(appdata.semester.split(" ")[1]) + else: + self.sem_sommer.setChecked( + True if appdata.erstellsemester.split(" ")[0] == "SoSe" else False + ) + self.sem_winter.setChecked( + True if appdata.erstellsemester.split(" ")[0] == "WiSe" else False + ) + self.sem_year.setText(appdata.erstellsemester.split(" ")[1]) + self.check_eternal_app.setChecked(appdata.dauerapp) + self.prof_id_adis.setText(str(appdata.prof_adis_id)) + self.apparat_id_adis.setText(str(appdata.apparat_adis_id)) + self.frame.setEnabled(True) + + def update_apparat(self): + appdata = ApparatData() + appdata.app_fach = self.app_fach.text() + appdata.appname = self.app_name.text() + appdata.appnr = self.active_apparat() + appdata.dauerapp = self.check_eternal_app.isChecked() + appdata.prof_mail = self.prof_mail.text() + appdata.prof_tel = self.prof_tel_nr.text() + appdata.prof_title = self.drpdwn_prof_title.currentText() + appdata.profname = self.drpdwn_prof_name.currentText() + appdata.semester = ( + self.sem_sommer.text() + " " + self.sem_year.text() + if self.sem_sommer.isChecked() + else self.sem_winter.text() + " " + self.sem_year.text() + ) + appdata.prof_adis_id = self.prof_id_adis.text() + self.add_files() + appdata.apparat_adis_id = self.apparat_id_adis.text() + + self.db.update_apparat(appdata) + + self.update_app_media_list() + self.cancel_active_selection.click() + + + + def confirm_popup(self, message: str): + dial = QtWidgets.QDialog() + popup = popus_confirm() + popup.setupUi(dial) + popup.textEdit.setReadOnly(True) + popup.textEdit.setText(message) + dial.exec() + return dial.result() + + def threads(self): + while True: + self.validate_prof_mail() + self.validate_prof_name() + self.validate_prof_tel() + self.validate_app_name() + self.validate_app_fach() + self.validate_semester() + + def thread_check(self): + self.prof_mail.textChanged.connect(self.validate_prof_mail) + self.drpdwn_prof_name.editTextChanged.connect(self.validate_prof_name) + self.prof_tel_nr.textChanged.connect(self.validate_prof_tel) + self.app_name.textChanged.connect(self.validate_app_name) + self.app_fach.currentTextChanged.connect(self.validate_app_fach) + self.sem_year.textChanged.connect(self.validate_semester) + self.check_eternal_app.stateChanged.connect(self.validate_semester) + + def validate_prof_name(self): + if self.frame.isEnabled(): + if "," in self.drpdwn_prof_name.currentText(): + self.drpdwn_prof_name.setStyleSheet("border: 1px solid green;") + self.profname_mand.setText("") + self.change_state(0, 1) + else: + self.drpdwn_prof_name.setStyleSheet("border: 1px solid red;") + self.profname_mand.setText("*") + self.change_state(0, 0) + else: + self.drpdwn_prof_name.setStyleSheet("border: 1px solid black;") + + def validate_prof_mail(self): + if self.frame.isEnabled(): + if self.prof_mail.hasAcceptableInput(): + self.prof_mail.setStyleSheet("border: 1px solid green;") + self.mail_mand.setText("") + self.change_state(1, 1) + else: + self.prof_mail.setStyleSheet("border: 1px solid red;") + self.mail_mand.setText("*") + self.change_state(1, 0) + else: + self.prof_mail.setStyleSheet("border: 1px solid black;") + + def validate_prof_tel(self): + if self.frame.isEnabled(): + if self.prof_tel_nr.text() != "": + self.prof_tel_nr.setStyleSheet("border: 1px solid green;") + self.telnr_mand.setText("") + self.change_state(2, 1) + else: + self.prof_tel_nr.setStyleSheet("border: 1px solid red;") + self.telnr_mand.setText("*") + self.change_state(2, 0) + + def validate_app_name(self): + if self.frame.isEnabled(): + if self.app_name.hasAcceptableInput(): + self.app_name.setStyleSheet("border: 1px solid green;") + self.appname_mand.setText("") + self.change_state(3, 1) + else: + self.app_name.setStyleSheet("border: 1px solid red;") + self.appname_mand.setText("*") + self.change_state(3, 0) + + def validate_app_fach(self): + if self.frame.isEnabled(): + if self.app_fach.currentText() != "": + self.app_fach.setStyleSheet("border: 1px solid green;") + self.fach_mand.setText("") + self.change_state(4, 1) + else: + self.app_fach.setStyleSheet("border: 1px solid red;") + self.fach_mand.setText("*") + self.change_state(4, 0) + + def validate_semester(self): + if self.frame.isEnabled(): + if ( + (self.sem_sommer.isChecked() or self.sem_winter.isChecked()) + and self.sem_year.hasAcceptableInput() + ) or self.check_eternal_app.isChecked(): + self._mand.setText("") + self.change_state(5, 1) + else: + self._mand.setText("*") + self.change_state(5, 0) + + def change_state(self, index, state): + global valid_input + valid_input = list(valid_input) + valid_input[index] = state + valid_input = tuple(valid_input) + + def set_state(self): + # set state of semester and year + if self.check_eternal_app.isChecked(): + self.sem_winter.setEnabled(False) + self.sem_sommer.setEnabled(False) + self.sem_year.setEnabled(False) + else: + self.sem_winter.setEnabled(True) + self.sem_sommer.setEnabled(True) + self.sem_year.setEnabled(True) + + def validate_fields(self): + return all(valid_input) + + # def req_fields_filled(self): + # # check if all required fields are filled + # values = [] + # for item in self.frame.findChildren(QtWidgets.QLabel): + # # if label name contains "req" and the text is empty, return false + # if "mand" in item.objectName() and item.text() == "": + # values.append(True) + # elif "mand" in item.objectName() and item.text() != "": + # values.append(False) + # return all(values) + # + def buttonClicked(self): + print("Button clicked") + + def set_prof_data(self): + if "," not in self.drpdwn_prof_name.currentText(): + self.prof_mail.clear() + self.prof_tel_nr.clear() + return + selected_prof = self.drpdwn_prof_name.currentText() + data = self.db.get_prof_data(selected_prof) + prof_title = data["prof_title"] + if prof_title == "None": + prof_title = "Kein Titel" + self.drpdwn_prof_title.setCurrentText(prof_title) + self.prof_tel_nr.setText(data["prof_tel"]) + self.prof_mail.setText(data["prof_mail"]) + + def get_index_of_value(self, table_widget, value): + for i in range(table_widget.rowCount()): + for j in range(table_widget.columnCount()): + if table_widget.item(i, j) is not None and table_widget.item(i, j).text() == value: + return i, j + return None + + def load_app_data(self,app_id=None): + print(type(app_id)) + if isinstance(app_id, str): + #double click the tableWidget_apparate row with the given app_id + row,column = self.get_index_of_value(self.tableWidget_apparate,app_id) + #set the current index to the row + self.tableWidget_apparate.setCurrentCell(row,0) + app_pos = self.tableWidget_apparate.currentIndex() + appnr = self.tableWidget_apparate.item(app_pos.row(), 0).text() + appname = self.tableWidget_apparate.item(app_pos.row(), 1).text() + self.sem_sommer.setEnabled(False) + self.sem_winter.setEnabled(False) + self.sem_year.setEnabled(False) + self.dokument_list.setRowCount(0) + self.chkbx_show_del_media.setEnabled(True) + appdata = self.db.get_app_data(appnr, appname) + self.populate_frame(appdata) + self.btn_apparat_save.hide() + self.btn_reserve.show() + self.drpdwn_app_nr.setDisabled(True) + self.app_fach.setDisabled(True) + self.update_app_media_list() + self.update_documemt_list() + + def update_documemt_list(self): + app_id = self.active_apparat() + prof_id = self.db.get_prof_id( + self.drpdwn_prof_name.currentText().replace(", ", " ") + ) + files = self.db.get_files(app_id, prof_id) + for file in files: + self.dokument_list.insertRow(0) + self.dokument_list.setItem(0, 0, QtWidgets.QTableWidgetItem(file[0])) + self.dokument_list.setItem(0, 1, QtWidgets.QTableWidgetItem(file[1])) + self.dokument_list.setItem(0, 2, QtWidgets.QTableWidgetItem("")) + self.dokument_list.setItem(0, 3, QtWidgets.QTableWidgetItem("Database")) + + # def btn_load_apparat(self): + # # remove all rows from table + # #get all + # self.tableWidget_apparate.sortItems(0, QtCore.Qt.SortOrder.AscendingOrder) + # self.frame.setDisabled(True) + # for child in self.frame.findChildren(QtWidgets.QLineEdit): + # child.clear() + + def btn_create_new_apparat(self): + global valid_input + # *create a new apparat + self.btn_apparat_save.show() if self.btn_apparat_save.isHidden() else None + # clear dokumemt_list + self.dokument_list.setRowCount(0) + self.frame.setEnabled(True) + + self.sem_year.setEnabled(True) + self.sem_sommer.setEnabled(True) + self.sem_winter.setEnabled(True) + self.chkbx_show_del_media.setEnabled(True) + self.drpdwn_app_nr.setEnabled(True) + self.app_fach.setEnabled(True) + self.app_fach.addItems([subject[1] for subject in self.db.get_subjects()]) + self.app_fach.addItem("") + self.app_fach.setCurrentText("") + if self.tableWidget_apparat_media.rowCount() > 0: + self.tableWidget_apparat_media.setRowCount(0) + # clear all fields + for item in self.frame.findChildren(QtWidgets.QLineEdit): + item.clear() + self.drpdwn_app_nr.clear() + self.drpdwn_prof_title.clear() + self.drpdwn_prof_name.clear() + # set drop down menu for apparat numbers to only available numbers + self.drpdwn_app_nr.addItems( + [str(i) for i in APP_NRS if i not in self.db.get_apparat_nrs()] + ) + self.drpdwn_prof_title.addItems(PROF_TITLES) + valid_input = (0, 0, 0, 0, 0, 0) + self.populate_prof_dropdown() + # self.horizontalLayout_6.show() + # increase size by 300px + + def update_progress_label(self, curr, total): + text = f"Medium {curr}/{total}" + self.logger.log_info(text) + self.progress_label.setText(text) + # update tableWidget_apparat_media + self.update_app_media_list() + + def hide_progress_label(self): + self.logger.log_info("Finished adding media, hiding progress label") + self.progress_label.hide() + self.line_2.hide() + self.label_info.hide() + + def btn_add_medium(self): + if not self.frame.isEnabled(): + self.confirm_popup("Bitte erst einen Apparat auswählen!") + return + + def __new_ui(): + dialog = QtWidgets.QDialog() + frame = Medien() + frame.setupUi(dialog) + dialog.exec() + mode = frame.get_mode() + data = frame.get_list_data() + return mode, data, dialog.result() + + self.progress_label.show() + self.line_2.show() + self.label_info.show() + self.progress_label.setText("Bitte warten...") + mode, data, result = __new_ui() + if result == 1: + if data == []: + self.confirm_popup("Bitte mindestens ein Medium hinzufügen!") + + app_id = self.active_apparat() + prof_id = self.db.get_prof_id(self.drpdwn_prof_name.currentText()) + # check if app_id is in database + if not self.db.app_exists(app_id): + # create apparat + self.btn_save_apparat() + # create a thread that updates the progress label after each medium + count = len(data) + thread = QThread() + grabber = BookGrabber(mode, data, app_id, prof_id) + grabber.moveToThread(thread) + grabber.finished.connect(thread.quit) + grabber.finished.connect(grabber.deleteLater) + grabber.finished.connect(self.hide_progress_label) + grabber.finished.connect(self.update_app_media_list) + grabber.updateSignal.connect(self.update_progress_label) + # worker.finished.connect(worker.deleteLater) + + grabber.start() + self.thread = thread + self.grabbers.append(grabber) + + # for book in data: + # # self.progress_label.setText(f"Medium {ct}/{len(data)}") + # # update the progress label + # self.logger.log_info(f"trying to add BookData for Signature {book}") + # webdata = WebRequest().get_ppn(book).get_data() + # bd: BookData = BibTextTransformer(mode).get_data(webdata).return_data() + # bd.signature = book + # self.db.add_medium(bookdata=bd, app_id=app_id, prof_id=prof_id) + + # get all media list books + + else: + return + + def check_availability(self): + # get all links from the table + # if no index in tableWidget_apparat_media is selected, check all + if self.tableWidget_apparat_media.currentRow() == -1: + links = [ + self.tableWidget_apparat_media.item(i, 1).text() + for i in range(self.tableWidget_apparat_media.rowCount()) + if self.tableWidget_apparat_media.item(i, 4).text() == "❌" + or self.tableWidget_apparat_media.item(i, 4).text() == "" + ] + else: + links = [ + self.tableWidget_apparat_media.item( + self.tableWidget_apparat_media.currentRow(), 1 + ).text() + ] + + self.label_info.setText("Verfügbarkeit wird geprüft, bitte warten...") + self.label_info.show() + books = self.db.get_media( + self.active_apparat(), + self.db.get_prof_id(self.drpdwn_prof_name.currentText()), + del_state=0, + ) + + thread = QThread() + appnumber = self.active_apparat() + print(links) + availcheck = AvailChecker(links, appnumber, books=books) + availcheck.moveToThread(thread) + availcheck.finished.connect(thread.quit) + availcheck.finished.connect(availcheck.deleteLater) + availcheck.finished.connect(self.hide_progress_label) + availcheck.finished.connect(self.update_app_media_list) + availcheck.start() + self.thread = thread + self.grabbers.append(availcheck) + + def btn_cancel_active_selection(self): + # clear the rows of the table + self.tableWidget_apparat_media.setRowCount(0) + self.dokument_list.setRowCount(0) + self.frame.setEnabled(False) + for child in self.frame.findChildren(QtWidgets.QLineEdit): + child.clear() + + def update_app_media_list(self): + deleted = 0 if not self.chkbx_show_del_media.isChecked() else 1 + app_id = self.active_apparat() + prof_id = self.db.get_prof_id(self.drpdwn_prof_name.currentText()) + books: list[dict[int, BookData, int]] = self.db.get_media( + app_id, prof_id, deleted + ) + + # print(books) + # take the dataclass from the tuple + # booklist:list[BookData]=[book[0] for book in books] + self.tableWidget_apparat_media.setRowCount(0) + for book in books: + book_id = book["id"] + book_data = book["bookdata"] + availability = book["available"] + # bd = BookData().from_string(book) + # print(bd, type(bd)) + # create a new row below the last one + self.tableWidget_apparat_media.insertRow( + self.tableWidget_apparat_media.rowCount() + ) + # #set the data + self.tableWidget_apparat_media.setItem( + self.tableWidget_apparat_media.rowCount() - 1, + 0, + QtWidgets.QTableWidgetItem(book_data.title), + ) + self.tableWidget_apparat_media.setItem( + self.tableWidget_apparat_media.rowCount() - 1, + 1, + QtWidgets.QTableWidgetItem(book_data.signature), + ) + self.tableWidget_apparat_media.setItem( + self.tableWidget_apparat_media.rowCount() - 1, + 2, + QtWidgets.QTableWidgetItem(book_data.edition), + ) + self.tableWidget_apparat_media.setItem( + self.tableWidget_apparat_media.rowCount() - 1, + 3, + QtWidgets.QTableWidgetItem(book_data.author), + ) + self.tableWidget_apparat_media.setItem( + self.tableWidget_apparat_media.rowCount() - 1, + 6, + QtWidgets.QTableWidgetItem(book_data.link), + ) + if availability == 1: + # display green checkmark at column 4 in the row + self.tableWidget_apparat_media.setItem( + self.tableWidget_apparat_media.rowCount() - 1, + 4, + QtWidgets.QTableWidgetItem("✅"), + ) + # set tooltip + self.tableWidget_apparat_media.item( + self.tableWidget_apparat_media.rowCount() - 1, 4 + ).setToolTip("Das Medium wurde im Apparat gefunden") + else: + self.tableWidget_apparat_media.setItem( + self.tableWidget_apparat_media.rowCount() - 1, + 4, + QtWidgets.QTableWidgetItem("❌"), + ) + self.tableWidget_apparat_media.item( + self.tableWidget_apparat_media.rowCount() - 1, 4 + ).setToolTip("Das Medium wurde nicht im Apparat gefunden") + + # make table link clickable + self.tableWidget_apparat_media.itemClicked.connect(self.open_link) + + def open_link(self, item): + # get the name of the column + columnname = self.tableWidget_apparat_media.horizontalHeaderItem( + item.column() + ).text() + if columnname == "Link": + QtGui.QDesktopServices.openUrl(QtCore.QUrl(item.text())) + else: + pass + + def text_to_clipboard(self): + app_id = self.active_apparat() + text = f"SQ=select distinct akkey from aupr01 where aufst='{app_id}' union select pr_isn from aks4pd where akruf ='{app_id}'" + clipboard = QtWidgets.QApplication.clipboard() + clipboard.setText(text) + + def populate_prof_dropdown(self): + profs = self.db.get_profs() + # add empty entry to dropdown and set it as current + self.drpdwn_prof_name.addItem("Kein Name") + for prof in profs: + self.drpdwn_prof_name.addItem(f"{prof[3]}, {prof[2]}") + + def add_document(self): + print("Add document") + picker = FilePicker() + files = picker.pick_files() + + for file in files: + print(file) + filename = file.split("/")[-1] + filetype = filename.split(".")[-1] + self.dokument_list.insertRow(0) + self.dokument_list.setItem(0, 0, QtWidgets.QTableWidgetItem(filename)) + self.dokument_list.setItem(0, 1, QtWidgets.QTableWidgetItem(filetype)) + self.dokument_list.setItem(0, 2, QtWidgets.QTableWidgetItem("*")) + self.dokument_list.setItem(0, 3, QtWidgets.QTableWidgetItem(file)) + # set tooltip of row 3 to the file path for each row + self.dokument_list.item(0, 3).setToolTip(file) + +# self.db.insert_file(files, self.active_apparat(), self.db.get_prof_id(self.drpdwn_prof_name.currentText())) + + def open_document(self): + print("trying to open document:") + + _selected_doc_name = "" + _selected_doc_filetype = "" + try: + _selected_doc_name = self.dokument_list.item( + self.dokument_list.currentRow(), 0 + ).text() + _selected_doc_location = self.dokument_list.item( + self.dokument_list.currentRow(), 3 + ).text() + _selected_doc_filetype = self.dokument_list.item( + self.dokument_list.currentRow(), 1 + ).text() + except AttributeError: + self.confirm_popup("Bitte erst ein Dokument auswählen!") + return + print(_selected_doc_name, _selected_doc_filetype) + if not _selected_doc_location == "Database": + path = Path(_selected_doc_location) + path = path + "/" + _selected_doc_name + if os.getenv("OS") == "Windows_NT": + path = path.resolve() + os.startfile(path) + else: + path = path.resolve() + os.system(f"open {path}") + else: + try: + self.db.recreate_file(_selected_doc_name, self.active_apparat()) + except Exception as e: + self.logger.log_exception(e) + path = config.save_path + _selected_doc_name + # if ~ in path, replace it with the home directory + if "~" in path: + path = path.replace("~", str(Path.home())) + path = Path(path) + if os.getenv("OS") == "Windows_NT": + path = path.resolve() + os.startfile(path) + else: + path = path.resolve() + os.system(f"open {path}") + # filebytes = self.db.get_blob( + # _selected_doc_name, + # self.active_apparat(), + # ) + # # use io.BytesIO to create a file-like object from the bytes and open it in the respective program + # file = io.BytesIO(filebytes) + # file.name = _selected_doc_name + + # QtGui.QDesktopServices.openUrl(QtCore.QUrl(file)) + # print(type(filebytes)) + + def add_media_from_file(self): + def __open_dialog(signatures): + dialog = QtWidgets.QDialog() + frame = parsed_titles_ui() + frame.setupUi(dialog) + dialog.show() + frame.signatures = signatures + frame.populate_table() + frame.progressBar.setMaximum(len(signatures)) + frame.progressBar.setValue(0) + frame.progressBar.show() + frame.count.setText(str(len(signatures))) + frame.toolButton.click() + data = frame.return_data() + print(data) + # if no data was returned, return + + return data + # get + + # if files are in the table, and are selected, check for books in the file + if self.dokument_list.rowCount() == 0: + return + else: + # if file is selected, check for books in the file + if self.dokument_list.currentRow() != -1: + print("File selected") + file = self.dokument_list.item( + self.dokument_list.currentRow(), 3 + ).text() + + file_type = self.dokument_list.item( + self.dokument_list.currentRow(), 1 + ).text() + file_location = self.dokument_list.item( + self.dokument_list.currentRow(), 3 + ).text() + file_name = self.dokument_list.item( + self.dokument_list.currentRow(), 0 + ).text() + if file_location == "Database": + # create a temporaty file to use, delete it after use + temp_file = tempfile.NamedTemporaryFile( + delete=False, suffix="." + file_type + ) + temp_file.write( + self.db.get_blob(file_name, int(self.active_apparat())) + ) + temp_file.close() + file = temp_file.name + print(file) + if file_type == "pdf": + # Todo: implement parser here + self.confirm_popup("PDF Dateien werden nochnicht unterstützt!") + return + if file_type == "csv": + signatures = utils.csv_to_list(file) + data = __open_dialog(signatures) + # get the app_id and prof_id + app_id = self.active_apparat() + prof_id = self.db.get_prof_id(self.drpdwn_prof_name.currentText()) + # add the data to the database + for book in data: + if type(book) != BookData: + continue + self.db.add_medium( + bookdata=book, app_id=app_id, prof_id=prof_id + ) + if file_type == "docx": + data = utils.word_docx_to_csv(file) + signatures = [ + i + for i in data["Standnummer"].values + if i != "\u2002\u2002\u2002\u2002\u2002" + ] + data = __open_dialog(signatures) + # if no data was returned, return + if data == []: + return + # get the app_id and prof_id + app_id = self.active_apparat() + prof_id = self.db.get_prof_id(self.drpdwn_prof_name.currentText()) + # add the data to the database + for book in data: + if type(book) != BookData: + continue + self.db.add_medium( + bookdata=book, app_id=app_id, prof_id=prof_id + ) + self.update_app_media_list() + print(len(signatures)) + + def btn_check_file_threaded(self): + # get active app_id and prof_id + self.tableWidget_apparate.setEnabled(False) + self.tableWidget_apparate.setToolTip( + "Bitte warten, bis alle Medien hinzugefügt wurden" + ) + app_id = self.active_apparat() + prof_id = self.db.get_prof_id(self.drpdwn_prof_name.currentText()) + # check if apparat in database + if not self.db.app_exists(app_id): + # create apparat + self.btn_save_apparat() + if self.dokument_list.rowCount() == 0: + self.tableWidget_apparate.setEnabled(True) + self.tableWidget_apparate.setToolTip("") + return + + # if file is selected, check for books in the file + if self.dokument_list.currentRow() != -1: + print("File selected") + file = self.dokument_list.item(self.dokument_list.currentRow(), 3).text() + + file_type = self.dokument_list.item( + self.dokument_list.currentRow(), 1 + ).text() + file_location = self.dokument_list.item( + self.dokument_list.currentRow(), 3 + ).text() + file_name = self.dokument_list.item( + self.dokument_list.currentRow(), 0 + ).text() + if file_location == "Database": + # create a temporaty file to use, delete it after use + temp_file = tempfile.NamedTemporaryFile( + delete=False, suffix="." + file_type + ) + temp_file.write(self.db.get_blob(file_name, int(self.active_apparat()))) + temp_file.close() + file = temp_file.name + print(file) + if file_type == "pdf": + # Todo: implement parser here + self.confirm_popup("PDF Dateien werden nochnicht unterstützt!") + return + if file_type == "csv": + signatures = csv_to_list(file) + # add the data to the database + if file_type == "docx": + data = word_docx_to_csv(file) + signatures = [ + i + for i in data["Standnummer"].values + if i != "\u2002\u2002\u2002\u2002\u2002" + ] + + signatures = [i for i in signatures if i != ""] + thread = QThread() + grabber = BookGrabber("ARRAY", signatures, app_id, prof_id) + grabber.moveToThread(thread) + self.label_info.show() + self.progress_label.show() + self.line_2.show() + grabber.finished.connect(thread.quit) + grabber.finished.connect(grabber.deleteLater) + grabber.finished.connect(self.hide_progress_label) + grabber.finished.connect(self.update_app_media_list) + grabber.finished.connect(self.unlock_apparate) + grabber.updateSignal.connect(self.update_progress_label) + # worker.finished.connect(worker.deleteLater) + + grabber.start() + # self.thread = thread + self.grabbers.append(grabber) + + def unlock_apparate(self): + self.tableWidget_apparate.setEnabled(True) + self.tableWidget_apparate.setToolTip("") + + def btn_save_apparat(self): + def __clear_fields(): + self.drpdwn_app_nr.clear() + self.drpdwn_prof_title.clear() + self.drpdwn_prof_name.clearMask() + self.app_name.clear() + self.prof_mail.clear() + self.prof_tel_nr.clear() + self.app_fach.clear() + self.app_name.clear() + self.sem_year.clear() + self.dokument_list.setRowCount(0) + self.sem_winter.setChecked(False) + self.sem_sommer.setChecked(False) + self.check_eternal_app.setChecked(False) + self.prof_id_adis.clear() + self.prof_id_adis.clear() + self.apparat_id_adis.clear() + self.drpdwn_prof_name.clear() + self.tableWidget_apparat_media.setRowCount(0) + self.frame.setEnabled(False) + + if not self.validate_fields(): + self.confirm_popup("Bitte alle Pflichtfelder ausfüllen!") + return + appd = ApparatData() + appd.appnr = self.active_apparat() + appd.prof_title = ( + None + if self.drpdwn_prof_title.currentText() == "Kein Titel" + else self.drpdwn_prof_title.currentText() + ) + appd.profname = self.drpdwn_prof_name.currentText() + appd.appname = self.app_name.text() + appd.semester = self.generateSemester() + appd.dauerapp = 1 if self.check_eternal_app.isChecked() else 0 + appd.prof_tel = self.prof_tel_nr.text() + appd.prof_mail = self.prof_mail.text() + app_fach = self.app_fach.currentText() + curr_fach_alias = self.db.get_subjects_and_aliases() + for fach in curr_fach_alias: + if app_fach in fach: + appd.app_fach = app_fach + break + else: + #create a popup to ask for the correct subject + dialog = QtWidgets.QDialog() + popup = new_subject_ui() + popup.setupUi(dialog) + new_subject = popup.return_state() + dialog.exec() + if dialog.result() == QtWidgets.QDialog.DialogCode.Accepted: + appd.app_fach = new_subject + self.db.add_subject(new_subject) + else: + return + + appd.deleted = 0 + appd.prof_adis_id = self.prof_id_adis.text() + appd.apparat_adis_id = self.apparat_id_adis.text() + self.add_files() + if not self.validate_fields(): + pass + self.db.create_apparat(appd) + if self.dokument_list.rowCount() > 0: + self.add_files() + appdata = self.db.get_apparats() + # merge self.appdata and appdata, remove duplicates + self.apparats = list(set(self.apparats + appdata)) + self.apparats = natsorted(self.apparats, key=lambda x: x[4], reverse=True) + self.update_apparat_list() + + # self.btn_load_apparat() + + __clear_fields() + + def active_apparat(self): + return self.drpdwn_app_nr.currentText() + + def add_files(self): + files = [] + for i in range(self.dokument_list.rowCount()): + files.append( + { + "name": self.dokument_list.item(i, 0).text(), + "type": self.dokument_list.item(i, 1).text(), + "date": self.dokument_list.item(i, 2).text(), + "path": self.dokument_list.item(i, 3).text(), + } + ) + self.dokument_list.item(i, 2).setText("") + self.db.insert_file(files, self.active_apparat(), self.db.get_prof_id(self.drpdwn_prof_name.currentText())) + + def update_apparat_list(self): + # get a list of new apparats based on self.apparats and self.old_apparats + new_apparats = [ + apparat for apparat in self.apparats if apparat not in self.old_apparats + ] + print(new_apparats) + # insert the new apparats into the table + for apparat in new_apparats: + self.insert_apparat_into_table(apparat) + # sort the table by apparat number using natural sorting + self.tableWidget_apparate.sortItems(0, QtCore.Qt.SortOrder.AscendingOrder) + self.old_apparats = self.apparats + + def insert_apparat_into_table(self, apparat): + def __dauer_check(apparat): + result = self.db.is_eternal(apparat[0]) + return "Ja" if result == ("True" or "1") else "Nein" + + self.tableWidget_apparate.insertRow(0) + self.tableWidget_apparate.setItem( + 0, 0, QtWidgets.QTableWidgetItem(str(apparat[4])) + ) + self.tableWidget_apparate.setItem( + 0, 1, QtWidgets.QTableWidgetItem(str(apparat[1])) + ) + self.tableWidget_apparate.setItem( + 0, + 2, + QtWidgets.QTableWidgetItem( + self.db.get_prof_name_by_id(apparat[2], add_title=False) + ), + ) + self.tableWidget_apparate.setItem( + 0, + 3, + QtWidgets.QTableWidgetItem( + str(apparat[8]) if apparat[8] != None else apparat[5] + ), + ) + self.tableWidget_apparate.setItem( + 0, 4, QtWidgets.QTableWidgetItem(__dauer_check(apparat)) + ) + self.tableWidget_apparate.setItem( + 0, 5, QtWidgets.QTableWidgetItem(str(apparat[13])) + ) + self.logger.log_info(f"Inserted apparat {apparat[4]}") + + def open_context_menu(self, position): + menu = QtWidgets.QMenu() + extend_action = menu.addAction("Verlängern") + contact_action = menu.addAction("Kontaktieren") + delete_action = menu.addAction("Löschen") + remind_action = menu.addAction("Erinnerung") + menu.addAction(extend_action) + menu.addActions([contact_action, delete_action, remind_action]) + extend_action.triggered.connect(self.extend_apparat) + delete_action.triggered.connect(self.delete_apparat) + contact_action.triggered.connect(self.contact_prof) + remind_action.triggered.connect(self.reminder) + menu.exec(self.tableWidget_apparate.mapToGlobal(position)) + + def reminder(self): + dialog = QtWidgets.QDialog() + reminder = reminder_ui() + reminder.setupUi(dialog) + dialog.exec() + if dialog.result() == QtWidgets.QDialog.DialogCode.Accepted: + data = reminder.return_message() + print(data) + self.db.add_message( + data, + self.active_user, + self.active_apparat if self.active_apparat() != "" else None, + ) + self.calendarWidget.setMessages([data]) + self.calendarWidget.updateCells() + # self.db.update_bookdata(data, book_id) + # self.db.update_bookdata(data) + self.logger.log_info("Commited message to database") + # self.update_app_media_list() + + def get_reminders(self): + messages = self.db.get_messages() + self.logger.log_info(f"Got {len(messages)} messages from database") + self.calendarWidget.setMessages(messages) + self.calendarWidget.updateCells() + + def open_reminder(self): + def __update_message(): + message_select = self.spin_select_message.value() + try: + message = messages[message_select - 1] + except IndexError: + self.message_frame.hide() + return + self.message_box.setText(message["message"]) + self.line_app_info.setText( + message["apparatnr"] if message["apparatnr"] != None else "/" + ) + + def __delete_message(): + message = messages[self.spin_select_message.value() - 1] + self.db.delete_message(message["id"]) + # remove message from list + messages.remove(message) + self.spin_select_message.setMaximum(len(messages)) + self.spin_select_message.setValue(1) + self.label_total_day_messages.setText("/ " + str(len(messages))) + + selected_date = self.calendarWidget.selectedDate().toString("yyyy-MM-dd") + print(selected_date) + messages = self.db.get_messages(selected_date) + if messages == []: + self.message_frame.hide() if self.message_frame.isVisible() else None + return + print(messages) + message_count = len(messages) + self.spin_select_message.setMaximum(message_count) + self.message_frame.show() + self.label_total_day_messages.setText("/ " + str(message_count)) + # if there is only one message, disable the spinbox + self.spin_select_message.setEnabled( + False + ) if message_count == 1 else self.spin_select_message.setEnabled(True) + self.spin_select_message.setValue(1) + # load the first message + __update_message() + # on valuechanged, update the message + self.spin_select_message.valueChanged.connect(__update_message) + self.btn_delete_message.clicked.connect(__delete_message) + + def open_settings(self): + dialog = QtWidgets.QDialog() + settings = settings_ui() + settings.setupUi(dialog) + dialog.exec() + if dialog.result() == QtWidgets.QDialog.DialogCode.Accepted: + data = settings.return_data() + print(data) + OmegaConf.save(data, "config.yaml") + #re-load the config + config = OmegaConf.load("config.yaml") + self.logger.log_info("Saved settings to config.yaml") + self.reload() + + def reload(self): + #create a new connection to the database, refresh table data and replace the old connection + self.db = Database() + self.apparats = self.db.get_all_apparts(deleted=0) + self.apparats = natsorted(self.apparats, key=lambda x: x[4], reverse=True) + self.tableWidget_apparate.setRowCount(0) + for apparat in self.apparats: + self.insert_apparat_into_table(apparat) + + def media_context_menu(self, position): + menu = QtWidgets.QMenu() + delete_action = menu.addAction("Löschen") + edit_action = menu.addAction("Bearbeiten") + menu.addAction(delete_action) + menu.addAction(edit_action) + delete_action.triggered.connect(self.delete_medium) + edit_action.triggered.connect(self.edit_medium) + menu.exec(self.tableWidget_apparat_media.mapToGlobal(position)) + + def edit_medium(self): + book = self.tableWidget_apparat_media.item( + self.tableWidget_apparat_media.currentRow(), 1 + ).text() + book_id = self.db.request_medium( + app_id=self.active_apparat(), + signature=book, + prof_id=self.db.get_prof_id(self.drpdwn_prof_name.currentText()), + ) + data = self.db.get_specific_book(book_id) + widget = QtWidgets.QDialog() + bookedit = edit_bookdata_ui() + bookedit.setupUi(widget) + # change title of dialog + widget.setWindowTitle("Metadaten") + bookedit.populate_fields(data) + widget.exec() + if widget.result() == QtWidgets.QDialog.DialogCode.Accepted: + data = bookedit.get_data() + print(data) + self.db.update_bookdata(data, book_id) + # self.db.update_bookdata(data) + print("accepted") + self.update_app_media_list() + else: + return + pass + + def delete_medium(self): + selected_apparat_id = self.tableWidget_apparate.item( + self.tableWidget_apparate.currentRow(), 0 + ).text() + signature = self.tableWidget_apparat_media.item( + self.tableWidget_apparat_media.currentRow(), 1 + ).text() + # bookdata= self.db.request_medium(selected_apparat_id,prof_id=self.db.get_prof_id(self.drpdwn_prof_name.currentText()),signature=signature) + book_id = self.db.request_medium( + selected_apparat_id, + prof_id=self.db.get_prof_id(self.drpdwn_prof_name.currentText()), + signature=signature, + ) + message = f'Soll das Medium "{self.tableWidget_apparat_media.item(self.tableWidget_apparat_media.currentRow(),0).text()}" wirklich gelöscht werden?' + state = self.confirm_popup(message) + print(state) + if state == 1: + self.db.delete_medium(book_id) + self.update_app_media_list() + pass + + def extend_apparat(self): + framework = QtWidgets.QDialog() + frame = App_Ext_Dialog() + frame.setupUi(framework) + frame.sem_year.setValidator(QtGui.QIntValidator()) + frame.sem_year.setText(str(QtCore.QDate.currentDate().year())) + framework.exec() + # return data from dialog if ok is pressed + if framework.result() == QtWidgets.QDialog.DialogCode.Accepted: + data = frame.get_data() + print(data) + # return data + selected_apparat_id = self.tableWidget_apparate.item( + self.tableWidget_apparate.currentRow(), 0 + ).text() + print(selected_apparat_id) + # update self.apparats with the new data + # find matching apparat + # for apparat in self.apparats: + # if apparat[4] == int(selected_apparat_id): + # apparat[5]=data["semester"] + # apparat[7]=data["dauerapp"] + # break + # self.old_apparats = self.apparats + self.db.set_new_sem_date( + selected_apparat_id, data["semester"], dauerapp=data["dauerapp"] + ) + else: + return + + def contact_prof(self): + dialog = QtWidgets.QDialog() + mail_prev = Mail_Dialog() + mail_prev.setupUi(dialog) + mail_prevs = os.listdir("mail_vorlagen") + if self.app_name.text() == "": + mail_prevs.remove("Information zum Semesterapparat.eml") + mail_prev.comboBox.addItems(mail_prevs) + active_apparat_id = self.tableWidget_apparate.item( + self.tableWidget_apparate.currentRow(), 0 + ).text() + general_data = { + "Appname": self.app_name.text(), + "AppSubject": self.app_fach.text(), + "appnr": active_apparat_id, + } + print(active_apparat_id) + mail_prev.appid = active_apparat_id + base_data = self.db.get_prof_data(id=active_apparat_id) + profname = self.db.get_prof_name_by_id(base_data["id"]) + profname = profname.split(" ") + profname = f"{profname[1]} {profname[0]}" + pass_data = { + "prof_name": profname, + "mail_name": base_data["prof_mail"], + "general": general_data, + } + + mail_prev.set_data(pass_data) + mail_prev.set_mail() + dialog.exec() + + def delete_apparat(self): + selected_apparat_id = self.tableWidget_apparate.item( + self.tableWidget_apparate.currentRow(), 0 + ).text() + message = f"Soll der Apparat {selected_apparat_id} wirklich gelöscht werden?" + state = self.confirm_popup(message) + print(state) + if state == 1: + self.db.delete_apparat( + selected_apparat_id, self.generateSemester(today=True) + ) + # delete the corresponding entry from self.apparats + for apparat in self.apparats: + if apparat[4] == int(selected_apparat_id): + self.apparats.remove(apparat) + break + self.old_apparats = self.apparats + print(self.apparats) + # remove the row from the table + self.tableWidget_apparate.removeRow(self.tableWidget_apparate.currentRow()) + # if state==QtWidgets.QDialog.DialogCode.Accepted: + # self.db.delete_apparat(selected_apparat_id) + # pass + + +def launch_gui(): + print("trying to login") + print("checking if database available") + # database = config.database.path + config.database.name + # print(database) + # if not os.path.exists(database): + # print("Database not found, creating new database") + # db = Database() + # db.create_database() + app = QtWidgets.QApplication(sys.argv) + login_dialog = QtWidgets.QDialog() + ui = login_ui() + ui.setupUi(login_dialog) + login_dialog.exec() # This will block until the dialog is closed + + if ui.lresult == 1: + # if login is successful, open main window + # show login dialog + print(ui.lusername) + MainWindow = QtWidgets.QMainWindow() + aui = Ui(MainWindow, username=ui.lusername) + + print(aui.active_user) + MainWindow.show() + atexit.register(aui.thread.terminate) + sys.exit(app.exec()) + elif ui.lresult == 0: + warning_dialog = QtWidgets.QMessageBox() + warning_dialog.setIcon(QtWidgets.QMessageBox.Icon.Warning) + warning_dialog.setText("Invalid username or password. Please try again.") + warning_dialog.setWindowTitle("Login Failed") + warning_dialog.exec() + elif ui.lresult == 2: + # TODO: implement admin functionality here + """change passwords for apparats, change passwords for users, list users, create and delete users etc""" + # open a console window + # console = "" + print("admin") + + +if __name__ == "__main__": + print("This is the main window") + # app = QtWidgets.QApplication(sys.argv) + # window = MainWindow() + # app.exec() + # open login screen + launch_gui() diff --git a/src/logic/webrequest.py b/src/logic/webrequest.py new file mode 100644 index 0000000..455718e --- /dev/null +++ b/src/logic/webrequest.py @@ -0,0 +1,176 @@ +import requests +from bs4 import BeautifulSoup +from omegaconf import OmegaConf + +from src.logic.dataclass import BookData +from log import MyLogger +from src.transformers import ARRAYData, BibTeXData, COinSData, RDSData, RISData +#import sleep_and_retry decorator to retry requests +from ratelimit import limits, sleep_and_retry + +logger = MyLogger(__name__) +config = OmegaConf.load("config.yaml") + +API_URL = "https://rds.ibs-bw.de/phfreiburg/opac/RDSIndexrecord/{}/" +PPN_URL = 'https://rds.ibs-bw.de/phfreiburg/opac/RDSIndex/Search?lookfor="{}"+&type=AllFields&limit=10&sort=py+desc%2C+title' +TITLE = "RDS_TITLE" +SIGNATURE = "RDS_SIGNATURE" +EDITION = "RDS_EDITION" +ISBN = "RDS_ISBN" +AUTHOR = "RDS_PERSON" + +HEADERS = { + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 \ + (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36", + "Accept-Language": "en-US, en;q=0.5", +} + + +class WebRequest: + def __init__(self) -> None: + """Request data from the web, and format it depending on the mode.""" + self.signature = None + self.ppn = None + self.data = None + logger.log_info("Initialized WebRequest") + + def get_ppn(self, signature): + self.signature = signature + if "+" in signature: + signature = signature.replace("+", "%2B") + if "doi.org" in signature: + signature = signature.split("/")[-1] + url = PPN_URL.format(signature) + page = requests.get(url) + + soup = BeautifulSoup(page.content, "html.parser", from_encoding="utf-8") + if soup.find("div", class_="media") is None: + logger.log_error(f"No data found for {signature}") + return self + ppn = soup.find("div", class_="media").get("id") + self.ppn = ppn + return self + + def get_link_data(self): + page = requests.get(PPN_URL.format(self.ppn)) + soup = BeautifulSoup(page.content, "html.parser") + # find div that contains daia_ in the id + # find the pre tag in that div + # return the text + # div = soup.find("div",id=lambda x: x and "daia_" in x) + # pre = div.find("pre") + return soup + + def get_data(self) -> list[str] | str: + # url = API_URL.format(self.ppn) + if self.ppn is None: + logger.log_error("No PPN found") + return "error" + page = requests.get(API_URL.format(self.ppn)) + logger.log_info(f"Requesting data from {API_URL.format(self.ppn)}") + logger.log_info(f"Status code: {page.status_code}") + # print(page.content) + soup = BeautifulSoup(page.content, "html.parser") + pre_tag = soup.find_all("pre") + # print(pre_tag) + return_data = [] + + if pre_tag: + for tag in pre_tag: + data = tag.text.strip() + return_data.append(data) + return return_data + else: + print("No
 tag found")
+            logger.log_error("No 
 tag found")
+            return return_data
+
+
+class BibTextTransformer:
+    def __init__(self, mode: str) -> None:
+        self.mode = mode
+        self.field = None
+        # print(self.field)
+        self.data = None
+        # self.bookdata = BookData(**self.data)
+
+    def get_data(self, data: list) -> str:
+        RIS_IDENT = "TY  -"
+        ARRAY_IDENT = "[kid]"
+        COinS_IDENT = "ctx_ver"
+        BIBTEX_IDENT = "@book"
+        RDS_IDENT = "RDS ---------------------------------- "
+        if self.mode == "RIS":
+            for line in data:
+                if RIS_IDENT in line:
+                    self.data = line
+        elif self.mode == "ARRAY":
+            for line in data:
+                if ARRAY_IDENT in line:
+                    self.data = line
+        elif self.mode == "COinS":
+            for line in data:
+                if COinS_IDENT in line:
+                    self.data = line
+        elif self.mode == "BibTeX":
+            for line in data:
+                if BIBTEX_IDENT in line:
+                    self.data = line
+        elif self.mode == "RDS":
+            for line in data:
+                if RDS_IDENT in line:
+                    self.data = line
+        return self
+
+    def return_data(self, option=None) -> BookData:
+        """Return Data to caller.
+
+        Args:
+            option (string, optional): Option for RDS as there are two filetypes. Use rds_availability or rds_data. Anything else gives a dict of both responses. Defaults to None.
+
+        Returns:
+            BookData: _description_
+        """
+        if self.mode == "ARRAY":
+            return ARRAYData().transform(self.data)
+        elif self.mode == "COinS":
+            return COinSData().transform(self.data)
+        elif self.mode == "BibTeX":
+            return BibTeXData().transform(self.data)
+        elif self.mode == "RIS":
+            return RISData().transform(self.data)
+        elif self.mode == "RDS":
+            return RDSData().transform(self.data).return_data(option)
+
+
+def cover(isbn):
+    test_url = f"https://www.buchhandel.de/cover/{isbn}/{isbn}-cover-m.jpg"
+    print(test_url)
+    data = requests.get(test_url, stream=True)
+    return data.content
+
+
+def get_content(soup, css_class):
+    return soup.find("div", class_=css_class).text.strip()
+
+
+if __name__ == "__main__":
+    print("main")
+    link = "ZE 77000 W492"
+    data = WebRequest().get_ppn(link).get_data()
+
+    print(data)
+    # # data.get_ppn("ME 3000 S186 (2)")
+    # # print(data.ppn)
+    # # desc=data.get_data()
+    # # print(type(desc))
+    # # print(desc)
+    # txt = (
+    #     BibTextTransformer("RIS")
+    #     .get_data(WebRequest().get_ppn("ST 250 U42 (15)").get_data())
+    #     .return_data()
+    # )
+    # print(txt)
+
+    # print(data)
+    # print(BibTextTransformer(data).bookdata)
diff --git a/src/logic/wordparser.py b/src/logic/wordparser.py
new file mode 100644
index 0000000..716a135
--- /dev/null
+++ b/src/logic/wordparser.py
@@ -0,0 +1,26 @@
+import pandas as pd
+from docx import Document
+
+
+def word_docx_to_csv(path) -> pd.DataFrame:
+    doc = Document(path)
+    tables = doc.tables
+
+    m_data = []
+    for table in tables:
+        data = []
+        for row in table.rows:
+            row_data = []
+            for cell in row.cells:
+                text = cell.text
+                text = text.replace("\n", "")
+                row_data.append(text)
+            data.append(row_data)
+        df = pd.DataFrame(data)
+        df.columns = df.iloc[0]
+        df = df.iloc[1:]
+
+        m_data.append(df)
+
+    df = m_data[2]
+    return df
diff --git a/src/transformers/__init__.py b/src/transformers/__init__.py
new file mode 100644
index 0000000..ea68985
--- /dev/null
+++ b/src/transformers/__init__.py
@@ -0,0 +1 @@
+from .transformers import RDS_AVAIL_DATA, ARRAYData, COinSData, BibTeXData, RISData, RDSData
\ No newline at end of file
diff --git a/src/transformers/transformers.py b/src/transformers/transformers.py
new file mode 100644
index 0000000..760afdd
--- /dev/null
+++ b/src/transformers/transformers.py
@@ -0,0 +1,310 @@
+from __future__ import annotations
+
+import json
+import re
+from dataclasses import dataclass
+from dataclasses import field as dataclass_field
+from typing import Any, List, Optional
+
+from pydantic import BaseModel, Field
+
+from src.logic.dataclass import BookData
+from log import MyLogger
+
+logger = MyLogger("transformers.py")
+
+
+###Pydatnic models
+@dataclass
+class Item:
+    superlocation: str | None = dataclass_field(default_factory=str)
+    status: str | None = dataclass_field(default_factory=str)
+    availability: str | None = dataclass_field(default_factory=str)
+    notes: str | None = dataclass_field(default_factory=str)
+    limitation: str | None = dataclass_field(default_factory=str)
+    duedate: str | None = dataclass_field(default_factory=str)
+    id: str | None = dataclass_field(default_factory=str)
+    item_id: str | None = dataclass_field(default_factory=str)
+    ilslink: str | None = dataclass_field(default_factory=str)
+    number: int | None = dataclass_field(default_factory=int)
+    barcode: str | None = dataclass_field(default_factory=str)
+    reserve: str | None = dataclass_field(default_factory=str)
+    callnumber: str | None = dataclass_field(default_factory=str)
+    department: str | None = dataclass_field(default_factory=str)
+    locationhref: str | None = dataclass_field(default_factory=str)
+    location: str | None = dataclass_field(default_factory=str)
+
+    def from_dict(self, data: dict) -> self:
+        """Import data from dict"""
+        data = data["items"]
+        for entry in data:
+            for key, value in entry.items():
+                setattr(self, key, value)
+        return self
+
+
+@dataclass
+class RDS_AVAIL_DATA:
+    """Class to store RDS availability data"""
+
+    library_sigil: str = dataclass_field(default_factory=str)
+    items: List[Item] = dataclass_field(default_factory=list)
+
+    def import_from_dict(self, data: str) -> self:
+        """Import data from dict"""
+        edata = json.loads(data)
+        # library sigil is first key
+
+        self.library_sigil = str(list(edata.keys())[0])
+        # get data from first key
+        edata = edata[self.library_sigil]
+        for location in edata:
+            item = Item(superlocation=location).from_dict(edata[location])
+
+            self.items.append(item)
+        return self
+
+
+@dataclass
+class RDS_DATA:
+    """Class to store RDS data"""
+
+    RDS_SIGNATURE: str = dataclass_field(default_factory=str)
+    RDS_STATUS: str = dataclass_field(default_factory=str)
+    RDS_LOCATION: str = dataclass_field(default_factory=str)
+    RDS_URL: Any = dataclass_field(default_factory=str)
+    RDS_HINT: Any = dataclass_field(default_factory=str)
+    RDS_COMMENT: Any = dataclass_field(default_factory=str)
+    RDS_HOLDING: Any = dataclass_field(default_factory=str)
+    RDS_HOLDING_LEAK: Any = dataclass_field(default_factory=str)
+    RDS_INTERN: Any = dataclass_field(default_factory=str)
+    RDS_PROVENIENCE: Any = dataclass_field(default_factory=str)
+    RDS_LOCAL_NOTATION: str = dataclass_field(default_factory=str)
+    RDS_LEA: Any = dataclass_field(default_factory=str)
+
+    def import_from_dict(self, data: dict) -> RDS_DATA:
+        """Import data from dict"""
+        for key, value in data.items():
+            setattr(self, key, value)
+        return self
+
+
+@dataclass
+class RDS_GENERIC_DATA:
+    LibrarySigil: str = dataclass_field(default_factory=str)
+    RDS_DATA: List[RDS_DATA] = dataclass_field(default_factory=list)
+
+    def import_from_dict(self, data: str) -> RDS_GENERIC_DATA:
+        """Import data from dict"""
+        edata = json.loads(data)
+        # library sigil is first key
+        self.LibrarySigil = str(list(edata.keys())[0])
+        # get data from first key
+        edata = edata[self.LibrarySigil]
+        for entry in edata:
+            rds_data = RDS_DATA()  # Create a new RDS_DATA instance
+            # Populate the RDS_DATA instance from the entry
+            # This assumes that the entry is a dictionary that matches the structure of the RDS_DATA class
+            rds_data.import_from_dict(entry)
+            self.RDS_DATA.append(rds_data)  # Add the RDS_DATA instance to the list
+        return self
+
+
+class BaseStruct:
+    def __init__(self, **kwargs):
+        for key, value in kwargs.items():
+            setattr(self, key, value)
+
+
+class ARRAYData:
+    def __init__(self):
+        pass
+
+    def transform(self, data: str) -> BookData:
+        def _get_line(source: str, search: str) -> str:
+            try:
+                return (
+                    source.split(search)[1]
+                    .split("\n")[0]
+                    .strip()
+                    .replace("=>", "")
+                    .strip()
+                )
+
+            except Exception as e:
+                logger.log_exception("ARRAYData.transform failed")
+                return ""
+
+        def _get_list_entry(source: str, search: str, entry: str) -> str:
+            try:
+                source = source.replace("\t", "").replace("\r", "")
+                source = source.split(search)[1].split(")")[0]
+                return _get_line(source, entry).replace("=>", "").strip()
+            except:
+                return ""
+
+        def _get_isbn(source: str) -> list:
+            try:
+                isbn = source.split("[isbn]")[1].split(")")[0].strip()
+                isbn = isbn.split("(")[1]
+                isbns = isbn.split("=>")
+                ret = []
+                for _ in isbns:
+                    # remove _ from list
+                    isb = _.split("\n")[0].strip()
+                    if isb == "":
+                        continue
+                    ret.append(isb) if isb not in ret else None
+                return ret
+            except:
+                isbn = []
+                return isbn
+
+        return BookData(
+            ppn=_get_line(data, "[kid]"),
+            title=_get_line(data, "[ti_long]").split("/")[0].strip(),
+            author=_get_list_entry(data, "[au]", "[0]"),
+            edition=_get_list_entry(data, "[ausgabe]", "[0]").replace(",", ""),
+            link=f"https://rds.ibs-bw.de/phfreiburg/link?kid={_get_line(data,'[kid]')}",
+            isbn=_get_isbn(data),
+            # [self._get_list_entry(data,"[isbn]","[0]"),self._get_list_entry(data,"[is]","[1]")],
+            language=_get_list_entry(data, "[la_facet]", "[0]"),
+            publisher=_get_list_entry(data, "[hg]", "[0]"),
+            year=_get_line(data, "[py]"),
+            pages=_get_list_entry(data, "[umfang]", "[0]").split(":")[0].strip(),
+        )
+
+
+class COinSData:
+    def __init__(self) -> None:
+        pass
+
+    def transform(self, data: str) -> BookData:
+        def _get_line(source: str, search: str) -> str:
+            try:
+                data = source.split(f"{search}=")[1]  # .split("")[0].strip()
+                return data.split("rft")[0].strip() if "rft" in data else data
+            except:
+                return ""
+
+        return BookData(
+            ppn=_get_line(data, "rft_id").split("=")[1],
+            title=_get_line(data, "rft.btitle"),
+            author=f"{_get_line(data,'rft.aulast')}, {_get_line(data,'rft.aufirst')}",
+            edition=_get_line(data, "rft.edition"),
+            link=_get_line(data, "rft_id"),
+            isbn=_get_line(data, "rft.isbn"),
+            publisher=_get_line(data, "rft.pub"),
+            year=_get_line(data, "rft.date"),
+            pages=_get_line(data, "rft.tpages").split(":")[0].strip(),
+        )
+
+
+class RISData:
+    def __init__(self) -> None:
+        pass
+
+    def transform(self, data: str) -> BookData:
+        def _get_line(source: str, search: str) -> str:
+            try:
+                data = source.split(f"{search}  - ")[1]  # .split("")[0].strip()
+                return data.split("\n")[0].strip() if "\n" in data else data
+            except:
+                return ""
+
+        return BookData(
+            ppn=_get_line(data, "DP").split("=")[1],
+            title=_get_line(data, "TI"),
+            signature=_get_line(data, "CN"),
+            edition=_get_line(data, "ET").replace(",", ""),
+            link=_get_line(data, "DP"),
+            isbn=_get_line(data, "SN").split(","),
+            author=_get_line(data, "AU").split("[")[0].strip(),
+            language=_get_line(data, "LA"),
+            publisher=_get_line(data, "PB"),
+            year=_get_line(data, "PY"),
+            pages=_get_line(data, "SP"),
+        )
+
+
+class BibTeXData:
+    def __init__(self):
+        pass
+
+    def transform(self, data: str) -> BookData:
+        def _get_line(source: str, search: str) -> str:
+            try:
+                return (
+                    data.split(search)[1]
+                    .split("\n")[0]
+                    .strip()
+                    .split("=")[1]
+                    .strip()
+                    .replace("{", "")
+                    .replace("}", "")
+                    .replace(",", "")
+                    .replace("[", "")
+                    .replace("];", "")
+                )
+            except:
+                return ""
+
+        return BookData(
+            ppn=None,
+            title=_get_line(data, "title"),
+            signature=_get_line(data, "bestand"),
+            edition=_get_line(data, "edition"),
+            isbn=_get_line(data, "isbn"),
+            author=";".join(_get_line(data, "author").split(" and ")),
+            language=_get_line(data, "language"),
+            publisher=_get_line(data, "publisher"),
+            year=_get_line(data, "year"),
+            pages=_get_line(data, "pages"),
+        )
+
+
+class RDSData:
+    retlist = []
+
+    def transform(self, data: str):
+        # rds_availability = RDS_AVAIL_DATA()
+        # rds_data = RDS_GENERIC_DATA()
+        def __get_raw_data(data: str) -> list:
+            # create base data to be turned into pydantic classes
+            data = data.split("RDS ----------------------------------")[1]
+            edata = data.strip()
+            edata = edata.split("\n", 9)[9]
+            edata = edata.split("\n")[1:]
+            entry_1 = edata[0]
+            edata = edata[1:]
+            entry_2 = "".join(edata)
+            edata = []
+            edata.append(entry_1)
+            edata.append(entry_2)
+            return edata
+
+        ret_data = __get_raw_data(data)
+        # assign data[1] to RDS_AVAIL_DATA
+        # assign data[0] to RDS_DATA
+        self.rds_data = RDS_GENERIC_DATA().import_from_dict(ret_data[1])
+        self.rds_availability = RDS_AVAIL_DATA().import_from_dict(ret_data[0])
+        self.retlist.append(self.rds_availability)
+        self.retlist.append(self.rds_data)
+        return self
+
+    def return_data(self, option=None):
+        if option == "rds_availability":
+            return self.retlist[0]
+        elif option == "rds_data":
+            return self.retlist[1]
+        else:
+            return {"rds_availability": self.retlist[0], "rds_data": self.retlist[1]}
+
+
+if __name__ == "__main__":
+    with open("daiadata", "r") as f:
+        data = f.read()
+
+    ret = RDSData().transform(data)
+    data = ret.return_data("rds_availability")
+    print(data)
diff --git a/src/ui/Ui_plotdata.py b/src/ui/Ui_plotdata.py
new file mode 100644
index 0000000..e0ee261
--- /dev/null
+++ b/src/ui/Ui_plotdata.py
@@ -0,0 +1,47 @@
+# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\Semesterapparate\ui\plotdata.ui'
+#
+# Created by: PyQt6 UI code generator 6.3.1
+#
+# WARNING: Any manual changes made to this file will be lost when pyuic6 is
+# run again.  Do not edit this file unless you know what you are doing.
+
+
+from PyQt6 import QtCore, QtWidgets
+
+
+class Ui_MainWindow(object):
+    def setupUi(self, MainWindow):
+        MainWindow.setObjectName("MainWindow")
+        MainWindow.resize(640, 480)
+        self.centralwidget = QtWidgets.QWidget(MainWindow)
+        self.centralwidget.setObjectName("centralwidget")
+        self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
+        self.graphicsView.setGeometry(QtCore.QRect(330, 10, 256, 192))
+        self.graphicsView.setObjectName("graphicsView")
+        self.widget = QtWidgets.QWidget(self.centralwidget)
+        self.widget.setGeometry(QtCore.QRect(10, 0, 251, 271))
+        self.widget.setObjectName("widget")
+        self.stackedWidget = QtWidgets.QStackedWidget(self.centralwidget)
+        self.stackedWidget.setGeometry(QtCore.QRect(300, 220, 291, 201))
+        self.stackedWidget.setObjectName("stackedWidget")
+        self.page = QtWidgets.QWidget()
+        self.page.setObjectName("page")
+        self.stackedWidget.addWidget(self.page)
+        self.page_2 = QtWidgets.QWidget()
+        self.page_2.setObjectName("page_2")
+        self.stackedWidget.addWidget(self.page_2)
+        MainWindow.setCentralWidget(self.centralwidget)
+        self.menubar = QtWidgets.QMenuBar(MainWindow)
+        self.menubar.setGeometry(QtCore.QRect(0, 0, 640, 21))
+        self.menubar.setObjectName("menubar")
+        MainWindow.setMenuBar(self.menubar)
+        self.statusbar = QtWidgets.QStatusBar(MainWindow)
+        self.statusbar.setObjectName("statusbar")
+        MainWindow.setStatusBar(self.statusbar)
+
+        self.retranslateUi(MainWindow)
+        QtCore.QMetaObject.connectSlotsByName(MainWindow)
+
+    def retranslateUi(self, MainWindow):
+        _translate = QtCore.QCoreApplication.translate
+        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
diff --git a/src/ui/Ui_semesterapparat_ui.py b/src/ui/Ui_semesterapparat_ui.py
new file mode 100644
index 0000000..8115464
--- /dev/null
+++ b/src/ui/Ui_semesterapparat_ui.py
@@ -0,0 +1,1445 @@
+# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\Semesterapparate-refactor\src\ui\semesterapparat_ui.ui'
+#
+# Created by: PyQt6 UI code generator 6.3.1
+#
+# WARNING: Any manual changes made to this file will be lost when pyuic6 is
+# run again.  Do not edit this file unless you know what you are doing.
+
+
+from PyQt6 import QtCore, QtGui, QtWidgets
+
+
+class Ui_MainWindow(object):
+    def setupUi(self, MainWindow):
+        MainWindow.setObjectName("MainWindow")
+        MainWindow.setWindowModality(QtCore.Qt.WindowModality.WindowModal)
+        MainWindow.setEnabled(True)
+        MainWindow.resize(1593, 800)
+        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
+        MainWindow.setSizePolicy(sizePolicy)
+        MainWindow.setMinimumSize(QtCore.QSize(1278, 800))
+        MainWindow.setMaximumSize(QtCore.QSize(1920, 800))
+        MainWindow.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu)
+        self.centralwidget = QtWidgets.QWidget(MainWindow)
+        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth())
+        self.centralwidget.setSizePolicy(sizePolicy)
+        self.centralwidget.setObjectName("centralwidget")
+        self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
+        self.verticalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 1271, 761))
+        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
+        self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
+        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+        self.verticalLayout.setObjectName("verticalLayout")
+        self.horizontalLayout = QtWidgets.QHBoxLayout()
+        self.horizontalLayout.setObjectName("horizontalLayout")
+        self.gridLayout = QtWidgets.QGridLayout()
+        self.gridLayout.setObjectName("gridLayout")
+        self.tabWidget = QtWidgets.QTabWidget(self.verticalLayoutWidget)
+        self.tabWidget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.tabWidget.setObjectName("tabWidget")
+        self.tab = QtWidgets.QWidget()
+        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.tab.sizePolicy().hasHeightForWidth())
+        self.tab.setSizePolicy(sizePolicy)
+        self.tab.setObjectName("tab")
+        self.horizontalLayoutWidget_2 = QtWidgets.QWidget(self.tab)
+        self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(0, 0, 1261, 163))
+        self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2")
+        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_2)
+        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
+        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+        self.formLayout = QtWidgets.QFormLayout()
+        self.formLayout.setObjectName("formLayout")
+        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
+        self.verticalLayout_2.setObjectName("verticalLayout_2")
+        spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
+        self.verticalLayout_2.addItem(spacerItem)
+        self.load_app = QtWidgets.QPushButton(self.horizontalLayoutWidget_2)
+        self.load_app.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.load_app.setObjectName("load_app")
+        self.verticalLayout_2.addWidget(self.load_app)
+        self.create_new_app = QtWidgets.QPushButton(self.horizontalLayoutWidget_2)
+        self.create_new_app.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.create_new_app.setObjectName("create_new_app")
+        self.verticalLayout_2.addWidget(self.create_new_app)
+        self.cancel_active_selection = QtWidgets.QPushButton(self.horizontalLayoutWidget_2)
+        self.cancel_active_selection.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.cancel_active_selection.setObjectName("cancel_active_selection")
+        self.verticalLayout_2.addWidget(self.cancel_active_selection)
+        spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
+        self.verticalLayout_2.addItem(spacerItem1)
+        self.formLayout.setLayout(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.verticalLayout_2)
+        self.tableWidget_apparate = QtWidgets.QTableWidget(self.horizontalLayoutWidget_2)
+        self.tableWidget_apparate.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.tableWidget_apparate.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents)
+        self.tableWidget_apparate.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.SelectedClicked)
+        self.tableWidget_apparate.setAlternatingRowColors(True)
+        self.tableWidget_apparate.setTextElideMode(QtCore.Qt.TextElideMode.ElideMiddle)
+        self.tableWidget_apparate.setObjectName("tableWidget_apparate")
+        self.tableWidget_apparate.setColumnCount(6)
+        self.tableWidget_apparate.setRowCount(0)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget_apparate.setHorizontalHeaderItem(0, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget_apparate.setHorizontalHeaderItem(1, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget_apparate.setHorizontalHeaderItem(2, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget_apparate.setHorizontalHeaderItem(3, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget_apparate.setHorizontalHeaderItem(4, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget_apparate.setHorizontalHeaderItem(5, item)
+        self.tableWidget_apparate.horizontalHeader().setCascadingSectionResizes(True)
+        self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.tableWidget_apparate)
+        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
+        self.formLayout.setLayout(2, QtWidgets.QFormLayout.ItemRole.FieldRole, self.horizontalLayout_4)
+        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+        self.formLayout.setLayout(3, QtWidgets.QFormLayout.ItemRole.LabelRole, self.horizontalLayout_3)
+        self.horizontalLayout_2.addLayout(self.formLayout)
+        self.line = QtWidgets.QFrame(self.tab)
+        self.line.setGeometry(QtCore.QRect(0, 160, 1261, 21))
+        self.line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
+        self.line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
+        self.line.setObjectName("line")
+        self.gridLayoutWidget_2 = QtWidgets.QWidget(self.tab)
+        self.gridLayoutWidget_2.setEnabled(True)
+        self.gridLayoutWidget_2.setGeometry(QtCore.QRect(0, 180, 1261, 511))
+        self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2")
+        self.gridLayout_2 = QtWidgets.QGridLayout(self.gridLayoutWidget_2)
+        self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
+        self.gridLayout_2.setObjectName("gridLayout_2")
+        self.app_group_box = QtWidgets.QGroupBox(self.gridLayoutWidget_2)
+        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.app_group_box.sizePolicy().hasHeightForWidth())
+        self.app_group_box.setSizePolicy(sizePolicy)
+        self.app_group_box.setMinimumSize(QtCore.QSize(0, 210))
+        font = QtGui.QFont()
+        font.setPointSize(12)
+        font.setBold(True)
+        font.setWeight(75)
+        self.app_group_box.setFont(font)
+        self.app_group_box.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignLeft|QtCore.Qt.AlignmentFlag.AlignVCenter)
+        self.app_group_box.setCheckable(False)
+        self.app_group_box.setObjectName("app_group_box")
+        self.dokument_list = QtWidgets.QTableWidget(self.app_group_box)
+        self.dokument_list.setGeometry(QtCore.QRect(765, 20, 321, 181))
+        font = QtGui.QFont()
+        font.setPointSize(10)
+        font.setBold(False)
+        font.setWeight(50)
+        font.setKerning(False)
+        self.dokument_list.setFont(font)
+        self.dokument_list.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.dokument_list.setAcceptDrops(True)
+        self.dokument_list.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents)
+        self.dokument_list.setDragEnabled(True)
+        self.dokument_list.setDragDropMode(QtWidgets.QAbstractItemView.DragDropMode.DropOnly)
+        self.dokument_list.setDefaultDropAction(QtCore.Qt.DropAction.LinkAction)
+        self.dokument_list.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.SingleSelection)
+        self.dokument_list.setObjectName("dokument_list")
+        self.dokument_list.setColumnCount(4)
+        self.dokument_list.setRowCount(0)
+        item = QtWidgets.QTableWidgetItem()
+        font = QtGui.QFont()
+        font.setFamily("Arial")
+        font.setPointSize(8)
+        item.setFont(font)
+        self.dokument_list.setHorizontalHeaderItem(0, item)
+        item = QtWidgets.QTableWidgetItem()
+        font = QtGui.QFont()
+        font.setFamily("Arial")
+        font.setPointSize(8)
+        item.setFont(font)
+        self.dokument_list.setHorizontalHeaderItem(1, item)
+        item = QtWidgets.QTableWidgetItem()
+        font = QtGui.QFont()
+        font.setFamily("Arial")
+        font.setPointSize(8)
+        item.setFont(font)
+        self.dokument_list.setHorizontalHeaderItem(2, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.dokument_list.setHorizontalHeaderItem(3, item)
+        self.frame = QtWidgets.QFrame(self.app_group_box)
+        self.frame.setEnabled(True)
+        self.frame.setGeometry(QtCore.QRect(10, 30, 1241, 151))
+        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
+        self.frame.setSizePolicy(sizePolicy)
+        self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
+        self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
+        self.frame.setObjectName("frame")
+        self.drpdwn_prof_title = QtWidgets.QComboBox(self.frame)
+        self.drpdwn_prof_title.setGeometry(QtCore.QRect(110, 50, 69, 22))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.drpdwn_prof_title.setFont(font)
+        self.drpdwn_prof_title.setEditable(True)
+        self.drpdwn_prof_title.setObjectName("drpdwn_prof_title")
+        self.label_5 = QtWidgets.QLabel(self.frame)
+        self.label_5.setGeometry(QtCore.QRect(250, 20, 91, 21))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.label_5.setFont(font)
+        self.label_5.setObjectName("label_5")
+        self.sem_winter = QtWidgets.QRadioButton(self.frame)
+        self.sem_winter.setGeometry(QtCore.QRect(340, 50, 82, 17))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.sem_winter.setFont(font)
+        self.sem_winter.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.sem_winter.setObjectName("sem_winter")
+        self.label_4 = QtWidgets.QLabel(self.frame)
+        self.label_4.setGeometry(QtCore.QRect(10, 80, 71, 21))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.label_4.setFont(font)
+        self.label_4.setObjectName("label_4")
+        self.drpdwn_app_nr = QtWidgets.QComboBox(self.frame)
+        self.drpdwn_app_nr.setGeometry(QtCore.QRect(110, 20, 69, 22))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.drpdwn_app_nr.setFont(font)
+        self.drpdwn_app_nr.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhDigitsOnly)
+        self.drpdwn_app_nr.setEditable(True)
+        self.drpdwn_app_nr.setObjectName("drpdwn_app_nr")
+        self.app_name = QtWidgets.QLineEdit(self.frame)
+        self.app_name.setGeometry(QtCore.QRect(340, 20, 113, 20))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.app_name.setFont(font)
+        self.app_name.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus)
+        self.app_name.setObjectName("app_name")
+        self.sem_sommer = QtWidgets.QRadioButton(self.frame)
+        self.sem_sommer.setGeometry(QtCore.QRect(340, 70, 82, 17))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.sem_sommer.setFont(font)
+        self.sem_sommer.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.sem_sommer.setObjectName("sem_sommer")
+        self.label_3 = QtWidgets.QLabel(self.frame)
+        self.label_3.setGeometry(QtCore.QRect(10, 50, 61, 20))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.label_3.setFont(font)
+        self.label_3.setObjectName("label_3")
+        self.label_6 = QtWidgets.QLabel(self.frame)
+        self.label_6.setGeometry(QtCore.QRect(270, 60, 61, 21))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.label_6.setFont(font)
+        self.label_6.setObjectName("label_6")
+        self.sem_year = QtWidgets.QLineEdit(self.frame)
+        self.sem_year.setGeometry(QtCore.QRect(410, 60, 113, 20))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.sem_year.setFont(font)
+        self.sem_year.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus)
+        self.sem_year.setMaxLength(4)
+        self.sem_year.setObjectName("sem_year")
+        self.label_2 = QtWidgets.QLabel(self.frame)
+        self.label_2.setGeometry(QtCore.QRect(10, 20, 101, 21))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.label_2.setFont(font)
+        self.label_2.setObjectName("label_2")
+        self.btn_apparat_save = QtWidgets.QPushButton(self.frame)
+        self.btn_apparat_save.setGeometry(QtCore.QRect(260, 120, 75, 23))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.btn_apparat_save.setFont(font)
+        self.btn_apparat_save.setObjectName("btn_apparat_save")
+        self.btn_apparat_apply = QtWidgets.QPushButton(self.frame)
+        self.btn_apparat_apply.setGeometry(QtCore.QRect(350, 120, 75, 23))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.btn_apparat_apply.setFont(font)
+        self.btn_apparat_apply.setObjectName("btn_apparat_apply")
+        self.check_eternal_app = QtWidgets.QCheckBox(self.frame)
+        self.check_eternal_app.setGeometry(QtCore.QRect(340, 90, 101, 17))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.check_eternal_app.setFont(font)
+        self.check_eternal_app.setObjectName("check_eternal_app")
+        self.label_8 = QtWidgets.QLabel(self.frame)
+        self.label_8.setGeometry(QtCore.QRect(10, 110, 71, 21))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.label_8.setFont(font)
+        self.label_8.setObjectName("label_8")
+        self.prof_mail = QtWidgets.QLineEdit(self.frame)
+        self.prof_mail.setGeometry(QtCore.QRect(110, 110, 121, 20))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.prof_mail.setFont(font)
+        self.prof_mail.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhEmailCharactersOnly)
+        self.prof_mail.setMaxLength(200)
+        self.prof_mail.setPlaceholderText("")
+        self.prof_mail.setObjectName("prof_mail")
+        self.label_9 = QtWidgets.QLabel(self.frame)
+        self.label_9.setGeometry(QtCore.QRect(10, 130, 71, 21))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.label_9.setFont(font)
+        self.label_9.setObjectName("label_9")
+        self.prof_tel_nr = QtWidgets.QLineEdit(self.frame)
+        self.prof_tel_nr.setGeometry(QtCore.QRect(110, 130, 121, 20))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.prof_tel_nr.setFont(font)
+        self.prof_tel_nr.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhDigitsOnly)
+        self.prof_tel_nr.setPlaceholderText("")
+        self.prof_tel_nr.setObjectName("prof_tel_nr")
+        self.label_10 = QtWidgets.QLabel(self.frame)
+        self.label_10.setGeometry(QtCore.QRect(470, 20, 51, 21))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.label_10.setFont(font)
+        self.label_10.setObjectName("label_10")
+        self.drpdwn_prof_name = QtWidgets.QComboBox(self.frame)
+        self.drpdwn_prof_name.setGeometry(QtCore.QRect(110, 80, 121, 22))
+        font = QtGui.QFont()
+        font.setPointSize(8)
+        font.setBold(False)
+        font.setWeight(50)
+        self.drpdwn_prof_name.setFont(font)
+        self.drpdwn_prof_name.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus)
+        self.drpdwn_prof_name.setEditable(True)
+        self.drpdwn_prof_name.setCurrentText("")
+        self.drpdwn_prof_name.setInsertPolicy(QtWidgets.QComboBox.InsertPolicy.InsertAlphabetically)
+        self.drpdwn_prof_name.setFrame(True)
+        self.drpdwn_prof_name.setObjectName("drpdwn_prof_name")
+        self.mail_mand = QtWidgets.QLabel(self.frame)
+        self.mail_mand.setGeometry(QtCore.QRect(100, 110, 47, 21))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.mail_mand.setFont(font)
+        self.mail_mand.setObjectName("mail_mand")
+        self.telnr_mand = QtWidgets.QLabel(self.frame)
+        self.telnr_mand.setGeometry(QtCore.QRect(100, 130, 47, 21))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.telnr_mand.setFont(font)
+        self.telnr_mand.setObjectName("telnr_mand")
+        self.profname_mand = QtWidgets.QLabel(self.frame)
+        self.profname_mand.setGeometry(QtCore.QRect(100, 80, 47, 21))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.profname_mand.setFont(font)
+        self.profname_mand.setObjectName("profname_mand")
+        self.appname_mand = QtWidgets.QLabel(self.frame)
+        self.appname_mand.setGeometry(QtCore.QRect(330, 20, 16, 21))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.appname_mand.setFont(font)
+        self.appname_mand.setObjectName("appname_mand")
+        self.fach_mand = QtWidgets.QLabel(self.frame)
+        self.fach_mand.setGeometry(QtCore.QRect(500, 20, 47, 21))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.fach_mand.setFont(font)
+        self.fach_mand.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.fach_mand.setObjectName("fach_mand")
+        self._mand = QtWidgets.QLabel(self.frame)
+        self._mand.setGeometry(QtCore.QRect(330, 60, 16, 21))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self._mand.setFont(font)
+        self._mand.setObjectName("_mand")
+        self.btn_add_document = QtWidgets.QPushButton(self.frame)
+        self.btn_add_document.setGeometry(QtCore.QRect(1090, 20, 131, 25))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.btn_add_document.setFont(font)
+        self.btn_add_document.setObjectName("btn_add_document")
+        self.btn_open_document = QtWidgets.QPushButton(self.frame)
+        self.btn_open_document.setGeometry(QtCore.QRect(1090, 60, 131, 25))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.btn_open_document.setFont(font)
+        self.btn_open_document.setObjectName("btn_open_document")
+        self.check_file = QtWidgets.QPushButton(self.frame)
+        self.check_file.setGeometry(QtCore.QRect(1090, 100, 131, 51))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.check_file.setFont(font)
+        self.check_file.setObjectName("check_file")
+        self.formLayoutWidget_2 = QtWidgets.QWidget(self.frame)
+        self.formLayoutWidget_2.setGeometry(QtCore.QRect(550, 70, 202, 80))
+        self.formLayoutWidget_2.setObjectName("formLayoutWidget_2")
+        self.formLayout_3 = QtWidgets.QFormLayout(self.formLayoutWidget_2)
+        self.formLayout_3.setContentsMargins(0, 0, 0, 0)
+        self.formLayout_3.setObjectName("formLayout_3")
+        self.label_12 = QtWidgets.QLabel(self.formLayoutWidget_2)
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.label_12.setFont(font)
+        self.label_12.setObjectName("label_12")
+        self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_12)
+        self.prof_id_adis = QtWidgets.QLineEdit(self.formLayoutWidget_2)
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.prof_id_adis.setFont(font)
+        self.prof_id_adis.setObjectName("prof_id_adis")
+        self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.prof_id_adis)
+        self.label_13 = QtWidgets.QLabel(self.formLayoutWidget_2)
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.label_13.setFont(font)
+        self.label_13.setObjectName("label_13")
+        self.formLayout_3.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_13)
+        self.apparat_id_adis = QtWidgets.QLineEdit(self.formLayoutWidget_2)
+        self.apparat_id_adis.setObjectName("apparat_id_adis")
+        self.formLayout_3.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.apparat_id_adis)
+        self.check_send_mail = QtWidgets.QCheckBox(self.frame)
+        self.check_send_mail.setGeometry(QtCore.QRect(450, 120, 91, 17))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        font.setBold(False)
+        font.setWeight(50)
+        self.check_send_mail.setFont(font)
+        self.check_send_mail.setObjectName("check_send_mail")
+        self.frame_3 = QtWidgets.QFrame(self.frame)
+        self.frame_3.setGeometry(QtCore.QRect(510, 0, 241, 61))
+        self.frame_3.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
+        self.frame_3.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
+        self.frame_3.setObjectName("frame_3")
+        self.gridLayoutWidget_5 = QtWidgets.QWidget(self.frame_3)
+        self.gridLayoutWidget_5.setGeometry(QtCore.QRect(0, 0, 241, 61))
+        self.gridLayoutWidget_5.setObjectName("gridLayoutWidget_5")
+        self.gridLayout_6 = QtWidgets.QGridLayout(self.gridLayoutWidget_5)
+        self.gridLayout_6.setContentsMargins(0, 0, 0, 0)
+        self.gridLayout_6.setObjectName("gridLayout_6")
+        self.app_fach = QtWidgets.QComboBox(self.gridLayoutWidget_5)
+        self.app_fach.setObjectName("app_fach")
+        self.gridLayout_6.addWidget(self.app_fach, 0, 0, 1, 1)
+        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
+        self.gridLayout_6.addItem(spacerItem2, 0, 1, 1, 1)
+        self._mand.raise_()
+        self.drpdwn_prof_title.raise_()
+        self.label_5.raise_()
+        self.sem_winter.raise_()
+        self.label_4.raise_()
+        self.drpdwn_app_nr.raise_()
+        self.sem_sommer.raise_()
+        self.label_3.raise_()
+        self.label_6.raise_()
+        self.sem_year.raise_()
+        self.label_2.raise_()
+        self.btn_apparat_save.raise_()
+        self.btn_apparat_apply.raise_()
+        self.check_eternal_app.raise_()
+        self.label_8.raise_()
+        self.label_9.raise_()
+        self.label_10.raise_()
+        self.mail_mand.raise_()
+        self.telnr_mand.raise_()
+        self.profname_mand.raise_()
+        self.appname_mand.raise_()
+        self.fach_mand.raise_()
+        self.btn_add_document.raise_()
+        self.btn_open_document.raise_()
+        self.app_name.raise_()
+        self.prof_tel_nr.raise_()
+        self.drpdwn_prof_name.raise_()
+        self.prof_mail.raise_()
+        self.check_file.raise_()
+        self.formLayoutWidget_2.raise_()
+        self.check_send_mail.raise_()
+        self.frame_3.raise_()
+        self.frame.raise_()
+        self.dokument_list.raise_()
+        self.gridLayout_2.addWidget(self.app_group_box, 1, 0, 1, 1)
+        self.tableWidget_apparat_media = QtWidgets.QTableWidget(self.gridLayoutWidget_2)
+        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.tableWidget_apparat_media.sizePolicy().hasHeightForWidth())
+        self.tableWidget_apparat_media.setSizePolicy(sizePolicy)
+        self.tableWidget_apparat_media.setMinimumSize(QtCore.QSize(1259, 0))
+        self.tableWidget_apparat_media.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.tableWidget_apparat_media.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.CustomContextMenu)
+        self.tableWidget_apparat_media.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents)
+        self.tableWidget_apparat_media.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers)
+        self.tableWidget_apparat_media.setAlternatingRowColors(True)
+        self.tableWidget_apparat_media.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows)
+        self.tableWidget_apparat_media.setObjectName("tableWidget_apparat_media")
+        self.tableWidget_apparat_media.setColumnCount(7)
+        self.tableWidget_apparat_media.setRowCount(0)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget_apparat_media.setHorizontalHeaderItem(0, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget_apparat_media.setHorizontalHeaderItem(1, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget_apparat_media.setHorizontalHeaderItem(2, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget_apparat_media.setHorizontalHeaderItem(3, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget_apparat_media.setHorizontalHeaderItem(4, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget_apparat_media.setHorizontalHeaderItem(5, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget_apparat_media.setHorizontalHeaderItem(6, item)
+        self.tableWidget_apparat_media.horizontalHeader().setCascadingSectionResizes(True)
+        self.gridLayout_2.addWidget(self.tableWidget_apparat_media, 9, 0, 1, 1)
+        self.label = QtWidgets.QLabel(self.gridLayoutWidget_2)
+        font = QtGui.QFont()
+        font.setPointSize(11)
+        font.setBold(True)
+        font.setWeight(75)
+        self.label.setFont(font)
+        self.label.setObjectName("label")
+        self.gridLayout_2.addWidget(self.label, 2, 0, 1, 1)
+        self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
+        spacerItem3 = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Minimum)
+        self.horizontalLayout_5.addItem(spacerItem3)
+        self.chkbx_show_del_media = QtWidgets.QCheckBox(self.gridLayoutWidget_2)
+        self.chkbx_show_del_media.setObjectName("chkbx_show_del_media")
+        self.horizontalLayout_5.addWidget(self.chkbx_show_del_media)
+        spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Minimum)
+        self.horizontalLayout_5.addItem(spacerItem4)
+        self.btn_reserve = QtWidgets.QPushButton(self.gridLayoutWidget_2)
+        self.btn_reserve.setObjectName("btn_reserve")
+        self.horizontalLayout_5.addWidget(self.btn_reserve)
+        self.add_layout = QtWidgets.QHBoxLayout()
+        self.add_layout.setObjectName("add_layout")
+        self.label_info = QtWidgets.QLabel(self.gridLayoutWidget_2)
+        self.label_info.setObjectName("label_info")
+        self.add_layout.addWidget(self.label_info)
+        self.line_2 = QtWidgets.QFrame(self.gridLayoutWidget_2)
+        self.line_2.setFrameShape(QtWidgets.QFrame.Shape.VLine)
+        self.line_2.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
+        self.line_2.setObjectName("line_2")
+        self.add_layout.addWidget(self.line_2)
+        self.progress_label = QtWidgets.QLabel(self.gridLayoutWidget_2)
+        self.progress_label.setObjectName("progress_label")
+        self.add_layout.addWidget(self.progress_label)
+        self.horizontalLayout_5.addLayout(self.add_layout)
+        spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Minimum)
+        self.horizontalLayout_5.addItem(spacerItem5)
+        self.avail_layout = QtWidgets.QHBoxLayout()
+        self.avail_layout.setObjectName("avail_layout")
+        self.horizontalLayout_5.addLayout(self.avail_layout)
+        self.label_20 = QtWidgets.QLabel(self.gridLayoutWidget_2)
+        self.label_20.setObjectName("label_20")
+        self.horizontalLayout_5.addWidget(self.label_20)
+        self.line_3 = QtWidgets.QFrame(self.gridLayoutWidget_2)
+        self.line_3.setFrameShape(QtWidgets.QFrame.Shape.VLine)
+        self.line_3.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
+        self.line_3.setObjectName("line_3")
+        self.horizontalLayout_5.addWidget(self.line_3)
+        self.avail_status = QtWidgets.QLabel(self.gridLayoutWidget_2)
+        self.avail_status.setObjectName("avail_status")
+        self.horizontalLayout_5.addWidget(self.avail_status)
+        spacerItem6 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
+        self.horizontalLayout_5.addItem(spacerItem6)
+        self.gridLayout_2.addLayout(self.horizontalLayout_5, 4, 0, 1, 1)
+        self.add_medium = QtWidgets.QPushButton(self.tab)
+        self.add_medium.setGeometry(QtCore.QRect(0, 700, 121, 20))
+        self.add_medium.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.add_medium.setObjectName("add_medium")
+        self.tabWidget.addTab(self.tab, "")
+        self.tab_2 = QtWidgets.QWidget()
+        self.tab_2.setObjectName("tab_2")
+        self.verticalLayoutWidget_2 = QtWidgets.QWidget(self.tab_2)
+        self.verticalLayoutWidget_2.setGeometry(QtCore.QRect(0, 0, 1251, 721))
+        self.verticalLayoutWidget_2.setObjectName("verticalLayoutWidget_2")
+        self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_2)
+        self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
+        self.verticalLayout_3.setObjectName("verticalLayout_3")
+        self.tabWidget_2 = QtWidgets.QTabWidget(self.verticalLayoutWidget_2)
+        self.tabWidget_2.setMaximumSize(QtCore.QSize(16777215, 250))
+        self.tabWidget_2.setObjectName("tabWidget_2")
+        self.tab_3 = QtWidgets.QWidget()
+        self.tab_3.setObjectName("tab_3")
+        self.btn_search = QtWidgets.QPushButton(self.tab_3)
+        self.btn_search.setGeometry(QtCore.QRect(10, 180, 75, 23))
+        self.btn_search.setObjectName("btn_search")
+        self.gridLayoutWidget = QtWidgets.QWidget(self.tab_3)
+        self.gridLayoutWidget.setGeometry(QtCore.QRect(10, 10, 491, 161))
+        self.gridLayoutWidget.setObjectName("gridLayoutWidget")
+        self.gridLayout_3 = QtWidgets.QGridLayout(self.gridLayoutWidget)
+        self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
+        self.gridLayout_3.setObjectName("gridLayout_3")
+        self.label_7 = QtWidgets.QLabel(self.gridLayoutWidget)
+        self.label_7.setObjectName("label_7")
+        self.gridLayout_3.addWidget(self.label_7, 0, 0, 1, 1)
+        self.box_erstellsemester = QtWidgets.QComboBox(self.gridLayoutWidget)
+        self.box_erstellsemester.setEditable(True)
+        self.box_erstellsemester.setObjectName("box_erstellsemester")
+        self.gridLayout_3.addWidget(self.box_erstellsemester, 1, 3, 1, 1)
+        self.label_18 = QtWidgets.QLabel(self.gridLayoutWidget)
+        self.label_18.setObjectName("label_18")
+        self.gridLayout_3.addWidget(self.label_18, 2, 2, 1, 1)
+        self.label_17 = QtWidgets.QLabel(self.gridLayoutWidget)
+        self.label_17.setObjectName("label_17")
+        self.gridLayout_3.addWidget(self.label_17, 0, 2, 1, 1)
+        self.label_19 = QtWidgets.QLabel(self.gridLayoutWidget)
+        self.label_19.setObjectName("label_19")
+        self.gridLayout_3.addWidget(self.label_19, 1, 2, 1, 1)
+        self.box_dauerapp = QtWidgets.QComboBox(self.gridLayoutWidget)
+        self.box_dauerapp.setObjectName("box_dauerapp")
+        self.gridLayout_3.addWidget(self.box_dauerapp, 2, 3, 1, 1)
+        self.label_11 = QtWidgets.QLabel(self.gridLayoutWidget)
+        self.label_11.setObjectName("label_11")
+        self.gridLayout_3.addWidget(self.label_11, 1, 0, 1, 1)
+        self.label_16 = QtWidgets.QLabel(self.gridLayoutWidget)
+        self.label_16.setObjectName("label_16")
+        self.gridLayout_3.addWidget(self.label_16, 2, 0, 1, 1)
+        self.box_semester = QtWidgets.QComboBox(self.gridLayoutWidget)
+        self.box_semester.setEditable(True)
+        self.box_semester.setObjectName("box_semester")
+        self.gridLayout_3.addWidget(self.box_semester, 0, 3, 1, 1)
+        self.box_appnrs = QtWidgets.QComboBox(self.gridLayoutWidget)
+        self.box_appnrs.setEditable(True)
+        self.box_appnrs.setObjectName("box_appnrs")
+        self.gridLayout_3.addWidget(self.box_appnrs, 0, 1, 1, 1)
+        self.box_fach = QtWidgets.QComboBox(self.gridLayoutWidget)
+        self.box_fach.setEditable(True)
+        self.box_fach.setObjectName("box_fach")
+        self.gridLayout_3.addWidget(self.box_fach, 2, 1, 1, 1)
+        self.box_person = QtWidgets.QComboBox(self.gridLayoutWidget)
+        self.box_person.setEditable(True)
+        self.box_person.setObjectName("box_person")
+        self.gridLayout_3.addWidget(self.box_person, 1, 1, 1, 1)
+        spacerItem7 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
+        self.gridLayout_3.addItem(spacerItem7, 4, 0, 1, 1)
+        self.label_15 = QtWidgets.QLabel(self.gridLayoutWidget)
+        self.label_15.setObjectName("label_15")
+        self.gridLayout_3.addWidget(self.label_15, 3, 0, 1, 1)
+        self.check_deletable = QtWidgets.QCheckBox(self.gridLayoutWidget)
+        self.check_deletable.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus)
+        self.check_deletable.setText("")
+        self.check_deletable.setObjectName("check_deletable")
+        self.gridLayout_3.addWidget(self.check_deletable, 3, 1, 1, 1)
+        self.db_err_message = QtWidgets.QLabel(self.tab_3)
+        self.db_err_message.setGeometry(QtCore.QRect(100, 180, 401, 23))
+        self.db_err_message.setText("")
+        self.db_err_message.setObjectName("db_err_message")
+        self.tabWidget_2.addTab(self.tab_3, "")
+        self.tab_4 = QtWidgets.QWidget()
+        self.tab_4.setObjectName("tab_4")
+        self.formLayoutWidget = QtWidgets.QWidget(self.tab_4)
+        self.formLayoutWidget.setGeometry(QtCore.QRect(10, 10, 451, 151))
+        self.formLayoutWidget.setObjectName("formLayoutWidget")
+        self.formLayout_6 = QtWidgets.QFormLayout(self.formLayoutWidget)
+        self.formLayout_6.setContentsMargins(0, 0, 0, 0)
+        self.formLayout_6.setObjectName("formLayout_6")
+        self.label_25 = QtWidgets.QLabel(self.formLayoutWidget)
+        self.label_25.setObjectName("label_25")
+        self.formLayout_6.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_25)
+        self.book_search = QtWidgets.QPushButton(self.formLayoutWidget)
+        self.book_search.setObjectName("book_search")
+        self.formLayout_6.setWidget(3, QtWidgets.QFormLayout.ItemRole.LabelRole, self.book_search)
+        self.seach_by_signature = QtWidgets.QLineEdit(self.formLayoutWidget)
+        self.seach_by_signature.setClearButtonEnabled(True)
+        self.seach_by_signature.setObjectName("seach_by_signature")
+        self.formLayout_6.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.seach_by_signature)
+        self.label_26 = QtWidgets.QLabel(self.formLayoutWidget)
+        self.label_26.setObjectName("label_26")
+        self.formLayout_6.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_26)
+        self.search_by_title = QtWidgets.QLineEdit(self.formLayoutWidget)
+        self.search_by_title.setClearButtonEnabled(True)
+        self.search_by_title.setObjectName("search_by_title")
+        self.formLayout_6.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.search_by_title)
+        spacerItem8 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
+        self.formLayout_6.setItem(2, QtWidgets.QFormLayout.ItemRole.LabelRole, spacerItem8)
+        self.tabWidget_2.addTab(self.tab_4, "")
+        self.verticalLayout_3.addWidget(self.tabWidget_2)
+        self.stackedWidget_4 = QtWidgets.QStackedWidget(self.verticalLayoutWidget_2)
+        self.stackedWidget_4.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
+        self.stackedWidget_4.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
+        self.stackedWidget_4.setObjectName("stackedWidget_4")
+        self.stackedWidget_4Page1 = QtWidgets.QWidget()
+        self.stackedWidget_4Page1.setObjectName("stackedWidget_4Page1")
+        #set focus to page 1
+        self.stackedWidget_4.setCurrentIndex(0)
+        self.tabWidget_3 = QtWidgets.QTabWidget(self.stackedWidget_4Page1)
+        self.tabWidget_3.setGeometry(QtCore.QRect(780, 10, 441, 441))
+        self.tabWidget_3.setObjectName("tabWidget_3")
+        self.tab_6 = QtWidgets.QWidget()
+        self.tab_6.setObjectName("tab_6")
+        self.gridLayoutWidget_3 = QtWidgets.QWidget(self.tab_6)
+        self.gridLayoutWidget_3.setGeometry(QtCore.QRect(0, 0, 431, 411))
+        self.gridLayoutWidget_3.setObjectName("gridLayoutWidget_3")
+        self.gridLayout_4 = QtWidgets.QGridLayout(self.gridLayoutWidget_3)
+        self.gridLayout_4.setContentsMargins(0, 0, 0, 0)
+        self.gridLayout_4.setObjectName("gridLayout_4")
+        self.statistics_table = QtWidgets.QTableWidget(self.gridLayoutWidget_3)
+        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.statistics_table.sizePolicy().hasHeightForWidth())
+        self.statistics_table.setSizePolicy(sizePolicy)
+        self.statistics_table.setMaximumSize(QtCore.QSize(16777215, 16777215))
+        self.statistics_table.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.statistics_table.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers)
+        self.statistics_table.setAlternatingRowColors(True)
+        self.statistics_table.setObjectName("statistics_table")
+        self.statistics_table.setColumnCount(3)
+        self.statistics_table.setRowCount(0)
+        item = QtWidgets.QTableWidgetItem()
+        self.statistics_table.setHorizontalHeaderItem(0, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.statistics_table.setHorizontalHeaderItem(1, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.statistics_table.setHorizontalHeaderItem(2, item)
+        self.statistics_table.horizontalHeader().setCascadingSectionResizes(True)
+        self.statistics_table.horizontalHeader().setDefaultSectionSize(59)
+        self.statistics_table.horizontalHeader().setMinimumSectionSize(24)
+        self.statistics_table.horizontalHeader().setSortIndicatorShown(True)
+        self.statistics_table.horizontalHeader().setStretchLastSection(False)
+        self.gridLayout_4.addWidget(self.statistics_table, 0, 0, 1, 1)
+        self.tabWidget_3.addTab(self.tab_6, "")
+        self.tab_7 = QtWidgets.QWidget()
+        self.tab_7.setObjectName("tab_7")
+        self.tabWidget_3.addTab(self.tab_7, "")
+        self.widget = QtWidgets.QWidget(self.stackedWidget_4Page1)
+        self.widget.setGeometry(QtCore.QRect(10, 10, 761, 441))
+        self.widget.setObjectName("widget")
+        self.horizontalLayoutWidget_3 = QtWidgets.QWidget(self.widget)
+        self.horizontalLayoutWidget_3.setGeometry(QtCore.QRect(0, 0, 761, 51))
+        self.horizontalLayoutWidget_3.setObjectName("horizontalLayoutWidget_3")
+        self.horizontalLayout_7 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_3)
+        self.horizontalLayout_7.setContentsMargins(0, 0, 0, 0)
+        self.horizontalLayout_7.setObjectName("horizontalLayout_7")
+        self.btn_del_select_apparats = QtWidgets.QPushButton(self.horizontalLayoutWidget_3)
+        self.btn_del_select_apparats.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus)
+        self.btn_del_select_apparats.setObjectName("btn_del_select_apparats")
+        self.horizontalLayout_7.addWidget(self.btn_del_select_apparats)
+        spacerItem9 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
+        self.horizontalLayout_7.addItem(spacerItem9)
+        self.table = QtWidgets.QWidget(self.widget)
+        self.table.setGeometry(QtCore.QRect(0, 50, 761, 391))
+        self.table.setObjectName("table")
+        self.tableWidget = QtWidgets.QTableWidget(self.table)
+        self.tableWidget.setGeometry(QtCore.QRect(0, 0, 761, 391))
+        self.tableWidget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers)
+        self.tableWidget.setObjectName("tableWidget")
+        self.tableWidget.setColumnCount(5)
+        self.tableWidget.setRowCount(0)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget.setHorizontalHeaderItem(0, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget.setHorizontalHeaderItem(1, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget.setHorizontalHeaderItem(2, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget.setHorizontalHeaderItem(3, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.tableWidget.setHorizontalHeaderItem(4, item)
+        self.stackedWidget_4.addWidget(self.stackedWidget_4Page1)
+        self.page = QtWidgets.QWidget()
+        self.page.setObjectName("page")
+        self.book_search_result = QtWidgets.QTableWidget(self.page)
+        self.book_search_result.setGeometry(QtCore.QRect(10, 20, 1081, 421))
+        self.book_search_result.setFrameShadow(QtWidgets.QFrame.Shadow.Plain)
+        self.book_search_result.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers)
+        self.book_search_result.setAlternatingRowColors(True)
+        self.book_search_result.setObjectName("book_search_result")
+        self.book_search_result.setColumnCount(3)
+        self.book_search_result.setRowCount(0)
+        item = QtWidgets.QTableWidgetItem()
+        self.book_search_result.setHorizontalHeaderItem(0, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.book_search_result.setHorizontalHeaderItem(1, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.book_search_result.setHorizontalHeaderItem(2, item)
+        self.book_search_result.horizontalHeader().setCascadingSectionResizes(True)
+        self.book_search_result.horizontalHeader().setStretchLastSection(True)
+        self.stackedWidget_4.addWidget(self.page)
+        self.verticalLayout_3.addWidget(self.stackedWidget_4)
+        self.tabWidget.addTab(self.tab_2, "")
+        self.tab_5 = QtWidgets.QWidget()
+        self.tab_5.setObjectName("tab_5")
+        self.label_21 = QtWidgets.QLabel(self.tab_5)
+        self.label_21.setGeometry(QtCore.QRect(10, 30, 47, 22))
+        self.label_21.setObjectName("label_21")
+        self.select_action_box = QtWidgets.QComboBox(self.tab_5)
+        self.select_action_box.setGeometry(QtCore.QRect(70, 30, 181, 22))
+        self.select_action_box.setObjectName("select_action_box")
+        self.select_action_box.addItem("")
+        self.select_action_box.addItem("")
+        self.select_action_box.addItem("")
+        self.select_action_box.addItem("")
+        self.user_create_frame = QtWidgets.QFrame(self.tab_5)
+        self.user_create_frame.setGeometry(QtCore.QRect(10, 60, 591, 141))
+        self.user_create_frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
+        self.user_create_frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
+        self.user_create_frame.setObjectName("user_create_frame")
+        self.gridLayoutWidget_4 = QtWidgets.QWidget(self.user_create_frame)
+        self.gridLayoutWidget_4.setGeometry(QtCore.QRect(0, 0, 581, 141))
+        self.gridLayoutWidget_4.setObjectName("gridLayoutWidget_4")
+        self.gridLayout_5 = QtWidgets.QGridLayout(self.gridLayoutWidget_4)
+        self.gridLayout_5.setContentsMargins(0, 0, 0, 0)
+        self.gridLayout_5.setObjectName("gridLayout_5")
+        self.label_22 = QtWidgets.QLabel(self.gridLayoutWidget_4)
+        self.label_22.setObjectName("label_22")
+        self.gridLayout_5.addWidget(self.label_22, 0, 0, 1, 1)
+        self.user_create_frame_username = QtWidgets.QLineEdit(self.gridLayoutWidget_4)
+        self.user_create_frame_username.setMaximumSize(QtCore.QSize(150, 16777215))
+        self.user_create_frame_username.setObjectName("user_create_frame_username")
+        self.gridLayout_5.addWidget(self.user_create_frame_username, 0, 1, 1, 1)
+        self.label_24 = QtWidgets.QLabel(self.gridLayoutWidget_4)
+        self.label_24.setObjectName("label_24")
+        self.gridLayout_5.addWidget(self.label_24, 0, 2, 1, 1)
+        self.label_23 = QtWidgets.QLabel(self.gridLayoutWidget_4)
+        self.label_23.setObjectName("label_23")
+        self.gridLayout_5.addWidget(self.label_23, 1, 0, 1, 1)
+        spacerItem10 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
+        self.gridLayout_5.addItem(spacerItem10, 0, 4, 1, 1)
+        self.user_frame_userrole = QtWidgets.QComboBox(self.gridLayoutWidget_4)
+        self.user_frame_userrole.setObjectName("user_frame_userrole")
+        self.gridLayout_5.addWidget(self.user_frame_userrole, 0, 3, 1, 1)
+        self.user_create_frame_password = QtWidgets.QLineEdit(self.gridLayoutWidget_4)
+        self.user_create_frame_password.setMaximumSize(QtCore.QSize(150, 16777215))
+        self.user_create_frame_password.setObjectName("user_create_frame_password")
+        self.gridLayout_5.addWidget(self.user_create_frame_password, 1, 1, 1, 1)
+        self.user_frame_addUser = QtWidgets.QPushButton(self.gridLayoutWidget_4)
+        self.user_frame_addUser.setObjectName("user_frame_addUser")
+        self.gridLayout_5.addWidget(self.user_frame_addUser, 1, 3, 1, 1)
+        self.user_frame_err_message = QtWidgets.QLabel(self.gridLayoutWidget_4)
+        self.user_frame_err_message.setText("")
+        self.user_frame_err_message.setObjectName("user_frame_err_message")
+        self.gridLayout_5.addWidget(self.user_frame_err_message, 1, 4, 1, 1)
+        self.user_delete_frame = QtWidgets.QFrame(self.tab_5)
+        self.user_delete_frame.setGeometry(QtCore.QRect(10, 60, 591, 141))
+        self.user_delete_frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
+        self.user_delete_frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
+        self.user_delete_frame.setObjectName("user_delete_frame")
+        self.gridLayoutWidget_7 = QtWidgets.QWidget(self.user_delete_frame)
+        self.gridLayoutWidget_7.setGeometry(QtCore.QRect(0, 0, 581, 141))
+        self.gridLayoutWidget_7.setObjectName("gridLayoutWidget_7")
+        self.gridLayout_8 = QtWidgets.QGridLayout(self.gridLayoutWidget_7)
+        self.gridLayout_8.setContentsMargins(0, 0, 0, 0)
+        self.gridLayout_8.setObjectName("gridLayout_8")
+        self.horizontalLayout_8 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_8.setObjectName("horizontalLayout_8")
+        spacerItem11 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
+        self.horizontalLayout_8.addItem(spacerItem11)
+        self.pushButton = QtWidgets.QPushButton(self.gridLayoutWidget_7)
+        self.pushButton.setObjectName("pushButton")
+        self.horizontalLayout_8.addWidget(self.pushButton)
+        spacerItem12 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
+        self.horizontalLayout_8.addItem(spacerItem12)
+        self.gridLayout_8.addLayout(self.horizontalLayout_8, 1, 1, 1, 1)
+        self.label_34 = QtWidgets.QLabel(self.gridLayoutWidget_7)
+        self.label_34.setObjectName("label_34")
+        self.gridLayout_8.addWidget(self.label_34, 0, 0, 1, 1)
+        self.user_delete_frame_user_select = QtWidgets.QComboBox(self.gridLayoutWidget_7)
+        self.user_delete_frame_user_select.setObjectName("user_delete_frame_user_select")
+        self.gridLayout_8.addWidget(self.user_delete_frame_user_select, 0, 1, 1, 1)
+        self.user_delete_confirm = QtWidgets.QRadioButton(self.gridLayoutWidget_7)
+        self.user_delete_confirm.setLayoutDirection(QtCore.Qt.LayoutDirection.RightToLeft)
+        self.user_delete_confirm.setObjectName("user_delete_confirm")
+        self.gridLayout_8.addWidget(self.user_delete_confirm, 1, 0, 1, 1)
+        spacerItem13 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
+        self.gridLayout_8.addItem(spacerItem13, 0, 2, 1, 1)
+        self.user_delete_err_message = QtWidgets.QLabel(self.gridLayoutWidget_7)
+        self.user_delete_err_message.setText("")
+        self.user_delete_err_message.setObjectName("user_delete_err_message")
+        self.gridLayout_8.addWidget(self.user_delete_err_message, 1, 2, 1, 1)
+        self.user_edit_frame = QtWidgets.QFrame(self.tab_5)
+        self.user_edit_frame.setGeometry(QtCore.QRect(10, 60, 591, 141))
+        self.user_edit_frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
+        self.user_edit_frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
+        self.user_edit_frame.setObjectName("user_edit_frame")
+        self.gridLayoutWidget_10 = QtWidgets.QWidget(self.user_edit_frame)
+        self.gridLayoutWidget_10.setGeometry(QtCore.QRect(0, 0, 581, 141))
+        self.gridLayoutWidget_10.setObjectName("gridLayoutWidget_10")
+        self.gridLayout_11 = QtWidgets.QGridLayout(self.gridLayoutWidget_10)
+        self.gridLayout_11.setContentsMargins(0, 0, 0, 0)
+        self.gridLayout_11.setObjectName("gridLayout_11")
+        self.user_edit_frame_role_select = QtWidgets.QComboBox(self.gridLayoutWidget_10)
+        self.user_edit_frame_role_select.setObjectName("user_edit_frame_role_select")
+        self.gridLayout_11.addWidget(self.user_edit_frame_role_select, 0, 3, 1, 1)
+        self.label_38 = QtWidgets.QLabel(self.gridLayoutWidget_10)
+        self.label_38.setObjectName("label_38")
+        self.gridLayout_11.addWidget(self.label_38, 0, 0, 1, 1)
+        self.user_edit_frame_user_select = QtWidgets.QComboBox(self.gridLayoutWidget_10)
+        self.user_edit_frame_user_select.setMaximumSize(QtCore.QSize(150, 16777215))
+        self.user_edit_frame_user_select.setObjectName("user_edit_frame_user_select")
+        self.gridLayout_11.addWidget(self.user_edit_frame_user_select, 0, 1, 1, 1)
+        self.update_user = QtWidgets.QPushButton(self.gridLayoutWidget_10)
+        self.update_user.setObjectName("update_user")
+        self.gridLayout_11.addWidget(self.update_user, 1, 3, 1, 1)
+        self.label_40 = QtWidgets.QLabel(self.gridLayoutWidget_10)
+        self.label_40.setObjectName("label_40")
+        self.gridLayout_11.addWidget(self.label_40, 0, 2, 1, 1)
+        self.label_39 = QtWidgets.QLabel(self.gridLayoutWidget_10)
+        self.label_39.setObjectName("label_39")
+        self.gridLayout_11.addWidget(self.label_39, 1, 0, 1, 1)
+        self.user_edit_frame_new_password = QtWidgets.QLineEdit(self.gridLayoutWidget_10)
+        self.user_edit_frame_new_password.setMaximumSize(QtCore.QSize(150, 16777215))
+        self.user_edit_frame_new_password.setObjectName("user_edit_frame_new_password")
+        self.gridLayout_11.addWidget(self.user_edit_frame_new_password, 1, 1, 1, 1)
+        spacerItem14 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
+        self.gridLayout_11.addItem(spacerItem14, 0, 4, 1, 1)
+        self.edit_faculty_member = QtWidgets.QFrame(self.tab_5)
+        self.edit_faculty_member.setGeometry(QtCore.QRect(10, 60, 1051, 191))
+        self.edit_faculty_member.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
+        self.edit_faculty_member.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
+        self.edit_faculty_member.setObjectName("edit_faculty_member")
+        self.gridLayoutWidget_11 = QtWidgets.QWidget(self.edit_faculty_member)
+        self.gridLayoutWidget_11.setGeometry(QtCore.QRect(0, 0, 751, 223))
+        self.gridLayoutWidget_11.setObjectName("gridLayoutWidget_11")
+        self.gridLayout_12 = QtWidgets.QGridLayout(self.gridLayoutWidget_11)
+        self.gridLayout_12.setContentsMargins(0, 0, 0, 0)
+        self.gridLayout_12.setObjectName("gridLayout_12")
+        self.formLayout_2 = QtWidgets.QFormLayout()
+        self.formLayout_2.setObjectName("formLayout_2")
+        self.label_43 = QtWidgets.QLabel(self.gridLayoutWidget_11)
+        self.label_43.setObjectName("label_43")
+        self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_43)
+        self.edit_faculty_member_new_title = QtWidgets.QComboBox(self.gridLayoutWidget_11)
+        self.edit_faculty_member_new_title.setObjectName("edit_faculty_member_new_title")
+        self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.edit_faculty_member_new_title)
+        self.label_44 = QtWidgets.QLabel(self.gridLayoutWidget_11)
+        self.label_44.setObjectName("label_44")
+        self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_44)
+        self.edit_faculty_member_new_surname = QtWidgets.QLineEdit(self.gridLayoutWidget_11)
+        self.edit_faculty_member_new_surname.setObjectName("edit_faculty_member_new_surname")
+        self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.edit_faculty_member_new_surname)
+        self.label_45 = QtWidgets.QLabel(self.gridLayoutWidget_11)
+        self.label_45.setObjectName("label_45")
+        self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_45)
+        self.user_faculty_member_new_name = QtWidgets.QLineEdit(self.gridLayoutWidget_11)
+        self.user_faculty_member_new_name.setObjectName("user_faculty_member_new_name")
+        self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.ItemRole.FieldRole, self.user_faculty_member_new_name)
+        self.gridLayout_12.addLayout(self.formLayout_2, 2, 2, 1, 1)
+        self.formLayout_4 = QtWidgets.QFormLayout()
+        self.formLayout_4.setObjectName("formLayout_4")
+        self.edit_faculty_member_title = QtWidgets.QLineEdit(self.gridLayoutWidget_11)
+        self.edit_faculty_member_title.setFocusPolicy(QtCore.Qt.FocusPolicy.TabFocus)
+        self.edit_faculty_member_title.setReadOnly(True)
+        self.edit_faculty_member_title.setObjectName("edit_faculty_member_title")
+        self.formLayout_4.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.edit_faculty_member_title)
+        self.edit_faculty_member_select_member = QtWidgets.QComboBox(self.gridLayoutWidget_11)
+        self.edit_faculty_member_select_member.setObjectName("edit_faculty_member_select_member")
+        self.formLayout_4.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.edit_faculty_member_select_member)
+        self.label_46 = QtWidgets.QLabel(self.gridLayoutWidget_11)
+        self.label_46.setObjectName("label_46")
+        self.formLayout_4.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_46)
+        self.faculty_member_old_telnr = QtWidgets.QLineEdit(self.gridLayoutWidget_11)
+        self.faculty_member_old_telnr.setFocusPolicy(QtCore.Qt.FocusPolicy.ClickFocus)
+        self.faculty_member_old_telnr.setReadOnly(True)
+        self.faculty_member_old_telnr.setObjectName("faculty_member_old_telnr")
+        self.formLayout_4.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.faculty_member_old_telnr)
+        self.label_49 = QtWidgets.QLabel(self.gridLayoutWidget_11)
+        self.label_49.setObjectName("label_49")
+        self.formLayout_4.setWidget(2, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_49)
+        self.faculty_member_oldmail = QtWidgets.QLineEdit(self.gridLayoutWidget_11)
+        self.faculty_member_oldmail.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.faculty_member_oldmail.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhNone)
+        self.faculty_member_oldmail.setReadOnly(True)
+        self.faculty_member_oldmail.setObjectName("faculty_member_oldmail")
+        self.formLayout_4.setWidget(2, QtWidgets.QFormLayout.ItemRole.FieldRole, self.faculty_member_oldmail)
+        self.gridLayout_12.addLayout(self.formLayout_4, 0, 2, 1, 1)
+        self.formLayout_5 = QtWidgets.QFormLayout()
+        self.formLayout_5.setObjectName("formLayout_5")
+        self.label_47 = QtWidgets.QLabel(self.gridLayoutWidget_11)
+        self.label_47.setObjectName("label_47")
+        self.formLayout_5.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_47)
+        self.label_48 = QtWidgets.QLabel(self.gridLayoutWidget_11)
+        self.label_48.setObjectName("label_48")
+        self.formLayout_5.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_48)
+        self.lineEdit = QtWidgets.QLineEdit(self.gridLayoutWidget_11)
+        self.lineEdit.setObjectName("lineEdit")
+        self.formLayout_5.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.lineEdit)
+        self.lineEdit_5 = QtWidgets.QLineEdit(self.gridLayoutWidget_11)
+        self.lineEdit_5.setObjectName("lineEdit_5")
+        self.formLayout_5.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.lineEdit_5)
+        self.gridLayout_12.addLayout(self.formLayout_5, 2, 4, 1, 1)
+        self.label_41 = QtWidgets.QLabel(self.gridLayoutWidget_11)
+        self.label_41.setObjectName("label_41")
+        self.gridLayout_12.addWidget(self.label_41, 0, 0, 1, 1)
+        self.update_faculty_member = QtWidgets.QPushButton(self.gridLayoutWidget_11)
+        self.update_faculty_member.setObjectName("update_faculty_member")
+        self.gridLayout_12.addWidget(self.update_faculty_member, 3, 4, 1, 1)
+        self.label_42 = QtWidgets.QLabel(self.gridLayoutWidget_11)
+        self.label_42.setObjectName("label_42")
+        self.gridLayout_12.addWidget(self.label_42, 2, 0, 1, 1)
+        self.tabWidget.addTab(self.tab_5, "")
+        self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1)
+        self.horizontalLayout.addLayout(self.gridLayout)
+        self.verticalLayout.addLayout(self.horizontalLayout)
+        self.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
+        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(1280, 360, 311, 391))
+        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
+        self.horizontalLayout_6 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
+        self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0)
+        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
+        self.frame_creation_progress = QtWidgets.QFrame(self.horizontalLayoutWidget)
+        self.frame_creation_progress.setObjectName("frame_creation_progress")
+        self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.frame_creation_progress)
+        self.verticalLayout_4.setSpacing(6)
+        self.verticalLayout_4.setObjectName("verticalLayout_4")
+        self.groupBox_2 = QtWidgets.QGroupBox(self.frame_creation_progress)
+        self.groupBox_2.setEnabled(True)
+        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.groupBox_2.sizePolicy().hasHeightForWidth())
+        self.groupBox_2.setSizePolicy(sizePolicy)
+        self.groupBox_2.setObjectName("groupBox_2")
+        self.appdata_check = QtWidgets.QCheckBox(self.groupBox_2)
+        self.appdata_check.setGeometry(QtCore.QRect(20, 30, 241, 41))
+        font = QtGui.QFont()
+        font.setPointSize(8)
+        font.setBold(False)
+        font.setWeight(50)
+        self.appdata_check.setFont(font)
+        self.appdata_check.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.appdata_check.setObjectName("appdata_check")
+        self.media_check = QtWidgets.QCheckBox(self.groupBox_2)
+        self.media_check.setGeometry(QtCore.QRect(20, 70, 241, 41))
+        font = QtGui.QFont()
+        font.setPointSize(8)
+        font.setBold(False)
+        font.setWeight(50)
+        self.media_check.setFont(font)
+        self.media_check.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.media_check.setObjectName("media_check")
+        self.ids_check = QtWidgets.QCheckBox(self.groupBox_2)
+        self.ids_check.setGeometry(QtCore.QRect(20, 140, 241, 41))
+        font = QtGui.QFont()
+        font.setPointSize(8)
+        font.setBold(False)
+        font.setWeight(50)
+        self.ids_check.setFont(font)
+        self.ids_check.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.ids_check.setObjectName("ids_check")
+        self.verticalLayout_4.addWidget(self.groupBox_2)
+        self.groupBox = QtWidgets.QGroupBox(self.frame_creation_progress)
+        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth())
+        self.groupBox.setSizePolicy(sizePolicy)
+        self.groupBox.setObjectName("groupBox")
+        self.media_checked = QtWidgets.QCheckBox(self.groupBox)
+        self.media_checked.setGeometry(QtCore.QRect(20, 30, 241, 41))
+        font = QtGui.QFont()
+        font.setPointSize(8)
+        font.setBold(False)
+        font.setItalic(False)
+        font.setUnderline(False)
+        font.setWeight(50)
+        font.setKerning(True)
+        font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault)
+        self.media_checked.setFont(font)
+        self.media_checked.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.media_checked.setObjectName("media_checked")
+        self.media_edited_check = QtWidgets.QCheckBox(self.groupBox)
+        self.media_edited_check.setGeometry(QtCore.QRect(20, 70, 241, 41))
+        font = QtGui.QFont()
+        font.setPointSize(8)
+        font.setBold(False)
+        font.setItalic(False)
+        font.setUnderline(False)
+        font.setWeight(50)
+        font.setKerning(True)
+        font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault)
+        self.media_edited_check.setFont(font)
+        self.media_edited_check.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.media_edited_check.setObjectName("media_edited_check")
+        self.app_created = QtWidgets.QCheckBox(self.groupBox)
+        self.app_created.setGeometry(QtCore.QRect(20, 110, 161, 41))
+        font = QtGui.QFont()
+        font.setPointSize(8)
+        font.setBold(False)
+        font.setItalic(False)
+        font.setUnderline(False)
+        font.setWeight(50)
+        font.setKerning(True)
+        font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault)
+        self.app_created.setFont(font)
+        self.app_created.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.app_created.setObjectName("app_created")
+        self.btn_copy_adis_command = QtWidgets.QPushButton(self.groupBox)
+        self.btn_copy_adis_command.setGeometry(QtCore.QRect(170, 120, 101, 23))
+        font = QtGui.QFont()
+        font.setPointSize(8)
+        font.setBold(False)
+        font.setItalic(False)
+        font.setUnderline(False)
+        font.setWeight(50)
+        font.setKerning(True)
+        font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault)
+        self.btn_copy_adis_command.setFont(font)
+        self.btn_copy_adis_command.setStatusTip("")
+        self.btn_copy_adis_command.setWhatsThis("")
+        self.btn_copy_adis_command.setAccessibleDescription("")
+        self.btn_copy_adis_command.setAutoFillBackground(False)
+        icon = QtGui.QIcon()
+        icon.addPixmap(QtGui.QPixmap("c:\\Users\\aky547\\GitHub\\Semesterapparate-refactor\\src\\ui\\../../../.designer/backup/icons/information.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
+        self.btn_copy_adis_command.setIcon(icon)
+        self.btn_copy_adis_command.setCheckable(False)
+        self.btn_copy_adis_command.setChecked(False)
+        self.btn_copy_adis_command.setAutoDefault(False)
+        self.btn_copy_adis_command.setObjectName("btn_copy_adis_command")
+        self.verticalLayout_4.addWidget(self.groupBox)
+        self.horizontalLayout_6.addWidget(self.frame_creation_progress)
+        self.frame_2 = QtWidgets.QFrame(self.centralwidget)
+        self.frame_2.setGeometry(QtCore.QRect(1280, 10, 301, 341))
+        self.frame_2.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
+        self.frame_2.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
+        self.frame_2.setObjectName("frame_2")
+        self.calendarWidget = QtWidgets.QCalendarWidget(self.frame_2)
+        self.calendarWidget.setGeometry(QtCore.QRect(0, 0, 291, 191))
+        self.calendarWidget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.calendarWidget.setGridVisible(True)
+        self.calendarWidget.setVerticalHeaderFormat(QtWidgets.QCalendarWidget.VerticalHeaderFormat.NoVerticalHeader)
+        self.calendarWidget.setObjectName("calendarWidget")
+        self.message_frame = QtWidgets.QFrame(self.frame_2)
+        self.message_frame.setGeometry(QtCore.QRect(0, 210, 301, 121))
+        self.message_frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
+        self.message_frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
+        self.message_frame.setObjectName("message_frame")
+        self.label_14 = QtWidgets.QLabel(self.message_frame)
+        self.label_14.setGeometry(QtCore.QRect(10, 10, 47, 20))
+        self.label_14.setObjectName("label_14")
+        self.line_app_info = QtWidgets.QLineEdit(self.message_frame)
+        self.line_app_info.setEnabled(True)
+        self.line_app_info.setGeometry(QtCore.QRect(60, 10, 31, 20))
+        self.line_app_info.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.line_app_info.setObjectName("line_app_info")
+        self.message_box = QtWidgets.QTextEdit(self.message_frame)
+        self.message_box.setGeometry(QtCore.QRect(10, 40, 281, 71))
+        self.message_box.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.message_box.setObjectName("message_box")
+        self.btn_delete_message = QtWidgets.QPushButton(self.message_frame)
+        self.btn_delete_message.setGeometry(QtCore.QRect(130, 10, 75, 23))
+        self.btn_delete_message.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
+        self.btn_delete_message.setObjectName("btn_delete_message")
+        self.spin_select_message = QtWidgets.QSpinBox(self.message_frame)
+        self.spin_select_message.setGeometry(QtCore.QRect(210, 10, 74, 22))
+        self.spin_select_message.setMinimum(1)
+        self.spin_select_message.setObjectName("spin_select_message")
+        self.label_total_day_messages = QtWidgets.QLabel(self.message_frame)
+        self.label_total_day_messages.setGeometry(QtCore.QRect(260, 10, 21, 22))
+        self.label_total_day_messages.setObjectName("label_total_day_messages")
+        MainWindow.setCentralWidget(self.centralwidget)
+        self.menubar = QtWidgets.QMenuBar(MainWindow)
+        self.menubar.setGeometry(QtCore.QRect(0, 0, 1593, 21))
+        self.menubar.setObjectName("menubar")
+        self.menuDatei = QtWidgets.QMenu(self.menubar)
+        self.menuDatei.setObjectName("menuDatei")
+        self.menuEinstellungen = QtWidgets.QMenu(self.menubar)
+        self.menuEinstellungen.setObjectName("menuEinstellungen")
+        MainWindow.setMenuBar(self.menubar)
+        self.statusbar = QtWidgets.QStatusBar(MainWindow)
+        self.statusbar.setObjectName("statusbar")
+        MainWindow.setStatusBar(self.statusbar)
+        self.actionBeenden = QtGui.QAction(MainWindow)
+        self.actionBeenden.setShortcutVisibleInContextMenu(True)
+        self.actionBeenden.setObjectName("actionBeenden")
+        self.actionEinstellungen = QtGui.QAction(MainWindow)
+        self.actionEinstellungen.setShortcutVisibleInContextMenu(True)
+        self.actionEinstellungen.setObjectName("actionEinstellungen")
+        self.menuDatei.addAction(self.actionBeenden)
+        self.menuEinstellungen.addAction(self.actionEinstellungen)
+        self.menubar.addAction(self.menuDatei.menuAction())
+        self.menubar.addAction(self.menuEinstellungen.menuAction())
+
+        self.retranslateUi(MainWindow)
+        self.tabWidget.setCurrentIndex(0)
+        self.tabWidget_2.setCurrentIndex(0)
+        self.stackedWidget_4.setCurrentIndex(1)
+        self.tabWidget_3.setCurrentIndex(1)
+        QtCore.QMetaObject.connectSlotsByName(MainWindow)
+        MainWindow.setTabOrder(self.drpdwn_app_nr, self.drpdwn_prof_title)
+        MainWindow.setTabOrder(self.drpdwn_prof_title, self.drpdwn_prof_name)
+        MainWindow.setTabOrder(self.drpdwn_prof_name, self.prof_mail)
+        MainWindow.setTabOrder(self.prof_mail, self.prof_tel_nr)
+        MainWindow.setTabOrder(self.prof_tel_nr, self.app_name)
+        MainWindow.setTabOrder(self.app_name, self.sem_year)
+        MainWindow.setTabOrder(self.sem_year, self.check_eternal_app)
+        MainWindow.setTabOrder(self.check_eternal_app, self.btn_add_document)
+        MainWindow.setTabOrder(self.btn_add_document, self.btn_open_document)
+        MainWindow.setTabOrder(self.btn_open_document, self.check_file)
+        MainWindow.setTabOrder(self.check_file, self.btn_apparat_save)
+        MainWindow.setTabOrder(self.btn_apparat_save, self.btn_apparat_apply)
+        MainWindow.setTabOrder(self.btn_apparat_apply, self.check_send_mail)
+        MainWindow.setTabOrder(self.check_send_mail, self.chkbx_show_del_media)
+        MainWindow.setTabOrder(self.chkbx_show_del_media, self.btn_reserve)
+        MainWindow.setTabOrder(self.btn_reserve, self.prof_id_adis)
+        MainWindow.setTabOrder(self.prof_id_adis, self.apparat_id_adis)
+        MainWindow.setTabOrder(self.apparat_id_adis, self.tabWidget_2)
+        MainWindow.setTabOrder(self.tabWidget_2, self.btn_del_select_apparats)
+        MainWindow.setTabOrder(self.btn_del_select_apparats, self.tabWidget_3)
+        MainWindow.setTabOrder(self.tabWidget_3, self.select_action_box)
+        MainWindow.setTabOrder(self.select_action_box, self.user_create_frame_username)
+        MainWindow.setTabOrder(self.user_create_frame_username, self.user_frame_userrole)
+        MainWindow.setTabOrder(self.user_frame_userrole, self.user_create_frame_password)
+        MainWindow.setTabOrder(self.user_create_frame_password, self.user_frame_addUser)
+        MainWindow.setTabOrder(self.user_frame_addUser, self.user_delete_frame_user_select)
+        MainWindow.setTabOrder(self.user_delete_frame_user_select, self.user_delete_confirm)
+        MainWindow.setTabOrder(self.user_delete_confirm, self.pushButton)
+        MainWindow.setTabOrder(self.pushButton, self.user_edit_frame_user_select)
+        MainWindow.setTabOrder(self.user_edit_frame_user_select, self.user_edit_frame_role_select)
+        MainWindow.setTabOrder(self.user_edit_frame_role_select, self.user_edit_frame_new_password)
+        MainWindow.setTabOrder(self.user_edit_frame_new_password, self.update_user)
+        MainWindow.setTabOrder(self.update_user, self.edit_faculty_member_title)
+        MainWindow.setTabOrder(self.edit_faculty_member_title, self.edit_faculty_member_select_member)
+        MainWindow.setTabOrder(self.edit_faculty_member_select_member, self.faculty_member_old_telnr)
+        MainWindow.setTabOrder(self.faculty_member_old_telnr, self.faculty_member_oldmail)
+        MainWindow.setTabOrder(self.faculty_member_oldmail, self.edit_faculty_member_new_title)
+        MainWindow.setTabOrder(self.edit_faculty_member_new_title, self.edit_faculty_member_new_surname)
+        MainWindow.setTabOrder(self.edit_faculty_member_new_surname, self.user_faculty_member_new_name)
+        MainWindow.setTabOrder(self.user_faculty_member_new_name, self.lineEdit)
+        MainWindow.setTabOrder(self.lineEdit, self.lineEdit_5)
+        MainWindow.setTabOrder(self.lineEdit_5, self.update_faculty_member)
+        MainWindow.setTabOrder(self.update_faculty_member, self.box_fach)
+        MainWindow.setTabOrder(self.box_fach, self.box_person)
+        MainWindow.setTabOrder(self.box_person, self.btn_search)
+        MainWindow.setTabOrder(self.btn_search, self.check_deletable)
+        MainWindow.setTabOrder(self.check_deletable, self.box_erstellsemester)
+        MainWindow.setTabOrder(self.box_erstellsemester, self.box_semester)
+        MainWindow.setTabOrder(self.box_semester, self.box_dauerapp)
+        MainWindow.setTabOrder(self.box_dauerapp, self.box_appnrs)
+        MainWindow.setTabOrder(self.box_appnrs, self.btn_copy_adis_command)
+        MainWindow.setTabOrder(self.btn_copy_adis_command, self.spin_select_message)
+
+    def retranslateUi(self, MainWindow):
+        _translate = QtCore.QCoreApplication.translate
+        MainWindow.setWindowTitle(_translate("MainWindow", "Semesterapparatsmanagement"))
+        self.load_app.setToolTip(_translate("MainWindow", "Load the Semesterapparate from the database"))
+        self.load_app.setText(_translate("MainWindow", "App. aufrufen"))
+        self.create_new_app.setText(_translate("MainWindow", "neu. App anlegen"))
+        self.cancel_active_selection.setText(_translate("MainWindow", "Auswahl abbrechen"))
+        self.tableWidget_apparate.setSortingEnabled(True)
+        item = self.tableWidget_apparate.horizontalHeaderItem(0)
+        item.setText(_translate("MainWindow", "AppNr"))
+        item = self.tableWidget_apparate.horizontalHeaderItem(1)
+        item.setText(_translate("MainWindow", "App Name"))
+        item = self.tableWidget_apparate.horizontalHeaderItem(2)
+        item.setText(_translate("MainWindow", "Professor"))
+        item = self.tableWidget_apparate.horizontalHeaderItem(3)
+        item.setText(_translate("MainWindow", "gültig bis"))
+        item = self.tableWidget_apparate.horizontalHeaderItem(4)
+        item.setText(_translate("MainWindow", "Dauerapparat"))
+        item = self.tableWidget_apparate.horizontalHeaderItem(5)
+        item.setText(_translate("MainWindow", "KontoNr"))
+        self.app_group_box.setTitle(_translate("MainWindow", "Apparatsdetails"))
+        item = self.dokument_list.horizontalHeaderItem(0)
+        item.setText(_translate("MainWindow", "Dokumentname"))
+        item = self.dokument_list.horizontalHeaderItem(1)
+        item.setText(_translate("MainWindow", "Dateityp"))
+        item = self.dokument_list.horizontalHeaderItem(2)
+        item.setText(_translate("MainWindow", "Neu?"))
+        item = self.dokument_list.horizontalHeaderItem(3)
+        item.setText(_translate("MainWindow", "path"))
+        self.label_5.setText(_translate("MainWindow", "Apparatsname"))
+        self.sem_winter.setText(_translate("MainWindow", "Winter"))
+        self.label_4.setText(_translate("MainWindow", "Prof. Name"))
+        self.sem_sommer.setText(_translate("MainWindow", "Sommer"))
+        self.label_3.setText(_translate("MainWindow", "Prof. Titel"))
+        self.label_6.setText(_translate("MainWindow", "Semester"))
+        self.sem_year.setPlaceholderText(_translate("MainWindow", "2023"))
+        self.label_2.setText(_translate("MainWindow", "Apparatsnummer"))
+        self.btn_apparat_save.setText(_translate("MainWindow", "Speichern"))
+        self.btn_apparat_apply.setText(_translate("MainWindow", "Aktualisieren"))
+        self.check_eternal_app.setText(_translate("MainWindow", "Dauerapparat"))
+        self.label_8.setText(_translate("MainWindow", "Mail"))
+        self.label_9.setText(_translate("MainWindow", "Tel"))
+        self.label_10.setText(_translate("MainWindow", "Fach"))
+        self.mail_mand.setText(_translate("MainWindow", "*"))
+        self.telnr_mand.setText(_translate("MainWindow", "*"))
+        self.profname_mand.setText(_translate("MainWindow", "*"))
+        self.appname_mand.setText(_translate("MainWindow", "*"))
+        self.fach_mand.setText(_translate("MainWindow", "*"))
+        self._mand.setText(_translate("MainWindow", "*"))
+        self.btn_add_document.setText(_translate("MainWindow", "Dokument hinzufügen"))
+        self.btn_open_document.setText(_translate("MainWindow", "Dokument öffnen"))
+        self.check_file.setToolTip(_translate("MainWindow", "Abhängig von der Anzahl der Medien kann die Suche sehr lange dauern"))
+        self.check_file.setText(_translate("MainWindow", "Medien aus Dokument\n"
+" hinzufügen"))
+        self.label_12.setText(_translate("MainWindow", "Prof-ID-aDIS"))
+        self.label_13.setText(_translate("MainWindow", "Apparat-ID-aDIS"))
+        self.check_send_mail.setText(_translate("MainWindow", "Mail senden"))
+        self.tableWidget_apparat_media.setSortingEnabled(True)
+        item = self.tableWidget_apparat_media.horizontalHeaderItem(0)
+        item.setText(_translate("MainWindow", "Buchtitel"))
+        item = self.tableWidget_apparat_media.horizontalHeaderItem(1)
+        item.setText(_translate("MainWindow", "Signatur"))
+        item = self.tableWidget_apparat_media.horizontalHeaderItem(2)
+        item.setText(_translate("MainWindow", "Auflage"))
+        item = self.tableWidget_apparat_media.horizontalHeaderItem(3)
+        item.setText(_translate("MainWindow", "Autor"))
+        item = self.tableWidget_apparat_media.horizontalHeaderItem(4)
+        item.setText(_translate("MainWindow", "verfügbar?"))
+        item = self.tableWidget_apparat_media.horizontalHeaderItem(5)
+        item.setText(_translate("MainWindow", "Vorgemerkt"))
+        item = self.tableWidget_apparat_media.horizontalHeaderItem(6)
+        item.setText(_translate("MainWindow", "Link"))
+        self.label.setText(_translate("MainWindow", "  Medienliste"))
+        self.chkbx_show_del_media.setText(_translate("MainWindow", "gel. Medien anzeigen"))
+        self.btn_reserve.setText(_translate("MainWindow", "im Apparat?"))
+        self.label_info.setText(_translate("MainWindow", "Medien werden hinzugefügt"))
+        self.progress_label.setText(_translate("MainWindow", "Medium x/y"))
+        self.label_20.setText(_translate("MainWindow", "Medien werden geprüft"))
+        self.avail_status.setText(_translate("MainWindow", "TextLabel"))
+        self.add_medium.setText(_translate("MainWindow", "Medien hinzufügen"))
+        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Anlegen"))
+        self.btn_search.setText(_translate("MainWindow", "Suchen"))
+        self.label_7.setText(_translate("MainWindow", "Appnr.:"))
+        self.label_18.setText(_translate("MainWindow", "Dauerapp:"))
+        self.label_17.setText(_translate("MainWindow", "Endsemester:"))
+        self.label_19.setText(_translate("MainWindow", "Erstellsemester:"))
+        self.label_11.setText(_translate("MainWindow", "Person:"))
+        self.label_16.setText(_translate("MainWindow", "Fach:"))
+        self.label_15.setText(_translate("MainWindow", "Löschbar"))
+        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_3), _translate("MainWindow", "Statistik"))
+        self.label_25.setText(_translate("MainWindow", "Signatur"))
+        self.book_search.setText(_translate("MainWindow", "Suche"))
+        self.label_26.setText(_translate("MainWindow", "Titel"))
+        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_4), _translate("MainWindow", "Suchen"))
+        item = self.statistics_table.horizontalHeaderItem(0)
+        item.setText(_translate("MainWindow", "Semester"))
+        item = self.statistics_table.horizontalHeaderItem(1)
+        item.setText(_translate("MainWindow", "Zugang"))
+        item = self.statistics_table.horizontalHeaderItem(2)
+        item.setText(_translate("MainWindow", "Abgang"))
+        self.tabWidget_3.setTabText(self.tabWidget_3.indexOf(self.tab_6), _translate("MainWindow", "Tabelle"))
+        self.tabWidget_3.setTabText(self.tabWidget_3.indexOf(self.tab_7), _translate("MainWindow", "Erstellte und gelöschte Semesterapparate"))
+        self.btn_del_select_apparats.setText(_translate("MainWindow", "Ausgewählte Löschen"))
+        item = self.tableWidget.horizontalHeaderItem(1)
+        item.setText(_translate("MainWindow", "Apparatsname"))
+        item = self.tableWidget.horizontalHeaderItem(2)
+        item.setText(_translate("MainWindow", "Apparatsnummer"))
+        item = self.tableWidget.horizontalHeaderItem(3)
+        item.setText(_translate("MainWindow", "Person"))
+        item = self.tableWidget.horizontalHeaderItem(4)
+        item.setText(_translate("MainWindow", "Fach"))
+        item = self.book_search_result.horizontalHeaderItem(0)
+        item.setText(_translate("MainWindow", "Titel"))
+        item = self.book_search_result.horizontalHeaderItem(1)
+        item.setText(_translate("MainWindow", "Signatur"))
+        item = self.book_search_result.horizontalHeaderItem(2)
+        item.setText(_translate("MainWindow", "Apparat"))
+        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Suchen / Statistik"))
+        self.label_21.setText(_translate("MainWindow", "Aktion:"))
+        self.select_action_box.setItemText(0, _translate("MainWindow", "Nutzer anlegen"))
+        self.select_action_box.setItemText(1, _translate("MainWindow", "Nutzer löschen"))
+        self.select_action_box.setItemText(2, _translate("MainWindow", "Nutzer aktualisieren"))
+        self.select_action_box.setItemText(3, _translate("MainWindow", "Lehrperson bearbeiten"))
+        self.label_22.setText(_translate("MainWindow", "Nutzername"))
+        self.label_24.setText(_translate("MainWindow", "Rolle"))
+        self.label_23.setText(_translate("MainWindow", "Passwort"))
+        self.user_frame_addUser.setText(_translate("MainWindow", "Anlegen"))
+        self.pushButton.setText(_translate("MainWindow", "Nutzer löschen"))
+        self.label_34.setText(_translate("MainWindow", "Nutzername"))
+        self.user_delete_confirm.setText(_translate("MainWindow", "Wirklich löschen?"))
+        self.label_38.setText(_translate("MainWindow", "Nutzername"))
+        self.update_user.setText(_translate("MainWindow", "Aktualisieren"))
+        self.label_40.setText(_translate("MainWindow", "Rolle"))
+        self.label_39.setText(_translate("MainWindow", "Neues Passwort"))
+        self.label_43.setText(_translate("MainWindow", "Titel"))
+        self.label_44.setText(_translate("MainWindow", "Vorname"))
+        self.label_45.setText(_translate("MainWindow", "Nachname"))
+        self.label_46.setText(_translate("MainWindow", "Telefonnummer"))
+        self.label_49.setText(_translate("MainWindow", "Mail"))
+        self.label_47.setText(_translate("MainWindow", "Mail"))
+        self.label_48.setText(_translate("MainWindow", "Telefon"))
+        self.label_41.setText(_translate("MainWindow", "Alte Angaben"))
+        self.update_faculty_member.setText(_translate("MainWindow", "Aktualisieren"))
+        self.label_42.setText(_translate("MainWindow", "Neue Angaben"))
+        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_5), _translate("MainWindow", "Admin"))
+        self.groupBox_2.setTitle(_translate("MainWindow", "Software"))
+        self.appdata_check.setText(_translate("MainWindow", "Apparatsdaten eingegeben"))
+        self.media_check.setText(_translate("MainWindow", "Medien hinzugefügt / importiert"))
+        self.ids_check.setText(_translate("MainWindow", "Prof-ID und Apparat-ID eingetragen"))
+        self.groupBox.setTitle(_translate("MainWindow", "aDIS"))
+        self.media_checked.setText(_translate("MainWindow", "Medien geprüft"))
+        self.media_edited_check.setText(_translate("MainWindow", "Medien bearbeitet"))
+        self.app_created.setText(_translate("MainWindow", "Apparat angelegt"))
+        self.btn_copy_adis_command.setToolTip(_translate("MainWindow", "Hier klicken, um die aDIS Abfrage in die Zwischenablage zu kopieren"))
+        self.btn_copy_adis_command.setText(_translate("MainWindow", " aDIS Abfrage"))
+        self.label_14.setText(_translate("MainWindow", "Apparat"))
+        self.btn_delete_message.setText(_translate("MainWindow", "Löschen"))
+        self.label_total_day_messages.setText(_translate("MainWindow", "TextLabel"))
+        self.menuDatei.setTitle(_translate("MainWindow", "Datei"))
+        self.menuEinstellungen.setTitle(_translate("MainWindow", "Bearbeiten"))
+        self.actionBeenden.setText(_translate("MainWindow", "Beenden"))
+        self.actionBeenden.setShortcut(_translate("MainWindow", "Ctrl+Q"))
+        self.actionEinstellungen.setText(_translate("MainWindow", "Einstellungen"))
+        self.actionEinstellungen.setShortcut(_translate("MainWindow", "Alt+S"))
diff --git a/src/ui/Ui_semesterapparat_ui.ts b/src/ui/Ui_semesterapparat_ui.ts
new file mode 100644
index 0000000..69b16be
--- /dev/null
+++ b/src/ui/Ui_semesterapparat_ui.ts
@@ -0,0 +1,232 @@
+
+
+
+
+    MainWindow
+    
+        
+        MainWindow
+        
+    
+    
+        
+        Load the Semesterapparate from the database
+        
+    
+    
+        
+        App. aufrufen
+        
+    
+    
+        
+        neu. App anlegen
+        
+    
+    
+        
+        Auswahl abbrechen
+        
+    
+    
+        
+        AppNr
+        
+    
+    
+        
+        App Name
+        
+    
+    
+        
+        Professor
+        
+    
+    
+        
+        gültig bis
+        
+    
+    
+        
+        Dauerapparat
+        
+    
+    
+        
+        KontoNr
+        
+    
+    
+        
+        Apparatsdetails
+        
+    
+    
+        
+        Dokumentname
+        
+    
+    
+        
+        Dateityp
+        
+    
+    
+        
+        Neu?
+        
+    
+    
+        
+        path
+        
+    
+    
+        
+        Apparatsname
+        
+    
+    
+        
+        Winter
+        
+    
+    
+        
+        Prof. Name
+        
+    
+    
+        
+        Sommer
+        
+    
+    
+        
+        Prof. Titel
+        
+    
+    
+        
+        Semester
+        
+    
+    
+        
+        2023
+        
+    
+    
+        
+        Apparatsnummer
+        
+    
+    
+        
+        Speichern
+        
+    
+    
+        
+        Aktualisieren
+        
+    
+    
+        
+        Mail
+        
+    
+    
+        
+        Tel
+        
+    
+    
+        
+        Fach
+        
+    
+    
+        
+        *
+        
+    
+    
+        
+        Dokument hinzufügen
+        
+    
+    
+        
+        Dokument öffnen
+        
+    
+    
+        
+        Buchtitel
+        
+    
+    
+        
+        Signatur
+        
+    
+    
+        
+        Auflage
+        
+    
+    
+        
+        Autor
+        
+    
+    
+        
+        Link
+        
+    
+    
+        
+          Medienliste
+        
+    
+    
+        
+        gel. Medien anzeigen
+        
+    
+    
+        
+        Medien hinzufügen
+        
+    
+    
+        
+        Tab 1
+        
+    
+    
+        
+        Tab 2
+        
+    
+    
+        
+        Datei
+        
+    
+    
+        
+        Einstellungen
+        
+    
+    
+        
+        Beenden
+        
+    
+
+
diff --git a/src/ui/Ui_setupwizard.py b/src/ui/Ui_setupwizard.py
new file mode 100644
index 0000000..c12fc49
--- /dev/null
+++ b/src/ui/Ui_setupwizard.py
@@ -0,0 +1,71 @@
+# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\Semesterapparate\ui\setupwizard.ui'
+#
+# Created by: PyQt6 UI code generator 6.3.1
+#
+# WARNING: Any manual changes made to this file will be lost when pyuic6 is
+# run again.  Do not edit this file unless you know what you are doing.
+
+
+from PyQt6 import QtCore, QtGui, QtWidgets
+
+
+class Ui_Wizard(object):
+    def setupUi(self, Wizard):
+        Wizard.setObjectName("Wizard")
+        Wizard.resize(640, 480)
+        Wizard.setMaximumSize(QtCore.QSize(640, 480))
+        self.wizardPage1 = QtWidgets.QWizardPage()
+        self.wizardPage1.setObjectName("wizardPage1")
+        self.textBrowser = QtWidgets.QTextBrowser(self.wizardPage1)
+        self.textBrowser.setGeometry(QtCore.QRect(200, 10, 256, 192))
+        self.textBrowser.setObjectName("textBrowser")
+        Wizard.addPage(self.wizardPage1)
+        self.wizardPage2 = QtWidgets.QWizardPage()
+        self.wizardPage2.setObjectName("wizardPage2")
+        self.label = QtWidgets.QLabel(self.wizardPage2)
+        self.label.setGeometry(QtCore.QRect(10, 0, 131, 16))
+        self.label.setObjectName("label")
+        self.label_2 = QtWidgets.QLabel(self.wizardPage2)
+        self.label_2.setGeometry(QtCore.QRect(10, 40, 71, 16))
+        self.label_2.setObjectName("label_2")
+        self.default_apps = QtWidgets.QCheckBox(self.wizardPage2)
+        self.default_apps.setGeometry(QtCore.QRect(100, 40, 70, 17))
+        self.default_apps.setText("")
+        self.default_apps.setObjectName("default_apps")
+        self.label_3 = QtWidgets.QLabel(self.wizardPage2)
+        self.label_3.setGeometry(QtCore.QRect(10, 70, 61, 16))
+        self.label_3.setObjectName("label_3")
+        self.custom_applications = QtWidgets.QFrame(self.wizardPage2)
+        self.custom_applications.setGeometry(QtCore.QRect(280, 10, 331, 361))
+        self.custom_applications.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
+        self.custom_applications.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
+        self.custom_applications.setObjectName("custom_applications")
+        self.save_path = QtWidgets.QLineEdit(self.wizardPage2)
+        self.save_path.setGeometry(QtCore.QRect(80, 70, 113, 20))
+        self.save_path.setObjectName("save_path")
+        self.btn_save_path_select = QtWidgets.QToolButton(self.wizardPage2)
+        self.btn_save_path_select.setGeometry(QtCore.QRect(200, 70, 25, 19))
+        self.btn_save_path_select.setObjectName("btn_save_path_select")
+        Wizard.addPage(self.wizardPage2)
+
+        self.retranslateUi(Wizard)
+        QtCore.QMetaObject.connectSlotsByName(Wizard)
+
+    def retranslateUi(self, Wizard):
+        _translate = QtCore.QCoreApplication.translate
+        Wizard.setWindowTitle(_translate("Wizard", "Wizard"))
+        self.textBrowser.setHtml(_translate("Wizard", "\n"
+"\n"
+"

Setup für das Semesterapparatsprogram.

\n" +"


\n" +"

Im Anschluss werden wichtige Einstellungen gesetzt, welche auch im späteren Verlauf verändert werden können.

\n" +"


")) + self.label.setText(_translate("Wizard", "Grundeinstellungen")) + self.label_2.setToolTip(_translate("Wizard", "Opens the downloaded files with the default applications set in the OS")) + self.label_2.setText(_translate("Wizard", "Default Apps")) + self.label_3.setToolTip(_translate("Wizard", "Path where the downloaded files are stored. Defaults to ~/Desktop/SemapFiles")) + self.label_3.setText(_translate("Wizard", "Save Path")) + self.save_path.setPlaceholderText(_translate("Wizard", "~/Desktop/SemapFiles")) + self.btn_save_path_select.setText(_translate("Wizard", "...")) diff --git a/src/ui/__init__.py b/src/ui/__init__.py new file mode 100644 index 0000000..93f0297 --- /dev/null +++ b/src/ui/__init__.py @@ -0,0 +1,29 @@ +import pathlib + +from .dialogs import ( + App_Ext_Dialog, + Mail_Dialog, + Settings, + edit_bookdata_ui, + fileparser_ui, + login_ui, + medienadder_ui, + parsed_titles_ui, + popus_confirm, + reminder_ui, + settings_ui, + new_subject_ui, +) +from .Ui_semesterapparat_ui import Ui_MainWindow as Ui_Semesterapparat +from .Ui_setupwizard import Ui_Wizard as SetupWizard +from .widgets import ( + FilePicker, + GraphWidget, + Message_Widget, + StatusWidget, +) + +path = pathlib.Path(__file__).parent.absolute() +# from .mainwindow import Ui_MainWindow as Ui_MainWindow +# from .sap import Ui_MainWindow as MainWindow_SAP +__all__ = ["mainwindow", "sap", "dialogs", "widgets"] diff --git a/src/ui/dialogs/Ui_edit_bookdata.py b/src/ui/dialogs/Ui_edit_bookdata.py new file mode 100644 index 0000000..728cd17 --- /dev/null +++ b/src/ui/dialogs/Ui_edit_bookdata.py @@ -0,0 +1,157 @@ +# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\Semesterapparate\ui\dialogs\edit_bookdata.ui' +# +# Created by: PyQt6 UI code generator 6.3.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + +from src.logic.dataclass import BookData + + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName("Metadaten") + Dialog.resize(448, 572) + self.buttonBox = QtWidgets.QDialogButtonBox(Dialog) + self.buttonBox.setGeometry(QtCore.QRect(260, 530, 161, 32)) + self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal) + self.buttonBox.setStandardButtons( + QtWidgets.QDialogButtonBox.StandardButton.Cancel + | QtWidgets.QDialogButtonBox.StandardButton.Ok + ) + self.buttonBox.setObjectName("buttonBox") + self.gridLayoutWidget = QtWidgets.QWidget(Dialog) + self.gridLayoutWidget.setGeometry(QtCore.QRect(0, 0, 441, 531)) + self.gridLayoutWidget.setObjectName("gridLayoutWidget") + self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget) + self.gridLayout.setSizeConstraint( + QtWidgets.QLayout.SizeConstraint.SetDefaultConstraint + ) + self.gridLayout.setContentsMargins(0, 0, 0, 0) + self.gridLayout.setObjectName("gridLayout") + self.label_10 = QtWidgets.QLabel(self.gridLayoutWidget) + self.label_10.setObjectName("label_10") + self.gridLayout.addWidget(self.label_10, 10, 1, 1, 1) + self.label = QtWidgets.QLabel(self.gridLayoutWidget) + self.label.setObjectName("label") + self.gridLayout.addWidget(self.label, 0, 1, 1, 1) + self.label_9 = QtWidgets.QLabel(self.gridLayoutWidget) + self.label_9.setObjectName("label_9") + self.gridLayout.addWidget(self.label_9, 9, 1, 1, 1) + self.label_8 = QtWidgets.QLabel(self.gridLayoutWidget) + self.label_8.setObjectName("label_8") + self.gridLayout.addWidget(self.label_8, 8, 1, 1, 1) + self.label_12 = QtWidgets.QLabel(self.gridLayoutWidget) + self.label_12.setObjectName("label_12") + self.gridLayout.addWidget(self.label_12, 6, 1, 1, 1) + self.line_edition = QtWidgets.QLineEdit(self.gridLayoutWidget) + self.line_edition.setObjectName("line_edition") + self.gridLayout.addWidget(self.line_edition, 2, 2, 1, 1) + self.label_3 = QtWidgets.QLabel(self.gridLayoutWidget) + self.label_3.setObjectName("label_3") + self.gridLayout.addWidget(self.label_3, 2, 1, 1, 1) + self.label_4 = QtWidgets.QLabel(self.gridLayoutWidget) + self.label_4.setObjectName("label_4") + self.gridLayout.addWidget(self.label_4, 3, 1, 1, 1) + self.line_link = QtWidgets.QLineEdit(self.gridLayoutWidget) + self.line_link.setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.ArrowCursor)) + self.line_link.setReadOnly(True) + self.line_link.setObjectName("line_link") + self.gridLayout.addWidget(self.line_link, 6, 2, 1, 1) + self.label_5 = QtWidgets.QLabel(self.gridLayoutWidget) + self.label_5.setObjectName("label_5") + self.gridLayout.addWidget(self.label_5, 4, 1, 1, 1) + self.label_7 = QtWidgets.QLabel(self.gridLayoutWidget) + self.label_7.setObjectName("label_7") + self.gridLayout.addWidget(self.label_7, 7, 1, 1, 1) + self.label_6 = QtWidgets.QLabel(self.gridLayoutWidget) + self.label_6.setObjectName("label_6") + self.gridLayout.addWidget(self.label_6, 5, 1, 1, 1) + self.label_2 = QtWidgets.QLabel(self.gridLayoutWidget) + self.label_2.setObjectName("label_2") + self.gridLayout.addWidget(self.label_2, 1, 1, 1, 1) + spacerItem = QtWidgets.QSpacerItem( + 5, + 20, + QtWidgets.QSizePolicy.Policy.Fixed, + QtWidgets.QSizePolicy.Policy.Minimum, + ) + self.gridLayout.addItem(spacerItem, 8, 0, 1, 1) + self.line_title = QtWidgets.QLineEdit(self.gridLayoutWidget) + self.line_title.setObjectName("line_title") + self.gridLayout.addWidget(self.line_title, 0, 2, 1, 1) + self.line_signature = QtWidgets.QLineEdit(self.gridLayoutWidget) + self.line_signature.setObjectName("line_signature") + self.gridLayout.addWidget(self.line_signature, 1, 2, 1, 1) + self.line_author = QtWidgets.QLineEdit(self.gridLayoutWidget) + self.line_author.setObjectName("line_author") + self.gridLayout.addWidget(self.line_author, 3, 2, 1, 1) + self.line_lang = QtWidgets.QLineEdit(self.gridLayoutWidget) + self.line_lang.setObjectName("line_lang") + self.gridLayout.addWidget(self.line_lang, 8, 2, 1, 1) + self.line_ppn = QtWidgets.QLineEdit(self.gridLayoutWidget) + self.line_ppn.setObjectName("line_ppn") + self.gridLayout.addWidget(self.line_ppn, 5, 2, 1, 1) + self.line_isbn = QtWidgets.QLineEdit(self.gridLayoutWidget) + self.line_isbn.setObjectName("line_isbn") + self.gridLayout.addWidget(self.line_isbn, 7, 2, 1, 1) + self.line_year = QtWidgets.QLineEdit(self.gridLayoutWidget) + self.line_year.setObjectName("line_year") + self.gridLayout.addWidget(self.line_year, 9, 2, 1, 1) + self.line_pages = QtWidgets.QLineEdit(self.gridLayoutWidget) + self.line_pages.setObjectName("line_pages") + self.gridLayout.addWidget(self.line_pages, 10, 2, 1, 1) + self.line_publisher = QtWidgets.QLineEdit(self.gridLayoutWidget) + self.line_publisher.setObjectName("line_publisher") + self.gridLayout.addWidget(self.line_publisher, 4, 2, 1, 1) + + self.retranslateUi(Dialog) + self.buttonBox.accepted.connect(Dialog.accept) # type: ignore + self.buttonBox.rejected.connect(Dialog.reject) # type: ignore + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "Dialog")) + self.label_10.setText(_translate("Dialog", "Seiten")) + self.label.setText(_translate("Dialog", "Titel")) + self.label_9.setText(_translate("Dialog", "Jahr")) + self.label_8.setText(_translate("Dialog", "Sprache")) + self.label_12.setText(_translate("Dialog", "Link")) + self.label_3.setText(_translate("Dialog", "Auflage")) + self.label_4.setText(_translate("Dialog", "Autor")) + self.label_5.setText(_translate("Dialog", "Herausgeber")) + self.label_7.setText(_translate("Dialog", "ISBN(s)")) + self.label_6.setText(_translate("Dialog", "PPN")) + self.label_2.setText(_translate("Dialog", "Signatur")) + + def populate_fields(self, data: BookData): + self.line_author.setText(data.author) + self.line_edition.setText(data.edition) + self.line_isbn.setText(", ".join(data.isbn)) + self.line_lang.setText(data.language) + self.line_link.setText(data.link) + self.line_pages.setText(data.pages) + self.line_ppn.setText(data.ppn) + self.line_publisher.setText(data.publisher) + self.line_signature.setText(data.signature) + self.line_title.setText(data.title) + self.line_year.setText(data.year) + + def get_data(self) -> BookData: + return BookData( + ppn=self.line_ppn.text().strip(), + title=self.line_title.text().strip(), + signature=self.line_signature.text().strip(), + edition=self.line_edition.text().strip(), + link=self.line_link.text().strip(), + isbn=self.line_isbn.text().split(","), + author=self.line_author.text().strip(), + language=self.line_lang.text().strip(), + publisher=self.line_publisher.text().strip(), + year=self.line_year.text().strip(), + pages=self.line_pages.text().strip(), + ) diff --git a/src/ui/dialogs/Ui_fileparser.py b/src/ui/dialogs/Ui_fileparser.py new file mode 100644 index 0000000..05459bd --- /dev/null +++ b/src/ui/dialogs/Ui_fileparser.py @@ -0,0 +1,109 @@ +# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\Semesterapparate\ui\dialogs\fileparser.ui' +# +# Created by: PyQt6 UI code generator 6.3.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + +from src.logic.webrequest import BibTextTransformer, WebRequest + + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName("Dialog") + Dialog.resize(402, 301) + self.progressBar = QtWidgets.QProgressBar(Dialog) + self.progressBar.setGeometry(QtCore.QRect(10, 60, 381, 23)) + self.progressBar.setProperty("value", 24) + self.progressBar.setObjectName("progressBar") + self.frame = QtWidgets.QFrame(Dialog) + self.frame.setGeometry(QtCore.QRect(10, 10, 381, 41)) + self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame.setObjectName("frame") + self.horizontalLayoutWidget = QtWidgets.QWidget(self.frame) + self.horizontalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 381, 41)) + self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget") + self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget) + self.horizontalLayout.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout.setObjectName("horizontalLayout") + self.label = QtWidgets.QLabel(self.horizontalLayoutWidget) + self.label.setObjectName("label") + self.horizontalLayout.addWidget(self.label) + self.count = QtWidgets.QLabel(self.horizontalLayoutWidget) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + self.count.setFont(font) + self.count.setTextFormat(QtCore.Qt.TextFormat.PlainText) + self.count.setObjectName("count") + self.horizontalLayout.addWidget(self.count) + self.label_2 = QtWidgets.QLabel(self.horizontalLayoutWidget) + self.label_2.setObjectName("label_2") + self.horizontalLayout.addWidget(self.label_2) + spacerItem = QtWidgets.QSpacerItem( + 40, + 20, + QtWidgets.QSizePolicy.Policy.Expanding, + QtWidgets.QSizePolicy.Policy.Minimum, + ) + self.horizontalLayout.addItem(spacerItem) + self.frame_2 = QtWidgets.QFrame(Dialog) + self.frame_2.setGeometry(QtCore.QRect(10, 100, 381, 201)) + self.frame_2.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame_2.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame_2.setObjectName("frame_2") + self.listWidget = QtWidgets.QListWidget(self.frame_2) + self.listWidget.setGeometry(QtCore.QRect(0, 0, 381, 191)) + self.listWidget.setObjectName("listWidget") + self.signatures = [] + self.returned = [] + # self.data_gathering_complete = QtCore.pyqtSignal() + self.retranslateUi(Dialog) + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "Dialog")) + self.label.setText(_translate("Dialog", "Es wurden")) + self.count.setText(_translate("Dialog", "0")) + self.label_2.setText(_translate("Dialog", "Signaturen gefunden.")) + + def moveToThread(self, thread): + self.progressBar.moveToThread(thread) + self.frame.moveToThread(thread) + self.horizontalLayoutWidget.moveToThread(thread) + self.horizontalLayout.moveToThread(thread) + self.label.moveToThread(thread) + self.count.moveToThread(thread) + self.label_2.moveToThread(thread) + self.frame_2.moveToThread(thread) + self.listWidget.moveToThread(thread) + + def run(self): + for signature in self.signatures: + self.count.setText(str(self.signatures.index(signature) + 1)) + self.listWidget.addItem(signature) + webdata = WebRequest().get_ppn(signature).get_data() + bookdata = BibTextTransformer("ARRAY").get_data(webdata).return_data() + self.returned.append(bookdata) + self.progressBar.setValue(self.signatures.index(signature) + 1) + # self.data_gathering_complete.emit() + + def deleteLater(self): + self.progressBar.deleteLater() + self.frame.deleteLater() + self.horizontalLayoutWidget.deleteLater() + self.horizontalLayout.deleteLater() + self.label.deleteLater() + self.count.deleteLater() + self.label_2.deleteLater() + self.frame_2.deleteLater() + self.listWidget.deleteLater() + self.signatures = [] + self.returned = [] + self.retranslateUi.deleteLater() + super().deleteLater() diff --git a/src/ui/dialogs/Ui_login.py b/src/ui/dialogs/Ui_login.py new file mode 100644 index 0000000..1c1190d --- /dev/null +++ b/src/ui/dialogs/Ui_login.py @@ -0,0 +1,113 @@ +# Form implementation generated from reading ui file '/home/alexander/GitHub/Semesterapparate/ui/dialogs/login.ui' +# +# Created by: PyQt6 UI code generator 6.5.3 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +import hashlib + +from PyQt6 import QtCore, QtWidgets + +from src.backend.database import Database +from src.backend.admin_console import AdminCommands + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName("Dialog") + Dialog.resize(218, 190) + self.dialog = Dialog + self.login_button = QtWidgets.QPushButton(parent=Dialog) + self.login_button.setGeometry(QtCore.QRect(30, 140, 76, 32)) + self.login_button.setObjectName("login_button") + self.login_button.setText("Login") + self.login_button.setFocusPolicy(QtCore.Qt.FocusPolicy.ClickFocus) + self.cancel_button = QtWidgets.QPushButton(parent=Dialog) + self.cancel_button.setGeometry(QtCore.QRect(120, 140, 76, 32)) + self.cancel_button.setObjectName("cancel_button") + self.cancel_button.setText("Cancel") + self.cancel_button.setFocusPolicy(QtCore.Qt.FocusPolicy.ClickFocus) + self.cancel_button.clicked.connect(self.cancel_buttonfn) + self.label = QtWidgets.QLabel(parent=Dialog) + self.label.setGeometry(QtCore.QRect(20, 40, 71, 21)) + self.label.setObjectName("label") + self.lineEdit = QtWidgets.QLineEdit(parent=Dialog) + self.lineEdit.setGeometry(QtCore.QRect(80, 40, 113, 21)) + self.lineEdit.setObjectName("lineEdit") + # set strong focus to lineEdit + self.lineEdit.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.label_2 = QtWidgets.QLabel(parent=Dialog) + self.label_2.setGeometry(QtCore.QRect(20, 80, 71, 21)) + self.label_2.setObjectName("label_2") + self.lineEdit_2 = QtWidgets.QLineEdit(parent=Dialog) + self.lineEdit_2.setGeometry(QtCore.QRect(80, 80, 113, 21)) + self.lineEdit_2.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhSensitiveData) + # set echo mode to password + self.lineEdit_2.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password) + self.lineEdit_2.setClearButtonEnabled(True) + self.lineEdit_2.setObjectName("lineEdit_2") + + self.retranslateUi(Dialog) + # if buttonbox accepted is clicked, launch login test + self.login_button.clicked.connect(self.login) + self.lresult = -1 + self.lusername = "" + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "Dialog")) + self.label.setText(_translate("Dialog", "Username")) + self.label_2.setText(_translate("Dialog", "Password")) + + def login(self): + username = self.lineEdit.text() + password = self.lineEdit_2.text() + print(type(username), password) + # Assuming 'Database' is a class to interact with your database + db = Database() + + hashed_password = hashlib.sha256( + password.encode() + ).hexdigest() + if len(db.get_users()) == 0: + AdminCommands().create_admin() + self.lresult = 1 # Indicate successful login + self.lusername = username + self.dialog.accept() + if db.login(username, hashed_password): + self.lresult = 1 # Indicate successful login + self.lusername = username + self.dialog.accept() + db.close() + else: + # Credentials are invalid, display a warning + if username == "" or password == "": + warning_dialog = QtWidgets.QMessageBox() + warning_dialog.setIcon(QtWidgets.QMessageBox.Icon.Warning) + warning_dialog.setText("Please enter a username and password.") + warning_dialog.setWindowTitle("Login Failed") + warning_dialog.exec() + else: + warning_dialog = QtWidgets.QMessageBox() + warning_dialog.setIcon(QtWidgets.QMessageBox.Icon.Warning) + warning_dialog.setText( + "Invalid username or password. Please try again." + ) + warning_dialog.setWindowTitle("Login Failed") + warning_dialog.exec() + + def cancel_buttonfn(self): + self.dialog.reject() + + +if __name__ == "__main__": + import sys + + app = QtWidgets.QApplication(sys.argv) + Dialog = QtWidgets.QDialog() + ui = Ui_Dialog() + ui.setupUi(Dialog) + Dialog.show() + sys.exit(app.exec()) diff --git a/src/ui/dialogs/Ui_medianadder.py b/src/ui/dialogs/Ui_medianadder.py new file mode 100644 index 0000000..3578bab --- /dev/null +++ b/src/ui/dialogs/Ui_medianadder.py @@ -0,0 +1,240 @@ +# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\Semesterapparate\ui\dialogs\medianadder.ui' +# +# Created by: PyQt6 UI code generator 6.3.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName("Dialog") + Dialog.resize(637, 491) + self.label = QtWidgets.QLabel(Dialog) + self.label.setGeometry(QtCore.QRect(20, 10, 47, 21)) + self.label.setObjectName("label") + self.label_2 = QtWidgets.QLabel(Dialog) + self.label_2.setGeometry(QtCore.QRect(20, 40, 47, 21)) + self.label_2.setObjectName("label_2") + self.comboBox = QtWidgets.QComboBox(Dialog) + self.comboBox.setGeometry(QtCore.QRect(70, 40, 69, 22)) + self.comboBox.setObjectName("comboBox") + self.comboBox.addItem("") + self.comboBox.addItem("") + self.comboBox.addItem("") + self.comboBox.addItem("") + self.lineEdit = QtWidgets.QLineEdit(Dialog) + self.lineEdit.setGeometry(QtCore.QRect(70, 10, 113, 20)) + self.lineEdit.setObjectName("lineEdit") + self.label_3 = QtWidgets.QLabel(Dialog) + self.label_3.setGeometry(QtCore.QRect(20, 70, 47, 21)) + self.label_3.setObjectName("label_3") + self.widget = QtWidgets.QWidget(Dialog) + self.widget.setGeometry(QtCore.QRect(330, 90, 301, 341)) + self.widget.setObjectName("widget") + self.treeWidget = QtWidgets.QTreeWidget(self.widget) + self.treeWidget.setEnabled(True) + self.treeWidget.setGeometry(QtCore.QRect(0, 0, 301, 341)) + self.treeWidget.setAutoFillBackground(False) + self.treeWidget.setLineWidth(0) + self.treeWidget.setMidLineWidth(0) + self.treeWidget.setVerticalScrollBarPolicy( + QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff + ) + self.treeWidget.setHorizontalScrollBarPolicy( + QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff + ) + self.treeWidget.setSizeAdjustPolicy( + QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents + ) + self.treeWidget.setEditTriggers( + QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers + ) + self.treeWidget.setAlternatingRowColors(True) + self.treeWidget.setSelectionMode( + QtWidgets.QAbstractItemView.SelectionMode.NoSelection + ) + self.treeWidget.setTextElideMode(QtCore.Qt.TextElideMode.ElideMiddle) + self.treeWidget.setUniformRowHeights(True) + self.treeWidget.setItemsExpandable(False) + self.treeWidget.setExpandsOnDoubleClick(False) + self.treeWidget.setObjectName("treeWidget") + font = QtGui.QFont() + font.setPointSize(7) + self.treeWidget.headerItem().setFont(0, font) + item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget) + brush = QtGui.QBrush(QtGui.QColor(255, 0, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + item_0.setBackground(2, brush) + item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget) + brush = QtGui.QBrush(QtGui.QColor(0, 255, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + item_0.setBackground(2, brush) + item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget) + item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget) + item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget) + item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget) + item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget) + item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget) + item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget) + item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget) + item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget) + self.treeWidget.header().setCascadingSectionResizes(False) + self.treeWidget.header().setDefaultSectionSize(60) + self.treeWidget.header().setHighlightSections(False) + self.treeWidget.header().setMinimumSectionSize(20) + self.listWidget = QtWidgets.QListWidget(Dialog) + self.listWidget.setGeometry(QtCore.QRect(10, 90, 281, 341)) + self.listWidget.setContextMenuPolicy( + QtCore.Qt.ContextMenuPolicy.CustomContextMenu + ) + self.listWidget.setObjectName("listWidget") + self.label_4 = QtWidgets.QLabel(Dialog) + self.label_4.setGeometry(QtCore.QRect(330, 50, 181, 21)) + self.label_4.setObjectName("label_4") + self.label_5 = QtWidgets.QLabel(Dialog) + self.label_5.setGeometry(QtCore.QRect(200, 70, 41, 21)) + self.label_5.setObjectName("label_5") + self.list_amount = QtWidgets.QLabel(Dialog) + self.list_amount.setGeometry(QtCore.QRect(240, 70, 47, 21)) + self.list_amount.setObjectName("list_amount") + self.buttonBox = QtWidgets.QDialogButtonBox(Dialog) + self.buttonBox.setGeometry(QtCore.QRect(10, 450, 156, 23)) + self.buttonBox.setStandardButtons( + QtWidgets.QDialogButtonBox.StandardButton.Cancel + | QtWidgets.QDialogButtonBox.StandardButton.Ok + ) + self.buttonBox.setCenterButtons(False) + self.buttonBox.setObjectName("buttonBox") + self.buttonBox.setFocusPolicy(QtCore.Qt.FocusPolicy.ClickFocus) + # self.buttonBox.accepted.disconnect() + # set the activation action for the buttonBox to be shift enter + self.buttonBox.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.buttonBox.accepted.connect(Dialog.accept) # type: ignore + self.buttonBox.rejected.connect(Dialog.reject) # type: ignore + + self.lineEdit.returnPressed.connect(self.add_to_list) + self.retranslateUi(Dialog) + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "Dialog")) + self.label.setText(_translate("Dialog", "Signatur")) + self.label_2.setText(_translate("Dialog", "Modus")) + self.comboBox.setItemText(0, _translate("Dialog", "ARRAY")) + self.comboBox.setItemText(1, _translate("Dialog", "BibTeX")) + self.comboBox.setItemText(2, _translate("Dialog", "COinS")) + self.comboBox.setItemText(3, _translate("Dialog", "RIS")) + self.lineEdit.setPlaceholderText(_translate("Dialog", "Signatur / ISBN")) + self.label_3.setText(_translate("Dialog", "Queue")) + self.treeWidget.headerItem().setText( + 0, _translate("Dialog", "Datensatz\\Metadata") + ) + self.treeWidget.headerItem().setText(1, _translate("Dialog", "Array")) + self.treeWidget.headerItem().setText(2, _translate("Dialog", "BibTeX")) + self.treeWidget.headerItem().setText(3, _translate("Dialog", "COinS")) + self.treeWidget.headerItem().setText(4, _translate("Dialog", "RIS")) + __sortingEnabled = self.treeWidget.isSortingEnabled() + self.treeWidget.setSortingEnabled(False) + self.treeWidget.topLevelItem(0).setText(0, _translate("Dialog", "PPN")) + self.treeWidget.topLevelItem(0).setText(1, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(0).setText(2, _translate("Dialog", "0")) + self.treeWidget.topLevelItem(0).setText(3, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(0).setText(4, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(1).setText(0, _translate("Dialog", "Signatur")) + self.treeWidget.topLevelItem(1).setText(1, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(1).setText(2, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(1).setText(3, _translate("Dialog", "0")) + self.treeWidget.topLevelItem(1).setText(4, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(2).setText(0, _translate("Dialog", "Autor")) + self.treeWidget.topLevelItem(2).setText(1, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(2).setText(2, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(2).setText(3, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(2).setText(4, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(3).setText(0, _translate("Dialog", "ISBN")) + self.treeWidget.topLevelItem(3).setText(1, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(3).setText(2, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(3).setText(3, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(3).setText(4, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(4).setText(0, _translate("Dialog", "Jahr")) + self.treeWidget.topLevelItem(4).setText(1, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(4).setText(2, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(4).setText(3, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(4).setText(4, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(5).setText(0, _translate("Dialog", "Auflage")) + self.treeWidget.topLevelItem(5).setText(1, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(5).setText(2, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(5).setText(3, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(5).setText(4, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(6).setText(0, _translate("Dialog", "Sprache")) + self.treeWidget.topLevelItem(6).setText(1, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(6).setText(2, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(6).setText(3, _translate("Dialog", "0")) + self.treeWidget.topLevelItem(6).setText(4, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(7).setText(0, _translate("Dialog", "Herausgeber")) + self.treeWidget.topLevelItem(7).setText(1, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(7).setText(2, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(7).setText(3, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(7).setText(4, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(8).setText(0, _translate("Dialog", "Seiten")) + self.treeWidget.topLevelItem(8).setText(1, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(8).setText(2, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(8).setText(3, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(8).setText(4, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(9).setText(0, _translate("Dialog", "Titel")) + self.treeWidget.topLevelItem(9).setText(1, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(9).setText(2, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(9).setText(3, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(9).setText(4, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(10).setText(0, _translate("Dialog", "Link")) + self.treeWidget.topLevelItem(10).setText(1, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(10).setText(2, _translate("Dialog", "0")) + self.treeWidget.topLevelItem(10).setText(3, _translate("Dialog", "1")) + self.treeWidget.topLevelItem(10).setText(4, _translate("Dialog", "1")) + self.treeWidget.setSortingEnabled(__sortingEnabled) + self.label_4.setText(_translate("Dialog", "Belegbare Felder per Anbieter")) + self.label_5.setText(_translate("Dialog", "Anzahl:")) + self.list_amount.setText(_translate("Dialog", "0")) + self.recolorize() + self.listWidget.customContextMenuRequested.connect(self.custom_context_menu) + + def add_to_list(self): + text = self.lineEdit.text().strip() + if text == "": + return + else: + self.listWidget.addItem(text) + self.list_amount.setText(str(self.listWidget.count())) + self.lineEdit.clear() + + def recolorize(self): + # set the color of the cells of the treeWidget to red if the field is not supported by the provider + # else set it to green + for i in range(self.treeWidget.topLevelItemCount()): + for j in range(1, self.treeWidget.columnCount()): + if self.treeWidget.topLevelItem(i).text(j) == "0": + self.treeWidget.topLevelItem(i).setBackground( + j, QtGui.QColor(255, 0, 0) + ) + else: + self.treeWidget.topLevelItem(i).setBackground( + j, QtGui.QColor(0, 255, 0) + ) + # remove the text from the cells + self.treeWidget.topLevelItem(i).setText(j, "") + + def custom_context_menu(self): + menu = QtWidgets.QMenu() + menu.addAction("Remove") + + action = menu.exec(QtGui.QCursor.pos()) + if action.text() == "Remove": + self.remove_from_list() + + def remove_from_list(self): + self.listWidget.takeItem(self.listWidget.currentRow()) + self.list_amount.setText(str(self.listWidget.count())) diff --git a/src/ui/dialogs/Ui_medianadder.ts b/src/ui/dialogs/Ui_medianadder.ts new file mode 100644 index 0000000..6401616 --- /dev/null +++ b/src/ui/dialogs/Ui_medianadder.ts @@ -0,0 +1,4 @@ + + + + diff --git a/src/ui/dialogs/Ui_new_subject.py b/src/ui/dialogs/Ui_new_subject.py new file mode 100644 index 0000000..213eb1c --- /dev/null +++ b/src/ui/dialogs/Ui_new_subject.py @@ -0,0 +1,63 @@ +# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\Semesterapparate\ui\dialogs\new_subject.ui' +# +# Created by: PyQt6 UI code generator 6.3.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtWidgets + + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName("Dialog") + Dialog.resize(448, 165) + self.verticalLayout_2 = QtWidgets.QVBoxLayout(Dialog) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.verticalLayout = QtWidgets.QVBoxLayout() + self.verticalLayout.setObjectName("verticalLayout") + self.label = QtWidgets.QLabel(Dialog) + self.label.setObjectName("label") + self.verticalLayout.addWidget(self.label) + self.gridLayout = QtWidgets.QGridLayout() + self.gridLayout.setObjectName("gridLayout") + spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.gridLayout.addItem(spacerItem, 0, 1, 1, 1) + self.checkBox = QtWidgets.QCheckBox(Dialog) + self.checkBox.setObjectName("checkBox") + self.gridLayout.addWidget(self.checkBox, 0, 0, 1, 1) + self.verticalLayout.addLayout(self.gridLayout) + self.verticalLayout_2.addLayout(self.verticalLayout) + self.frame = QtWidgets.QFrame(Dialog) + self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame.setObjectName("frame") + self.label_2 = QtWidgets.QLabel(self.frame) + self.label_2.setGeometry(QtCore.QRect(0, 10, 141, 16)) + self.label_2.setObjectName("label_2") + self.lineEdit = QtWidgets.QLineEdit(self.frame) + self.lineEdit.setGeometry(QtCore.QRect(0, 30, 141, 20)) + self.lineEdit.setObjectName("lineEdit") + self.verticalLayout_2.addWidget(self.frame) + self.buttonBox = QtWidgets.QDialogButtonBox(Dialog) + self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal) + self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok) + self.buttonBox.setObjectName("buttonBox") + self.verticalLayout_2.addWidget(self.buttonBox) + self.frame.setVisible(False) + self.checkBox.stateChanged.connect(lambda: self.frame.setVisible(self.checkBox.isChecked())) + + self.retranslateUi(Dialog) + self.buttonBox.accepted.connect(Dialog.accept) # type: ignore + self.buttonBox.rejected.connect(Dialog.reject) # type: ignore + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "Dialog")) + self.label.setText(_translate("Dialog", "Das eingegebene Fach wurde nicht in der Datenbank gefunden. Soll es angelegt werden?")) + self.checkBox.setText(_translate("Dialog", "Ja")) + self.label_2.setText(_translate("Dialog", "Name des Neuen Faches:")) + def return_state(self): + return self.lineEdit.text() \ No newline at end of file diff --git a/src/ui/dialogs/Ui_parsed_titles.py b/src/ui/dialogs/Ui_parsed_titles.py new file mode 100644 index 0000000..8492d90 --- /dev/null +++ b/src/ui/dialogs/Ui_parsed_titles.py @@ -0,0 +1,158 @@ +# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\Semesterapparate\ui\dialogs\parsed_titles.ui' +# +# Created by: PyQt6 UI code generator 6.3.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + +from log import MyLogger +from src.logic.threads import AutoAdder + +logger = MyLogger("AutoTitleAdder") + + +class Ui_Form(object): + def setupUi(self, Form): + Form.setObjectName("Form") + Form.resize(402, 316) + self.frame = QtWidgets.QFrame(Form) + self.frame.setGeometry(QtCore.QRect(10, 10, 381, 41)) + self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame.setObjectName("frame") + self.horizontalLayoutWidget = QtWidgets.QWidget(self.frame) + self.horizontalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 381, 41)) + self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget") + self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget) + self.horizontalLayout.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout.setObjectName("horizontalLayout") + self.label = QtWidgets.QLabel(self.horizontalLayoutWidget) + self.label.setObjectName("label") + self.horizontalLayout.addWidget(self.label) + self.count = QtWidgets.QLabel(self.horizontalLayoutWidget) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + self.count.setFont(font) + self.count.setTextFormat(QtCore.Qt.TextFormat.PlainText) + self.count.setObjectName("count") + self.horizontalLayout.addWidget(self.count) + self.label_2 = QtWidgets.QLabel(self.horizontalLayoutWidget) + self.label_2.setObjectName("label_2") + self.horizontalLayout.addWidget(self.label_2) + spacerItem = QtWidgets.QSpacerItem( + 40, + 20, + QtWidgets.QSizePolicy.Policy.Expanding, + QtWidgets.QSizePolicy.Policy.Minimum, + ) + self.horizontalLayout.addItem(spacerItem) + self.frame_2 = QtWidgets.QFrame(Form) + self.frame_2.setGeometry(QtCore.QRect(10, 80, 381, 201)) + self.frame_2.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame_2.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame_2.setObjectName("frame_2") + self.horizontalLayoutWidget_2 = QtWidgets.QWidget(self.frame_2) + self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(0, 10, 381, 191)) + self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_2) + self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.listWidget = QtWidgets.QListWidget(self.horizontalLayoutWidget_2) + self.listWidget.setObjectName("listWidget") + self.horizontalLayout_2.addWidget(self.listWidget) + self.listWidget_done = QtWidgets.QListWidget(self.horizontalLayoutWidget_2) + self.listWidget_done.setObjectName("listWidget_done") + self.horizontalLayout_2.addWidget(self.listWidget_done) + self.progressBar = QtWidgets.QProgressBar(Form) + self.progressBar.setGeometry(QtCore.QRect(10, 60, 381, 23)) + self.progressBar.setProperty("value", 24) + self.progressBar.setObjectName("progressBar") + self.buttonBox = QtWidgets.QDialogButtonBox(Form) + self.buttonBox.setGeometry(QtCore.QRect(230, 290, 156, 23)) + self.buttonBox.setStandardButtons( + QtWidgets.QDialogButtonBox.StandardButton.Cancel + | QtWidgets.QDialogButtonBox.StandardButton.Ok + ) + self.buttonBox.setObjectName("buttonBox") + self.toolButton = QtWidgets.QToolButton(Form) + self.toolButton.setGeometry(QtCore.QRect(20, 290, 25, 19)) + self.toolButton.setObjectName("toolButton") + self.signatures = [] + self.prof_id = None + self.app_id = None + self.thread = QtCore.QThread() + self.toolButton.hide() + self.retranslateUi(Form) + QtCore.QMetaObject.connectSlotsByName(Form) + self.toolButton.clicked.connect(self.start) + # if cancel is clicked, terminate the thread + self.buttonBox.rejected.connect(self.thread_quit) + + def retranslateUi(self, Form): + _translate = QtCore.QCoreApplication.translate + Form.setWindowTitle(_translate("Form", "Form")) + self.label.setText(_translate("Form", "Es wurden")) + self.count.setText(_translate("Form", "0")) + self.label_2.setText(_translate("Form", "Signaturen gefunden.")) + self.toolButton.setText(_translate("Form", "...")) + + def populate_table(self): + for i in range(len(self.signatures)): + self.listWidget.addItem(QtWidgets.QListWidgetItem()) + self.listWidget.item(i).setText(self.signatures[i]) + self.listWidget.item(i).setToolTip("Daten werden gesammelt") + + def update_progress_bar(self, value: int): + self.progressBar.setValue(value) + + def thread_quit(self): + print("Terminating thread") + self.thread.terminate() + self.thread.quit() + self.thread.deleteLater() + self.thread = None + + def start(self): + logger.log_info("Starting AutoAdder") + + self.thread = AutoAdder( + data=self.signatures, + app_id=self.app_id, + prof_id=self.prof_id, + ) + self.thread.finished.connect(self.on_completion) + self.thread.updateSignal.connect(self.update_progress_bar) + self.thread.setTextSignal.connect(self.update_lists) + self.thread.progress.connect(self.determine_progress) + self.thread.finished.connect(self.thread.quit) + self.thread.finished.connect(self.thread.deleteLater) + # self.thread.updateSignal.connect(self.update_progress_label) + # worker.finished.connect(worker.deleteLater) + + self.thread.start() + + def on_completion(self): + logger.log_info("AutoAdder finished") + logger.log_info("Returning data") + + # create a function that closes the dialog + + def determine_progress(self, signal): + # check length of listWidget + length = self.listWidget.count() + print(f"Length of listWidget: {length}") + if length == 0: + logger.log_info("AutoAdder finished") + self.buttonBox.accepted.emit() + + def update_lists(self, signal): + # get text of first entry in listWidget + text = self.listWidget.item(0).text() + # remove first entry + self.listWidget.takeItem(0) + # add first entry to listWidget_done + self.listWidget_done.addItem(text) diff --git a/src/ui/dialogs/Ui_reminder.py b/src/ui/dialogs/Ui_reminder.py new file mode 100644 index 0000000..b1c805f --- /dev/null +++ b/src/ui/dialogs/Ui_reminder.py @@ -0,0 +1,52 @@ +# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\Semesterapparate\ui\dialogs\reminder.ui' +# +# Created by: PyQt6 UI code generator 6.3.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtWidgets + + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName("Dialog") + Dialog.resize(369, 308) + self.buttonBox = QtWidgets.QDialogButtonBox(Dialog) + self.buttonBox.setGeometry(QtCore.QRect(190, 270, 161, 32)) + self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal) + self.buttonBox.setStandardButtons( + QtWidgets.QDialogButtonBox.StandardButton.Cancel + | QtWidgets.QDialogButtonBox.StandardButton.Ok + ) + self.buttonBox.setObjectName("buttonBox") + self.message_box = QtWidgets.QTextEdit(Dialog) + self.message_box.setGeometry(QtCore.QRect(10, 60, 341, 201)) + self.message_box.setObjectName("message_box") + self.label = QtWidgets.QLabel(Dialog) + self.label.setGeometry(QtCore.QRect(10, 30, 61, 21)) + self.label.setObjectName("label") + self.label_2 = QtWidgets.QLabel(Dialog) + self.label_2.setGeometry(QtCore.QRect(150, 30, 81, 21)) + self.label_2.setObjectName("label_2") + self.dateEdit = QtWidgets.QDateEdit(Dialog) + self.dateEdit.setGeometry(QtCore.QRect(240, 30, 110, 22)) + self.dateEdit.setObjectName("dateEdit") + self.dateEdit.setDateTime(QtCore.QDateTime.currentDateTime()) + self.retranslateUi(Dialog) + self.buttonBox.accepted.connect(Dialog.accept) # type: ignore + self.buttonBox.rejected.connect(Dialog.reject) # type: ignore + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "Dialog")) + self.label.setText(_translate("Dialog", "Nachricht:")) + self.label_2.setText(_translate("Dialog", "Erinnerung am:")) + + def return_message(self) -> dict: + return { + "message": self.message_box.toPlainText(), + "remind_at": self.dateEdit.date().toString("yyyy-MM-dd"), + } diff --git a/src/ui/dialogs/Ui_settings.py b/src/ui/dialogs/Ui_settings.py new file mode 100644 index 0000000..bc50dfe --- /dev/null +++ b/src/ui/dialogs/Ui_settings.py @@ -0,0 +1,202 @@ +# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\Semesterapparate\ui\dialogs\settings.ui' +# +# Created by: PyQt6 UI code generator 6.3.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from omegaconf import OmegaConf +from PyQt6 import QtCore, QtWidgets + +config = OmegaConf.load("config.yaml") + + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName("Dialog") + Dialog.resize(743, 576) + self.buttonBox = QtWidgets.QDialogButtonBox(Dialog) + self.buttonBox.setGeometry(QtCore.QRect(120, 540, 621, 32)) + self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal) + self.buttonBox.setStandardButtons( + QtWidgets.QDialogButtonBox.StandardButton.Cancel + | QtWidgets.QDialogButtonBox.StandardButton.Ok + ) + self.buttonBox.setObjectName("buttonBox") + self.frame = QtWidgets.QFrame(Dialog) + self.frame.setGeometry(QtCore.QRect(0, 0, 741, 541)) + self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame.setObjectName("frame") + self.label = QtWidgets.QLabel(self.frame) + self.label.setGeometry(QtCore.QRect(400, 30, 161, 21)) + self.label.setObjectName("label") + self.line = QtWidgets.QFrame(self.frame) + self.line.setGeometry(QtCore.QRect(370, 0, 20, 541)) + self.line.setFrameShadow(QtWidgets.QFrame.Shadow.Plain) + self.line.setLineWidth(1) + self.line.setMidLineWidth(0) + self.line.setFrameShape(QtWidgets.QFrame.Shape.VLine) + self.line.setObjectName("line") + self.textBrowser = QtWidgets.QTextBrowser(self.frame) + self.textBrowser.setGeometry(QtCore.QRect(400, 50, 311, 51)) + self.textBrowser.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.textBrowser.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhNone) + self.textBrowser.setObjectName("textBrowser") + self.label_2 = QtWidgets.QLabel(self.frame) + self.label_2.setGeometry(QtCore.QRect(10, 20, 161, 21)) + self.label_2.setObjectName("label_2") + self.os_apps = QtWidgets.QCheckBox(self.frame) + self.os_apps.setGeometry(QtCore.QRect(410, 110, 161, 17)) + self.os_apps.setObjectName("os_apps") + self.formLayoutWidget = QtWidgets.QWidget(self.frame) + self.formLayoutWidget.setGeometry(QtCore.QRect(10, 50, 361, 491)) + self.formLayoutWidget.setObjectName("formLayoutWidget") + self.gridLayout = QtWidgets.QGridLayout(self.formLayoutWidget) + self.gridLayout.setContentsMargins(0, 0, 0, 0) + self.gridLayout.setObjectName("gridLayout") + self.label_3 = QtWidgets.QLabel(self.formLayoutWidget) + self.label_3.setObjectName("label_3") + self.gridLayout.addWidget(self.label_3, 0, 0, 1, 1) + self.label_5 = QtWidgets.QLabel(self.formLayoutWidget) + self.label_5.setObjectName("label_5") + self.gridLayout.addWidget(self.label_5, 2, 0, 1, 1) + self.db_path = QtWidgets.QLineEdit(self.formLayoutWidget) + self.db_path.setEnabled(False) + self.db_path.setObjectName("db_path") + self.gridLayout.addWidget(self.db_path, 1, 1, 1, 1) + self.save_path = QtWidgets.QLineEdit(self.formLayoutWidget) + self.save_path.setObjectName("save_path") + self.gridLayout.addWidget(self.save_path, 2, 1, 1, 1) + self.label_4 = QtWidgets.QLabel(self.formLayoutWidget) + self.label_4.setObjectName("label_4") + self.gridLayout.addWidget(self.label_4, 1, 0, 1, 1) + self.db_name = QtWidgets.QLineEdit(self.formLayoutWidget) + self.db_name.setObjectName("db_name") + self.gridLayout.addWidget(self.db_name, 0, 1, 1, 1) + self.tb_set_save_path = QtWidgets.QToolButton(self.formLayoutWidget) + self.tb_set_save_path.setObjectName("tb_set_save_path") + self.gridLayout.addWidget(self.tb_set_save_path, 2, 2, 1, 1) + spacerItem = QtWidgets.QSpacerItem( + 20, + 40, + QtWidgets.QSizePolicy.Policy.Minimum, + QtWidgets.QSizePolicy.Policy.Expanding, + ) + self.gridLayout.addItem(spacerItem, 3, 1, 1, 1) + self.tb_select_db = QtWidgets.QToolButton(self.formLayoutWidget) + self.tb_select_db.setObjectName("tb_select_db") + self.gridLayout.addWidget(self.tb_select_db, 0, 2, 1, 1) + self.scrollArea = QtWidgets.QScrollArea(self.frame) + self.scrollArea.setGeometry(QtCore.QRect(400, 130, 331, 411)) + self.scrollArea.setWidgetResizable(True) + self.scrollArea.setObjectName("scrollArea") + self.scrollAreaWidgetContents = QtWidgets.QWidget() + self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 329, 409)) + self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents") + self.treeWidget = QtWidgets.QTreeWidget(self.scrollAreaWidgetContents) + self.treeWidget.setGeometry(QtCore.QRect(0, 0, 331, 411)) + self.treeWidget.setObjectName("treeWidget") + self.treeWidget.setContextMenuPolicy( + QtCore.Qt.ContextMenuPolicy.ActionsContextMenu + ) + self.scrollArea.setWidget(self.scrollAreaWidgetContents) + self.label_3.setBuddy(self.db_name) + self.label_5.setBuddy(self.save_path) + self.label_4.setBuddy(self.db_path) + self.tb_select_db.clicked.connect(self.select_db) + self.tb_set_save_path.clicked.connect(self.set_save_path) + self.retranslateUi(Dialog) + self.buttonBox.accepted.connect(Dialog.accept) # type: ignore + self.buttonBox.rejected.connect(Dialog.reject) # type: ignore + QtCore.QMetaObject.connectSlotsByName(Dialog) + Dialog.setTabOrder(self.db_name, self.db_path) + Dialog.setTabOrder(self.db_path, self.save_path) + Dialog.setTabOrder(self.save_path, self.os_apps) + Dialog.setTabOrder(self.os_apps, self.textBrowser) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "Dialog")) + self.label.setText(_translate("Dialog", "Dateispezifische Einstellungen")) + self.textBrowser.setHtml( + _translate( + "Dialog", + '\n' + '\n" + '

Hier können Einstellungen f�r bestehende Dateiformate geändert, oder neue Dateiformate eingefügt werden

\n' + '


', + ) + ) + self.label_2.setText(_translate("Dialog", "Allgemeine Einstellungen")) + self.os_apps.setToolTip( + _translate( + "Dialog", + "Verwendet im Betriebssystem festgelegte Anwendungen um Dateien zu öffnen", + ) + ) + self.os_apps.setText(_translate("Dialog", "Standard-Apps verwenden")) + self.label_3.setToolTip( + _translate( + "Dialog", + '

Name der Datenbank, welche verwendet werden soll. Muss auf .db enden

', + ) + ) + self.label_3.setText(_translate("Dialog", "Datenbankname")) + self.label_5.setToolTip( + _translate( + "Dialog", + "Pfad, an dem heruntergeladene Dateien gespeichert werden sollen", + ) + ) + self.label_5.setText(_translate("Dialog", "Speicherpfad")) + self.label_4.setText(_translate("Dialog", "Datenbankpfad")) + self.db_name.setText(_translate("Dialog", "sap.db")) + self.tb_set_save_path.setText(_translate("Dialog", "...")) + self.tb_select_db.setText(_translate("Dialog", "...")) + self.load_config() + + def load_config(self): + self.db_name.setText(config.database.name) + self.db_path.setText(config.database.path) + self.save_path.setText(config.save_path) + self.os_apps.setChecked(config.default_apps) + applications = config.custom_applications + for application in applications: + name = application.application + file_type = application.extensions + display_name = application.name + print(name, file_type, display_name) # + # create new item + item = QtWidgets.QTreeWidgetItem(self.treeWidget) + item.setText(0, display_name) + + def select_db(self): + # open file dialog, limit to .db files + file_dialog = QtWidgets.QFileDialog() + file_dialog.setFileMode(QtWidgets.QFileDialog.FileMode.AnyFile) + file_dialog.setNameFilter("Datenbank (*.db)") + file_dialog.setViewMode(QtWidgets.QFileDialog.ViewMode.Detail) + if file_dialog.exec(): + self.db_name.setText(file_dialog.selectedFiles()[0].split("/")[-1]) + self.db_path.setText( + file_dialog.selectedFiles()[0].split(self.db_name.text())[0] + ) + + def set_save_path(self): + # open file dialog, limit to .db files + file_dialog = QtWidgets.QFileDialog() + file_dialog.setFileMode(QtWidgets.QFileDialog.FileMode.Directory) + file_dialog.setViewMode(QtWidgets.QFileDialog.ViewMode.Detail) + if file_dialog.exec(): + self.save_path.setText(file_dialog.selectedFiles()[0]) + + def return_data(self): + config.database.name = self.db_name.text() + config.database.path = self.db_path.text() + config.save_path = self.save_path.text() + config.default_apps = self.os_apps.isChecked() + return config diff --git a/src/ui/dialogs/Ui_settings.ts b/src/ui/dialogs/Ui_settings.ts new file mode 100644 index 0000000..6401616 --- /dev/null +++ b/src/ui/dialogs/Ui_settings.ts @@ -0,0 +1,4 @@ + + + + diff --git a/src/ui/dialogs/__init__.py b/src/ui/dialogs/__init__.py new file mode 100644 index 0000000..72ca62f --- /dev/null +++ b/src/ui/dialogs/__init__.py @@ -0,0 +1,24 @@ +from .app_ext import Ui_Dialog as App_Ext_Dialog +from .ext_app import Ui_Frame as App_Ext_Window +from .mail import Mail_Dialog +from .popup_confirm import Ui_extend_confirm as popus_confirm +from .settings import Settings +from .Ui_edit_bookdata import Ui_Dialog as edit_bookdata_ui +from .Ui_fileparser import Ui_Dialog as fileparser_ui +from .Ui_login import Ui_Dialog as login_ui +from .Ui_medianadder import Ui_Dialog as medienadder_ui +from .Ui_parsed_titles import Ui_Form as parsed_titles_ui +from .Ui_reminder import Ui_Dialog as reminder_ui +from .Ui_settings import Ui_Dialog as settings_ui +from .Ui_new_subject import Ui_Dialog as new_subject_ui + +__all__ = [ + "ext_app", + "app_ext", + "Mail_Dialog", + "medianadder_ui", + "popup_confirm", + "edit_bookdata_ui", + "settings_ui", + "parsed_titles_ui", +] diff --git a/src/ui/dialogs/add_media.ui b/src/ui/dialogs/add_media.ui new file mode 100644 index 0000000..8e941ef --- /dev/null +++ b/src/ui/dialogs/add_media.ui @@ -0,0 +1,90 @@ + + + Dialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + 30 + 260 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 10 + 10 + 381 + 241 + + + + + + + Signatur + + + + + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/dialogs/app_ext.py b/src/ui/dialogs/app_ext.py new file mode 100644 index 0000000..af9c0e3 --- /dev/null +++ b/src/ui/dialogs/app_ext.py @@ -0,0 +1,114 @@ +# Form implementation generated from reading ui file 'ui\dialogs\apparat_extend.ui' +# +# Created by: PyQt6 UI code generator 6.3.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName("Dialog") + Dialog.resize(388, 103) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed + ) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(Dialog.sizePolicy().hasHeightForWidth()) + Dialog.setSizePolicy(sizePolicy) + Dialog.setMinimumSize(QtCore.QSize(388, 103)) + Dialog.setMaximumSize(QtCore.QSize(388, 103)) + self.buttonBox = QtWidgets.QDialogButtonBox(Dialog) + self.buttonBox.setGeometry(QtCore.QRect(290, 30, 81, 241)) + self.buttonBox.setOrientation(QtCore.Qt.Orientation.Vertical) + self.buttonBox.setStandardButtons( + QtWidgets.QDialogButtonBox.StandardButton.Abort + | QtWidgets.QDialogButtonBox.StandardButton.Save + ) + self.buttonBox.setObjectName("buttonBox") + self.label = QtWidgets.QLabel(Dialog) + self.label.setGeometry(QtCore.QRect(10, 0, 281, 31)) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed + ) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth()) + self.label.setSizePolicy(sizePolicy) + font = QtGui.QFont() + font.setPointSize(10) + self.label.setFont(font) + self.label.setObjectName("label") + self.frame = QtWidgets.QFrame(Dialog) + self.frame.setGeometry(QtCore.QRect(10, 30, 241, 41)) + self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame.setObjectName("frame") + self.line = QtWidgets.QFrame(self.frame) + self.line.setGeometry(QtCore.QRect(120, 0, 3, 61)) + self.line.setFrameShape(QtWidgets.QFrame.Shape.VLine) + self.line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.line.setObjectName("line") + self.rad_sommer = QtWidgets.QRadioButton(self.frame) + self.rad_sommer.setGeometry(QtCore.QRect(10, 10, 82, 21)) + self.rad_sommer.setObjectName("rad_sommer") + self.rad_winter = QtWidgets.QRadioButton(self.frame) + self.rad_winter.setGeometry(QtCore.QRect(140, 10, 82, 21)) + self.rad_winter.setObjectName("rad_winter") + self.sem_year = QtWidgets.QLineEdit(Dialog) + self.sem_year.setGeometry(QtCore.QRect(10, 70, 121, 20)) + self.sem_year.setObjectName("sem_year") + self.dauerapp = QtWidgets.QCheckBox(Dialog) + self.dauerapp.setGeometry(QtCore.QRect(150, 70, 91, 21)) + self.dauerapp.setObjectName("dauerapp") + + self.retranslateUi(Dialog) + self.buttonBox.accepted.connect(Dialog.accept) # type: ignore + self.buttonBox.rejected.connect(Dialog.reject) # type: ignore + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "Dialog")) + self.label.setText( + _translate("Dialog", "Bis wann soll der Apparat verlängert werden?") + ) + self.rad_sommer.setText(_translate("Dialog", "Sommer")) + self.rad_winter.setText(_translate("Dialog", "Winter")) + self.sem_year.setPlaceholderText(_translate("Dialog", "2023")) + self.dauerapp.setText(_translate("Dialog", "Dauerapparat")) + + def get_data(self): + # def __select_sem_state(): + # curr_month=QtCore.QDate.currentDate().month() + # if curr_month>=4 and curr_month<=9: + # return "SoSe" + # else: + # return "WiSe" + # if __select_sem_state()=="SoSe": + # self.rad_sommer.setChecked(True) + # else: + # self.rad_winter.setChecked(True) + return { + "semester": f"SoSe {int(self.sem_year.text()[-2:])}" + if self.rad_sommer.isChecked() + else f"WiSe {int(self.sem_year.text()[-2:])}/{int(self.sem_year.text()[-2:])+1}", + "dauerapp": self.dauerapp.isChecked() + if self.dauerapp.isChecked() + else False, + } + + +if __name__ == "__main__": + import sys + + app = QtWidgets.QApplication(sys.argv) + Dialog = QtWidgets.QDialog() + ui = Ui_Dialog() + ui.setupUi(Dialog) + Dialog.show() + sys.exit(app.exec()) diff --git a/src/ui/dialogs/app_status.ui b/src/ui/dialogs/app_status.ui new file mode 100644 index 0000000..bc4fc7b --- /dev/null +++ b/src/ui/dialogs/app_status.ui @@ -0,0 +1,19 @@ + + + Form + + + + 0 + 0 + 300 + 500 + + + + Form + + + + + diff --git a/src/ui/dialogs/apparat_extend.ui b/src/ui/dialogs/apparat_extend.ui new file mode 100644 index 0000000..f8b513e --- /dev/null +++ b/src/ui/dialogs/apparat_extend.ui @@ -0,0 +1,191 @@ + + + Dialog + + + + 0 + 0 + 388 + 103 + + + + + 0 + 0 + + + + + 388 + 103 + + + + + 388 + 103 + + + + Dialog + + + + + 290 + 30 + 81 + 241 + + + + Qt::Vertical + + + QDialogButtonBox::Abort|QDialogButtonBox::Save + + + + + + 10 + 0 + 281 + 31 + + + + + 0 + 0 + + + + + 10 + + + + Bis wann soll der Apparat verlängert werden? + + + + + + 10 + 30 + 241 + 41 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 120 + 0 + 3 + 61 + + + + Qt::Vertical + + + + + + 10 + 10 + 82 + 21 + + + + Sommer + + + + + + 140 + 10 + 82 + 21 + + + + Winter + + + + + + + 10 + 70 + 121 + 20 + + + + 2023 + + + + + + 150 + 70 + 91 + 21 + + + + Dauerapparat + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/dialogs/apparat_extend_ui.py b/src/ui/dialogs/apparat_extend_ui.py new file mode 100644 index 0000000..edeaf52 --- /dev/null +++ b/src/ui/dialogs/apparat_extend_ui.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'apparat_extend.ui' +## +## Created by: Qt User Interface Compiler version 6.4.0 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, + QMetaObject, QObject, QPoint, QRect, + QSize, QTime, QUrl, Qt) +from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, + QFont, QFontDatabase, QGradient, QIcon, + QImage, QKeySequence, QLinearGradient, QPainter, + QPalette, QPixmap, QRadialGradient, QTransform) +from PySide6.QtWidgets import (QAbstractButton, QApplication, QCheckBox, QDialog, + QDialogButtonBox, QFrame, QLabel, QLineEdit, + QRadioButton, QSizePolicy, QWidget) + +class Ui_Dialog(object): + def setupUi(self, Dialog): + if not Dialog.objectName(): + Dialog.setObjectName(u"Dialog") + Dialog.resize(388, 103) + sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(Dialog.sizePolicy().hasHeightForWidth()) + Dialog.setSizePolicy(sizePolicy) + Dialog.setMinimumSize(QSize(388, 103)) + Dialog.setMaximumSize(QSize(388, 103)) + self.buttonBox = QDialogButtonBox(Dialog) + self.buttonBox.setObjectName(u"buttonBox") + self.buttonBox.setGeometry(QRect(290, 30, 81, 241)) + self.buttonBox.setOrientation(Qt.Vertical) + self.buttonBox.setStandardButtons(QDialogButtonBox.Abort|QDialogButtonBox.Save) + self.label = QLabel(Dialog) + self.label.setObjectName(u"label") + self.label.setGeometry(QRect(10, 0, 281, 31)) + font = QFont() + font.setPointSize(10) + self.label.setFont(font) + self.frame = QFrame(Dialog) + self.frame.setObjectName(u"frame") + self.frame.setGeometry(QRect(10, 30, 241, 41)) + self.frame.setFrameShape(QFrame.StyledPanel) + self.frame.setFrameShadow(QFrame.Raised) + self.line = QFrame(self.frame) + self.line.setObjectName(u"line") + self.line.setGeometry(QRect(120, 0, 3, 61)) + self.line.setFrameShape(QFrame.VLine) + self.line.setFrameShadow(QFrame.Sunken) + self.rad_sommer = QRadioButton(self.frame) + self.rad_sommer.setObjectName(u"rad_sommer") + self.rad_sommer.setGeometry(QRect(10, 10, 82, 21)) + self.rad_winter = QRadioButton(self.frame) + self.rad_winter.setObjectName(u"rad_winter") + self.rad_winter.setGeometry(QRect(140, 10, 82, 21)) + self.sem_year = QLineEdit(Dialog) + self.sem_year.setObjectName(u"sem_year") + self.sem_year.setGeometry(QRect(10, 70, 121, 20)) + self.checkBox = QCheckBox(Dialog) + self.checkBox.setObjectName(u"checkBox") + self.checkBox.setGeometry(QRect(150, 70, 91, 21)) + + self.retranslateUi(Dialog) + self.buttonBox.accepted.connect(Dialog.accept) + self.buttonBox.rejected.connect(Dialog.reject) + + QMetaObject.connectSlotsByName(Dialog) + # setupUi + + def retranslateUi(self, Dialog): + Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Dialog", None)) + self.label.setText(QCoreApplication.translate("Dialog", u"Bis wann soll der Apparat verl\u00e4ngert werden?", None)) + self.rad_sommer.setText(QCoreApplication.translate("Dialog", u"Sommer", None)) + self.rad_winter.setText(QCoreApplication.translate("Dialog", u"Winter", None)) + self.sem_year.setPlaceholderText(QCoreApplication.translate("Dialog", u"2023", None)) + self.checkBox.setText(QCoreApplication.translate("Dialog", u"Dauerapparat", None)) + # retranslateUi + diff --git a/src/ui/dialogs/confirm_extend.ui b/src/ui/dialogs/confirm_extend.ui new file mode 100644 index 0000000..7b2cde2 --- /dev/null +++ b/src/ui/dialogs/confirm_extend.ui @@ -0,0 +1,78 @@ + + + extend_confirm + + + + 0 + 0 + 380 + 97 + + + + Dialog + + + + + 290 + 20 + 81 + 241 + + + + Qt::Vertical + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 10 + 10 + 271 + 81 + + + + + + + + buttonBox + accepted() + extend_confirm + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + extend_confirm + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/dialogs/confirm_extend_ui.py b/src/ui/dialogs/confirm_extend_ui.py new file mode 100644 index 0000000..8d087f6 --- /dev/null +++ b/src/ui/dialogs/confirm_extend_ui.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'confirm_extend.ui' +## +## Created by: Qt User Interface Compiler version 6.4.0 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, + QMetaObject, QObject, QPoint, QRect, + QSize, QTime, QUrl, Qt) +from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, + QFont, QFontDatabase, QGradient, QIcon, + QImage, QKeySequence, QLinearGradient, QPainter, + QPalette, QPixmap, QRadialGradient, QTransform) +from PySide6.QtWidgets import (QAbstractButton, QApplication, QDialog, QDialogButtonBox, + QSizePolicy, QTextEdit, QWidget) + +class Ui_extend_confirm(object): + def setupUi(self, extend_confirm): + if not extend_confirm.objectName(): + extend_confirm.setObjectName(u"extend_confirm") + extend_confirm.resize(380, 97) + self.buttonBox = QDialogButtonBox(extend_confirm) + self.buttonBox.setObjectName(u"buttonBox") + self.buttonBox.setGeometry(QRect(290, 20, 81, 241)) + self.buttonBox.setOrientation(Qt.Vertical) + self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok) + self.textEdit = QTextEdit(extend_confirm) + self.textEdit.setObjectName(u"textEdit") + self.textEdit.setGeometry(QRect(10, 10, 271, 81)) + + self.retranslateUi(extend_confirm) + self.buttonBox.accepted.connect(extend_confirm.accept) + self.buttonBox.rejected.connect(extend_confirm.reject) + + QMetaObject.connectSlotsByName(extend_confirm) + # setupUi + + def retranslateUi(self, extend_confirm): + extend_confirm.setWindowTitle(QCoreApplication.translate("extend_confirm", u"Dialog", None)) + # retranslateUi + diff --git a/src/ui/dialogs/edit_bookdata.ui b/src/ui/dialogs/edit_bookdata.ui new file mode 100644 index 0000000..0ad922d --- /dev/null +++ b/src/ui/dialogs/edit_bookdata.ui @@ -0,0 +1,216 @@ + + + Dialog + + + + 0 + 0 + 448 + 572 + + + + Dialog + + + + + 260 + 530 + 161 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 0 + 0 + 441 + 531 + + + + + QLayout::SetDefaultConstraint + + + + + Seiten + + + + + + + Titel + + + + + + + Jahr + + + + + + + Sprache + + + + + + + Link + + + + + + + + + + Auflage + + + + + + + Autor + + + + + + + ArrowCursor + + + true + + + + + + + Herausgeber + + + + + + + ISBN(s) + + + + + + + PPN + + + + + + + Signatur + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/dialogs/ext_app.py b/src/ui/dialogs/ext_app.py new file mode 100644 index 0000000..5ff330d --- /dev/null +++ b/src/ui/dialogs/ext_app.py @@ -0,0 +1,51 @@ +# Form implementation generated from reading ui file 'ui/dialogs/extend_apparat.ui' +# +# Created by: PyQt6 UI code generator 6.3.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_Frame(object): + def setupUi(self, Frame): + Frame.setObjectName("Frame") + Frame.resize(317, 126) + self.label = QtWidgets.QLabel(Frame) + self.label.setGeometry(QtCore.QRect(60, 20, 231, 16)) + self.label.setObjectName("label") + self.buttonBox = QtWidgets.QDialogButtonBox(Frame) + self.buttonBox.setGeometry(QtCore.QRect(90, 90, 156, 23)) + self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok) + self.buttonBox.setObjectName("buttonBox") + self.sem_winter = QtWidgets.QRadioButton(Frame) + self.sem_winter.setGeometry(QtCore.QRect(60, 40, 82, 17)) + self.sem_winter.setObjectName("sem_winter") + self.sem_sommer = QtWidgets.QRadioButton(Frame) + self.sem_sommer.setGeometry(QtCore.QRect(60, 60, 82, 17)) + self.sem_sommer.setObjectName("sem_sommer") + self.sem_year = QtWidgets.QLineEdit(Frame) + self.sem_year.setGeometry(QtCore.QRect(160, 50, 113, 20)) + self.sem_year.setObjectName("sem_year") + + self.retranslateUi(Frame) + QtCore.QMetaObject.connectSlotsByName(Frame) + + def retranslateUi(self, Frame): + _translate = QtCore.QCoreApplication.translate + Frame.setWindowTitle(_translate("Frame", "Frame")) + self.label.setText(_translate("Frame", "Bis wann soll der Apparat verlängert werden?")) + self.sem_winter.setText(_translate("Frame", "Winter")) + self.sem_sommer.setText(_translate("Frame", "Sommer")) + + +if __name__ == "__main__": + import sys + app = QtWidgets.QApplication(sys.argv) + Frame = QtWidgets.QFrame() + ui = Ui_Frame() + ui.setupUi(Frame) + Frame.show() + sys.exit(app.exec()) diff --git a/src/ui/dialogs/extend_apparat.ui b/src/ui/dialogs/extend_apparat.ui new file mode 100644 index 0000000..ade388f --- /dev/null +++ b/src/ui/dialogs/extend_apparat.ui @@ -0,0 +1,81 @@ + + + Frame + + + + 0 + 0 + 317 + 126 + + + + Frame + + + + + 60 + 20 + 231 + 16 + + + + Bis wann soll der Apparat verlängert werden? + + + + + + 90 + 90 + 156 + 23 + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 60 + 40 + 82 + 17 + + + + Winter + + + + + + 60 + 60 + 82 + 17 + + + + Sommer + + + + + + 160 + 50 + 113 + 20 + + + + + + + diff --git a/src/ui/dialogs/fileparser.ui b/src/ui/dialogs/fileparser.ui new file mode 100644 index 0000000..86e7bdf --- /dev/null +++ b/src/ui/dialogs/fileparser.ui @@ -0,0 +1,129 @@ + + + Dialog + + + + 0 + 0 + 402 + 301 + + + + Dialog + + + + + 10 + 60 + 381 + 23 + + + + 24 + + + + + + 10 + 10 + 381 + 41 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 0 + 0 + 381 + 41 + + + + + + + Es wurden + + + + + + + + 75 + true + + + + 0 + + + Qt::PlainText + + + + + + + Signaturen gefunden. + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 10 + 100 + 381 + 201 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 0 + 0 + 381 + 191 + + + + + + + + diff --git a/src/ui/dialogs/login.ui b/src/ui/dialogs/login.ui new file mode 100644 index 0000000..5b3239b --- /dev/null +++ b/src/ui/dialogs/login.ui @@ -0,0 +1,120 @@ + + + Dialog + + + + 0 + 0 + 218 + 190 + + + + Dialog + + + + + 30 + 140 + 161 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 20 + 40 + 71 + 21 + + + + Username + + + + + + 80 + 40 + 113 + 21 + + + + + + + 20 + 80 + 71 + 21 + + + + Password + + + + + + 80 + 80 + 113 + 21 + + + + Qt::ImhSensitiveData + + + true + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/dialogs/mail.py b/src/ui/dialogs/mail.py new file mode 100644 index 0000000..cd57712 --- /dev/null +++ b/src/ui/dialogs/mail.py @@ -0,0 +1,69 @@ +import subprocess +import tempfile + +from PyQt6 import QtCore, QtGui, QtWidgets + +from src.ui.dialogs.mail_preview import Ui_Dialog + + +class Mail_Dialog(QtWidgets.QDialog, Ui_Dialog): + def __init__(self, parent=None): + super().__init__(parent) + self.setupUi(self) + self.appid = "" + self.mail_data = "" + self.data = None + self.buttonBox.accepted.connect(self.save_mail) + + def set_data(self, data: dict): + self.prof_name.setText(data["prof_name"]) + self.mail_name.setText(data["mail_name"]) + # assign data["general"] to self.data + self.data = data["general"] + + def set_mail(self): + email_template = self.comboBox.currentText() + with open(f"mail_vorlagen/{email_template}", "r", encoding="utf-8") as f: + mail_template = f.read() + email_header = email_template.split(".eml")[0] + if "{AppNr}" in email_template: + email_header = email_template.split(".eml")[0].format(AppNr=self.appid) + self.mail_header.setText(email_header) + self.mail_data = mail_template.split("")[0] + mail_html = mail_template.split("")[1] + mail_html = "" + mail_html + print(self.data) + Appname = self.data["Appname"] + mail_html = mail_html.format( + Profname=self.prof_name.text().split(" ")[-1], Appname=Appname + ) + + self.mail_body.setHtml(mail_html) + + def save_mail(self): + # create a temporary file + mail_header = self.mail_header.text() + mail_body = self.mail_body.toHtml() + mail = self.mail_data + mail_body + mail = mail.replace("Subject:", f"Subject: {mail_header}") + with tempfile.NamedTemporaryFile( + mode="w", delete=False, suffix=".eml", encoding="utf-8", dir="mails" + ) as f: + f.write(mail) + self.mail_path = f.name + print(self.mail_path) + # open the file using thunderbird + subprocess.Popen(["thunderbird", f"{self.mail_path}"]) + # delete the file + # os.remove(self.mail_path) + + +if __name__ == "__main__": + import sys + + app = QtWidgets.QApplication(sys.argv) + Dialog = QtWidgets.QDialog() + ui = Mail_Dialog() + ui.setupUi(Dialog) + Dialog.show() + sys.exit(app.exec()) diff --git a/src/ui/dialogs/mail_preview.py b/src/ui/dialogs/mail_preview.py new file mode 100644 index 0000000..c258514 --- /dev/null +++ b/src/ui/dialogs/mail_preview.py @@ -0,0 +1,81 @@ +# Form implementation generated from reading ui file 'ui\dialogs\mail_preview.ui' +# +# Created by: PyQt6 UI code generator 6.3.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName("Dialog") + Dialog.resize(676, 676) + self.buttonBox = QtWidgets.QDialogButtonBox(Dialog) + self.buttonBox.setGeometry(QtCore.QRect(310, 630, 341, 32)) + self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal) + self.buttonBox.setStandardButtons( + QtWidgets.QDialogButtonBox.StandardButton.Cancel + | QtWidgets.QDialogButtonBox.StandardButton.Ok + ) + self.buttonBox.setObjectName("buttonBox") + self.gridLayoutWidget = QtWidgets.QWidget(Dialog) + self.gridLayoutWidget.setGeometry(QtCore.QRect(10, 10, 661, 621)) + self.gridLayoutWidget.setObjectName("gridLayoutWidget") + self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget) + self.gridLayout.setContentsMargins(0, 0, 0, 0) + self.gridLayout.setObjectName("gridLayout") + self.prof_name = QtWidgets.QLineEdit(self.gridLayoutWidget) + self.prof_name.setObjectName("prof_name") + self.gridLayout.addWidget(self.prof_name, 2, 2, 1, 1) + self.label_3 = QtWidgets.QLabel(self.gridLayoutWidget) + self.label_3.setAlignment( + QtCore.Qt.AlignmentFlag.AlignLeading + | QtCore.Qt.AlignmentFlag.AlignLeft + | QtCore.Qt.AlignmentFlag.AlignTop + ) + self.label_3.setObjectName("label_3") + self.gridLayout.addWidget(self.label_3, 4, 0, 1, 1) + self.label_2 = QtWidgets.QLabel(self.gridLayoutWidget) + self.label_2.setObjectName("label_2") + self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1) + self.label_4 = QtWidgets.QLabel(self.gridLayoutWidget) + self.label_4.setObjectName("label_4") + self.gridLayout.addWidget(self.label_4, 3, 0, 1, 1) + self.mail_header = QtWidgets.QLineEdit(self.gridLayoutWidget) + self.mail_header.setObjectName("mail_header") + self.gridLayout.addWidget(self.mail_header, 3, 2, 1, 1) + self.mail_name = QtWidgets.QLineEdit(self.gridLayoutWidget) + self.mail_name.setObjectName("mail_name") + self.gridLayout.addWidget(self.mail_name, 1, 2, 1, 1) + self.mail_body = QtWidgets.QTextEdit(self.gridLayoutWidget) + self.mail_body.setObjectName("mail_body") + self.gridLayout.addWidget(self.mail_body, 4, 2, 1, 1) + self.label = QtWidgets.QLabel(self.gridLayoutWidget) + self.label.setObjectName("label") + self.gridLayout.addWidget(self.label, 1, 0, 1, 1) + self.comboBox = QtWidgets.QComboBox(self.gridLayoutWidget) + self.comboBox.setObjectName("comboBox") + self.gridLayout.addWidget(self.comboBox, 0, 2, 1, 1) + self.label_5 = QtWidgets.QLabel(self.gridLayoutWidget) + self.label_5.setObjectName("label_5") + self.gridLayout.addWidget(self.label_5, 0, 0, 1, 1) + # at selection change, load mail text + + self.comboBox.currentIndexChanged.connect(self.set_mail) + self.retranslateUi(Dialog) + self.buttonBox.accepted.connect(Dialog.accept) # type: ignore + self.buttonBox.rejected.connect(Dialog.reject) # type: ignore + # if the dialog is accepted, save the mail and send it + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "Dialog")) + self.label_3.setText(_translate("Dialog", "Mail")) + self.label_2.setText(_translate("Dialog", "Prof")) + self.label_4.setText(_translate("Dialog", "Betreff")) + self.label.setText(_translate("Dialog", "eMail")) + self.label_5.setText(_translate("Dialog", "Art")) diff --git a/src/ui/dialogs/mail_preview.ui b/src/ui/dialogs/mail_preview.ui new file mode 100644 index 0000000..847ea39 --- /dev/null +++ b/src/ui/dialogs/mail_preview.ui @@ -0,0 +1,133 @@ + + + Dialog + + + + 0 + 0 + 676 + 676 + + + + Dialog + + + + + 310 + 630 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 10 + 10 + 661 + 621 + + + + + + + + + + Mail + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + Prof + + + + + + + Betreff + + + + + + + + + + + + + + + + eMail + + + + + + + + + + Art + + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/dialogs/medianadder.ui b/src/ui/dialogs/medianadder.ui new file mode 100644 index 0000000..9a5b6ac --- /dev/null +++ b/src/ui/dialogs/medianadder.ui @@ -0,0 +1,557 @@ + + + Dialog + + + + 0 + 0 + 637 + 491 + + + + Dialog + + + + + 20 + 10 + 47 + 21 + + + + Signatur + + + + + + 20 + 40 + 47 + 21 + + + + Modus + + + + + + 70 + 40 + 69 + 22 + + + + + ARRAY + + + + + BibTeX + + + + + COinS + + + + + RIS + + + + + + + 70 + 10 + 113 + 20 + + + + Signatur / ISBN + + + + + + 20 + 70 + 47 + 21 + + + + Queue + + + + + + 330 + 90 + 301 + 341 + + + + + true + + + + 0 + 0 + 301 + 341 + + + + Qt::NoFocus + + + false + + + 0 + + + 0 + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + QAbstractScrollArea::AdjustToContents + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::NoSelection + + + Qt::ElideMiddle + + + true + + + false + + + false + + + false + + + 96 + + + false + + + 20 + + + false + + + + Datensatz\Metadata + + + + 7 + + + + + + Array + + + + + BibTeX + + + + + COinS + + + + + RIS + + + + + PPN + + + 1 + + + 0 + + + + + 255 + 0 + 0 + + + + + 1 + + + 1 + + + + + Signatur + + + 1 + + + 1 + + + + + 0 + 255 + 0 + + + + + 0 + + + 1 + + + + + Autor + + + 1 + + + 1 + + + 1 + + + 1 + + + + + ISBN + + + 1 + + + 1 + + + 1 + + + 1 + + + + + Jahr + + + 1 + + + 1 + + + 1 + + + 1 + + + + + Auflage + + + 1 + + + 1 + + + 1 + + + 1 + + + + + Sprache + + + 1 + + + 1 + + + 0 + + + 1 + + + + + Herausgeber + + + 1 + + + 1 + + + 1 + + + 1 + + + + + Seiten + + + 1 + + + 1 + + + 1 + + + 1 + + + + + Titel + + + 1 + + + 1 + + + 1 + + + 1 + + + + + Link + + + 1 + + + 0 + + + 1 + + + 1 + + + + + + + + 10 + 90 + 281 + 341 + + + + Qt::CustomContextMenu + + + + + + 330 + 50 + 181 + 21 + + + + Belegbare Felder per Anbieter + + + + + + 200 + 70 + 41 + 21 + + + + Anzahl: + + + + + + 240 + 70 + 47 + 21 + + + + 0 + + + + + + 10 + 450 + 156 + 23 + + + + Qt::NoFocus + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + false + + + + + + 190 + 10 + 21 + 23 + + + + Qt::ClickFocus + + + Clicken oder Shift Enter drücken um den Eintrag hinzuzufügen + + + + + + + :/information/icons/information.png:/information/icons/information.png + + + Shift+Return + + + false + + + + + lineEdit + comboBox + listWidget + treeWidget + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 87 + 461 + + + 318 + 245 + + + + + buttonBox + rejected() + Dialog + reject() + + + 87 + 461 + + + 318 + 245 + + + + + diff --git a/src/ui/dialogs/medianadder_ui.ts b/src/ui/dialogs/medianadder_ui.ts new file mode 100644 index 0000000..978f01e --- /dev/null +++ b/src/ui/dialogs/medianadder_ui.ts @@ -0,0 +1,47 @@ + + + + + Dialog + + + Dialog + + + + + Signatur + + + + + Modus + + + + + ARRAY + + + + + BibTeX + + + + + COinS + + + + + RIS + + + + + Queue + + + + diff --git a/src/ui/dialogs/medienadder.py b/src/ui/dialogs/medienadder.py new file mode 100644 index 0000000..31f26cc --- /dev/null +++ b/src/ui/dialogs/medienadder.py @@ -0,0 +1,82 @@ +from PyQt6 import QtCore, QtGui, QtWidgets + +from .Ui_medianadder import Ui_Dialog + + +class MedienAdder(QtWidgets.QDialog): + def __init__(self): + super().__init__() + self.ui = Ui_Dialog() + self.ui.setupUi(self) + + # Connect signals and slots for your custom functionality + self.ui.buttonBox.accepted.connect(self.accept) + self.ui.buttonBox.rejected.connect(self.reject) + self.ui.l_add.clicked.connect(self.add_to_list) + self.ui.l_add.setShortcut("Shift+Return") + # Initialize data variables to store the results + self.result_data = [] + + self.recolorize() + + def add_to_list(self): + text = self.ui.lineEdit.text().strip() + if text == "": + return + else: + self.ui.listWidget.addItem(text) + self.ui.list_amount.setText(str(self.ui.listWidget.count())) + self.ui.lineEdit.clear() + + def recolorize(self): + # set the color of the cells of the treeWidget to red if the field is not supported by the provider + # else set it to green + for i in range(self.ui.treeWidget.topLevelItemCount()): + for j in range(1, self.ui.treeWidget.columnCount()): + if self.ui.treeWidget.topLevelItem(i).text(j) == "0": + self.ui.treeWidget.topLevelItem(i).setBackground( + j, QtGui.QColor(255, 0, 0) + ) + else: + self.ui.treeWidget.topLevelItem(i).setBackground( + j, QtGui.QColor(0, 255, 0) + ) + # remove the text from the cells + self.ui.treeWidget.topLevelItem(i).setText(j, "") + + def custom_context_menu(self): + menu = QtWidgets.QMenu() + menu.addAction("Remove") + + action = menu.exec(QtGui.QCursor.pos()) + if action.text() == "Remove": + self.remove_from_list() + + def remove_from_list(self): + self.ui.listWidget.takeItem(self.ui.listWidget.currentRow()) + self.ui.list_amount.setText(str(self.ui.listWidget.count())) + + def add_to_list(self): + text = self.ui.lineEdit.text().strip() + if text: + self.ui.listWidget.addItem(text) + self.ui.list_amount.setText(str(self.ui.listWidget.count())) + self.ui.lineEdit.clear() + + def accept(self): + # Gather and store the data you want to return + self.result_data = [ + self.ui.listWidget.item(i).text() for i in range(self.ui.listWidget.count()) + ] + super().accept() + + def keyPressEvent(self, event): + if ( + event.key() == QtCore.Qt.Key.Key_Return + or event.key() == QtCore.Qt.Key.Key_Enter + ): + # Handle the Return key press as needed (e.g., add to list) + self.add_to_list() + event.accept() + else: + super().keyPressEvent(event) diff --git a/src/ui/dialogs/new_subject.ui b/src/ui/dialogs/new_subject.ui new file mode 100644 index 0000000..3eca687 --- /dev/null +++ b/src/ui/dialogs/new_subject.ui @@ -0,0 +1,132 @@ + + + Dialog + + + + 0 + 0 + 448 + 165 + + + + Dialog + + + + + + + + Das eingegebene Fach wurde nicht in der Datenbank gefunden. Soll es angelegt werden? + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ja + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 0 + 10 + 141 + 16 + + + + Name des Neuen Faches: + + + + + + 0 + 30 + 141 + 20 + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/dialogs/new_subject_ui.py b/src/ui/dialogs/new_subject_ui.py new file mode 100644 index 0000000..bbcc9dd --- /dev/null +++ b/src/ui/dialogs/new_subject_ui.py @@ -0,0 +1,59 @@ +# Form implementation generated from reading ui file '/home/alexander/GitHub/Semesterapparate/ui/dialogs/new_subject.ui' +# +# Created by: PyQt6 UI code generator 6.5.3 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName("Dialog") + Dialog.resize(448, 165) + self.verticalLayout_2 = QtWidgets.QVBoxLayout(Dialog) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.verticalLayout = QtWidgets.QVBoxLayout() + self.verticalLayout.setObjectName("verticalLayout") + self.label = QtWidgets.QLabel(parent=Dialog) + self.label.setObjectName("label") + self.verticalLayout.addWidget(self.label) + self.gridLayout = QtWidgets.QGridLayout() + self.gridLayout.setObjectName("gridLayout") + spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.gridLayout.addItem(spacerItem, 0, 1, 1, 1) + self.checkBox = QtWidgets.QCheckBox(parent=Dialog) + self.checkBox.setObjectName("checkBox") + self.gridLayout.addWidget(self.checkBox, 0, 0, 1, 1) + self.verticalLayout.addLayout(self.gridLayout) + self.verticalLayout_2.addLayout(self.verticalLayout) + self.frame = QtWidgets.QFrame(parent=Dialog) + self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame.setObjectName("frame") + self.label_2 = QtWidgets.QLabel(parent=self.frame) + self.label_2.setGeometry(QtCore.QRect(0, 10, 141, 16)) + self.label_2.setObjectName("label_2") + self.lineEdit = QtWidgets.QLineEdit(parent=self.frame) + self.lineEdit.setGeometry(QtCore.QRect(0, 30, 141, 20)) + self.lineEdit.setObjectName("lineEdit") + self.verticalLayout_2.addWidget(self.frame) + self.buttonBox = QtWidgets.QDialogButtonBox(parent=Dialog) + self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal) + self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok) + self.buttonBox.setObjectName("buttonBox") + self.verticalLayout_2.addWidget(self.buttonBox) + + self.retranslateUi(Dialog) + self.buttonBox.accepted.connect(Dialog.accept) # type: ignore + self.buttonBox.rejected.connect(Dialog.reject) # type: ignore + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "Dialog")) + self.label.setText(_translate("Dialog", "Das eingegebene Fach wurde nicht in der Datenbank gefunden. Soll es angelegt werden?")) + self.checkBox.setText(_translate("Dialog", "Ja")) + self.label_2.setText(_translate("Dialog", "Name des Neuen Faches:")) diff --git a/src/ui/dialogs/parsed_titles.ui b/src/ui/dialogs/parsed_titles.ui new file mode 100644 index 0000000..1789f2f --- /dev/null +++ b/src/ui/dialogs/parsed_titles.ui @@ -0,0 +1,163 @@ + + + Form + + + + 0 + 0 + 402 + 316 + + + + Form + + + + + 10 + 10 + 381 + 41 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 0 + 0 + 381 + 41 + + + + + + + Es wurden + + + + + + + + 75 + true + + + + 0 + + + Qt::PlainText + + + + + + + Signaturen gefunden. + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 10 + 80 + 381 + 201 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 0 + 10 + 381 + 191 + + + + + + + + + + + + + + + + 10 + 60 + 381 + 23 + + + + 24 + + + + + + 230 + 290 + 156 + 23 + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 20 + 290 + 25 + 19 + + + + ... + + + + + + diff --git a/src/ui/dialogs/parsed_titles_ui.py b/src/ui/dialogs/parsed_titles_ui.py new file mode 100644 index 0000000..746f908 --- /dev/null +++ b/src/ui/dialogs/parsed_titles_ui.py @@ -0,0 +1,81 @@ +# Form implementation generated from reading ui file '/home/alexander/GitHub/Semesterapparate/ui/dialogs/parsed_titles.ui' +# +# Created by: PyQt6 UI code generator 6.5.3 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_Form(object): + def setupUi(self, Form): + Form.setObjectName("Form") + Form.resize(402, 316) + self.frame = QtWidgets.QFrame(parent=Form) + self.frame.setGeometry(QtCore.QRect(10, 10, 381, 41)) + self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame.setObjectName("frame") + self.horizontalLayoutWidget = QtWidgets.QWidget(parent=self.frame) + self.horizontalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 381, 41)) + self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget") + self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget) + self.horizontalLayout.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout.setObjectName("horizontalLayout") + self.label = QtWidgets.QLabel(parent=self.horizontalLayoutWidget) + self.label.setObjectName("label") + self.horizontalLayout.addWidget(self.label) + self.count = QtWidgets.QLabel(parent=self.horizontalLayoutWidget) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + self.count.setFont(font) + self.count.setTextFormat(QtCore.Qt.TextFormat.PlainText) + self.count.setObjectName("count") + self.horizontalLayout.addWidget(self.count) + self.label_2 = QtWidgets.QLabel(parent=self.horizontalLayoutWidget) + self.label_2.setObjectName("label_2") + self.horizontalLayout.addWidget(self.label_2) + spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout.addItem(spacerItem) + self.frame_2 = QtWidgets.QFrame(parent=Form) + self.frame_2.setGeometry(QtCore.QRect(10, 80, 381, 201)) + self.frame_2.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame_2.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame_2.setObjectName("frame_2") + self.horizontalLayoutWidget_2 = QtWidgets.QWidget(parent=self.frame_2) + self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(0, 10, 381, 191)) + self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_2) + self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.listWidget = QtWidgets.QListWidget(parent=self.horizontalLayoutWidget_2) + self.listWidget.setObjectName("listWidget") + self.horizontalLayout_2.addWidget(self.listWidget) + self.listWidget_done = QtWidgets.QListWidget(parent=self.horizontalLayoutWidget_2) + self.listWidget_done.setObjectName("listWidget_done") + self.horizontalLayout_2.addWidget(self.listWidget_done) + self.progressBar = QtWidgets.QProgressBar(parent=Form) + self.progressBar.setGeometry(QtCore.QRect(10, 60, 381, 23)) + self.progressBar.setProperty("value", 24) + self.progressBar.setObjectName("progressBar") + self.buttonBox = QtWidgets.QDialogButtonBox(parent=Form) + self.buttonBox.setGeometry(QtCore.QRect(230, 290, 156, 23)) + self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok) + self.buttonBox.setObjectName("buttonBox") + self.toolButton = QtWidgets.QToolButton(parent=Form) + self.toolButton.setGeometry(QtCore.QRect(20, 290, 25, 19)) + self.toolButton.setObjectName("toolButton") + + self.retranslateUi(Form) + QtCore.QMetaObject.connectSlotsByName(Form) + + def retranslateUi(self, Form): + _translate = QtCore.QCoreApplication.translate + Form.setWindowTitle(_translate("Form", "Form")) + self.label.setText(_translate("Form", "Es wurden")) + self.count.setText(_translate("Form", "0")) + self.label_2.setText(_translate("Form", "Signaturen gefunden.")) + self.toolButton.setText(_translate("Form", "...")) diff --git a/src/ui/dialogs/popup_confirm.py b/src/ui/dialogs/popup_confirm.py new file mode 100644 index 0000000..a27c0bc --- /dev/null +++ b/src/ui/dialogs/popup_confirm.py @@ -0,0 +1,48 @@ +# Form implementation generated from reading ui file 'ui\dialogs\confirm_extend.ui' +# +# Created by: PyQt6 UI code generator 6.3.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_extend_confirm(object): + def setupUi(self, extend_confirm): + extend_confirm.setObjectName("extend_confirm") + extend_confirm.resize(380, 97) + # icon=QtGui.QIcon(f"ui/icons/{icon}.png") + # extend_confirm.setWindowIcon(icon) + self.buttonBox = QtWidgets.QDialogButtonBox(extend_confirm) + self.buttonBox.setGeometry(QtCore.QRect(290, 20, 81, 241)) + self.buttonBox.setOrientation(QtCore.Qt.Orientation.Vertical) + self.buttonBox.setStandardButtons( + QtWidgets.QDialogButtonBox.StandardButton.Cancel + | QtWidgets.QDialogButtonBox.StandardButton.Ok + ) + self.buttonBox.setObjectName("buttonBox") + self.textEdit = QtWidgets.QTextEdit(extend_confirm) + self.textEdit.setGeometry(QtCore.QRect(10, 10, 271, 81)) + self.textEdit.setObjectName("textEdit") + + self.retranslateUi(extend_confirm) + self.buttonBox.accepted.connect(extend_confirm.accept) # type: ignore + self.buttonBox.rejected.connect(extend_confirm.reject) # type: ignore + QtCore.QMetaObject.connectSlotsByName(extend_confirm) + + def retranslateUi(self, extend_confirm): + _translate = QtCore.QCoreApplication.translate + extend_confirm.setWindowTitle(_translate("extend_confirm", "Dialog")) + + +if __name__ == "__main__": + import sys + + app = QtWidgets.QApplication(sys.argv) + extend_confirm = QtWidgets.QDialog() + ui = Ui_extend_confirm() + ui.setupUi(extend_confirm) + extend_confirm.show() + sys.exit(app.exec()) diff --git a/src/ui/dialogs/reminder.ui b/src/ui/dialogs/reminder.ui new file mode 100644 index 0000000..a461a74 --- /dev/null +++ b/src/ui/dialogs/reminder.ui @@ -0,0 +1,114 @@ + + + Dialog + + + + 0 + 0 + 369 + 308 + + + + Dialog + + + + + 190 + 270 + 161 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 10 + 60 + 341 + 201 + + + + + + + 10 + 30 + 61 + 21 + + + + Nachricht: + + + + + + 150 + 30 + 81 + 21 + + + + Erinnerung am: + + + + + + 240 + 30 + 110 + 22 + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/dialogs/resources.qrc b/src/ui/dialogs/resources.qrc new file mode 100644 index 0000000..e69de29 diff --git a/src/ui/dialogs/settings.py b/src/ui/dialogs/settings.py new file mode 100644 index 0000000..63d7b62 --- /dev/null +++ b/src/ui/dialogs/settings.py @@ -0,0 +1,48 @@ +from omegaconf import OmegaConf +from PyQt6 import QtWidgets + +from src.ui.dialogs.Ui_settings import Ui_Dialog as _settings + +config = OmegaConf.load("config.yaml") + + +class Settings(_settings): + def __init__(self): + super().__init__() + self.setupUi(self) + self.retranslateUi(self) + self.load_config() + + def load_config(self): + self.db_name.setText(config.database.name) + self.db_path.setText(config.database.path) + self.save_path.setText(config.save_path) + self.os_apps.setChecked(config.default_apps) + + def select_db(self): + # open file dialog, limit to .db files + file_dialog = QtWidgets.QFileDialog() + file_dialog.setFileMode(QtWidgets.QFileDialog.FileMode.AnyFile) + file_dialog.setNameFilter("Datenbank (*.db)") + file_dialog.setViewMode(QtWidgets.QFileDialog.ViewMode.Detail) + if file_dialog.exec(): + self.db_name.setText(file_dialog.selectedFiles()[0].split("/")[-1]) + self.db_path.setText( + file_dialog.selectedFiles()[0].split(self.db_name.text())[0] + ) + + def set_save_path(self): + # open file dialog, limit to .db files + file_dialog = QtWidgets.QFileDialog() + file_dialog.setFileMode(QtWidgets.QFileDialog.FileMode.Directory) + file_dialog.setViewMode(QtWidgets.QFileDialog.ViewMode.Detail) + if file_dialog.exec(): + self.save_path.setText(file_dialog.selectedFiles()[0]) + + def return_data(self): + config.database.name = self.db_name.text() + config.database.path = self.db_path.text() + config.save_path = self.save_path.text() + config.default_apps = self.os_apps.isChecked() + + return config diff --git a/src/ui/dialogs/settings.ui b/src/ui/dialogs/settings.ui new file mode 100644 index 0000000..a3da916 --- /dev/null +++ b/src/ui/dialogs/settings.ui @@ -0,0 +1,308 @@ + + + Dialog + + + + 0 + 0 + 743 + 576 + + + + Dialog + + + + + 120 + 540 + 621 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 0 + 0 + 741 + 541 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 400 + 30 + 161 + 21 + + + + Dateispezifische Einstellungen + + + + + + 370 + 0 + 20 + 541 + + + + QFrame::Plain + + + 1 + + + 0 + + + Qt::Vertical + + + + + + 400 + 50 + 311 + 51 + + + + Qt::NoFocus + + + Qt::ImhNone + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Hier können Einstellungen für bestehende Dateiformate geändert, oder neue Dateiformate eingefügt werden.</p></body></html> + + + + + + 10 + 20 + 161 + 21 + + + + Allgemeine Einstellungen + + + + + + 410 + 110 + 161 + 17 + + + + Verwendet im Betriebssystem festgelegte Anwendungen um Dateien zu öffnen + + + Standard-Apps verwenden + + + + + + 10 + 50 + 361 + 491 + + + + + + + <html><head/><body><p>Name der Datenbank, welche verwendet werden soll. <span style=" font-weight:600;">Muss</span> auf .db enden</p></body></html> + + + Datenbankname + + + db_name + + + + + + + Pfad, an dem heruntergeladene Dateien gespeichert werden sollen + + + Speicherpfad + + + save_path + + + + + + + false + + + + + + + + + + Datenbankpfad + + + db_path + + + + + + + sap.db + + + + + + + ... + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + ... + + + + + + + + + 400 + 130 + 331 + 381 + + + + true + + + + + 0 + 0 + 329 + 379 + + + + + + 0 + 0 + 331 + 381 + + + + Qt::ActionsContextMenu + + + + + + + + db_name + db_path + save_path + os_apps + textBrowser + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 358 + 540 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 426 + 540 + + + 286 + 274 + + + + + diff --git a/src/ui/extensions/__init__.py b/src/ui/extensions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/ui/icons/critical.png b/src/ui/icons/critical.png new file mode 100644 index 0000000..cc65ce9 Binary files /dev/null and b/src/ui/icons/critical.png differ diff --git a/src/ui/icons/information.png b/src/ui/icons/information.png new file mode 100644 index 0000000..622dc87 Binary files /dev/null and b/src/ui/icons/information.png differ diff --git a/src/ui/icons/logo_SAP.ico b/src/ui/icons/logo_SAP.ico new file mode 100644 index 0000000..d62f0cb Binary files /dev/null and b/src/ui/icons/logo_SAP.ico differ diff --git a/src/ui/icons/logo_SAP.png b/src/ui/icons/logo_SAP.png new file mode 100644 index 0000000..8d4e350 Binary files /dev/null and b/src/ui/icons/logo_SAP.png differ diff --git a/src/ui/icons/question.png b/src/ui/icons/question.png new file mode 100644 index 0000000..35d103b Binary files /dev/null and b/src/ui/icons/question.png differ diff --git a/src/ui/icons/warning.png b/src/ui/icons/warning.png new file mode 100644 index 0000000..ae04ee4 Binary files /dev/null and b/src/ui/icons/warning.png differ diff --git a/src/ui/mainwindow.py b/src/ui/mainwindow.py new file mode 100644 index 0000000..fb8f979 --- /dev/null +++ b/src/ui/mainwindow.py @@ -0,0 +1,360 @@ +# Form implementation generated from reading ui file 'untitled.ui' +# +# Created by: PyQt6 UI code generator 6.3.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName("MainWindow") + MainWindow.resize(1280, 720) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth()) + MainWindow.setSizePolicy(sizePolicy) + self.centralwidget = QtWidgets.QWidget(MainWindow) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth()) + self.centralwidget.setSizePolicy(sizePolicy) + self.centralwidget.setObjectName("centralwidget") + self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget) + self.verticalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 1271, 671)) + self.verticalLayoutWidget.setObjectName("verticalLayoutWidget") + self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget) + self.verticalLayout.setContentsMargins(0, 0, 0, 0) + self.verticalLayout.setObjectName("verticalLayout") + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.gridLayout = QtWidgets.QGridLayout() + self.gridLayout.setObjectName("gridLayout") + self.tabWidget = QtWidgets.QTabWidget(self.verticalLayoutWidget) + self.tabWidget.setObjectName("tabWidget") + self.tab = QtWidgets.QWidget() + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.tab.sizePolicy().hasHeightForWidth()) + self.tab.setSizePolicy(sizePolicy) + self.tab.setObjectName("tab") + self.horizontalLayoutWidget_2 = QtWidgets.QWidget(self.tab) + self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(0, 0, 1261, 161)) + self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_2) + self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.formLayout = QtWidgets.QFormLayout() + self.formLayout.setObjectName("formLayout") + self.verticalLayout_2 = QtWidgets.QVBoxLayout() + self.verticalLayout_2.setObjectName("verticalLayout_2") + spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout_2.addItem(spacerItem) + self.load_app = QtWidgets.QPushButton(self.horizontalLayoutWidget_2) + self.load_app.setObjectName("load_app") + self.verticalLayout_2.addWidget(self.load_app) + self.create_new_app = QtWidgets.QPushButton(self.horizontalLayoutWidget_2) + self.create_new_app.setObjectName("create_new_app") + self.verticalLayout_2.addWidget(self.create_new_app) + spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout_2.addItem(spacerItem1) + self.formLayout.setLayout(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.verticalLayout_2) + self.tableWidget_apparate = QtWidgets.QTableWidget(self.horizontalLayoutWidget_2) + self.tableWidget_apparate.setObjectName("tableWidget_apparate") + self.tableWidget_apparate.setColumnCount(4) + self.tableWidget_apparate.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(3, item) + self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.tableWidget_apparate) + self.horizontalLayout_3 = QtWidgets.QHBoxLayout() + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.formLayout.setLayout(2, QtWidgets.QFormLayout.ItemRole.LabelRole, self.horizontalLayout_3) + self.horizontalLayout_4 = QtWidgets.QHBoxLayout() + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + self.formLayout.setLayout(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.horizontalLayout_4) + self.horizontalLayout_2.addLayout(self.formLayout) + self.line = QtWidgets.QFrame(self.tab) + self.line.setGeometry(QtCore.QRect(0, 160, 1261, 21)) + self.line.setFrameShape(QtWidgets.QFrame.Shape.HLine) + self.line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.line.setObjectName("line") + self.gridLayoutWidget_2 = QtWidgets.QWidget(self.tab) + self.gridLayoutWidget_2.setGeometry(QtCore.QRect(0, 180, 1261, 461)) + self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2") + self.gridLayout_2 = QtWidgets.QGridLayout(self.gridLayoutWidget_2) + self.gridLayout_2.setContentsMargins(0, 0, 0, 0) + self.gridLayout_2.setObjectName("gridLayout_2") + self.tableWidget_apparat_media = QtWidgets.QTableWidget(self.gridLayoutWidget_2) + self.tableWidget_apparat_media.setObjectName("tableWidget_apparat_media") + self.tableWidget_apparat_media.setColumnCount(4) + self.tableWidget_apparat_media.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(3, item) + self.gridLayout_2.addWidget(self.tableWidget_apparat_media, 3, 0, 1, 1) + self.label = QtWidgets.QLabel(self.gridLayoutWidget_2) + font = QtGui.QFont() + font.setPointSize(11) + font.setBold(True) + font.setWeight(75) + self.label.setFont(font) + self.label.setObjectName("label") + self.gridLayout_2.addWidget(self.label, 1, 0, 1, 1) + self.app_group_box = QtWidgets.QGroupBox(self.gridLayoutWidget_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.app_group_box.sizePolicy().hasHeightForWidth()) + self.app_group_box.setSizePolicy(sizePolicy) + font = QtGui.QFont() + font.setPointSize(12) + font.setBold(True) + font.setWeight(75) + self.app_group_box.setFont(font) + self.app_group_box.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignLeft|QtCore.Qt.AlignmentFlag.AlignVCenter) + self.app_group_box.setCheckable(False) + self.app_group_box.setObjectName("app_group_box") + self.tableWidget = QtWidgets.QTableWidget(self.app_group_box) + self.tableWidget.setGeometry(QtCore.QRect(820, 20, 256, 192)) + self.tableWidget.setObjectName("tableWidget") + self.tableWidget.setColumnCount(2) + self.tableWidget.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidget.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget.setHorizontalHeaderItem(1, item) + self.frame = QtWidgets.QFrame(self.app_group_box) + self.frame.setGeometry(QtCore.QRect(10, 30, 731, 151)) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth()) + self.frame.setSizePolicy(sizePolicy) + self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame.setObjectName("frame") + self.drpdwn_prof_title = QtWidgets.QComboBox(self.frame) + self.drpdwn_prof_title.setGeometry(QtCore.QRect(110, 50, 69, 22)) + self.drpdwn_prof_title.setObjectName("drpdwn_prof_title") + self.label_5 = QtWidgets.QLabel(self.frame) + self.label_5.setGeometry(QtCore.QRect(250, 20, 91, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_5.setFont(font) + self.label_5.setObjectName("label_5") + self.lineEdit = QtWidgets.QLineEdit(self.frame) + self.lineEdit.setGeometry(QtCore.QRect(110, 80, 121, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.lineEdit.setFont(font) + self.lineEdit.setObjectName("lineEdit") + self.sem_winter = QtWidgets.QRadioButton(self.frame) + self.sem_winter.setGeometry(QtCore.QRect(340, 50, 82, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.sem_winter.setFont(font) + self.sem_winter.setObjectName("sem_winter") + self.label_4 = QtWidgets.QLabel(self.frame) + self.label_4.setGeometry(QtCore.QRect(10, 80, 71, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_4.setFont(font) + self.label_4.setObjectName("label_4") + self.drpdwn_app_nr = QtWidgets.QComboBox(self.frame) + self.drpdwn_app_nr.setGeometry(QtCore.QRect(110, 20, 69, 22)) + self.drpdwn_app_nr.setObjectName("drpdwn_app_nr") + self.app_name = QtWidgets.QLineEdit(self.frame) + self.app_name.setGeometry(QtCore.QRect(340, 20, 113, 20)) + self.app_name.setObjectName("app_name") + self.sem_sommer = QtWidgets.QRadioButton(self.frame) + self.sem_sommer.setGeometry(QtCore.QRect(340, 70, 82, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.sem_sommer.setFont(font) + self.sem_sommer.setObjectName("sem_sommer") + self.label_3 = QtWidgets.QLabel(self.frame) + self.label_3.setGeometry(QtCore.QRect(10, 50, 61, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_3.setFont(font) + self.label_3.setObjectName("label_3") + self.label_6 = QtWidgets.QLabel(self.frame) + self.label_6.setGeometry(QtCore.QRect(270, 60, 51, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_6.setFont(font) + self.label_6.setObjectName("label_6") + self.sem_year = QtWidgets.QLineEdit(self.frame) + self.sem_year.setGeometry(QtCore.QRect(410, 60, 113, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.sem_year.setFont(font) + self.sem_year.setObjectName("sem_year") + self.label_2 = QtWidgets.QLabel(self.frame) + self.label_2.setGeometry(QtCore.QRect(10, 20, 101, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_2.setFont(font) + self.label_2.setObjectName("label_2") + self.btn_apparat_save = QtWidgets.QPushButton(self.frame) + self.btn_apparat_save.setGeometry(QtCore.QRect(260, 120, 75, 23)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.btn_apparat_save.setFont(font) + self.btn_apparat_save.setObjectName("btn_apparat_save") + self.btn_apparat_apply = QtWidgets.QPushButton(self.frame) + self.btn_apparat_apply.setGeometry(QtCore.QRect(350, 120, 75, 23)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.btn_apparat_apply.setFont(font) + self.btn_apparat_apply.setObjectName("btn_apparat_apply") + self.checkBox = QtWidgets.QCheckBox(self.frame) + self.checkBox.setGeometry(QtCore.QRect(340, 90, 101, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.checkBox.setFont(font) + self.checkBox.setObjectName("checkBox") + self.btn_add_document = QtWidgets.QPushButton(self.app_group_box) + self.btn_add_document.setGeometry(QtCore.QRect(1100, 40, 131, 25)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.btn_add_document.setFont(font) + self.btn_add_document.setObjectName("btn_add_document") + self.btn_open_document = QtWidgets.QPushButton(self.app_group_box) + self.btn_open_document.setGeometry(QtCore.QRect(1100, 80, 131, 25)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.btn_open_document.setFont(font) + self.btn_open_document.setObjectName("btn_open_document") + self.toolButton = QtWidgets.QToolButton(self.app_group_box) + self.toolButton.setGeometry(QtCore.QRect(1110, 110, 25, 19)) + self.toolButton.setObjectName("toolButton") + self.gridLayout_2.addWidget(self.app_group_box, 2, 0, 1, 1) + self.tabWidget.addTab(self.tab, "") + self.tab_2 = QtWidgets.QWidget() + self.tab_2.setObjectName("tab_2") + self.tabWidget.addTab(self.tab_2, "") + self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) + self.horizontalLayout.addLayout(self.gridLayout) + self.verticalLayout.addLayout(self.horizontalLayout) + MainWindow.setCentralWidget(self.centralwidget) + self.menubar = QtWidgets.QMenuBar(MainWindow) + self.menubar.setGeometry(QtCore.QRect(0, 0, 1280, 21)) + self.menubar.setObjectName("menubar") + self.menuDatei = QtWidgets.QMenu(self.menubar) + self.menuDatei.setObjectName("menuDatei") + self.menuEinstellungen = QtWidgets.QMenu(self.menubar) + self.menuEinstellungen.setObjectName("menuEinstellungen") + MainWindow.setMenuBar(self.menubar) + self.statusbar = QtWidgets.QStatusBar(MainWindow) + self.statusbar.setObjectName("statusbar") + MainWindow.setStatusBar(self.statusbar) + self.menubar.addAction(self.menuDatei.menuAction()) + self.menubar.addAction(self.menuEinstellungen.menuAction()) + + self.retranslateUi(MainWindow) + self.tabWidget.setCurrentIndex(0) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + + def retranslateUi(self, MainWindow): + _translate = QtCore.QCoreApplication.translate + MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) + self.load_app.setToolTip(_translate("MainWindow", "Load the Semesterapparate from the database")) + self.load_app.setText(_translate("MainWindow", "App. Laden")) + self.create_new_app.setText(_translate("MainWindow", "neu. App anlegen")) + item = self.tableWidget_apparate.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "AppNr")) + item = self.tableWidget_apparate.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "App Name")) + item = self.tableWidget_apparate.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Professor")) + item = self.tableWidget_apparate.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "Dauerapparat")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Buchtitel")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Autor")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Auflage")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "Signatur")) + self.label.setText(_translate("MainWindow", "Medienliste")) + self.app_group_box.setTitle(_translate("MainWindow", "Apparatsdetails")) + item = self.tableWidget.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Dokumentname")) + item = self.tableWidget.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Typ")) + self.label_5.setText(_translate("MainWindow", "Apparatsname")) + self.lineEdit.setPlaceholderText(_translate("MainWindow", "Nachname, Vorname")) + self.sem_winter.setText(_translate("MainWindow", "Winter")) + self.label_4.setText(_translate("MainWindow", "Prof. Name")) + self.sem_sommer.setText(_translate("MainWindow", "Sommer")) + self.label_3.setText(_translate("MainWindow", "Prof. Titel")) + self.label_6.setText(_translate("MainWindow", "Semester")) + self.sem_year.setPlaceholderText(_translate("MainWindow", "2023")) + self.label_2.setText(_translate("MainWindow", "Apparatsnummer")) + self.btn_apparat_save.setText(_translate("MainWindow", "Speichern")) + self.btn_apparat_apply.setText(_translate("MainWindow", "Aktualisieren")) + self.checkBox.setText(_translate("MainWindow", "Dauerapparat")) + self.btn_add_document.setText(_translate("MainWindow", "Dokument hinzufügen")) + self.btn_open_document.setText(_translate("MainWindow", "Dokument öffnen")) + self.toolButton.setText(_translate("MainWindow", "...")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Tab 1")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Tab 2")) + self.menuDatei.setTitle(_translate("MainWindow", "Datei")) + self.menuEinstellungen.setTitle(_translate("MainWindow", "Einstellungen")) + + +if __name__ == "__main__": + import sys + app = QtWidgets.QApplication(sys.argv) + MainWindow = QtWidgets.QMainWindow() + ui = Ui_MainWindow() + ui.setupUi(MainWindow) + MainWindow.show() + sys.exit(app.exec()) diff --git a/src/ui/plotdata.ui b/src/ui/plotdata.ui new file mode 100644 index 0000000..9ec94dc --- /dev/null +++ b/src/ui/plotdata.ui @@ -0,0 +1,64 @@ + + + MainWindow + + + + 0 + 0 + 640 + 480 + + + + MainWindow + + + + + + 330 + 10 + 256 + 192 + + + + + + + 10 + 0 + 251 + 271 + + + + + + + 300 + 220 + 291 + 201 + + + + + + + + + + 0 + 0 + 640 + 21 + + + + + + + + diff --git a/src/ui/plotdata_ui.py b/src/ui/plotdata_ui.py new file mode 100644 index 0000000..f0738dc --- /dev/null +++ b/src/ui/plotdata_ui.py @@ -0,0 +1,47 @@ +# Form implementation generated from reading ui file '/home/alexander/GitHub/Semesterapparate/ui/plotdata.ui' +# +# Created by: PyQt6 UI code generator 6.5.3 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName("MainWindow") + MainWindow.resize(640, 480) + self.centralwidget = QtWidgets.QWidget(parent=MainWindow) + self.centralwidget.setObjectName("centralwidget") + self.graphicsView = QtWidgets.QGraphicsView(parent=self.centralwidget) + self.graphicsView.setGeometry(QtCore.QRect(330, 10, 256, 192)) + self.graphicsView.setObjectName("graphicsView") + self.widget = QtWidgets.QWidget(parent=self.centralwidget) + self.widget.setGeometry(QtCore.QRect(10, 0, 251, 271)) + self.widget.setObjectName("widget") + self.stackedWidget = QtWidgets.QStackedWidget(parent=self.centralwidget) + self.stackedWidget.setGeometry(QtCore.QRect(300, 220, 291, 201)) + self.stackedWidget.setObjectName("stackedWidget") + self.page = QtWidgets.QWidget() + self.page.setObjectName("page") + self.stackedWidget.addWidget(self.page) + self.page_2 = QtWidgets.QWidget() + self.page_2.setObjectName("page_2") + self.stackedWidget.addWidget(self.page_2) + MainWindow.setCentralWidget(self.centralwidget) + self.menubar = QtWidgets.QMenuBar(parent=MainWindow) + self.menubar.setGeometry(QtCore.QRect(0, 0, 640, 21)) + self.menubar.setObjectName("menubar") + MainWindow.setMenuBar(self.menubar) + self.statusbar = QtWidgets.QStatusBar(parent=MainWindow) + self.statusbar.setObjectName("statusbar") + MainWindow.setStatusBar(self.statusbar) + + self.retranslateUi(MainWindow) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + + def retranslateUi(self, MainWindow): + _translate = QtCore.QCoreApplication.translate + MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) diff --git a/src/ui/resources.qrc b/src/ui/resources.qrc new file mode 100644 index 0000000..aa2997d --- /dev/null +++ b/src/ui/resources.qrc @@ -0,0 +1,14 @@ + + + icons/warning.png + + + icons/critical.png + + + icons/information.png + + + icons/question.png + + diff --git a/src/ui/sap.py b/src/ui/sap.py new file mode 100644 index 0000000..8d65970 --- /dev/null +++ b/src/ui/sap.py @@ -0,0 +1,512 @@ +# Form implementation generated from reading ui file 'ui/semesterapparat_ui.ui' +# +# Created by: PyQt6 UI code generator 6.3.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName("MainWindow") + MainWindow.resize(1280, 747) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth()) + MainWindow.setSizePolicy(sizePolicy) + self.centralwidget = QtWidgets.QWidget(MainWindow) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth()) + self.centralwidget.setSizePolicy(sizePolicy) + self.centralwidget.setObjectName("centralwidget") + self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget) + self.verticalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 1271, 691)) + self.verticalLayoutWidget.setObjectName("verticalLayoutWidget") + self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget) + self.verticalLayout.setContentsMargins(0, 0, 0, 0) + self.verticalLayout.setObjectName("verticalLayout") + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.gridLayout = QtWidgets.QGridLayout() + self.gridLayout.setObjectName("gridLayout") + self.tabWidget = QtWidgets.QTabWidget(self.verticalLayoutWidget) + self.tabWidget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.tabWidget.setObjectName("tabWidget") + self.tab = QtWidgets.QWidget() + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.tab.sizePolicy().hasHeightForWidth()) + self.tab.setSizePolicy(sizePolicy) + self.tab.setObjectName("tab") + self.horizontalLayoutWidget_2 = QtWidgets.QWidget(self.tab) + self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(0, 0, 1261, 161)) + self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_2) + self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.formLayout = QtWidgets.QFormLayout() + self.formLayout.setObjectName("formLayout") + self.verticalLayout_2 = QtWidgets.QVBoxLayout() + self.verticalLayout_2.setObjectName("verticalLayout_2") + spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout_2.addItem(spacerItem) + self.load_app = QtWidgets.QPushButton(self.horizontalLayoutWidget_2) + self.load_app.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.load_app.setObjectName("load_app") + self.verticalLayout_2.addWidget(self.load_app) + self.create_new_app = QtWidgets.QPushButton(self.horizontalLayoutWidget_2) + self.create_new_app.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.create_new_app.setObjectName("create_new_app") + self.verticalLayout_2.addWidget(self.create_new_app) + spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout_2.addItem(spacerItem1) + self.formLayout.setLayout(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.verticalLayout_2) + self.tableWidget_apparate = QtWidgets.QTableWidget(self.horizontalLayoutWidget_2) + self.tableWidget_apparate.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.tableWidget_apparate.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) + self.tableWidget_apparate.setObjectName("tableWidget_apparate") + self.tableWidget_apparate.setColumnCount(4) + self.tableWidget_apparate.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(3, item) + self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.tableWidget_apparate) + self.horizontalLayout_3 = QtWidgets.QHBoxLayout() + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.formLayout.setLayout(2, QtWidgets.QFormLayout.ItemRole.LabelRole, self.horizontalLayout_3) + self.horizontalLayout_4 = QtWidgets.QHBoxLayout() + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + self.formLayout.setLayout(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.horizontalLayout_4) + self.horizontalLayout_2.addLayout(self.formLayout) + self.line = QtWidgets.QFrame(self.tab) + self.line.setGeometry(QtCore.QRect(0, 160, 1261, 21)) + self.line.setFrameShape(QtWidgets.QFrame.Shape.HLine) + self.line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.line.setObjectName("line") + self.gridLayoutWidget_2 = QtWidgets.QWidget(self.tab) + self.gridLayoutWidget_2.setGeometry(QtCore.QRect(0, 180, 1261, 461)) + self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2") + self.gridLayout_2 = QtWidgets.QGridLayout(self.gridLayoutWidget_2) + self.gridLayout_2.setContentsMargins(0, 0, 0, 0) + self.gridLayout_2.setObjectName("gridLayout_2") + self.app_group_box = QtWidgets.QGroupBox(self.gridLayoutWidget_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.app_group_box.sizePolicy().hasHeightForWidth()) + self.app_group_box.setSizePolicy(sizePolicy) + font = QtGui.QFont() + font.setPointSize(12) + font.setBold(True) + font.setWeight(75) + self.app_group_box.setFont(font) + self.app_group_box.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignLeft|QtCore.Qt.AlignmentFlag.AlignVCenter) + self.app_group_box.setCheckable(False) + self.app_group_box.setObjectName("app_group_box") + self.dokument_list = QtWidgets.QTableWidget(self.app_group_box) + self.dokument_list.setGeometry(QtCore.QRect(830, 20, 256, 192)) + font = QtGui.QFont() + font.setKerning(False) + self.dokument_list.setFont(font) + self.dokument_list.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.dokument_list.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.SingleSelection) + self.dokument_list.setObjectName("dokument_list") + self.dokument_list.setColumnCount(4) + self.dokument_list.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + font = QtGui.QFont() + font.setFamily("Arial") + font.setPointSize(8) + item.setFont(font) + self.dokument_list.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + font = QtGui.QFont() + font.setFamily("Arial") + font.setPointSize(8) + item.setFont(font) + self.dokument_list.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + font = QtGui.QFont() + font.setFamily("Arial") + font.setPointSize(8) + item.setFont(font) + self.dokument_list.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.dokument_list.setHorizontalHeaderItem(3, item) + self.frame = QtWidgets.QFrame(self.app_group_box) + self.frame.setEnabled(True) + self.frame.setGeometry(QtCore.QRect(10, 30, 731, 151)) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth()) + self.frame.setSizePolicy(sizePolicy) + self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame.setObjectName("frame") + self.drpdwn_prof_title = QtWidgets.QComboBox(self.frame) + self.drpdwn_prof_title.setGeometry(QtCore.QRect(110, 50, 69, 22)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.drpdwn_prof_title.setFont(font) + self.drpdwn_prof_title.setEditable(True) + self.drpdwn_prof_title.setObjectName("drpdwn_prof_title") + self.label_5 = QtWidgets.QLabel(self.frame) + self.label_5.setGeometry(QtCore.QRect(250, 20, 91, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_5.setFont(font) + self.label_5.setObjectName("label_5") + self.sem_winter = QtWidgets.QRadioButton(self.frame) + self.sem_winter.setGeometry(QtCore.QRect(340, 50, 82, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.sem_winter.setFont(font) + self.sem_winter.setObjectName("sem_winter") + self.label_4 = QtWidgets.QLabel(self.frame) + self.label_4.setGeometry(QtCore.QRect(10, 80, 71, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_4.setFont(font) + self.label_4.setObjectName("label_4") + self.drpdwn_app_nr = QtWidgets.QComboBox(self.frame) + self.drpdwn_app_nr.setGeometry(QtCore.QRect(110, 20, 69, 22)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.drpdwn_app_nr.setFont(font) + self.drpdwn_app_nr.setEditable(True) + self.drpdwn_app_nr.setObjectName("drpdwn_app_nr") + self.app_name = QtWidgets.QLineEdit(self.frame) + self.app_name.setGeometry(QtCore.QRect(340, 20, 113, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.app_name.setFont(font) + self.app_name.setObjectName("app_name") + self.sem_sommer = QtWidgets.QRadioButton(self.frame) + self.sem_sommer.setGeometry(QtCore.QRect(340, 70, 82, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.sem_sommer.setFont(font) + self.sem_sommer.setObjectName("sem_sommer") + self.label_3 = QtWidgets.QLabel(self.frame) + self.label_3.setGeometry(QtCore.QRect(10, 50, 61, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_3.setFont(font) + self.label_3.setObjectName("label_3") + self.label_6 = QtWidgets.QLabel(self.frame) + self.label_6.setGeometry(QtCore.QRect(270, 60, 51, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_6.setFont(font) + self.label_6.setObjectName("label_6") + self.sem_year = QtWidgets.QLineEdit(self.frame) + self.sem_year.setGeometry(QtCore.QRect(410, 60, 113, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.sem_year.setFont(font) + self.sem_year.setMaxLength(4) + self.sem_year.setObjectName("sem_year") + self.label_2 = QtWidgets.QLabel(self.frame) + self.label_2.setGeometry(QtCore.QRect(10, 20, 101, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_2.setFont(font) + self.label_2.setObjectName("label_2") + self.btn_apparat_save = QtWidgets.QPushButton(self.frame) + self.btn_apparat_save.setGeometry(QtCore.QRect(260, 120, 75, 23)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.btn_apparat_save.setFont(font) + self.btn_apparat_save.setObjectName("btn_apparat_save") + self.btn_apparat_apply = QtWidgets.QPushButton(self.frame) + self.btn_apparat_apply.setGeometry(QtCore.QRect(350, 120, 75, 23)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.btn_apparat_apply.setFont(font) + self.btn_apparat_apply.setObjectName("btn_apparat_apply") + self.check_eternal_app = QtWidgets.QCheckBox(self.frame) + self.check_eternal_app.setGeometry(QtCore.QRect(340, 90, 101, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.check_eternal_app.setFont(font) + self.check_eternal_app.setObjectName("check_eternal_app") + self.label_8 = QtWidgets.QLabel(self.frame) + self.label_8.setGeometry(QtCore.QRect(10, 110, 71, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_8.setFont(font) + self.label_8.setObjectName("label_8") + self.prof_mail = QtWidgets.QLineEdit(self.frame) + self.prof_mail.setGeometry(QtCore.QRect(110, 110, 121, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.prof_mail.setFont(font) + self.prof_mail.setPlaceholderText("") + self.prof_mail.setObjectName("prof_mail") + self.label_9 = QtWidgets.QLabel(self.frame) + self.label_9.setGeometry(QtCore.QRect(10, 130, 71, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_9.setFont(font) + self.label_9.setObjectName("label_9") + self.prof_tel_nr = QtWidgets.QLineEdit(self.frame) + self.prof_tel_nr.setGeometry(QtCore.QRect(110, 130, 121, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.prof_tel_nr.setFont(font) + self.prof_tel_nr.setPlaceholderText("") + self.prof_tel_nr.setObjectName("prof_tel_nr") + self.label_10 = QtWidgets.QLabel(self.frame) + self.label_10.setGeometry(QtCore.QRect(470, 20, 51, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_10.setFont(font) + self.label_10.setObjectName("label_10") + self.app_fach = QtWidgets.QLineEdit(self.frame) + self.app_fach.setGeometry(QtCore.QRect(510, 20, 113, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.app_fach.setFont(font) + self.app_fach.setObjectName("app_fach") + self.drpdwn_prof_name = QtWidgets.QComboBox(self.frame) + self.drpdwn_prof_name.setGeometry(QtCore.QRect(110, 80, 121, 22)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setWeight(50) + self.drpdwn_prof_name.setFont(font) + self.drpdwn_prof_name.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.drpdwn_prof_name.setEditable(True) + self.drpdwn_prof_name.setCurrentText("") + self.drpdwn_prof_name.setInsertPolicy(QtWidgets.QComboBox.InsertPolicy.InsertAlphabetically) + self.drpdwn_prof_name.setFrame(True) + self.drpdwn_prof_name.setObjectName("drpdwn_prof_name") + self.btn_add_document = QtWidgets.QPushButton(self.app_group_box) + self.btn_add_document.setGeometry(QtCore.QRect(1100, 40, 131, 25)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.btn_add_document.setFont(font) + self.btn_add_document.setObjectName("btn_add_document") + self.btn_open_document = QtWidgets.QPushButton(self.app_group_box) + self.btn_open_document.setGeometry(QtCore.QRect(1100, 80, 131, 25)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.btn_open_document.setFont(font) + self.btn_open_document.setObjectName("btn_open_document") + self.toolButton = QtWidgets.QToolButton(self.app_group_box) + self.toolButton.setGeometry(QtCore.QRect(1110, 110, 25, 19)) + self.toolButton.setObjectName("toolButton") + self.label_7 = QtWidgets.QLabel(self.app_group_box) + self.label_7.setGeometry(QtCore.QRect(20, 200, 47, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_7.setFont(font) + self.label_7.setObjectName("label_7") + self.search_media = QtWidgets.QLineEdit(self.app_group_box) + self.search_media.setGeometry(QtCore.QRect(80, 200, 211, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.search_media.setFont(font) + self.search_media.setObjectName("search_media") + self.label = QtWidgets.QLabel(self.app_group_box) + self.label.setGeometry(QtCore.QRect(10, 180, 1259, 18)) + font = QtGui.QFont() + font.setPointSize(11) + font.setBold(True) + font.setWeight(75) + self.label.setFont(font) + self.label.setObjectName("label") + self.gridLayout_2.addWidget(self.app_group_box, 1, 0, 1, 1) + self.tableWidget_apparat_media = QtWidgets.QTableWidget(self.gridLayoutWidget_2) + self.tableWidget_apparat_media.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.tableWidget_apparat_media.setObjectName("tableWidget_apparat_media") + self.tableWidget_apparat_media.setColumnCount(4) + self.tableWidget_apparat_media.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(3, item) + self.gridLayout_2.addWidget(self.tableWidget_apparat_media, 2, 0, 1, 1) + self.search = QtWidgets.QPushButton(self.tab) + self.search.setGeometry(QtCore.QRect(130, 640, 75, 20)) + self.search.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.search.setObjectName("search") + self.add_medium = QtWidgets.QPushButton(self.tab) + self.add_medium.setGeometry(QtCore.QRect(10, 640, 111, 20)) + self.add_medium.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.add_medium.setObjectName("add_medium") + self.tabWidget.addTab(self.tab, "") + self.tab_2 = QtWidgets.QWidget() + self.tab_2.setObjectName("tab_2") + self.tabWidget.addTab(self.tab_2, "") + self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) + self.horizontalLayout.addLayout(self.gridLayout) + self.verticalLayout.addLayout(self.horizontalLayout) + MainWindow.setCentralWidget(self.centralwidget) + self.menubar = QtWidgets.QMenuBar(MainWindow) + self.menubar.setGeometry(QtCore.QRect(0, 0, 1280, 21)) + self.menubar.setObjectName("menubar") + self.menuDatei = QtWidgets.QMenu(self.menubar) + self.menuDatei.setObjectName("menuDatei") + self.menuEinstellungen = QtWidgets.QMenu(self.menubar) + self.menuEinstellungen.setObjectName("menuEinstellungen") + MainWindow.setMenuBar(self.menubar) + self.statusbar = QtWidgets.QStatusBar(MainWindow) + self.statusbar.setObjectName("statusbar") + MainWindow.setStatusBar(self.statusbar) + self.menubar.addAction(self.menuDatei.menuAction()) + self.menubar.addAction(self.menuEinstellungen.menuAction()) + + self.retranslateUi(MainWindow) + self.tabWidget.setCurrentIndex(0) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + MainWindow.setTabOrder(self.drpdwn_app_nr, self.drpdwn_prof_title) + MainWindow.setTabOrder(self.drpdwn_prof_title, self.drpdwn_prof_name) + MainWindow.setTabOrder(self.drpdwn_prof_name, self.prof_mail) + MainWindow.setTabOrder(self.prof_mail, self.prof_tel_nr) + MainWindow.setTabOrder(self.prof_tel_nr, self.app_name) + MainWindow.setTabOrder(self.app_name, self.app_fach) + MainWindow.setTabOrder(self.app_fach, self.sem_winter) + MainWindow.setTabOrder(self.sem_winter, self.sem_sommer) + MainWindow.setTabOrder(self.sem_sommer, self.sem_year) + MainWindow.setTabOrder(self.sem_year, self.check_eternal_app) + MainWindow.setTabOrder(self.check_eternal_app, self.btn_add_document) + MainWindow.setTabOrder(self.btn_add_document, self.btn_open_document) + MainWindow.setTabOrder(self.btn_open_document, self.toolButton) + MainWindow.setTabOrder(self.toolButton, self.btn_apparat_save) + MainWindow.setTabOrder(self.btn_apparat_save, self.btn_apparat_apply) + MainWindow.setTabOrder(self.btn_apparat_apply, self.search_media) + + def retranslateUi(self, MainWindow): + _translate = QtCore.QCoreApplication.translate + MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) + self.load_app.setToolTip(_translate("MainWindow", "Load the Semesterapparate from the database")) + self.load_app.setText(_translate("MainWindow", "App. aufrufen")) + self.create_new_app.setText(_translate("MainWindow", "neu. App anlegen")) + item = self.tableWidget_apparate.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "AppNr")) + item = self.tableWidget_apparate.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "App Name")) + item = self.tableWidget_apparate.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Professor")) + item = self.tableWidget_apparate.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "Dauerapparat")) + self.app_group_box.setTitle(_translate("MainWindow", "Apparatsdetails")) + item = self.dokument_list.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Dokumentname")) + item = self.dokument_list.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Dateityp")) + item = self.dokument_list.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Neu?")) + item = self.dokument_list.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "path")) + self.label_5.setText(_translate("MainWindow", "Apparatsname")) + self.sem_winter.setText(_translate("MainWindow", "Winter")) + self.label_4.setText(_translate("MainWindow", "Prof. Name")) + self.sem_sommer.setText(_translate("MainWindow", "Sommer")) + self.label_3.setText(_translate("MainWindow", "Prof. Titel")) + self.label_6.setText(_translate("MainWindow", "Semester")) + self.sem_year.setPlaceholderText(_translate("MainWindow", "2023")) + self.label_2.setText(_translate("MainWindow", "Apparatsnummer")) + self.btn_apparat_save.setText(_translate("MainWindow", "Speichern")) + self.btn_apparat_apply.setText(_translate("MainWindow", "Aktualisieren")) + self.check_eternal_app.setText(_translate("MainWindow", "Dauerapparat")) + self.label_8.setText(_translate("MainWindow", "Mail")) + self.label_9.setText(_translate("MainWindow", "Tel")) + self.label_10.setText(_translate("MainWindow", "Fach")) + self.btn_add_document.setText(_translate("MainWindow", "Dokument hinzufügen")) + self.btn_open_document.setText(_translate("MainWindow", "Dokument öffnen")) + self.toolButton.setText(_translate("MainWindow", "...")) + self.label_7.setText(_translate("MainWindow", "Suche")) + self.search_media.setPlaceholderText(_translate("MainWindow", "Buch oder Signatur")) + self.label.setText(_translate("MainWindow", "Medienliste")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Buchtitel")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Autor")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Auflage")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "Signatur")) + self.search.setToolTip(_translate("MainWindow", "Sucht im Katalog nach allen Medien, die die Apparatsnummer enthalten")) + self.search.setText(_translate("MainWindow", "Suche")) + self.add_medium.setText(_translate("MainWindow", "Medium hinzufügen")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Tab 1")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Tab 2")) + self.menuDatei.setTitle(_translate("MainWindow", "Datei")) + self.menuEinstellungen.setTitle(_translate("MainWindow", "Einstellungen")) + + +if __name__ == "__main__": + import sys + app = QtWidgets.QApplication(sys.argv) + MainWindow = QtWidgets.QMainWindow() + ui = Ui_MainWindow() + ui.setupUi(MainWindow) + MainWindow.show() + sys.exit(app.exec()) diff --git a/src/ui/semesterapparat_ui.ts b/src/ui/semesterapparat_ui.ts new file mode 100644 index 0000000..6a28a55 --- /dev/null +++ b/src/ui/semesterapparat_ui.ts @@ -0,0 +1,234 @@ + + + + + MainWindow + + + MainWindow + + + + + Tab 1 + + + + + Load the Semesterapparate from the database + + + + + App. aufrufen + + + + + neu. App anlegen + + + + + AppNr + + + + + App Name + + + + + Professor + + + + + + Dauerapparat + + + + + KontoNr + + + + + Dateityp + + + + + Neu? + + + + + path + + + + + Mail + + + + + Tel + + + + + Fach + + + + + + + + + + * + + + + + Buchtitel + + + + + Autor + + + + + Auflage + + + + + Signatur + + + + + Beenden + + + + + Apparatsdetails + + + + + Dokumentname + + + + + Apparatsname + + + + + Winter + + + + + Prof. Name + + + + + Sommer + + + + + Prof. Titel + + + + + Semester + + + + + 2023 + + + + + Apparatsnummer + + + + + Speichern + + + + + Aktualisieren + + + + + Dokument hinzufügen + + + + + Dokument öffnen + + + + + + Suche + + + + + Buch oder Signatur + + + + + Medienliste + + + + + Sucht im Katalog nach allen Medien, die die Apparatsnummer enthalten + + + + + Medium hinzufügen + + + + + Tab 2 + + + + + Datei + + + + + Einstellungen + + + + diff --git a/src/ui/semesterapparat_ui.ui b/src/ui/semesterapparat_ui.ui new file mode 100644 index 0000000..1cf7452 --- /dev/null +++ b/src/ui/semesterapparat_ui.ui @@ -0,0 +1,2890 @@ + + + MainWindow + + + Qt::WindowModal + + + true + + + + 0 + 0 + 1593 + 800 + + + + + 0 + 0 + + + + + 1278 + 800 + + + + + 1920 + 800 + + + + Qt::NoContextMenu + + + Semesterapparatsmanagement + + + + + 0 + 0 + + + + + + 0 + 0 + 1271 + 761 + + + + + + + + + + + Qt::NoFocus + + + 0 + + + + + 0 + 0 + + + + Anlegen + + + + + 0 + 0 + 1261 + 163 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::NoFocus + + + Load the Semesterapparate from the database + + + App. aufrufen + + + + + + + Qt::NoFocus + + + neu. App anlegen + + + + + + + Qt::NoFocus + + + Auswahl abbrechen + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::NoFocus + + + QAbstractScrollArea::AdjustToContents + + + QAbstractItemView::SelectedClicked + + + true + + + Qt::ElideMiddle + + + true + + + true + + + + AppNr + + + + + App Name + + + + + Professor + + + + + gültig bis + + + + + Dauerapparat + + + + + KontoNr + + + + + + + + + + + + + + + + + + 0 + 160 + 1261 + 21 + + + + Qt::Horizontal + + + + + true + + + + 0 + 180 + 1261 + 511 + + + + + + + + 0 + 0 + + + + + 0 + 210 + + + + + 12 + 75 + true + + + + Apparatsdetails + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + false + + + + + 765 + 20 + 321 + 181 + + + + + 10 + 50 + false + false + + + + Qt::NoFocus + + + true + + + QAbstractScrollArea::AdjustToContents + + + true + + + QAbstractItemView::DropOnly + + + Qt::LinkAction + + + QAbstractItemView::SingleSelection + + + + Dokumentname + + + + Arial + 8 + + + + + + Dateityp + + + + Arial + 8 + + + + + + Neu? + + + + Arial + 8 + + + + + + path + + + + + + true + + + + 10 + 30 + 1241 + 151 + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 110 + 50 + 69 + 22 + + + + + 9 + 50 + false + + + + true + + + + + + 250 + 20 + 91 + 21 + + + + + 9 + 50 + false + + + + Apparatsname + + + + + + 340 + 50 + 82 + 17 + + + + + 9 + 50 + false + + + + Qt::NoFocus + + + Winter + + + + + + 10 + 80 + 71 + 21 + + + + + 9 + 50 + false + + + + Prof. Name + + + + + + 110 + 20 + 69 + 22 + + + + + 9 + 50 + false + + + + Qt::ImhDigitsOnly + + + true + + + + + + 340 + 20 + 113 + 20 + + + + + 9 + 50 + false + + + + Qt::StrongFocus + + + + + + 340 + 70 + 82 + 17 + + + + + 9 + 50 + false + + + + Qt::NoFocus + + + Sommer + + + + + + 10 + 50 + 61 + 20 + + + + + 9 + 50 + false + + + + Prof. Titel + + + + + + 270 + 60 + 61 + 21 + + + + + 9 + 50 + false + + + + Semester + + + + + + 410 + 60 + 113 + 20 + + + + + 9 + 50 + false + + + + Qt::StrongFocus + + + 4 + + + 2023 + + + + + + 10 + 20 + 101 + 21 + + + + + 9 + 50 + false + + + + Apparatsnummer + + + + + + 260 + 120 + 75 + 23 + + + + + 9 + 50 + false + + + + Speichern + + + + + + 350 + 120 + 75 + 23 + + + + + 9 + 50 + false + + + + Aktualisieren + + + + + + 340 + 90 + 101 + 17 + + + + + 9 + 50 + false + + + + Dauerapparat + + + + + + 10 + 110 + 71 + 21 + + + + + 9 + 50 + false + + + + Mail + + + + + + 110 + 110 + 121 + 20 + + + + + 9 + 50 + false + + + + Qt::ImhEmailCharactersOnly + + + 200 + + + + + + + + + 10 + 130 + 71 + 21 + + + + + 9 + 50 + false + + + + Tel + + + + + + 110 + 130 + 121 + 20 + + + + + 9 + 50 + false + + + + Qt::ImhDigitsOnly + + + + + + + + + 470 + 20 + 51 + 21 + + + + + 9 + 50 + false + + + + Fach + + + + + + 110 + 80 + 121 + 22 + + + + + 8 + 50 + false + + + + Qt::StrongFocus + + + true + + + + + + QComboBox::InsertAlphabetically + + + true + + + + + + 100 + 110 + 47 + 21 + + + + + 9 + 50 + false + + + + * + + + + + + 100 + 130 + 47 + 21 + + + + + 9 + 50 + false + + + + * + + + + + + 100 + 80 + 47 + 21 + + + + + 9 + 50 + false + + + + * + + + + + + 330 + 20 + 16 + 21 + + + + + 9 + 50 + false + + + + * + + + + + + 500 + 20 + 47 + 21 + + + + + 9 + 50 + false + + + + Qt::NoFocus + + + * + + + + + + 330 + 60 + 16 + 21 + + + + + 9 + 50 + false + + + + * + + + + + + 1090 + 20 + 131 + 25 + + + + + 9 + 50 + false + + + + Dokument hinzufügen + + + + + + 1090 + 60 + 131 + 25 + + + + + 9 + 50 + false + + + + Dokument öffnen + + + + + + 1090 + 100 + 131 + 51 + + + + + 9 + 50 + false + + + + Abhängig von der Anzahl der Medien kann die Suche sehr lange dauern + + + Medien aus Dokument + hinzufügen + + + + + + 550 + 70 + 202 + 80 + + + + + + + + 9 + 50 + false + + + + Prof-ID-aDIS + + + + + + + + 9 + 50 + false + + + + + + + + + 9 + 50 + false + + + + Apparat-ID-aDIS + + + + + + + + + + + + 450 + 120 + 91 + 17 + + + + + 9 + 50 + false + + + + Mail senden + + + + + + 510 + 0 + 241 + 61 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 0 + 0 + 241 + 61 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + _mand + drpdwn_prof_title + label_5 + sem_winter + label_4 + drpdwn_app_nr + sem_sommer + label_3 + label_6 + sem_year + label_2 + btn_apparat_save + btn_apparat_apply + check_eternal_app + label_8 + label_9 + label_10 + mail_mand + telnr_mand + profname_mand + appname_mand + fach_mand + btn_add_document + btn_open_document + app_name + prof_tel_nr + drpdwn_prof_name + prof_mail + check_file + formLayoutWidget_2 + check_send_mail + frame_3 + + frame + dokument_list + + + + + + + 0 + 0 + + + + + 1259 + 0 + + + + Qt::NoFocus + + + Qt::CustomContextMenu + + + QAbstractScrollArea::AdjustToContents + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::SelectRows + + + true + + + true + + + + Buchtitel + + + + + Signatur + + + + + Auflage + + + + + Autor + + + + + verfügbar? + + + + + Vorgemerkt + + + + + Link + + + + + + + + + 11 + 75 + true + + + + Medienliste + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + gel. Medien anzeigen + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + im Apparat? + + + + + + + + + Medien werden hinzugefügt + + + + + + + Qt::Vertical + + + + + + + Medium x/y + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + + + + Medien werden geprüft + + + + + + + Qt::Vertical + + + + + + + TextLabel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 0 + 700 + 121 + 20 + + + + Qt::NoFocus + + + Medien hinzufügen + + + + + + Suchen / Statistik + + + + + 0 + 0 + 1251 + 721 + + + + + + + + 16777215 + 250 + + + + 0 + + + + Statistik + + + + + 10 + 180 + 75 + 23 + + + + Suchen + + + + + + 10 + 10 + 491 + 161 + + + + + + + Appnr.: + + + + + + + true + + + + + + + Dauerapp: + + + + + + + Endsemester: + + + + + + + Erstellsemester: + + + + + + + + + + Person: + + + + + + + Fach: + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Löschbar + + + + + + + Qt::StrongFocus + + + + + + + + + + + + 100 + 180 + 401 + 23 + + + + + + + + + + Suchen + + + + + 10 + 10 + 451 + 151 + + + + + + + Signatur + + + + + + + Suche + + + + + + + true + + + + + + + Titel + + + + + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + 1 + + + + + + 780 + 10 + 441 + 441 + + + + 1 + + + + Tabelle + + + + + 0 + 0 + 431 + 411 + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Qt::NoFocus + + + QAbstractItemView::NoEditTriggers + + + true + + + true + + + 59 + + + 24 + + + true + + + false + + + + Semester + + + + + Zugang + + + + + Abgang + + + + + + + + + + Erstellte und gelöschte Semesterapparate + + + + + + + 10 + 10 + 761 + 441 + + + + + + 0 + 0 + 761 + 51 + + + + + + + Qt::StrongFocus + + + Ausgewählte Löschen + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 50 + 761 + 391 + + + + + + 0 + 0 + 761 + 391 + + + + Qt::NoFocus + + + QAbstractItemView::NoEditTriggers + + + + + + + + + Apparatsname + + + + + Apparatsnummer + + + + + Person + + + + + Fach + + + + + + + + + + + 10 + 20 + 1081 + 421 + + + + QFrame::Plain + + + QAbstractItemView::NoEditTriggers + + + true + + + true + + + true + + + + Titel + + + + + Signatur + + + + + Apparat + + + + + + + + + + + + Admin + + + + + 10 + 30 + 47 + 22 + + + + Aktion: + + + + + + 70 + 30 + 181 + 22 + + + + + Nutzer anlegen + + + + + Nutzer löschen + + + + + Nutzer aktualisieren + + + + + Lehrperson bearbeiten + + + + + + + 10 + 60 + 591 + 141 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 0 + 0 + 581 + 141 + + + + + + + Nutzername + + + + + + + + 150 + 16777215 + + + + + + + + Rolle + + + + + + + Passwort + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 150 + 16777215 + + + + + + + + Anlegen + + + + + + + + + + + + + + + + + 10 + 60 + 591 + 141 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 0 + 0 + 581 + 141 + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Nutzer löschen + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Nutzername + + + + + + + + + + Qt::RightToLeft + + + Wirklich löschen? + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + 10 + 60 + 591 + 141 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 0 + 0 + 581 + 141 + + + + + + + + + + Nutzername + + + + + + + + 150 + 16777215 + + + + + + + + Aktualisieren + + + + + + + Rolle + + + + + + + Neues Passwort + + + + + + + + 150 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 10 + 60 + 1051 + 191 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 0 + 0 + 751 + 223 + + + + + + + + + Titel + + + + + + + + + + Vorname + + + + + + + + + + Nachname + + + + + + + + + + + + + + Qt::TabFocus + + + true + + + + + + + + + + Telefonnummer + + + + + + + Qt::ClickFocus + + + true + + + + + + + Mail + + + + + + + Qt::NoFocus + + + Qt::ImhNone + + + true + + + + + + + + + + + Mail + + + + + + + Telefon + + + + + + + + + + + + + + + Alte Angaben + + + + + + + Aktualisieren + + + + + + + Neue Angaben + + + + + + + + + + + + + + + + + + + 1280 + 360 + 311 + 391 + + + + + + + + 6 + + + + + true + + + + 0 + 0 + + + + Software + + + + + 20 + 30 + 241 + 41 + + + + + 8 + 50 + false + + + + Qt::NoFocus + + + Apparatsdaten eingegeben + + + + + + 20 + 70 + 241 + 41 + + + + + 8 + 50 + false + + + + Qt::NoFocus + + + Medien hinzugefügt / importiert + + + + + + 20 + 140 + 241 + 41 + + + + + 8 + 50 + false + + + + Qt::NoFocus + + + Prof-ID und Apparat-ID eingetragen + + + + + + + + + 0 + 0 + + + + aDIS + + + + + 20 + 30 + 241 + 41 + + + + + 8 + 50 + false + false + false + PreferDefault + true + + + + Qt::NoFocus + + + Medien geprüft + + + + + + 20 + 70 + 241 + 41 + + + + + 8 + 50 + false + false + false + PreferDefault + true + + + + Qt::NoFocus + + + Medien bearbeitet + + + + + + 20 + 110 + 161 + 41 + + + + + 8 + 50 + false + false + false + PreferDefault + true + + + + Qt::NoFocus + + + Apparat angelegt + + + + + + 170 + 120 + 101 + 23 + + + + + 8 + 50 + false + false + false + PreferDefault + true + + + + Hier klicken, um die aDIS Abfrage in die Zwischenablage zu kopieren + + + + + + + + + + + + false + + + aDIS Abfrage + + + + ../../../.designer/backup/icons/information.png../../../.designer/backup/icons/information.png + + + false + + + false + + + false + + + + + + + + + + + + + 1280 + 10 + 301 + 341 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 0 + 0 + 291 + 191 + + + + Qt::NoFocus + + + true + + + QCalendarWidget::NoVerticalHeader + + + + + + 0 + 210 + 301 + 121 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 10 + 10 + 47 + 20 + + + + Apparat + + + + + true + + + + 60 + 10 + 31 + 20 + + + + Qt::NoFocus + + + + + + 10 + 40 + 281 + 71 + + + + Qt::NoFocus + + + + + + 130 + 10 + 75 + 23 + + + + Qt::NoFocus + + + Löschen + + + + + + 210 + 10 + 74 + 22 + + + + 1 + + + + + + 260 + 10 + 21 + 22 + + + + TextLabel + + + + + + + + + 0 + 0 + 1593 + 21 + + + + + Datei + + + + + + Bearbeiten + + + + + + + + + + Beenden + + + Ctrl+Q + + + true + + + + + Einstellungen + + + Alt+S + + + true + + + + + drpdwn_app_nr + drpdwn_prof_title + drpdwn_prof_name + prof_mail + prof_tel_nr + app_name + sem_year + check_eternal_app + btn_add_document + btn_open_document + check_file + btn_apparat_save + btn_apparat_apply + check_send_mail + chkbx_show_del_media + btn_reserve + prof_id_adis + apparat_id_adis + tabWidget_2 + btn_del_select_apparats + tabWidget_3 + select_action_box + user_create_frame_username + user_frame_userrole + user_create_frame_password + user_frame_addUser + user_delete_frame_user_select + user_delete_confirm + pushButton + user_edit_frame_user_select + user_edit_frame_role_select + user_edit_frame_new_password + update_user + edit_faculty_member_title + edit_faculty_member_select_member + faculty_member_old_telnr + faculty_member_oldmail + edit_faculty_member_new_title + edit_faculty_member_new_surname + user_faculty_member_new_name + lineEdit + lineEdit_5 + update_faculty_member + box_fach + box_person + btn_search + check_deletable + box_erstellsemester + box_semester + box_dauerapp + box_appnrs + btn_copy_adis_command + spin_select_message + + + + diff --git a/src/ui/semesterapparat_ui_ui.py b/src/ui/semesterapparat_ui_ui.py new file mode 100644 index 0000000..582742a --- /dev/null +++ b/src/ui/semesterapparat_ui_ui.py @@ -0,0 +1,1437 @@ +# Form implementation generated from reading ui file '/home/alexander/GitHub/Semesterapparate/ui/semesterapparat_ui.ui' +# +# Created by: PyQt6 UI code generator 6.5.3 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName("MainWindow") + MainWindow.setWindowModality(QtCore.Qt.WindowModality.WindowModal) + MainWindow.setEnabled(True) + MainWindow.resize(1593, 800) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth()) + MainWindow.setSizePolicy(sizePolicy) + MainWindow.setMinimumSize(QtCore.QSize(1278, 800)) + MainWindow.setMaximumSize(QtCore.QSize(1920, 800)) + MainWindow.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) + self.centralwidget = QtWidgets.QWidget(parent=MainWindow) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth()) + self.centralwidget.setSizePolicy(sizePolicy) + self.centralwidget.setObjectName("centralwidget") + self.verticalLayoutWidget = QtWidgets.QWidget(parent=self.centralwidget) + self.verticalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 1271, 761)) + self.verticalLayoutWidget.setObjectName("verticalLayoutWidget") + self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget) + self.verticalLayout.setContentsMargins(0, 0, 0, 0) + self.verticalLayout.setObjectName("verticalLayout") + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.gridLayout = QtWidgets.QGridLayout() + self.gridLayout.setObjectName("gridLayout") + self.tabWidget = QtWidgets.QTabWidget(parent=self.verticalLayoutWidget) + self.tabWidget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.tabWidget.setObjectName("tabWidget") + self.tab = QtWidgets.QWidget() + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.tab.sizePolicy().hasHeightForWidth()) + self.tab.setSizePolicy(sizePolicy) + self.tab.setObjectName("tab") + self.horizontalLayoutWidget_2 = QtWidgets.QWidget(parent=self.tab) + self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(0, 0, 1261, 163)) + self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_2) + self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.formLayout = QtWidgets.QFormLayout() + self.formLayout.setObjectName("formLayout") + self.verticalLayout_2 = QtWidgets.QVBoxLayout() + self.verticalLayout_2.setObjectName("verticalLayout_2") + spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout_2.addItem(spacerItem) + self.load_app = QtWidgets.QPushButton(parent=self.horizontalLayoutWidget_2) + self.load_app.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.load_app.setObjectName("load_app") + self.verticalLayout_2.addWidget(self.load_app) + self.create_new_app = QtWidgets.QPushButton(parent=self.horizontalLayoutWidget_2) + self.create_new_app.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.create_new_app.setObjectName("create_new_app") + self.verticalLayout_2.addWidget(self.create_new_app) + self.cancel_active_selection = QtWidgets.QPushButton(parent=self.horizontalLayoutWidget_2) + self.cancel_active_selection.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.cancel_active_selection.setObjectName("cancel_active_selection") + self.verticalLayout_2.addWidget(self.cancel_active_selection) + spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout_2.addItem(spacerItem1) + self.formLayout.setLayout(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.verticalLayout_2) + self.tableWidget_apparate = QtWidgets.QTableWidget(parent=self.horizontalLayoutWidget_2) + self.tableWidget_apparate.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.tableWidget_apparate.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents) + self.tableWidget_apparate.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.SelectedClicked) + self.tableWidget_apparate.setAlternatingRowColors(True) + self.tableWidget_apparate.setTextElideMode(QtCore.Qt.TextElideMode.ElideMiddle) + self.tableWidget_apparate.setObjectName("tableWidget_apparate") + self.tableWidget_apparate.setColumnCount(6) + self.tableWidget_apparate.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(3, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(4, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(5, item) + self.tableWidget_apparate.horizontalHeader().setCascadingSectionResizes(True) + self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.tableWidget_apparate) + self.horizontalLayout_4 = QtWidgets.QHBoxLayout() + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + self.formLayout.setLayout(2, QtWidgets.QFormLayout.ItemRole.FieldRole, self.horizontalLayout_4) + self.horizontalLayout_3 = QtWidgets.QHBoxLayout() + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.formLayout.setLayout(3, QtWidgets.QFormLayout.ItemRole.LabelRole, self.horizontalLayout_3) + self.horizontalLayout_2.addLayout(self.formLayout) + self.line = QtWidgets.QFrame(parent=self.tab) + self.line.setGeometry(QtCore.QRect(0, 160, 1261, 21)) + self.line.setFrameShape(QtWidgets.QFrame.Shape.HLine) + self.line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.line.setObjectName("line") + self.gridLayoutWidget_2 = QtWidgets.QWidget(parent=self.tab) + self.gridLayoutWidget_2.setEnabled(True) + self.gridLayoutWidget_2.setGeometry(QtCore.QRect(0, 180, 1261, 511)) + self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2") + self.gridLayout_2 = QtWidgets.QGridLayout(self.gridLayoutWidget_2) + self.gridLayout_2.setContentsMargins(0, 0, 0, 0) + self.gridLayout_2.setObjectName("gridLayout_2") + self.app_group_box = QtWidgets.QGroupBox(parent=self.gridLayoutWidget_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.app_group_box.sizePolicy().hasHeightForWidth()) + self.app_group_box.setSizePolicy(sizePolicy) + self.app_group_box.setMinimumSize(QtCore.QSize(0, 210)) + font = QtGui.QFont() + font.setPointSize(12) + font.setBold(True) + font.setWeight(75) + self.app_group_box.setFont(font) + self.app_group_box.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignLeft|QtCore.Qt.AlignmentFlag.AlignVCenter) + self.app_group_box.setCheckable(False) + self.app_group_box.setObjectName("app_group_box") + self.dokument_list = QtWidgets.QTableWidget(parent=self.app_group_box) + self.dokument_list.setGeometry(QtCore.QRect(765, 20, 321, 181)) + font = QtGui.QFont() + font.setPointSize(10) + font.setBold(False) + font.setWeight(50) + font.setKerning(False) + self.dokument_list.setFont(font) + self.dokument_list.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.dokument_list.setAcceptDrops(True) + self.dokument_list.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents) + self.dokument_list.setDragEnabled(True) + self.dokument_list.setDragDropMode(QtWidgets.QAbstractItemView.DragDropMode.DropOnly) + self.dokument_list.setDefaultDropAction(QtCore.Qt.DropAction.LinkAction) + self.dokument_list.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.SingleSelection) + self.dokument_list.setObjectName("dokument_list") + self.dokument_list.setColumnCount(4) + self.dokument_list.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + font = QtGui.QFont() + font.setFamily("Arial") + font.setPointSize(8) + item.setFont(font) + self.dokument_list.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + font = QtGui.QFont() + font.setFamily("Arial") + font.setPointSize(8) + item.setFont(font) + self.dokument_list.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + font = QtGui.QFont() + font.setFamily("Arial") + font.setPointSize(8) + item.setFont(font) + self.dokument_list.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.dokument_list.setHorizontalHeaderItem(3, item) + self.frame = QtWidgets.QFrame(parent=self.app_group_box) + self.frame.setEnabled(True) + self.frame.setGeometry(QtCore.QRect(10, 30, 1241, 151)) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth()) + self.frame.setSizePolicy(sizePolicy) + self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame.setObjectName("frame") + self.drpdwn_prof_title = QtWidgets.QComboBox(parent=self.frame) + self.drpdwn_prof_title.setGeometry(QtCore.QRect(110, 50, 69, 22)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.drpdwn_prof_title.setFont(font) + self.drpdwn_prof_title.setEditable(True) + self.drpdwn_prof_title.setObjectName("drpdwn_prof_title") + self.label_5 = QtWidgets.QLabel(parent=self.frame) + self.label_5.setGeometry(QtCore.QRect(250, 20, 91, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_5.setFont(font) + self.label_5.setObjectName("label_5") + self.sem_winter = QtWidgets.QRadioButton(parent=self.frame) + self.sem_winter.setGeometry(QtCore.QRect(340, 50, 82, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.sem_winter.setFont(font) + self.sem_winter.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.sem_winter.setObjectName("sem_winter") + self.label_4 = QtWidgets.QLabel(parent=self.frame) + self.label_4.setGeometry(QtCore.QRect(10, 80, 71, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_4.setFont(font) + self.label_4.setObjectName("label_4") + self.drpdwn_app_nr = QtWidgets.QComboBox(parent=self.frame) + self.drpdwn_app_nr.setGeometry(QtCore.QRect(110, 20, 69, 22)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.drpdwn_app_nr.setFont(font) + self.drpdwn_app_nr.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhDigitsOnly) + self.drpdwn_app_nr.setEditable(True) + self.drpdwn_app_nr.setObjectName("drpdwn_app_nr") + self.app_name = QtWidgets.QLineEdit(parent=self.frame) + self.app_name.setGeometry(QtCore.QRect(340, 20, 113, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.app_name.setFont(font) + self.app_name.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.app_name.setObjectName("app_name") + self.sem_sommer = QtWidgets.QRadioButton(parent=self.frame) + self.sem_sommer.setGeometry(QtCore.QRect(340, 70, 82, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.sem_sommer.setFont(font) + self.sem_sommer.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.sem_sommer.setObjectName("sem_sommer") + self.label_3 = QtWidgets.QLabel(parent=self.frame) + self.label_3.setGeometry(QtCore.QRect(10, 50, 61, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_3.setFont(font) + self.label_3.setObjectName("label_3") + self.label_6 = QtWidgets.QLabel(parent=self.frame) + self.label_6.setGeometry(QtCore.QRect(270, 60, 61, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_6.setFont(font) + self.label_6.setObjectName("label_6") + self.sem_year = QtWidgets.QLineEdit(parent=self.frame) + self.sem_year.setGeometry(QtCore.QRect(410, 60, 113, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.sem_year.setFont(font) + self.sem_year.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.sem_year.setMaxLength(4) + self.sem_year.setObjectName("sem_year") + self.label_2 = QtWidgets.QLabel(parent=self.frame) + self.label_2.setGeometry(QtCore.QRect(10, 20, 101, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_2.setFont(font) + self.label_2.setObjectName("label_2") + self.btn_apparat_save = QtWidgets.QPushButton(parent=self.frame) + self.btn_apparat_save.setGeometry(QtCore.QRect(260, 120, 75, 23)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.btn_apparat_save.setFont(font) + self.btn_apparat_save.setObjectName("btn_apparat_save") + self.btn_apparat_apply = QtWidgets.QPushButton(parent=self.frame) + self.btn_apparat_apply.setGeometry(QtCore.QRect(350, 120, 75, 23)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.btn_apparat_apply.setFont(font) + self.btn_apparat_apply.setObjectName("btn_apparat_apply") + self.check_eternal_app = QtWidgets.QCheckBox(parent=self.frame) + self.check_eternal_app.setGeometry(QtCore.QRect(340, 90, 101, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.check_eternal_app.setFont(font) + self.check_eternal_app.setObjectName("check_eternal_app") + self.label_8 = QtWidgets.QLabel(parent=self.frame) + self.label_8.setGeometry(QtCore.QRect(10, 110, 71, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_8.setFont(font) + self.label_8.setObjectName("label_8") + self.prof_mail = QtWidgets.QLineEdit(parent=self.frame) + self.prof_mail.setGeometry(QtCore.QRect(110, 110, 121, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.prof_mail.setFont(font) + self.prof_mail.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhEmailCharactersOnly) + self.prof_mail.setMaxLength(200) + self.prof_mail.setPlaceholderText("") + self.prof_mail.setObjectName("prof_mail") + self.label_9 = QtWidgets.QLabel(parent=self.frame) + self.label_9.setGeometry(QtCore.QRect(10, 130, 71, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_9.setFont(font) + self.label_9.setObjectName("label_9") + self.prof_tel_nr = QtWidgets.QLineEdit(parent=self.frame) + self.prof_tel_nr.setGeometry(QtCore.QRect(110, 130, 121, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.prof_tel_nr.setFont(font) + self.prof_tel_nr.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhDigitsOnly) + self.prof_tel_nr.setPlaceholderText("") + self.prof_tel_nr.setObjectName("prof_tel_nr") + self.label_10 = QtWidgets.QLabel(parent=self.frame) + self.label_10.setGeometry(QtCore.QRect(470, 20, 51, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_10.setFont(font) + self.label_10.setObjectName("label_10") + self.app_fach = QtWidgets.QLineEdit(parent=self.frame) + self.app_fach.setGeometry(QtCore.QRect(510, 20, 113, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.app_fach.setFont(font) + self.app_fach.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.app_fach.setObjectName("app_fach") + self.drpdwn_prof_name = QtWidgets.QComboBox(parent=self.frame) + self.drpdwn_prof_name.setGeometry(QtCore.QRect(110, 80, 121, 22)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setWeight(50) + self.drpdwn_prof_name.setFont(font) + self.drpdwn_prof_name.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.drpdwn_prof_name.setEditable(True) + self.drpdwn_prof_name.setCurrentText("") + self.drpdwn_prof_name.setInsertPolicy(QtWidgets.QComboBox.InsertPolicy.InsertAlphabetically) + self.drpdwn_prof_name.setFrame(True) + self.drpdwn_prof_name.setObjectName("drpdwn_prof_name") + self.mail_mand = QtWidgets.QLabel(parent=self.frame) + self.mail_mand.setGeometry(QtCore.QRect(100, 110, 47, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.mail_mand.setFont(font) + self.mail_mand.setObjectName("mail_mand") + self.telnr_mand = QtWidgets.QLabel(parent=self.frame) + self.telnr_mand.setGeometry(QtCore.QRect(100, 130, 47, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.telnr_mand.setFont(font) + self.telnr_mand.setObjectName("telnr_mand") + self.profname_mand = QtWidgets.QLabel(parent=self.frame) + self.profname_mand.setGeometry(QtCore.QRect(100, 80, 47, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.profname_mand.setFont(font) + self.profname_mand.setObjectName("profname_mand") + self.appname_mand = QtWidgets.QLabel(parent=self.frame) + self.appname_mand.setGeometry(QtCore.QRect(330, 20, 16, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.appname_mand.setFont(font) + self.appname_mand.setObjectName("appname_mand") + self.fach_mand = QtWidgets.QLabel(parent=self.frame) + self.fach_mand.setGeometry(QtCore.QRect(500, 20, 47, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.fach_mand.setFont(font) + self.fach_mand.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.fach_mand.setObjectName("fach_mand") + self._mand = QtWidgets.QLabel(parent=self.frame) + self._mand.setGeometry(QtCore.QRect(330, 60, 16, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self._mand.setFont(font) + self._mand.setObjectName("_mand") + self.btn_add_document = QtWidgets.QPushButton(parent=self.frame) + self.btn_add_document.setGeometry(QtCore.QRect(1090, 20, 131, 25)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.btn_add_document.setFont(font) + self.btn_add_document.setObjectName("btn_add_document") + self.btn_open_document = QtWidgets.QPushButton(parent=self.frame) + self.btn_open_document.setGeometry(QtCore.QRect(1090, 60, 131, 25)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.btn_open_document.setFont(font) + self.btn_open_document.setObjectName("btn_open_document") + self.check_file = QtWidgets.QPushButton(parent=self.frame) + self.check_file.setGeometry(QtCore.QRect(1090, 100, 131, 51)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.check_file.setFont(font) + self.check_file.setObjectName("check_file") + self.formLayoutWidget_2 = QtWidgets.QWidget(parent=self.frame) + self.formLayoutWidget_2.setGeometry(QtCore.QRect(550, 70, 202, 80)) + self.formLayoutWidget_2.setObjectName("formLayoutWidget_2") + self.formLayout_3 = QtWidgets.QFormLayout(self.formLayoutWidget_2) + self.formLayout_3.setContentsMargins(0, 0, 0, 0) + self.formLayout_3.setObjectName("formLayout_3") + self.label_12 = QtWidgets.QLabel(parent=self.formLayoutWidget_2) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_12.setFont(font) + self.label_12.setObjectName("label_12") + self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_12) + self.prof_id_adis = QtWidgets.QLineEdit(parent=self.formLayoutWidget_2) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.prof_id_adis.setFont(font) + self.prof_id_adis.setObjectName("prof_id_adis") + self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.prof_id_adis) + self.label_13 = QtWidgets.QLabel(parent=self.formLayoutWidget_2) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_13.setFont(font) + self.label_13.setObjectName("label_13") + self.formLayout_3.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_13) + self.apparat_id_adis = QtWidgets.QLineEdit(parent=self.formLayoutWidget_2) + self.apparat_id_adis.setObjectName("apparat_id_adis") + self.formLayout_3.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.apparat_id_adis) + self.check_send_mail = QtWidgets.QCheckBox(parent=self.frame) + self.check_send_mail.setGeometry(QtCore.QRect(450, 120, 91, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.check_send_mail.setFont(font) + self.check_send_mail.setObjectName("check_send_mail") + self._mand.raise_() + self.drpdwn_prof_title.raise_() + self.label_5.raise_() + self.sem_winter.raise_() + self.label_4.raise_() + self.drpdwn_app_nr.raise_() + self.sem_sommer.raise_() + self.label_3.raise_() + self.label_6.raise_() + self.sem_year.raise_() + self.label_2.raise_() + self.btn_apparat_save.raise_() + self.btn_apparat_apply.raise_() + self.check_eternal_app.raise_() + self.label_8.raise_() + self.label_9.raise_() + self.label_10.raise_() + self.mail_mand.raise_() + self.telnr_mand.raise_() + self.profname_mand.raise_() + self.appname_mand.raise_() + self.fach_mand.raise_() + self.btn_add_document.raise_() + self.btn_open_document.raise_() + self.app_fach.raise_() + self.app_name.raise_() + self.prof_tel_nr.raise_() + self.drpdwn_prof_name.raise_() + self.prof_mail.raise_() + self.check_file.raise_() + self.formLayoutWidget_2.raise_() + self.check_send_mail.raise_() + self.frame.raise_() + self.dokument_list.raise_() + self.gridLayout_2.addWidget(self.app_group_box, 1, 0, 1, 1) + self.tableWidget_apparat_media = QtWidgets.QTableWidget(parent=self.gridLayoutWidget_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.tableWidget_apparat_media.sizePolicy().hasHeightForWidth()) + self.tableWidget_apparat_media.setSizePolicy(sizePolicy) + self.tableWidget_apparat_media.setMinimumSize(QtCore.QSize(1259, 0)) + self.tableWidget_apparat_media.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.tableWidget_apparat_media.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.CustomContextMenu) + self.tableWidget_apparat_media.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents) + self.tableWidget_apparat_media.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) + self.tableWidget_apparat_media.setAlternatingRowColors(True) + self.tableWidget_apparat_media.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) + self.tableWidget_apparat_media.setObjectName("tableWidget_apparat_media") + self.tableWidget_apparat_media.setColumnCount(7) + self.tableWidget_apparat_media.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(3, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(4, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(5, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(6, item) + self.tableWidget_apparat_media.horizontalHeader().setCascadingSectionResizes(True) + self.gridLayout_2.addWidget(self.tableWidget_apparat_media, 9, 0, 1, 1) + self.label = QtWidgets.QLabel(parent=self.gridLayoutWidget_2) + font = QtGui.QFont() + font.setPointSize(11) + font.setBold(True) + font.setWeight(75) + self.label.setFont(font) + self.label.setObjectName("label") + self.gridLayout_2.addWidget(self.label, 2, 0, 1, 1) + self.horizontalLayout_5 = QtWidgets.QHBoxLayout() + self.horizontalLayout_5.setObjectName("horizontalLayout_5") + spacerItem2 = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_5.addItem(spacerItem2) + self.chkbx_show_del_media = QtWidgets.QCheckBox(parent=self.gridLayoutWidget_2) + self.chkbx_show_del_media.setObjectName("chkbx_show_del_media") + self.horizontalLayout_5.addWidget(self.chkbx_show_del_media) + spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_5.addItem(spacerItem3) + self.btn_reserve = QtWidgets.QPushButton(parent=self.gridLayoutWidget_2) + self.btn_reserve.setObjectName("btn_reserve") + self.horizontalLayout_5.addWidget(self.btn_reserve) + self.add_layout = QtWidgets.QHBoxLayout() + self.add_layout.setObjectName("add_layout") + self.label_info = QtWidgets.QLabel(parent=self.gridLayoutWidget_2) + self.label_info.setObjectName("label_info") + self.add_layout.addWidget(self.label_info) + self.line_2 = QtWidgets.QFrame(parent=self.gridLayoutWidget_2) + self.line_2.setFrameShape(QtWidgets.QFrame.Shape.VLine) + self.line_2.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.line_2.setObjectName("line_2") + self.add_layout.addWidget(self.line_2) + self.progress_label = QtWidgets.QLabel(parent=self.gridLayoutWidget_2) + self.progress_label.setObjectName("progress_label") + self.add_layout.addWidget(self.progress_label) + self.horizontalLayout_5.addLayout(self.add_layout) + spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_5.addItem(spacerItem4) + self.avail_layout = QtWidgets.QHBoxLayout() + self.avail_layout.setObjectName("avail_layout") + self.horizontalLayout_5.addLayout(self.avail_layout) + self.label_20 = QtWidgets.QLabel(parent=self.gridLayoutWidget_2) + self.label_20.setObjectName("label_20") + self.horizontalLayout_5.addWidget(self.label_20) + self.line_3 = QtWidgets.QFrame(parent=self.gridLayoutWidget_2) + self.line_3.setFrameShape(QtWidgets.QFrame.Shape.VLine) + self.line_3.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.line_3.setObjectName("line_3") + self.horizontalLayout_5.addWidget(self.line_3) + self.avail_status = QtWidgets.QLabel(parent=self.gridLayoutWidget_2) + self.avail_status.setObjectName("avail_status") + self.horizontalLayout_5.addWidget(self.avail_status) + spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_5.addItem(spacerItem5) + self.gridLayout_2.addLayout(self.horizontalLayout_5, 4, 0, 1, 1) + self.add_medium = QtWidgets.QPushButton(parent=self.tab) + self.add_medium.setGeometry(QtCore.QRect(0, 700, 121, 20)) + self.add_medium.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.add_medium.setObjectName("add_medium") + self.tabWidget.addTab(self.tab, "") + self.tab_2 = QtWidgets.QWidget() + self.tab_2.setObjectName("tab_2") + self.verticalLayoutWidget_2 = QtWidgets.QWidget(parent=self.tab_2) + self.verticalLayoutWidget_2.setGeometry(QtCore.QRect(0, 0, 1251, 721)) + self.verticalLayoutWidget_2.setObjectName("verticalLayoutWidget_2") + self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_2) + self.verticalLayout_3.setContentsMargins(0, 0, 0, 0) + self.verticalLayout_3.setObjectName("verticalLayout_3") + self.tabWidget_2 = QtWidgets.QTabWidget(parent=self.verticalLayoutWidget_2) + self.tabWidget_2.setMaximumSize(QtCore.QSize(16777215, 250)) + self.tabWidget_2.setObjectName("tabWidget_2") + self.tab_3 = QtWidgets.QWidget() + self.tab_3.setObjectName("tab_3") + self.btn_search = QtWidgets.QPushButton(parent=self.tab_3) + self.btn_search.setGeometry(QtCore.QRect(10, 180, 75, 23)) + self.btn_search.setObjectName("btn_search") + self.gridLayoutWidget = QtWidgets.QWidget(parent=self.tab_3) + self.gridLayoutWidget.setGeometry(QtCore.QRect(10, 10, 491, 161)) + self.gridLayoutWidget.setObjectName("gridLayoutWidget") + self.gridLayout_3 = QtWidgets.QGridLayout(self.gridLayoutWidget) + self.gridLayout_3.setContentsMargins(0, 0, 0, 0) + self.gridLayout_3.setObjectName("gridLayout_3") + self.label_7 = QtWidgets.QLabel(parent=self.gridLayoutWidget) + self.label_7.setObjectName("label_7") + self.gridLayout_3.addWidget(self.label_7, 0, 0, 1, 1) + self.box_erstellsemester = QtWidgets.QComboBox(parent=self.gridLayoutWidget) + self.box_erstellsemester.setEditable(True) + self.box_erstellsemester.setObjectName("box_erstellsemester") + self.gridLayout_3.addWidget(self.box_erstellsemester, 1, 3, 1, 1) + self.label_18 = QtWidgets.QLabel(parent=self.gridLayoutWidget) + self.label_18.setObjectName("label_18") + self.gridLayout_3.addWidget(self.label_18, 2, 2, 1, 1) + self.label_17 = QtWidgets.QLabel(parent=self.gridLayoutWidget) + self.label_17.setObjectName("label_17") + self.gridLayout_3.addWidget(self.label_17, 0, 2, 1, 1) + self.label_19 = QtWidgets.QLabel(parent=self.gridLayoutWidget) + self.label_19.setObjectName("label_19") + self.gridLayout_3.addWidget(self.label_19, 1, 2, 1, 1) + self.box_dauerapp = QtWidgets.QComboBox(parent=self.gridLayoutWidget) + self.box_dauerapp.setObjectName("box_dauerapp") + self.gridLayout_3.addWidget(self.box_dauerapp, 2, 3, 1, 1) + self.label_11 = QtWidgets.QLabel(parent=self.gridLayoutWidget) + self.label_11.setObjectName("label_11") + self.gridLayout_3.addWidget(self.label_11, 1, 0, 1, 1) + self.label_16 = QtWidgets.QLabel(parent=self.gridLayoutWidget) + self.label_16.setObjectName("label_16") + self.gridLayout_3.addWidget(self.label_16, 2, 0, 1, 1) + self.box_semester = QtWidgets.QComboBox(parent=self.gridLayoutWidget) + self.box_semester.setEditable(True) + self.box_semester.setObjectName("box_semester") + self.gridLayout_3.addWidget(self.box_semester, 0, 3, 1, 1) + self.box_appnrs = QtWidgets.QComboBox(parent=self.gridLayoutWidget) + self.box_appnrs.setEditable(True) + self.box_appnrs.setObjectName("box_appnrs") + self.gridLayout_3.addWidget(self.box_appnrs, 0, 1, 1, 1) + self.box_fach = QtWidgets.QComboBox(parent=self.gridLayoutWidget) + self.box_fach.setEditable(True) + self.box_fach.setObjectName("box_fach") + self.gridLayout_3.addWidget(self.box_fach, 2, 1, 1, 1) + self.box_person = QtWidgets.QComboBox(parent=self.gridLayoutWidget) + self.box_person.setEditable(True) + self.box_person.setObjectName("box_person") + self.gridLayout_3.addWidget(self.box_person, 1, 1, 1, 1) + spacerItem6 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.gridLayout_3.addItem(spacerItem6, 4, 0, 1, 1) + self.label_15 = QtWidgets.QLabel(parent=self.gridLayoutWidget) + self.label_15.setObjectName("label_15") + self.gridLayout_3.addWidget(self.label_15, 3, 0, 1, 1) + self.check_deletable = QtWidgets.QCheckBox(parent=self.gridLayoutWidget) + self.check_deletable.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.check_deletable.setText("") + self.check_deletable.setObjectName("check_deletable") + self.gridLayout_3.addWidget(self.check_deletable, 3, 1, 1, 1) + self.db_err_message = QtWidgets.QLabel(parent=self.tab_3) + self.db_err_message.setGeometry(QtCore.QRect(100, 180, 401, 23)) + self.db_err_message.setText("") + self.db_err_message.setObjectName("db_err_message") + self.tabWidget_2.addTab(self.tab_3, "") + self.tab_4 = QtWidgets.QWidget() + self.tab_4.setObjectName("tab_4") + self.formLayoutWidget = QtWidgets.QWidget(parent=self.tab_4) + self.formLayoutWidget.setGeometry(QtCore.QRect(10, 10, 451, 151)) + self.formLayoutWidget.setObjectName("formLayoutWidget") + self.formLayout_6 = QtWidgets.QFormLayout(self.formLayoutWidget) + self.formLayout_6.setContentsMargins(0, 0, 0, 0) + self.formLayout_6.setObjectName("formLayout_6") + self.label_25 = QtWidgets.QLabel(parent=self.formLayoutWidget) + self.label_25.setObjectName("label_25") + self.formLayout_6.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_25) + self.book_search = QtWidgets.QPushButton(parent=self.formLayoutWidget) + self.book_search.setObjectName("book_search") + self.formLayout_6.setWidget(3, QtWidgets.QFormLayout.ItemRole.LabelRole, self.book_search) + self.seach_by_signature = QtWidgets.QLineEdit(parent=self.formLayoutWidget) + self.seach_by_signature.setClearButtonEnabled(True) + self.seach_by_signature.setObjectName("seach_by_signature") + self.formLayout_6.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.seach_by_signature) + self.label_26 = QtWidgets.QLabel(parent=self.formLayoutWidget) + self.label_26.setObjectName("label_26") + self.formLayout_6.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_26) + self.search_by_title = QtWidgets.QLineEdit(parent=self.formLayoutWidget) + self.search_by_title.setClearButtonEnabled(True) + self.search_by_title.setObjectName("search_by_title") + self.formLayout_6.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.search_by_title) + spacerItem7 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.formLayout_6.setItem(2, QtWidgets.QFormLayout.ItemRole.LabelRole, spacerItem7) + self.tabWidget_2.addTab(self.tab_4, "") + self.verticalLayout_3.addWidget(self.tabWidget_2) + self.stackedWidget_4 = QtWidgets.QStackedWidget(parent=self.verticalLayoutWidget_2) + self.stackedWidget_4.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.stackedWidget_4.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.stackedWidget_4.setObjectName("stackedWidget_4") + self.stackedWidget_4Page1 = QtWidgets.QWidget() + self.stackedWidget_4Page1.setObjectName("stackedWidget_4Page1") + self.tabWidget_3 = QtWidgets.QTabWidget(parent=self.stackedWidget_4Page1) + self.tabWidget_3.setGeometry(QtCore.QRect(780, 10, 441, 441)) + self.tabWidget_3.setObjectName("tabWidget_3") + self.tab_6 = QtWidgets.QWidget() + self.tab_6.setObjectName("tab_6") + self.gridLayoutWidget_3 = QtWidgets.QWidget(parent=self.tab_6) + self.gridLayoutWidget_3.setGeometry(QtCore.QRect(0, 0, 431, 411)) + self.gridLayoutWidget_3.setObjectName("gridLayoutWidget_3") + self.gridLayout_4 = QtWidgets.QGridLayout(self.gridLayoutWidget_3) + self.gridLayout_4.setContentsMargins(0, 0, 0, 0) + self.gridLayout_4.setObjectName("gridLayout_4") + self.statistics_table = QtWidgets.QTableWidget(parent=self.gridLayoutWidget_3) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.statistics_table.sizePolicy().hasHeightForWidth()) + self.statistics_table.setSizePolicy(sizePolicy) + self.statistics_table.setMaximumSize(QtCore.QSize(16777215, 16777215)) + self.statistics_table.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.statistics_table.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) + self.statistics_table.setAlternatingRowColors(True) + self.statistics_table.setObjectName("statistics_table") + self.statistics_table.setColumnCount(3) + self.statistics_table.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.statistics_table.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.statistics_table.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.statistics_table.setHorizontalHeaderItem(2, item) + self.statistics_table.horizontalHeader().setCascadingSectionResizes(True) + self.statistics_table.horizontalHeader().setDefaultSectionSize(59) + self.statistics_table.horizontalHeader().setMinimumSectionSize(24) + self.statistics_table.horizontalHeader().setSortIndicatorShown(True) + self.statistics_table.horizontalHeader().setStretchLastSection(False) + self.gridLayout_4.addWidget(self.statistics_table, 0, 0, 1, 1) + self.tabWidget_3.addTab(self.tab_6, "") + self.tab_7 = QtWidgets.QWidget() + self.tab_7.setObjectName("tab_7") + self.tabWidget_3.addTab(self.tab_7, "") + self.widget = QtWidgets.QWidget(parent=self.stackedWidget_4Page1) + self.widget.setGeometry(QtCore.QRect(10, 10, 761, 441)) + self.widget.setObjectName("widget") + self.horizontalLayoutWidget_3 = QtWidgets.QWidget(parent=self.widget) + self.horizontalLayoutWidget_3.setGeometry(QtCore.QRect(0, 0, 761, 51)) + self.horizontalLayoutWidget_3.setObjectName("horizontalLayoutWidget_3") + self.horizontalLayout_7 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_3) + self.horizontalLayout_7.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_7.setObjectName("horizontalLayout_7") + self.btn_del_select_apparats = QtWidgets.QPushButton(parent=self.horizontalLayoutWidget_3) + self.btn_del_select_apparats.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.btn_del_select_apparats.setObjectName("btn_del_select_apparats") + self.horizontalLayout_7.addWidget(self.btn_del_select_apparats) + spacerItem8 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_7.addItem(spacerItem8) + self.table = QtWidgets.QWidget(parent=self.widget) + self.table.setGeometry(QtCore.QRect(0, 50, 761, 391)) + self.table.setObjectName("table") + self.tableWidget = QtWidgets.QTableWidget(parent=self.table) + self.tableWidget.setGeometry(QtCore.QRect(0, 0, 761, 391)) + self.tableWidget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) + self.tableWidget.setObjectName("tableWidget") + self.tableWidget.setColumnCount(5) + self.tableWidget.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidget.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget.setHorizontalHeaderItem(3, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget.setHorizontalHeaderItem(4, item) + self.stackedWidget_4.addWidget(self.stackedWidget_4Page1) + self.page = QtWidgets.QWidget() + self.page.setObjectName("page") + self.book_search_result = QtWidgets.QTableWidget(parent=self.page) + self.book_search_result.setGeometry(QtCore.QRect(10, 20, 1081, 421)) + self.book_search_result.setFrameShadow(QtWidgets.QFrame.Shadow.Plain) + self.book_search_result.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) + self.book_search_result.setAlternatingRowColors(True) + self.book_search_result.setObjectName("book_search_result") + self.book_search_result.setColumnCount(3) + self.book_search_result.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.book_search_result.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.book_search_result.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.book_search_result.setHorizontalHeaderItem(2, item) + self.book_search_result.horizontalHeader().setCascadingSectionResizes(True) + self.book_search_result.horizontalHeader().setStretchLastSection(True) + self.stackedWidget_4.addWidget(self.page) + self.verticalLayout_3.addWidget(self.stackedWidget_4) + self.tabWidget.addTab(self.tab_2, "") + self.tab_5 = QtWidgets.QWidget() + self.tab_5.setObjectName("tab_5") + self.label_21 = QtWidgets.QLabel(parent=self.tab_5) + self.label_21.setGeometry(QtCore.QRect(10, 30, 47, 22)) + self.label_21.setObjectName("label_21") + self.select_action_box = QtWidgets.QComboBox(parent=self.tab_5) + self.select_action_box.setGeometry(QtCore.QRect(70, 30, 181, 22)) + self.select_action_box.setObjectName("select_action_box") + self.select_action_box.addItem("") + self.select_action_box.addItem("") + self.select_action_box.addItem("") + self.select_action_box.addItem("") + self.user_create_frame = QtWidgets.QFrame(parent=self.tab_5) + self.user_create_frame.setGeometry(QtCore.QRect(10, 60, 591, 141)) + self.user_create_frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.user_create_frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.user_create_frame.setObjectName("user_create_frame") + self.gridLayoutWidget_4 = QtWidgets.QWidget(parent=self.user_create_frame) + self.gridLayoutWidget_4.setGeometry(QtCore.QRect(0, 0, 581, 141)) + self.gridLayoutWidget_4.setObjectName("gridLayoutWidget_4") + self.gridLayout_5 = QtWidgets.QGridLayout(self.gridLayoutWidget_4) + self.gridLayout_5.setContentsMargins(0, 0, 0, 0) + self.gridLayout_5.setObjectName("gridLayout_5") + self.label_22 = QtWidgets.QLabel(parent=self.gridLayoutWidget_4) + self.label_22.setObjectName("label_22") + self.gridLayout_5.addWidget(self.label_22, 0, 0, 1, 1) + self.user_create_frame_username = QtWidgets.QLineEdit(parent=self.gridLayoutWidget_4) + self.user_create_frame_username.setMaximumSize(QtCore.QSize(150, 16777215)) + self.user_create_frame_username.setObjectName("user_create_frame_username") + self.gridLayout_5.addWidget(self.user_create_frame_username, 0, 1, 1, 1) + self.label_24 = QtWidgets.QLabel(parent=self.gridLayoutWidget_4) + self.label_24.setObjectName("label_24") + self.gridLayout_5.addWidget(self.label_24, 0, 2, 1, 1) + self.label_23 = QtWidgets.QLabel(parent=self.gridLayoutWidget_4) + self.label_23.setObjectName("label_23") + self.gridLayout_5.addWidget(self.label_23, 1, 0, 1, 1) + spacerItem9 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.gridLayout_5.addItem(spacerItem9, 0, 4, 1, 1) + self.user_frame_userrole = QtWidgets.QComboBox(parent=self.gridLayoutWidget_4) + self.user_frame_userrole.setObjectName("user_frame_userrole") + self.gridLayout_5.addWidget(self.user_frame_userrole, 0, 3, 1, 1) + self.user_create_frame_password = QtWidgets.QLineEdit(parent=self.gridLayoutWidget_4) + self.user_create_frame_password.setMaximumSize(QtCore.QSize(150, 16777215)) + self.user_create_frame_password.setObjectName("user_create_frame_password") + self.gridLayout_5.addWidget(self.user_create_frame_password, 1, 1, 1, 1) + self.user_frame_addUser = QtWidgets.QPushButton(parent=self.gridLayoutWidget_4) + self.user_frame_addUser.setObjectName("user_frame_addUser") + self.gridLayout_5.addWidget(self.user_frame_addUser, 1, 3, 1, 1) + self.user_frame_err_message = QtWidgets.QLabel(parent=self.gridLayoutWidget_4) + self.user_frame_err_message.setText("") + self.user_frame_err_message.setObjectName("user_frame_err_message") + self.gridLayout_5.addWidget(self.user_frame_err_message, 1, 4, 1, 1) + self.user_delete_frame = QtWidgets.QFrame(parent=self.tab_5) + self.user_delete_frame.setGeometry(QtCore.QRect(10, 60, 591, 141)) + self.user_delete_frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.user_delete_frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.user_delete_frame.setObjectName("user_delete_frame") + self.gridLayoutWidget_7 = QtWidgets.QWidget(parent=self.user_delete_frame) + self.gridLayoutWidget_7.setGeometry(QtCore.QRect(0, 0, 581, 141)) + self.gridLayoutWidget_7.setObjectName("gridLayoutWidget_7") + self.gridLayout_8 = QtWidgets.QGridLayout(self.gridLayoutWidget_7) + self.gridLayout_8.setContentsMargins(0, 0, 0, 0) + self.gridLayout_8.setObjectName("gridLayout_8") + self.horizontalLayout_8 = QtWidgets.QHBoxLayout() + self.horizontalLayout_8.setObjectName("horizontalLayout_8") + spacerItem10 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_8.addItem(spacerItem10) + self.pushButton = QtWidgets.QPushButton(parent=self.gridLayoutWidget_7) + self.pushButton.setObjectName("pushButton") + self.horizontalLayout_8.addWidget(self.pushButton) + spacerItem11 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_8.addItem(spacerItem11) + self.gridLayout_8.addLayout(self.horizontalLayout_8, 1, 1, 1, 1) + self.label_34 = QtWidgets.QLabel(parent=self.gridLayoutWidget_7) + self.label_34.setObjectName("label_34") + self.gridLayout_8.addWidget(self.label_34, 0, 0, 1, 1) + self.user_delete_frame_user_select = QtWidgets.QComboBox(parent=self.gridLayoutWidget_7) + self.user_delete_frame_user_select.setObjectName("user_delete_frame_user_select") + self.gridLayout_8.addWidget(self.user_delete_frame_user_select, 0, 1, 1, 1) + self.user_delete_confirm = QtWidgets.QRadioButton(parent=self.gridLayoutWidget_7) + self.user_delete_confirm.setLayoutDirection(QtCore.Qt.LayoutDirection.RightToLeft) + self.user_delete_confirm.setObjectName("user_delete_confirm") + self.gridLayout_8.addWidget(self.user_delete_confirm, 1, 0, 1, 1) + spacerItem12 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.gridLayout_8.addItem(spacerItem12, 0, 2, 1, 1) + self.user_delete_err_message = QtWidgets.QLabel(parent=self.gridLayoutWidget_7) + self.user_delete_err_message.setText("") + self.user_delete_err_message.setObjectName("user_delete_err_message") + self.gridLayout_8.addWidget(self.user_delete_err_message, 1, 2, 1, 1) + self.user_edit_frame = QtWidgets.QFrame(parent=self.tab_5) + self.user_edit_frame.setGeometry(QtCore.QRect(10, 60, 591, 141)) + self.user_edit_frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.user_edit_frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.user_edit_frame.setObjectName("user_edit_frame") + self.gridLayoutWidget_10 = QtWidgets.QWidget(parent=self.user_edit_frame) + self.gridLayoutWidget_10.setGeometry(QtCore.QRect(0, 0, 581, 141)) + self.gridLayoutWidget_10.setObjectName("gridLayoutWidget_10") + self.gridLayout_11 = QtWidgets.QGridLayout(self.gridLayoutWidget_10) + self.gridLayout_11.setContentsMargins(0, 0, 0, 0) + self.gridLayout_11.setObjectName("gridLayout_11") + self.user_edit_frame_role_select = QtWidgets.QComboBox(parent=self.gridLayoutWidget_10) + self.user_edit_frame_role_select.setObjectName("user_edit_frame_role_select") + self.gridLayout_11.addWidget(self.user_edit_frame_role_select, 0, 3, 1, 1) + self.label_38 = QtWidgets.QLabel(parent=self.gridLayoutWidget_10) + self.label_38.setObjectName("label_38") + self.gridLayout_11.addWidget(self.label_38, 0, 0, 1, 1) + self.user_edit_frame_user_select = QtWidgets.QComboBox(parent=self.gridLayoutWidget_10) + self.user_edit_frame_user_select.setMaximumSize(QtCore.QSize(150, 16777215)) + self.user_edit_frame_user_select.setObjectName("user_edit_frame_user_select") + self.gridLayout_11.addWidget(self.user_edit_frame_user_select, 0, 1, 1, 1) + self.update_user = QtWidgets.QPushButton(parent=self.gridLayoutWidget_10) + self.update_user.setObjectName("update_user") + self.gridLayout_11.addWidget(self.update_user, 1, 3, 1, 1) + self.label_40 = QtWidgets.QLabel(parent=self.gridLayoutWidget_10) + self.label_40.setObjectName("label_40") + self.gridLayout_11.addWidget(self.label_40, 0, 2, 1, 1) + self.label_39 = QtWidgets.QLabel(parent=self.gridLayoutWidget_10) + self.label_39.setObjectName("label_39") + self.gridLayout_11.addWidget(self.label_39, 1, 0, 1, 1) + self.user_edit_frame_new_password = QtWidgets.QLineEdit(parent=self.gridLayoutWidget_10) + self.user_edit_frame_new_password.setMaximumSize(QtCore.QSize(150, 16777215)) + self.user_edit_frame_new_password.setObjectName("user_edit_frame_new_password") + self.gridLayout_11.addWidget(self.user_edit_frame_new_password, 1, 1, 1, 1) + spacerItem13 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.gridLayout_11.addItem(spacerItem13, 0, 4, 1, 1) + self.edit_faculty_member = QtWidgets.QFrame(parent=self.tab_5) + self.edit_faculty_member.setGeometry(QtCore.QRect(10, 60, 1051, 191)) + self.edit_faculty_member.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.edit_faculty_member.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.edit_faculty_member.setObjectName("edit_faculty_member") + self.gridLayoutWidget_11 = QtWidgets.QWidget(parent=self.edit_faculty_member) + self.gridLayoutWidget_11.setGeometry(QtCore.QRect(0, 0, 751, 223)) + self.gridLayoutWidget_11.setObjectName("gridLayoutWidget_11") + self.gridLayout_12 = QtWidgets.QGridLayout(self.gridLayoutWidget_11) + self.gridLayout_12.setContentsMargins(0, 0, 0, 0) + self.gridLayout_12.setObjectName("gridLayout_12") + self.formLayout_2 = QtWidgets.QFormLayout() + self.formLayout_2.setObjectName("formLayout_2") + self.label_43 = QtWidgets.QLabel(parent=self.gridLayoutWidget_11) + self.label_43.setObjectName("label_43") + self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_43) + self.edit_faculty_member_new_title = QtWidgets.QComboBox(parent=self.gridLayoutWidget_11) + self.edit_faculty_member_new_title.setObjectName("edit_faculty_member_new_title") + self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.edit_faculty_member_new_title) + self.label_44 = QtWidgets.QLabel(parent=self.gridLayoutWidget_11) + self.label_44.setObjectName("label_44") + self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_44) + self.edit_faculty_member_new_surname = QtWidgets.QLineEdit(parent=self.gridLayoutWidget_11) + self.edit_faculty_member_new_surname.setObjectName("edit_faculty_member_new_surname") + self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.edit_faculty_member_new_surname) + self.label_45 = QtWidgets.QLabel(parent=self.gridLayoutWidget_11) + self.label_45.setObjectName("label_45") + self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_45) + self.user_faculty_member_new_name = QtWidgets.QLineEdit(parent=self.gridLayoutWidget_11) + self.user_faculty_member_new_name.setObjectName("user_faculty_member_new_name") + self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.ItemRole.FieldRole, self.user_faculty_member_new_name) + self.gridLayout_12.addLayout(self.formLayout_2, 2, 2, 1, 1) + self.formLayout_4 = QtWidgets.QFormLayout() + self.formLayout_4.setObjectName("formLayout_4") + self.edit_faculty_member_title = QtWidgets.QLineEdit(parent=self.gridLayoutWidget_11) + self.edit_faculty_member_title.setFocusPolicy(QtCore.Qt.FocusPolicy.TabFocus) + self.edit_faculty_member_title.setReadOnly(True) + self.edit_faculty_member_title.setObjectName("edit_faculty_member_title") + self.formLayout_4.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.edit_faculty_member_title) + self.edit_faculty_member_select_member = QtWidgets.QComboBox(parent=self.gridLayoutWidget_11) + self.edit_faculty_member_select_member.setObjectName("edit_faculty_member_select_member") + self.formLayout_4.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.edit_faculty_member_select_member) + self.label_46 = QtWidgets.QLabel(parent=self.gridLayoutWidget_11) + self.label_46.setObjectName("label_46") + self.formLayout_4.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_46) + self.faculty_member_old_telnr = QtWidgets.QLineEdit(parent=self.gridLayoutWidget_11) + self.faculty_member_old_telnr.setFocusPolicy(QtCore.Qt.FocusPolicy.ClickFocus) + self.faculty_member_old_telnr.setReadOnly(True) + self.faculty_member_old_telnr.setObjectName("faculty_member_old_telnr") + self.formLayout_4.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.faculty_member_old_telnr) + self.label_49 = QtWidgets.QLabel(parent=self.gridLayoutWidget_11) + self.label_49.setObjectName("label_49") + self.formLayout_4.setWidget(2, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_49) + self.faculty_member_oldmail = QtWidgets.QLineEdit(parent=self.gridLayoutWidget_11) + self.faculty_member_oldmail.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.faculty_member_oldmail.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhNone) + self.faculty_member_oldmail.setReadOnly(True) + self.faculty_member_oldmail.setObjectName("faculty_member_oldmail") + self.formLayout_4.setWidget(2, QtWidgets.QFormLayout.ItemRole.FieldRole, self.faculty_member_oldmail) + self.gridLayout_12.addLayout(self.formLayout_4, 0, 2, 1, 1) + self.formLayout_5 = QtWidgets.QFormLayout() + self.formLayout_5.setObjectName("formLayout_5") + self.label_47 = QtWidgets.QLabel(parent=self.gridLayoutWidget_11) + self.label_47.setObjectName("label_47") + self.formLayout_5.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_47) + self.label_48 = QtWidgets.QLabel(parent=self.gridLayoutWidget_11) + self.label_48.setObjectName("label_48") + self.formLayout_5.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_48) + self.lineEdit = QtWidgets.QLineEdit(parent=self.gridLayoutWidget_11) + self.lineEdit.setObjectName("lineEdit") + self.formLayout_5.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.lineEdit) + self.lineEdit_5 = QtWidgets.QLineEdit(parent=self.gridLayoutWidget_11) + self.lineEdit_5.setObjectName("lineEdit_5") + self.formLayout_5.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.lineEdit_5) + self.gridLayout_12.addLayout(self.formLayout_5, 2, 4, 1, 1) + self.label_41 = QtWidgets.QLabel(parent=self.gridLayoutWidget_11) + self.label_41.setObjectName("label_41") + self.gridLayout_12.addWidget(self.label_41, 0, 0, 1, 1) + self.update_faculty_member = QtWidgets.QPushButton(parent=self.gridLayoutWidget_11) + self.update_faculty_member.setObjectName("update_faculty_member") + self.gridLayout_12.addWidget(self.update_faculty_member, 3, 4, 1, 1) + self.label_42 = QtWidgets.QLabel(parent=self.gridLayoutWidget_11) + self.label_42.setObjectName("label_42") + self.gridLayout_12.addWidget(self.label_42, 2, 0, 1, 1) + self.tabWidget.addTab(self.tab_5, "") + self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) + self.horizontalLayout.addLayout(self.gridLayout) + self.verticalLayout.addLayout(self.horizontalLayout) + self.horizontalLayoutWidget = QtWidgets.QWidget(parent=self.centralwidget) + self.horizontalLayoutWidget.setGeometry(QtCore.QRect(1280, 360, 311, 391)) + self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget") + self.horizontalLayout_6 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget) + self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_6.setObjectName("horizontalLayout_6") + self.frame_creation_progress = QtWidgets.QFrame(parent=self.horizontalLayoutWidget) + self.frame_creation_progress.setObjectName("frame_creation_progress") + self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.frame_creation_progress) + self.verticalLayout_4.setSpacing(6) + self.verticalLayout_4.setObjectName("verticalLayout_4") + self.groupBox_2 = QtWidgets.QGroupBox(parent=self.frame_creation_progress) + self.groupBox_2.setEnabled(True) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.groupBox_2.sizePolicy().hasHeightForWidth()) + self.groupBox_2.setSizePolicy(sizePolicy) + self.groupBox_2.setObjectName("groupBox_2") + self.appdata_check = QtWidgets.QCheckBox(parent=self.groupBox_2) + self.appdata_check.setGeometry(QtCore.QRect(20, 30, 241, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setWeight(50) + self.appdata_check.setFont(font) + self.appdata_check.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.appdata_check.setObjectName("appdata_check") + self.media_check = QtWidgets.QCheckBox(parent=self.groupBox_2) + self.media_check.setGeometry(QtCore.QRect(20, 70, 241, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setWeight(50) + self.media_check.setFont(font) + self.media_check.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.media_check.setObjectName("media_check") + self.ids_check = QtWidgets.QCheckBox(parent=self.groupBox_2) + self.ids_check.setGeometry(QtCore.QRect(20, 140, 241, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setWeight(50) + self.ids_check.setFont(font) + self.ids_check.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.ids_check.setObjectName("ids_check") + self.verticalLayout_4.addWidget(self.groupBox_2) + self.groupBox = QtWidgets.QGroupBox(parent=self.frame_creation_progress) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth()) + self.groupBox.setSizePolicy(sizePolicy) + self.groupBox.setObjectName("groupBox") + self.media_checked = QtWidgets.QCheckBox(parent=self.groupBox) + self.media_checked.setGeometry(QtCore.QRect(20, 30, 241, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setItalic(False) + font.setUnderline(False) + font.setWeight(50) + font.setKerning(True) + font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault) + self.media_checked.setFont(font) + self.media_checked.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.media_checked.setObjectName("media_checked") + self.media_edited_check = QtWidgets.QCheckBox(parent=self.groupBox) + self.media_edited_check.setGeometry(QtCore.QRect(20, 70, 241, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setItalic(False) + font.setUnderline(False) + font.setWeight(50) + font.setKerning(True) + font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault) + self.media_edited_check.setFont(font) + self.media_edited_check.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.media_edited_check.setObjectName("media_edited_check") + self.app_created = QtWidgets.QCheckBox(parent=self.groupBox) + self.app_created.setGeometry(QtCore.QRect(20, 110, 161, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setItalic(False) + font.setUnderline(False) + font.setWeight(50) + font.setKerning(True) + font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault) + self.app_created.setFont(font) + self.app_created.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.app_created.setObjectName("app_created") + self.btn_copy_adis_command = QtWidgets.QPushButton(parent=self.groupBox) + self.btn_copy_adis_command.setGeometry(QtCore.QRect(170, 120, 101, 23)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setItalic(False) + font.setUnderline(False) + font.setWeight(50) + font.setKerning(True) + font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault) + self.btn_copy_adis_command.setFont(font) + self.btn_copy_adis_command.setStatusTip("") + self.btn_copy_adis_command.setWhatsThis("") + self.btn_copy_adis_command.setAccessibleDescription("") + self.btn_copy_adis_command.setAutoFillBackground(False) + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap("/home/alexander/GitHub/Semesterapparate/ui/../../../.designer/backup/icons/information.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.btn_copy_adis_command.setIcon(icon) + self.btn_copy_adis_command.setCheckable(False) + self.btn_copy_adis_command.setChecked(False) + self.btn_copy_adis_command.setAutoDefault(False) + self.btn_copy_adis_command.setObjectName("btn_copy_adis_command") + self.verticalLayout_4.addWidget(self.groupBox) + self.horizontalLayout_6.addWidget(self.frame_creation_progress) + self.frame_2 = QtWidgets.QFrame(parent=self.centralwidget) + self.frame_2.setGeometry(QtCore.QRect(1280, 10, 301, 341)) + self.frame_2.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame_2.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame_2.setObjectName("frame_2") + self.calendarWidget = QtWidgets.QCalendarWidget(parent=self.frame_2) + self.calendarWidget.setGeometry(QtCore.QRect(0, 0, 291, 191)) + self.calendarWidget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.calendarWidget.setGridVisible(True) + self.calendarWidget.setVerticalHeaderFormat(QtWidgets.QCalendarWidget.VerticalHeaderFormat.NoVerticalHeader) + self.calendarWidget.setObjectName("calendarWidget") + self.message_frame = QtWidgets.QFrame(parent=self.frame_2) + self.message_frame.setGeometry(QtCore.QRect(0, 210, 301, 121)) + self.message_frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.message_frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.message_frame.setObjectName("message_frame") + self.label_14 = QtWidgets.QLabel(parent=self.message_frame) + self.label_14.setGeometry(QtCore.QRect(10, 10, 47, 20)) + self.label_14.setObjectName("label_14") + self.line_app_info = QtWidgets.QLineEdit(parent=self.message_frame) + self.line_app_info.setEnabled(True) + self.line_app_info.setGeometry(QtCore.QRect(60, 10, 31, 20)) + self.line_app_info.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.line_app_info.setObjectName("line_app_info") + self.message_box = QtWidgets.QTextEdit(parent=self.message_frame) + self.message_box.setGeometry(QtCore.QRect(10, 40, 281, 71)) + self.message_box.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.message_box.setObjectName("message_box") + self.btn_delete_message = QtWidgets.QPushButton(parent=self.message_frame) + self.btn_delete_message.setGeometry(QtCore.QRect(130, 10, 75, 23)) + self.btn_delete_message.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.btn_delete_message.setObjectName("btn_delete_message") + self.spin_select_message = QtWidgets.QSpinBox(parent=self.message_frame) + self.spin_select_message.setGeometry(QtCore.QRect(210, 10, 74, 22)) + self.spin_select_message.setMinimum(1) + self.spin_select_message.setObjectName("spin_select_message") + self.label_total_day_messages = QtWidgets.QLabel(parent=self.message_frame) + self.label_total_day_messages.setGeometry(QtCore.QRect(260, 10, 21, 22)) + self.label_total_day_messages.setObjectName("label_total_day_messages") + MainWindow.setCentralWidget(self.centralwidget) + self.menubar = QtWidgets.QMenuBar(parent=MainWindow) + self.menubar.setGeometry(QtCore.QRect(0, 0, 1593, 30)) + self.menubar.setObjectName("menubar") + self.menuDatei = QtWidgets.QMenu(parent=self.menubar) + self.menuDatei.setObjectName("menuDatei") + self.menuEinstellungen = QtWidgets.QMenu(parent=self.menubar) + self.menuEinstellungen.setObjectName("menuEinstellungen") + MainWindow.setMenuBar(self.menubar) + self.statusbar = QtWidgets.QStatusBar(parent=MainWindow) + self.statusbar.setObjectName("statusbar") + MainWindow.setStatusBar(self.statusbar) + self.actionBeenden = QtGui.QAction(parent=MainWindow) + self.actionBeenden.setShortcutVisibleInContextMenu(True) + self.actionBeenden.setObjectName("actionBeenden") + self.actionEinstellungen = QtGui.QAction(parent=MainWindow) + self.actionEinstellungen.setShortcutVisibleInContextMenu(True) + self.actionEinstellungen.setObjectName("actionEinstellungen") + self.menuDatei.addAction(self.actionBeenden) + self.menuEinstellungen.addAction(self.actionEinstellungen) + self.menubar.addAction(self.menuDatei.menuAction()) + self.menubar.addAction(self.menuEinstellungen.menuAction()) + + self.retranslateUi(MainWindow) + self.tabWidget.setCurrentIndex(0) + self.tabWidget_2.setCurrentIndex(0) + self.stackedWidget_4.setCurrentIndex(1) + self.tabWidget_3.setCurrentIndex(1) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + MainWindow.setTabOrder(self.drpdwn_app_nr, self.drpdwn_prof_title) + MainWindow.setTabOrder(self.drpdwn_prof_title, self.drpdwn_prof_name) + MainWindow.setTabOrder(self.drpdwn_prof_name, self.prof_mail) + MainWindow.setTabOrder(self.prof_mail, self.prof_tel_nr) + MainWindow.setTabOrder(self.prof_tel_nr, self.app_name) + MainWindow.setTabOrder(self.app_name, self.app_fach) + MainWindow.setTabOrder(self.app_fach, self.sem_year) + MainWindow.setTabOrder(self.sem_year, self.check_eternal_app) + MainWindow.setTabOrder(self.check_eternal_app, self.btn_add_document) + MainWindow.setTabOrder(self.btn_add_document, self.btn_open_document) + MainWindow.setTabOrder(self.btn_open_document, self.check_file) + MainWindow.setTabOrder(self.check_file, self.btn_apparat_save) + MainWindow.setTabOrder(self.btn_apparat_save, self.btn_apparat_apply) + MainWindow.setTabOrder(self.btn_apparat_apply, self.check_send_mail) + MainWindow.setTabOrder(self.check_send_mail, self.chkbx_show_del_media) + MainWindow.setTabOrder(self.chkbx_show_del_media, self.btn_reserve) + MainWindow.setTabOrder(self.btn_reserve, self.prof_id_adis) + MainWindow.setTabOrder(self.prof_id_adis, self.apparat_id_adis) + MainWindow.setTabOrder(self.apparat_id_adis, self.tabWidget_2) + MainWindow.setTabOrder(self.tabWidget_2, self.btn_del_select_apparats) + MainWindow.setTabOrder(self.btn_del_select_apparats, self.tabWidget_3) + MainWindow.setTabOrder(self.tabWidget_3, self.select_action_box) + MainWindow.setTabOrder(self.select_action_box, self.user_create_frame_username) + MainWindow.setTabOrder(self.user_create_frame_username, self.user_frame_userrole) + MainWindow.setTabOrder(self.user_frame_userrole, self.user_create_frame_password) + MainWindow.setTabOrder(self.user_create_frame_password, self.user_frame_addUser) + MainWindow.setTabOrder(self.user_frame_addUser, self.user_delete_frame_user_select) + MainWindow.setTabOrder(self.user_delete_frame_user_select, self.user_delete_confirm) + MainWindow.setTabOrder(self.user_delete_confirm, self.pushButton) + MainWindow.setTabOrder(self.pushButton, self.user_edit_frame_user_select) + MainWindow.setTabOrder(self.user_edit_frame_user_select, self.user_edit_frame_role_select) + MainWindow.setTabOrder(self.user_edit_frame_role_select, self.user_edit_frame_new_password) + MainWindow.setTabOrder(self.user_edit_frame_new_password, self.update_user) + MainWindow.setTabOrder(self.update_user, self.edit_faculty_member_title) + MainWindow.setTabOrder(self.edit_faculty_member_title, self.edit_faculty_member_select_member) + MainWindow.setTabOrder(self.edit_faculty_member_select_member, self.faculty_member_old_telnr) + MainWindow.setTabOrder(self.faculty_member_old_telnr, self.faculty_member_oldmail) + MainWindow.setTabOrder(self.faculty_member_oldmail, self.edit_faculty_member_new_title) + MainWindow.setTabOrder(self.edit_faculty_member_new_title, self.edit_faculty_member_new_surname) + MainWindow.setTabOrder(self.edit_faculty_member_new_surname, self.user_faculty_member_new_name) + MainWindow.setTabOrder(self.user_faculty_member_new_name, self.lineEdit) + MainWindow.setTabOrder(self.lineEdit, self.lineEdit_5) + MainWindow.setTabOrder(self.lineEdit_5, self.update_faculty_member) + MainWindow.setTabOrder(self.update_faculty_member, self.box_fach) + MainWindow.setTabOrder(self.box_fach, self.box_person) + MainWindow.setTabOrder(self.box_person, self.btn_search) + MainWindow.setTabOrder(self.btn_search, self.check_deletable) + MainWindow.setTabOrder(self.check_deletable, self.box_erstellsemester) + MainWindow.setTabOrder(self.box_erstellsemester, self.box_semester) + MainWindow.setTabOrder(self.box_semester, self.box_dauerapp) + MainWindow.setTabOrder(self.box_dauerapp, self.box_appnrs) + MainWindow.setTabOrder(self.box_appnrs, self.btn_copy_adis_command) + MainWindow.setTabOrder(self.btn_copy_adis_command, self.spin_select_message) + + def retranslateUi(self, MainWindow): + _translate = QtCore.QCoreApplication.translate + MainWindow.setWindowTitle(_translate("MainWindow", "Semesterapparatsmanagement")) + self.load_app.setToolTip(_translate("MainWindow", "Load the Semesterapparate from the database")) + self.load_app.setText(_translate("MainWindow", "App. aufrufen")) + self.create_new_app.setText(_translate("MainWindow", "neu. App anlegen")) + self.cancel_active_selection.setText(_translate("MainWindow", "Auswahl abbrechen")) + self.tableWidget_apparate.setSortingEnabled(True) + item = self.tableWidget_apparate.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "AppNr")) + item = self.tableWidget_apparate.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "App Name")) + item = self.tableWidget_apparate.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Professor")) + item = self.tableWidget_apparate.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "gültig bis")) + item = self.tableWidget_apparate.horizontalHeaderItem(4) + item.setText(_translate("MainWindow", "Dauerapparat")) + item = self.tableWidget_apparate.horizontalHeaderItem(5) + item.setText(_translate("MainWindow", "KontoNr")) + self.app_group_box.setTitle(_translate("MainWindow", "Apparatsdetails")) + item = self.dokument_list.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Dokumentname")) + item = self.dokument_list.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Dateityp")) + item = self.dokument_list.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Neu?")) + item = self.dokument_list.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "path")) + self.label_5.setText(_translate("MainWindow", "Apparatsname")) + self.sem_winter.setText(_translate("MainWindow", "Winter")) + self.label_4.setText(_translate("MainWindow", "Prof. Name")) + self.sem_sommer.setText(_translate("MainWindow", "Sommer")) + self.label_3.setText(_translate("MainWindow", "Prof. Titel")) + self.label_6.setText(_translate("MainWindow", "Semester")) + self.sem_year.setPlaceholderText(_translate("MainWindow", "2023")) + self.label_2.setText(_translate("MainWindow", "Apparatsnummer")) + self.btn_apparat_save.setText(_translate("MainWindow", "Speichern")) + self.btn_apparat_apply.setText(_translate("MainWindow", "Aktualisieren")) + self.check_eternal_app.setText(_translate("MainWindow", "Dauerapparat")) + self.label_8.setText(_translate("MainWindow", "Mail")) + self.label_9.setText(_translate("MainWindow", "Tel")) + self.label_10.setText(_translate("MainWindow", "Fach")) + self.mail_mand.setText(_translate("MainWindow", "*")) + self.telnr_mand.setText(_translate("MainWindow", "*")) + self.profname_mand.setText(_translate("MainWindow", "*")) + self.appname_mand.setText(_translate("MainWindow", "*")) + self.fach_mand.setText(_translate("MainWindow", "*")) + self._mand.setText(_translate("MainWindow", "*")) + self.btn_add_document.setText(_translate("MainWindow", "Dokument hinzufügen")) + self.btn_open_document.setText(_translate("MainWindow", "Dokument öffnen")) + self.check_file.setToolTip(_translate("MainWindow", "Abhängig von der Anzahl der Medien kann die Suche sehr lange dauern")) + self.check_file.setText(_translate("MainWindow", "Medien aus Dokument\n" +" hinzufügen")) + self.label_12.setText(_translate("MainWindow", "Prof-ID-aDIS")) + self.label_13.setText(_translate("MainWindow", "Apparat-ID-aDIS")) + self.check_send_mail.setText(_translate("MainWindow", "Mail senden")) + self.tableWidget_apparat_media.setSortingEnabled(True) + item = self.tableWidget_apparat_media.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Buchtitel")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Signatur")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Auflage")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "Autor")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(4) + item.setText(_translate("MainWindow", "verfügbar?")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(5) + item.setText(_translate("MainWindow", "Vorgemerkt")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(6) + item.setText(_translate("MainWindow", "Link")) + self.label.setText(_translate("MainWindow", " Medienliste")) + self.chkbx_show_del_media.setText(_translate("MainWindow", "gel. Medien anzeigen")) + self.btn_reserve.setText(_translate("MainWindow", "im Apparat?")) + self.label_info.setText(_translate("MainWindow", "Medien werden hinzugefügt")) + self.progress_label.setText(_translate("MainWindow", "Medium x/y")) + self.label_20.setText(_translate("MainWindow", "Medien werden geprüft")) + self.avail_status.setText(_translate("MainWindow", "TextLabel")) + self.add_medium.setText(_translate("MainWindow", "Medien hinzufügen")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Anlegen")) + self.btn_search.setText(_translate("MainWindow", "Suchen")) + self.label_7.setText(_translate("MainWindow", "Appnr.:")) + self.label_18.setText(_translate("MainWindow", "Dauerapp:")) + self.label_17.setText(_translate("MainWindow", "Endsemester:")) + self.label_19.setText(_translate("MainWindow", "Erstellsemester:")) + self.label_11.setText(_translate("MainWindow", "Person:")) + self.label_16.setText(_translate("MainWindow", "Fach:")) + self.label_15.setText(_translate("MainWindow", "Löschbar")) + self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_3), _translate("MainWindow", "Statistik")) + self.label_25.setText(_translate("MainWindow", "Signatur")) + self.book_search.setText(_translate("MainWindow", "Suche")) + self.label_26.setText(_translate("MainWindow", "Titel")) + self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_4), _translate("MainWindow", "Suchen")) + item = self.statistics_table.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Semester")) + item = self.statistics_table.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Zugang")) + item = self.statistics_table.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Abgang")) + self.tabWidget_3.setTabText(self.tabWidget_3.indexOf(self.tab_6), _translate("MainWindow", "Tabelle")) + self.tabWidget_3.setTabText(self.tabWidget_3.indexOf(self.tab_7), _translate("MainWindow", "Erstellte und gelöschte Semesterapparate")) + self.btn_del_select_apparats.setText(_translate("MainWindow", "Ausgewählte Löschen")) + item = self.tableWidget.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Apparatsname")) + item = self.tableWidget.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Apparatsnummer")) + item = self.tableWidget.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "Person")) + item = self.tableWidget.horizontalHeaderItem(4) + item.setText(_translate("MainWindow", "Fach")) + item = self.book_search_result.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Titel")) + item = self.book_search_result.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Signatur")) + item = self.book_search_result.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Apparat")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Suchen / Statistik")) + self.label_21.setText(_translate("MainWindow", "Aktion:")) + self.select_action_box.setItemText(0, _translate("MainWindow", "Nutzer anlegen")) + self.select_action_box.setItemText(1, _translate("MainWindow", "Nutzer löschen")) + self.select_action_box.setItemText(2, _translate("MainWindow", "Nutzer aktualisieren")) + self.select_action_box.setItemText(3, _translate("MainWindow", "Lehrperson bearbeiten")) + self.label_22.setText(_translate("MainWindow", "Nutzername")) + self.label_24.setText(_translate("MainWindow", "Rolle")) + self.label_23.setText(_translate("MainWindow", "Passwort")) + self.user_frame_addUser.setText(_translate("MainWindow", "Anlegen")) + self.pushButton.setText(_translate("MainWindow", "Nutzer löschen")) + self.label_34.setText(_translate("MainWindow", "Nutzername")) + self.user_delete_confirm.setText(_translate("MainWindow", "Wirklich löschen?")) + self.label_38.setText(_translate("MainWindow", "Nutzername")) + self.update_user.setText(_translate("MainWindow", "Aktualisieren")) + self.label_40.setText(_translate("MainWindow", "Rolle")) + self.label_39.setText(_translate("MainWindow", "Neues Passwort")) + self.label_43.setText(_translate("MainWindow", "Titel")) + self.label_44.setText(_translate("MainWindow", "Vorname")) + self.label_45.setText(_translate("MainWindow", "Nachname")) + self.label_46.setText(_translate("MainWindow", "Telefonnummer")) + self.label_49.setText(_translate("MainWindow", "Mail")) + self.label_47.setText(_translate("MainWindow", "Mail")) + self.label_48.setText(_translate("MainWindow", "Telefon")) + self.label_41.setText(_translate("MainWindow", "Alte Angaben")) + self.update_faculty_member.setText(_translate("MainWindow", "Aktualisieren")) + self.label_42.setText(_translate("MainWindow", "Neue Angaben")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_5), _translate("MainWindow", "Admin")) + self.groupBox_2.setTitle(_translate("MainWindow", "Software")) + self.appdata_check.setText(_translate("MainWindow", "Apparatsdaten eingegeben")) + self.media_check.setText(_translate("MainWindow", "Medien hinzugefügt / importiert")) + self.ids_check.setText(_translate("MainWindow", "Prof-ID und Apparat-ID eingetragen")) + self.groupBox.setTitle(_translate("MainWindow", "aDIS")) + self.media_checked.setText(_translate("MainWindow", "Medien geprüft")) + self.media_edited_check.setText(_translate("MainWindow", "Medien bearbeitet")) + self.app_created.setText(_translate("MainWindow", "Apparat angelegt")) + self.btn_copy_adis_command.setToolTip(_translate("MainWindow", "Hier klicken, um die aDIS Abfrage in die Zwischenablage zu kopieren")) + self.btn_copy_adis_command.setText(_translate("MainWindow", " aDIS Abfrage")) + self.label_14.setText(_translate("MainWindow", "Apparat")) + self.btn_delete_message.setText(_translate("MainWindow", "Löschen")) + self.label_total_day_messages.setText(_translate("MainWindow", "TextLabel")) + self.menuDatei.setTitle(_translate("MainWindow", "Datei")) + self.menuEinstellungen.setTitle(_translate("MainWindow", "Bearbeiten")) + self.actionBeenden.setText(_translate("MainWindow", "Beenden")) + self.actionBeenden.setShortcut(_translate("MainWindow", "Ctrl+Q")) + self.actionEinstellungen.setText(_translate("MainWindow", "Einstellungen")) + self.actionEinstellungen.setShortcut(_translate("MainWindow", "Alt+S")) diff --git a/src/ui/setupwizard.ui b/src/ui/setupwizard.ui new file mode 100644 index 0000000..3875a94 --- /dev/null +++ b/src/ui/setupwizard.ui @@ -0,0 +1,149 @@ + + + Wizard + + + + 0 + 0 + 640 + 480 + + + + + 640 + 480 + + + + Wizard + + + + + + 200 + 10 + 256 + 192 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Setup für das Semesterapparatsprogram.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Im Anschluss werden wichtige Einstellungen gesetzt, welche auch im späteren Verlauf verändert werden können.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + + + + 10 + 0 + 131 + 16 + + + + Grundeinstellungen + + + + + + 10 + 40 + 71 + 16 + + + + Opens the downloaded files with the default applications set in the OS + + + Default Apps + + + + + + 100 + 40 + 70 + 17 + + + + + + + + + + 10 + 70 + 61 + 16 + + + + Path where the downloaded files are stored. Defaults to ~/Desktop/SemapFiles + + + Save Path + + + + + + 280 + 10 + 331 + 361 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + 80 + 70 + 113 + 20 + + + + ~/Desktop/SemapFiles + + + + + + 200 + 70 + 25 + 19 + + + + ... + + + + + + + diff --git a/src/ui/setupwizard_ui.py b/src/ui/setupwizard_ui.py new file mode 100644 index 0000000..f99cad1 --- /dev/null +++ b/src/ui/setupwizard_ui.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'setupwizard.ui' +## +## Created by: Qt User Interface Compiler version 6.5.2 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, + QMetaObject, QObject, QPoint, QRect, + QSize, QTime, QUrl, Qt) +from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, + QFont, QFontDatabase, QGradient, QIcon, + QImage, QKeySequence, QLinearGradient, QPainter, + QPalette, QPixmap, QRadialGradient, QTransform) +from PySide6.QtWidgets import (QApplication, QCheckBox, QFrame, QLabel, + QLineEdit, QSizePolicy, QTextBrowser, QToolButton, + QWidget, QWizard, QWizardPage) + +class Ui_Wizard(object): + def setupUi(self, Wizard): + if not Wizard.objectName(): + Wizard.setObjectName(u"Wizard") + Wizard.resize(640, 480) + Wizard.setMaximumSize(QSize(640, 480)) + self.wizardPage1 = QWizardPage() + self.wizardPage1.setObjectName(u"wizardPage1") + self.textBrowser = QTextBrowser(self.wizardPage1) + self.textBrowser.setObjectName(u"textBrowser") + self.textBrowser.setGeometry(QRect(200, 10, 256, 192)) + Wizard.addPage(self.wizardPage1) + self.wizardPage2 = QWizardPage() + self.wizardPage2.setObjectName(u"wizardPage2") + self.label = QLabel(self.wizardPage2) + self.label.setObjectName(u"label") + self.label.setGeometry(QRect(10, 0, 131, 16)) + self.label_2 = QLabel(self.wizardPage2) + self.label_2.setObjectName(u"label_2") + self.label_2.setGeometry(QRect(10, 40, 71, 16)) + self.default_apps = QCheckBox(self.wizardPage2) + self.default_apps.setObjectName(u"default_apps") + self.default_apps.setGeometry(QRect(100, 40, 70, 17)) + self.label_3 = QLabel(self.wizardPage2) + self.label_3.setObjectName(u"label_3") + self.label_3.setGeometry(QRect(10, 70, 61, 16)) + self.custom_applications = QFrame(self.wizardPage2) + self.custom_applications.setObjectName(u"custom_applications") + self.custom_applications.setGeometry(QRect(280, 10, 331, 361)) + self.custom_applications.setFrameShape(QFrame.StyledPanel) + self.custom_applications.setFrameShadow(QFrame.Raised) + self.save_path = QLineEdit(self.wizardPage2) + self.save_path.setObjectName(u"save_path") + self.save_path.setGeometry(QRect(80, 70, 113, 20)) + self.btn_save_path_select = QToolButton(self.wizardPage2) + self.btn_save_path_select.setObjectName(u"btn_save_path_select") + self.btn_save_path_select.setGeometry(QRect(200, 70, 25, 19)) + Wizard.addPage(self.wizardPage2) + + self.retranslateUi(Wizard) + + QMetaObject.connectSlotsByName(Wizard) + # setupUi + + def retranslateUi(self, Wizard): + Wizard.setWindowTitle(QCoreApplication.translate("Wizard", u"Wizard", None)) + self.textBrowser.setHtml(QCoreApplication.translate("Wizard", u"\n" +"\n" +"

Setup f\u00fcr das Semesterapparatsprogram.

\n" +"


\n" +"

Im Anschluss werden wichtige Einstellungen gesetzt, welche auch im sp\u00e4teren Verlauf ver\u00e4ndert werden k\u00f6nnen.

\n" +"


", None)) + self.label.setText(QCoreApplication.translate("Wizard", u"Grundeinstellungen", None)) +#if QT_CONFIG(tooltip) + self.label_2.setToolTip(QCoreApplication.translate("Wizard", u"Opens the downloaded files with the default applications set in the OS", None)) +#endif // QT_CONFIG(tooltip) + self.label_2.setText(QCoreApplication.translate("Wizard", u"Default Apps", None)) + self.default_apps.setText("") +#if QT_CONFIG(tooltip) + self.label_3.setToolTip(QCoreApplication.translate("Wizard", u"Path where the downloaded files are stored. Defaults to ~/Desktop/SemapFiles", None)) +#endif // QT_CONFIG(tooltip) + self.label_3.setText(QCoreApplication.translate("Wizard", u"Save Path", None)) + self.save_path.setPlaceholderText(QCoreApplication.translate("Wizard", u"~/Desktop/SemapFiles", None)) + self.btn_save_path_select.setText(QCoreApplication.translate("Wizard", u"...", None)) + # retranslateUi + diff --git a/src/ui/sounds/semesterapparat_ui.ui b/src/ui/sounds/semesterapparat_ui.ui new file mode 100644 index 0000000..529011b --- /dev/null +++ b/src/ui/sounds/semesterapparat_ui.ui @@ -0,0 +1,2146 @@ + + + MainWindow + + + Qt::WindowModal + + + true + + + + 0 + 0 + 1593 + 800 + + + + + 0 + 0 + + + + + 1278 + 800 + + + + + 1920 + 800 + + + + Qt::NoContextMenu + + + Semesterapparatsmanagement + + + + + 0 + 0 + + + + + + 0 + 0 + 1271 + 761 + + + + + + + + + + + Qt::NoFocus + + + 1 + + + + + 0 + 0 + + + + Anlegen + + + + + 0 + 0 + 1261 + 163 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::NoFocus + + + Load the Semesterapparate from the database + + + App. aufrufen + + + + + + + Qt::NoFocus + + + neu. App anlegen + + + + + + + Auswahl abbrechen + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::NoFocus + + + QAbstractScrollArea::AdjustToContents + + + QAbstractItemView::SelectedClicked + + + true + + + Qt::ElideMiddle + + + true + + + true + + + + AppNr + + + + + App Name + + + + + Professor + + + + + gültig bis + + + + + Dauerapparat + + + + + KontoNr + + + + + + + + + + + + + + + + + + 0 + 160 + 1261 + 21 + + + + Qt::Horizontal + + + + + true + + + + 0 + 180 + 1261 + 511 + + + + + + + + 0 + 0 + + + + + 0 + 210 + + + + + 12 + 75 + true + + + + Apparatsdetails + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + false + + + + + 765 + 20 + 321 + 181 + + + + + 10 + 50 + false + false + + + + Qt::NoFocus + + + true + + + QAbstractScrollArea::AdjustToContents + + + true + + + QAbstractItemView::DropOnly + + + Qt::LinkAction + + + QAbstractItemView::SingleSelection + + + + Dokumentname + + + + Arial + 8 + + + + + + Dateityp + + + + Arial + 8 + + + + + + Neu? + + + + Arial + 8 + + + + + + path + + + + + + true + + + + 10 + 30 + 1241 + 151 + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 110 + 50 + 69 + 22 + + + + + 9 + 50 + false + + + + true + + + + + + 250 + 20 + 91 + 21 + + + + + 9 + 50 + false + + + + Apparatsname + + + + + + 340 + 50 + 82 + 17 + + + + + 9 + 50 + false + + + + Qt::NoFocus + + + Winter + + + + + + 10 + 80 + 71 + 21 + + + + + 9 + 50 + false + + + + Prof. Name + + + + + + 110 + 20 + 69 + 22 + + + + + 9 + 50 + false + + + + Qt::ImhDigitsOnly + + + true + + + + + + 340 + 20 + 113 + 20 + + + + + 9 + 50 + false + + + + Qt::StrongFocus + + + + + + 340 + 70 + 82 + 17 + + + + + 9 + 50 + false + + + + Qt::NoFocus + + + Sommer + + + + + + 10 + 50 + 61 + 20 + + + + + 9 + 50 + false + + + + Prof. Titel + + + + + + 270 + 60 + 61 + 21 + + + + + 9 + 50 + false + + + + Semester + + + + + + 410 + 60 + 113 + 20 + + + + + 9 + 50 + false + + + + Qt::StrongFocus + + + 4 + + + 2023 + + + + + + 10 + 20 + 101 + 21 + + + + + 9 + 50 + false + + + + Apparatsnummer + + + + + + 260 + 120 + 75 + 23 + + + + + 9 + 50 + false + + + + Speichern + + + + + + 350 + 120 + 75 + 23 + + + + + 9 + 50 + false + + + + Aktualisieren + + + + + + 340 + 90 + 101 + 17 + + + + + 9 + 50 + false + + + + Dauerapparat + + + + + + 10 + 110 + 71 + 21 + + + + + 9 + 50 + false + + + + Mail + + + + + + 110 + 110 + 121 + 20 + + + + + 9 + 50 + false + + + + Qt::ImhEmailCharactersOnly + + + 200 + + + + + + + + + 10 + 130 + 71 + 21 + + + + + 9 + 50 + false + + + + Tel + + + + + + 110 + 130 + 121 + 20 + + + + + 9 + 50 + false + + + + Qt::ImhDigitsOnly + + + + + + + + + 470 + 20 + 51 + 21 + + + + + 9 + 50 + false + + + + Fach + + + + + + 510 + 20 + 113 + 20 + + + + + 9 + 50 + false + + + + Qt::StrongFocus + + + + + + 110 + 80 + 121 + 22 + + + + + 8 + 50 + false + + + + Qt::StrongFocus + + + true + + + + + + QComboBox::InsertAlphabetically + + + true + + + + + + 100 + 110 + 47 + 21 + + + + + 9 + 50 + false + + + + * + + + + + + 100 + 130 + 47 + 21 + + + + + 9 + 50 + false + + + + * + + + + + + 100 + 80 + 47 + 21 + + + + + 9 + 50 + false + + + + * + + + + + + 330 + 20 + 16 + 21 + + + + + 9 + 50 + false + + + + * + + + + + + 500 + 20 + 47 + 21 + + + + + 9 + 50 + false + + + + Qt::NoFocus + + + * + + + + + + 330 + 60 + 16 + 21 + + + + + 9 + 50 + false + + + + * + + + + + + 1090 + 20 + 131 + 25 + + + + + 9 + 50 + false + + + + Dokument hinzufügen + + + + + + 1090 + 60 + 131 + 25 + + + + + 9 + 50 + false + + + + Dokument öffnen + + + + + + 1090 + 100 + 131 + 51 + + + + + 9 + 50 + false + + + + Abhängig von der Anzahl der Medien kann die Suche sehr lange dauern + + + Medien aus Dokument + hinzufügen + + + + + + 550 + 70 + 202 + 80 + + + + + + + + 9 + 50 + false + + + + Prof-ID-aDIS + + + + + + + + 9 + 50 + false + + + + + + + + + 9 + 50 + false + + + + Apparat-ID-aDIS + + + + + + + + + + + + 450 + 120 + 91 + 17 + + + + + 9 + 50 + false + + + + Mail senden + + + _mand + drpdwn_prof_title + label_5 + sem_winter + label_4 + drpdwn_app_nr + sem_sommer + label_3 + label_6 + sem_year + label_2 + btn_apparat_save + btn_apparat_apply + check_eternal_app + label_8 + label_9 + label_10 + mail_mand + telnr_mand + profname_mand + appname_mand + fach_mand + btn_add_document + btn_open_document + app_fach + app_name + prof_tel_nr + drpdwn_prof_name + prof_mail + check_file + formLayoutWidget_2 + check_send_mail + + frame + dokument_list + + + + + + + 0 + 0 + + + + + 1259 + 0 + + + + Qt::NoFocus + + + Qt::CustomContextMenu + + + QAbstractScrollArea::AdjustToContents + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::SelectRows + + + true + + + true + + + + Buchtitel + + + + + Signatur + + + + + Auflage + + + + + Autor + + + + + verfügbar? + + + + + Vorgemerkt + + + + + Link + + + + + + + + + 11 + 75 + true + + + + Medienliste + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + gel. Medien anzeigen + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + + + Medien werden hinzugefügt + + + + + + + Qt::Vertical + + + + + + + Medium x/y + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + Vorgemertk? + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 0 + 700 + 121 + 20 + + + + Qt::NoFocus + + + Medien hinzufügen + + + + + + Suchen / Statistik + + + + + 0 + 0 + 1251 + 721 + + + + + + + + 16777215 + 250 + + + + 0 + + + + Statistik + + + + + 10 + 180 + 75 + 23 + + + + Suchen + + + + + + 10 + 10 + 491 + 161 + + + + + + + Appnr.: + + + + + + + true + + + + + + + Dauerapp: + + + + + + + Endsemester: + + + + + + + Erstellsemester: + + + + + + + + + + Person: + + + + + + + Fach: + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Löschbar + + + + + + + + + + + + + + + + 100 + 180 + 401 + 23 + + + + + + + + + + Suchen + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + 780 + 10 + 441 + 441 + + + + 0 + + + + Tabelle + + + + + 0 + 0 + 435 + 191 + + + + + 0 + 0 + + + + + 16777215 + 191 + + + + QAbstractItemView::NoEditTriggers + + + true + + + false + + + + Semester + + + + + Zugang + + + + + Abgang + + + + + + + 0 + 210 + 431 + 211 + + + + + + + Erstellte und gelöschte Semesterapparate + + + + + + + 10 + 10 + 761 + 441 + + + + + + 0 + 0 + 761 + 51 + + + + + + + Ausgewählte Löschen + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 50 + 761 + 391 + + + + + + 0 + 0 + 761 + 391 + + + + QAbstractItemView::NoEditTriggers + + + + + + + + + Apparatsname + + + + + Apparatsnummer + + + + + Person + + + + + Fach + + + + + + + + + + + + + + Admin + + + + + + + + + + + + + + 1280 + 360 + 311 + 391 + + + + + + + + 6 + + + + + true + + + + 0 + 0 + + + + Software + + + + + 20 + 30 + 241 + 41 + + + + + 8 + 50 + false + + + + Apparatsdaten eingegeben + + + + + + 20 + 70 + 241 + 41 + + + + + 8 + 50 + false + + + + Medien hinzugefügt / importiert + + + + + + 20 + 140 + 241 + 41 + + + + + 8 + 50 + false + + + + Prof-ID und Apparat-ID eingetragen + + + + + + + + + 0 + 0 + + + + aDIS + + + + + 20 + 30 + 241 + 41 + + + + + 8 + 50 + false + false + false + PreferDefault + true + + + + Medien geprüft + + + + + + 20 + 70 + 241 + 41 + + + + + 8 + 50 + false + false + false + PreferDefault + true + + + + Medien bearbeitet + + + + + + 20 + 110 + 161 + 41 + + + + + 8 + 50 + false + false + false + PreferDefault + true + + + + Apparat angelegt + + + + + + 170 + 120 + 101 + 23 + + + + + 8 + 50 + false + false + false + PreferDefault + true + + + + Hier klicken, um die aDIS Abfrage in die Zwischenablage zu kopieren + + + + + + + + + + + + false + + + aDIS Abfrage + + + + ../../../.designer/backup/icons/information.png../../../.designer/backup/icons/information.png + + + false + + + false + + + false + + + + + + + + + + + + + 1280 + 10 + 301 + 341 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 0 + 0 + 291 + 191 + + + + true + + + QCalendarWidget::NoVerticalHeader + + + + + + 0 + 210 + 291 + 121 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 10 + 10 + 47 + 20 + + + + Apparat + + + + + true + + + + 60 + 10 + 31 + 20 + + + + + + + 10 + 40 + 271 + 71 + + + + + + + 130 + 10 + 75 + 23 + + + + Löschen + + + + + + 210 + 10 + 42 + 22 + + + + 1 + + + + + + 260 + 10 + 21 + 22 + + + + TextLabel + + + + + + + + + 0 + 0 + 1593 + 21 + + + + + Datei + + + + + + Bearbeiten + + + + + + + + + + Beenden + + + Ctrl+Q + + + true + + + + + Einstellungen + + + Alt+S + + + true + + + + + drpdwn_app_nr + drpdwn_prof_title + drpdwn_prof_name + prof_mail + prof_tel_nr + app_name + app_fach + sem_winter + sem_sommer + sem_year + check_eternal_app + btn_add_document + btn_open_document + btn_apparat_save + btn_apparat_apply + + + + diff --git a/src/ui/sounds/semesterapparat_ui_ui.py b/src/ui/sounds/semesterapparat_ui_ui.py new file mode 100644 index 0000000..6b0fafd --- /dev/null +++ b/src/ui/sounds/semesterapparat_ui_ui.py @@ -0,0 +1,1075 @@ +# Form implementation generated from reading ui file '/home/alexander/GitHub/Semesterapparate/ui/sounds/semesterapparat_ui.ui' +# +# Created by: PyQt6 UI code generator 6.5.3 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName("MainWindow") + MainWindow.setWindowModality(QtCore.Qt.WindowModality.WindowModal) + MainWindow.setEnabled(True) + MainWindow.resize(1593, 800) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth()) + MainWindow.setSizePolicy(sizePolicy) + MainWindow.setMinimumSize(QtCore.QSize(1278, 800)) + MainWindow.setMaximumSize(QtCore.QSize(1920, 800)) + MainWindow.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) + self.centralwidget = QtWidgets.QWidget(parent=MainWindow) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth()) + self.centralwidget.setSizePolicy(sizePolicy) + self.centralwidget.setObjectName("centralwidget") + self.verticalLayoutWidget = QtWidgets.QWidget(parent=self.centralwidget) + self.verticalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 1271, 761)) + self.verticalLayoutWidget.setObjectName("verticalLayoutWidget") + self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget) + self.verticalLayout.setContentsMargins(0, 0, 0, 0) + self.verticalLayout.setObjectName("verticalLayout") + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.gridLayout = QtWidgets.QGridLayout() + self.gridLayout.setObjectName("gridLayout") + self.tabWidget = QtWidgets.QTabWidget(parent=self.verticalLayoutWidget) + self.tabWidget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.tabWidget.setObjectName("tabWidget") + self.tab = QtWidgets.QWidget() + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.tab.sizePolicy().hasHeightForWidth()) + self.tab.setSizePolicy(sizePolicy) + self.tab.setObjectName("tab") + self.horizontalLayoutWidget_2 = QtWidgets.QWidget(parent=self.tab) + self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(0, 0, 1261, 163)) + self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_2) + self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.formLayout = QtWidgets.QFormLayout() + self.formLayout.setObjectName("formLayout") + self.verticalLayout_2 = QtWidgets.QVBoxLayout() + self.verticalLayout_2.setObjectName("verticalLayout_2") + spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout_2.addItem(spacerItem) + self.load_app = QtWidgets.QPushButton(parent=self.horizontalLayoutWidget_2) + self.load_app.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.load_app.setObjectName("load_app") + self.verticalLayout_2.addWidget(self.load_app) + self.create_new_app = QtWidgets.QPushButton(parent=self.horizontalLayoutWidget_2) + self.create_new_app.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.create_new_app.setObjectName("create_new_app") + self.verticalLayout_2.addWidget(self.create_new_app) + self.cancel_active_selection = QtWidgets.QPushButton(parent=self.horizontalLayoutWidget_2) + self.cancel_active_selection.setObjectName("cancel_active_selection") + self.verticalLayout_2.addWidget(self.cancel_active_selection) + spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout_2.addItem(spacerItem1) + self.formLayout.setLayout(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.verticalLayout_2) + self.tableWidget_apparate = QtWidgets.QTableWidget(parent=self.horizontalLayoutWidget_2) + self.tableWidget_apparate.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.tableWidget_apparate.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents) + self.tableWidget_apparate.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.SelectedClicked) + self.tableWidget_apparate.setAlternatingRowColors(True) + self.tableWidget_apparate.setTextElideMode(QtCore.Qt.TextElideMode.ElideMiddle) + self.tableWidget_apparate.setObjectName("tableWidget_apparate") + self.tableWidget_apparate.setColumnCount(6) + self.tableWidget_apparate.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(3, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(4, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(5, item) + self.tableWidget_apparate.horizontalHeader().setCascadingSectionResizes(True) + self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.tableWidget_apparate) + self.horizontalLayout_4 = QtWidgets.QHBoxLayout() + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + self.formLayout.setLayout(2, QtWidgets.QFormLayout.ItemRole.FieldRole, self.horizontalLayout_4) + self.horizontalLayout_3 = QtWidgets.QHBoxLayout() + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.formLayout.setLayout(3, QtWidgets.QFormLayout.ItemRole.LabelRole, self.horizontalLayout_3) + self.horizontalLayout_2.addLayout(self.formLayout) + self.line = QtWidgets.QFrame(parent=self.tab) + self.line.setGeometry(QtCore.QRect(0, 160, 1261, 21)) + self.line.setFrameShape(QtWidgets.QFrame.Shape.HLine) + self.line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.line.setObjectName("line") + self.gridLayoutWidget_2 = QtWidgets.QWidget(parent=self.tab) + self.gridLayoutWidget_2.setEnabled(True) + self.gridLayoutWidget_2.setGeometry(QtCore.QRect(0, 180, 1261, 511)) + self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2") + self.gridLayout_2 = QtWidgets.QGridLayout(self.gridLayoutWidget_2) + self.gridLayout_2.setContentsMargins(0, 0, 0, 0) + self.gridLayout_2.setObjectName("gridLayout_2") + self.app_group_box = QtWidgets.QGroupBox(parent=self.gridLayoutWidget_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.app_group_box.sizePolicy().hasHeightForWidth()) + self.app_group_box.setSizePolicy(sizePolicy) + self.app_group_box.setMinimumSize(QtCore.QSize(0, 210)) + font = QtGui.QFont() + font.setPointSize(12) + font.setBold(True) + font.setWeight(75) + self.app_group_box.setFont(font) + self.app_group_box.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignLeft|QtCore.Qt.AlignmentFlag.AlignVCenter) + self.app_group_box.setCheckable(False) + self.app_group_box.setObjectName("app_group_box") + self.dokument_list = QtWidgets.QTableWidget(parent=self.app_group_box) + self.dokument_list.setGeometry(QtCore.QRect(765, 20, 321, 181)) + font = QtGui.QFont() + font.setPointSize(10) + font.setBold(False) + font.setWeight(50) + font.setKerning(False) + self.dokument_list.setFont(font) + self.dokument_list.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.dokument_list.setAcceptDrops(True) + self.dokument_list.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents) + self.dokument_list.setDragEnabled(True) + self.dokument_list.setDragDropMode(QtWidgets.QAbstractItemView.DragDropMode.DropOnly) + self.dokument_list.setDefaultDropAction(QtCore.Qt.DropAction.LinkAction) + self.dokument_list.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.SingleSelection) + self.dokument_list.setObjectName("dokument_list") + self.dokument_list.setColumnCount(4) + self.dokument_list.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + font = QtGui.QFont() + font.setFamily("Arial") + font.setPointSize(8) + item.setFont(font) + self.dokument_list.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + font = QtGui.QFont() + font.setFamily("Arial") + font.setPointSize(8) + item.setFont(font) + self.dokument_list.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + font = QtGui.QFont() + font.setFamily("Arial") + font.setPointSize(8) + item.setFont(font) + self.dokument_list.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.dokument_list.setHorizontalHeaderItem(3, item) + self.frame = QtWidgets.QFrame(parent=self.app_group_box) + self.frame.setEnabled(True) + self.frame.setGeometry(QtCore.QRect(10, 30, 1241, 151)) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth()) + self.frame.setSizePolicy(sizePolicy) + self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame.setObjectName("frame") + self.drpdwn_prof_title = QtWidgets.QComboBox(parent=self.frame) + self.drpdwn_prof_title.setGeometry(QtCore.QRect(110, 50, 69, 22)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.drpdwn_prof_title.setFont(font) + self.drpdwn_prof_title.setEditable(True) + self.drpdwn_prof_title.setObjectName("drpdwn_prof_title") + self.label_5 = QtWidgets.QLabel(parent=self.frame) + self.label_5.setGeometry(QtCore.QRect(250, 20, 91, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_5.setFont(font) + self.label_5.setObjectName("label_5") + self.sem_winter = QtWidgets.QRadioButton(parent=self.frame) + self.sem_winter.setGeometry(QtCore.QRect(340, 50, 82, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.sem_winter.setFont(font) + self.sem_winter.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.sem_winter.setObjectName("sem_winter") + self.label_4 = QtWidgets.QLabel(parent=self.frame) + self.label_4.setGeometry(QtCore.QRect(10, 80, 71, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_4.setFont(font) + self.label_4.setObjectName("label_4") + self.drpdwn_app_nr = QtWidgets.QComboBox(parent=self.frame) + self.drpdwn_app_nr.setGeometry(QtCore.QRect(110, 20, 69, 22)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.drpdwn_app_nr.setFont(font) + self.drpdwn_app_nr.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhDigitsOnly) + self.drpdwn_app_nr.setEditable(True) + self.drpdwn_app_nr.setObjectName("drpdwn_app_nr") + self.app_name = QtWidgets.QLineEdit(parent=self.frame) + self.app_name.setGeometry(QtCore.QRect(340, 20, 113, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.app_name.setFont(font) + self.app_name.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.app_name.setObjectName("app_name") + self.sem_sommer = QtWidgets.QRadioButton(parent=self.frame) + self.sem_sommer.setGeometry(QtCore.QRect(340, 70, 82, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.sem_sommer.setFont(font) + self.sem_sommer.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.sem_sommer.setObjectName("sem_sommer") + self.label_3 = QtWidgets.QLabel(parent=self.frame) + self.label_3.setGeometry(QtCore.QRect(10, 50, 61, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_3.setFont(font) + self.label_3.setObjectName("label_3") + self.label_6 = QtWidgets.QLabel(parent=self.frame) + self.label_6.setGeometry(QtCore.QRect(270, 60, 61, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_6.setFont(font) + self.label_6.setObjectName("label_6") + self.sem_year = QtWidgets.QLineEdit(parent=self.frame) + self.sem_year.setGeometry(QtCore.QRect(410, 60, 113, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.sem_year.setFont(font) + self.sem_year.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.sem_year.setMaxLength(4) + self.sem_year.setObjectName("sem_year") + self.label_2 = QtWidgets.QLabel(parent=self.frame) + self.label_2.setGeometry(QtCore.QRect(10, 20, 101, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_2.setFont(font) + self.label_2.setObjectName("label_2") + self.btn_apparat_save = QtWidgets.QPushButton(parent=self.frame) + self.btn_apparat_save.setGeometry(QtCore.QRect(260, 120, 75, 23)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.btn_apparat_save.setFont(font) + self.btn_apparat_save.setObjectName("btn_apparat_save") + self.btn_apparat_apply = QtWidgets.QPushButton(parent=self.frame) + self.btn_apparat_apply.setGeometry(QtCore.QRect(350, 120, 75, 23)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.btn_apparat_apply.setFont(font) + self.btn_apparat_apply.setObjectName("btn_apparat_apply") + self.check_eternal_app = QtWidgets.QCheckBox(parent=self.frame) + self.check_eternal_app.setGeometry(QtCore.QRect(340, 90, 101, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.check_eternal_app.setFont(font) + self.check_eternal_app.setObjectName("check_eternal_app") + self.label_8 = QtWidgets.QLabel(parent=self.frame) + self.label_8.setGeometry(QtCore.QRect(10, 110, 71, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_8.setFont(font) + self.label_8.setObjectName("label_8") + self.prof_mail = QtWidgets.QLineEdit(parent=self.frame) + self.prof_mail.setGeometry(QtCore.QRect(110, 110, 121, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.prof_mail.setFont(font) + self.prof_mail.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhEmailCharactersOnly) + self.prof_mail.setMaxLength(200) + self.prof_mail.setPlaceholderText("") + self.prof_mail.setObjectName("prof_mail") + self.label_9 = QtWidgets.QLabel(parent=self.frame) + self.label_9.setGeometry(QtCore.QRect(10, 130, 71, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_9.setFont(font) + self.label_9.setObjectName("label_9") + self.prof_tel_nr = QtWidgets.QLineEdit(parent=self.frame) + self.prof_tel_nr.setGeometry(QtCore.QRect(110, 130, 121, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.prof_tel_nr.setFont(font) + self.prof_tel_nr.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhDigitsOnly) + self.prof_tel_nr.setPlaceholderText("") + self.prof_tel_nr.setObjectName("prof_tel_nr") + self.label_10 = QtWidgets.QLabel(parent=self.frame) + self.label_10.setGeometry(QtCore.QRect(470, 20, 51, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_10.setFont(font) + self.label_10.setObjectName("label_10") + self.app_fach = QtWidgets.QLineEdit(parent=self.frame) + self.app_fach.setGeometry(QtCore.QRect(510, 20, 113, 20)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.app_fach.setFont(font) + self.app_fach.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.app_fach.setObjectName("app_fach") + self.drpdwn_prof_name = QtWidgets.QComboBox(parent=self.frame) + self.drpdwn_prof_name.setGeometry(QtCore.QRect(110, 80, 121, 22)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setWeight(50) + self.drpdwn_prof_name.setFont(font) + self.drpdwn_prof_name.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.drpdwn_prof_name.setEditable(True) + self.drpdwn_prof_name.setCurrentText("") + self.drpdwn_prof_name.setInsertPolicy(QtWidgets.QComboBox.InsertPolicy.InsertAlphabetically) + self.drpdwn_prof_name.setFrame(True) + self.drpdwn_prof_name.setObjectName("drpdwn_prof_name") + self.mail_mand = QtWidgets.QLabel(parent=self.frame) + self.mail_mand.setGeometry(QtCore.QRect(100, 110, 47, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.mail_mand.setFont(font) + self.mail_mand.setObjectName("mail_mand") + self.telnr_mand = QtWidgets.QLabel(parent=self.frame) + self.telnr_mand.setGeometry(QtCore.QRect(100, 130, 47, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.telnr_mand.setFont(font) + self.telnr_mand.setObjectName("telnr_mand") + self.profname_mand = QtWidgets.QLabel(parent=self.frame) + self.profname_mand.setGeometry(QtCore.QRect(100, 80, 47, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.profname_mand.setFont(font) + self.profname_mand.setObjectName("profname_mand") + self.appname_mand = QtWidgets.QLabel(parent=self.frame) + self.appname_mand.setGeometry(QtCore.QRect(330, 20, 16, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.appname_mand.setFont(font) + self.appname_mand.setObjectName("appname_mand") + self.fach_mand = QtWidgets.QLabel(parent=self.frame) + self.fach_mand.setGeometry(QtCore.QRect(500, 20, 47, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.fach_mand.setFont(font) + self.fach_mand.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.fach_mand.setObjectName("fach_mand") + self._mand = QtWidgets.QLabel(parent=self.frame) + self._mand.setGeometry(QtCore.QRect(330, 60, 16, 21)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self._mand.setFont(font) + self._mand.setObjectName("_mand") + self.btn_add_document = QtWidgets.QPushButton(parent=self.frame) + self.btn_add_document.setGeometry(QtCore.QRect(1090, 20, 131, 25)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.btn_add_document.setFont(font) + self.btn_add_document.setObjectName("btn_add_document") + self.btn_open_document = QtWidgets.QPushButton(parent=self.frame) + self.btn_open_document.setGeometry(QtCore.QRect(1090, 60, 131, 25)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.btn_open_document.setFont(font) + self.btn_open_document.setObjectName("btn_open_document") + self.check_file = QtWidgets.QPushButton(parent=self.frame) + self.check_file.setGeometry(QtCore.QRect(1090, 100, 131, 51)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.check_file.setFont(font) + self.check_file.setObjectName("check_file") + self.formLayoutWidget_2 = QtWidgets.QWidget(parent=self.frame) + self.formLayoutWidget_2.setGeometry(QtCore.QRect(550, 70, 202, 80)) + self.formLayoutWidget_2.setObjectName("formLayoutWidget_2") + self.formLayout_3 = QtWidgets.QFormLayout(self.formLayoutWidget_2) + self.formLayout_3.setContentsMargins(0, 0, 0, 0) + self.formLayout_3.setObjectName("formLayout_3") + self.label_12 = QtWidgets.QLabel(parent=self.formLayoutWidget_2) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_12.setFont(font) + self.label_12.setObjectName("label_12") + self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_12) + self.prof_id_adis = QtWidgets.QLineEdit(parent=self.formLayoutWidget_2) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.prof_id_adis.setFont(font) + self.prof_id_adis.setObjectName("prof_id_adis") + self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.prof_id_adis) + self.label_13 = QtWidgets.QLabel(parent=self.formLayoutWidget_2) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.label_13.setFont(font) + self.label_13.setObjectName("label_13") + self.formLayout_3.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_13) + self.apparat_id_adis = QtWidgets.QLineEdit(parent=self.formLayoutWidget_2) + self.apparat_id_adis.setObjectName("apparat_id_adis") + self.formLayout_3.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.apparat_id_adis) + self.check_send_mail = QtWidgets.QCheckBox(parent=self.frame) + self.check_send_mail.setGeometry(QtCore.QRect(450, 120, 91, 17)) + font = QtGui.QFont() + font.setPointSize(9) + font.setBold(False) + font.setWeight(50) + self.check_send_mail.setFont(font) + self.check_send_mail.setObjectName("check_send_mail") + self._mand.raise_() + self.drpdwn_prof_title.raise_() + self.label_5.raise_() + self.sem_winter.raise_() + self.label_4.raise_() + self.drpdwn_app_nr.raise_() + self.sem_sommer.raise_() + self.label_3.raise_() + self.label_6.raise_() + self.sem_year.raise_() + self.label_2.raise_() + self.btn_apparat_save.raise_() + self.btn_apparat_apply.raise_() + self.check_eternal_app.raise_() + self.label_8.raise_() + self.label_9.raise_() + self.label_10.raise_() + self.mail_mand.raise_() + self.telnr_mand.raise_() + self.profname_mand.raise_() + self.appname_mand.raise_() + self.fach_mand.raise_() + self.btn_add_document.raise_() + self.btn_open_document.raise_() + self.app_fach.raise_() + self.app_name.raise_() + self.prof_tel_nr.raise_() + self.drpdwn_prof_name.raise_() + self.prof_mail.raise_() + self.check_file.raise_() + self.formLayoutWidget_2.raise_() + self.check_send_mail.raise_() + self.frame.raise_() + self.dokument_list.raise_() + self.gridLayout_2.addWidget(self.app_group_box, 1, 0, 1, 1) + self.tableWidget_apparat_media = QtWidgets.QTableWidget(parent=self.gridLayoutWidget_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.tableWidget_apparat_media.sizePolicy().hasHeightForWidth()) + self.tableWidget_apparat_media.setSizePolicy(sizePolicy) + self.tableWidget_apparat_media.setMinimumSize(QtCore.QSize(1259, 0)) + self.tableWidget_apparat_media.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.tableWidget_apparat_media.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.CustomContextMenu) + self.tableWidget_apparat_media.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents) + self.tableWidget_apparat_media.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) + self.tableWidget_apparat_media.setAlternatingRowColors(True) + self.tableWidget_apparat_media.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) + self.tableWidget_apparat_media.setObjectName("tableWidget_apparat_media") + self.tableWidget_apparat_media.setColumnCount(7) + self.tableWidget_apparat_media.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(3, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(4, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(5, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(6, item) + self.tableWidget_apparat_media.horizontalHeader().setCascadingSectionResizes(True) + self.gridLayout_2.addWidget(self.tableWidget_apparat_media, 9, 0, 1, 1) + self.label = QtWidgets.QLabel(parent=self.gridLayoutWidget_2) + font = QtGui.QFont() + font.setPointSize(11) + font.setBold(True) + font.setWeight(75) + self.label.setFont(font) + self.label.setObjectName("label") + self.gridLayout_2.addWidget(self.label, 2, 0, 1, 1) + self.horizontalLayout_5 = QtWidgets.QHBoxLayout() + self.horizontalLayout_5.setObjectName("horizontalLayout_5") + spacerItem2 = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_5.addItem(spacerItem2) + self.chkbx_show_del_media = QtWidgets.QCheckBox(parent=self.gridLayoutWidget_2) + self.chkbx_show_del_media.setObjectName("chkbx_show_del_media") + self.horizontalLayout_5.addWidget(self.chkbx_show_del_media) + spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_5.addItem(spacerItem3) + self.add_layout = QtWidgets.QHBoxLayout() + self.add_layout.setObjectName("add_layout") + self.label_info = QtWidgets.QLabel(parent=self.gridLayoutWidget_2) + self.label_info.setObjectName("label_info") + self.add_layout.addWidget(self.label_info) + self.line_2 = QtWidgets.QFrame(parent=self.gridLayoutWidget_2) + self.line_2.setFrameShape(QtWidgets.QFrame.Shape.VLine) + self.line_2.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.line_2.setObjectName("line_2") + self.add_layout.addWidget(self.line_2) + self.progress_label = QtWidgets.QLabel(parent=self.gridLayoutWidget_2) + self.progress_label.setObjectName("progress_label") + self.add_layout.addWidget(self.progress_label) + self.horizontalLayout_5.addLayout(self.add_layout) + spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_5.addItem(spacerItem4) + self.btn_reserve = QtWidgets.QPushButton(parent=self.gridLayoutWidget_2) + self.btn_reserve.setObjectName("btn_reserve") + self.horizontalLayout_5.addWidget(self.btn_reserve) + spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_5.addItem(spacerItem5) + self.gridLayout_2.addLayout(self.horizontalLayout_5, 4, 0, 1, 1) + self.add_medium = QtWidgets.QPushButton(parent=self.tab) + self.add_medium.setGeometry(QtCore.QRect(0, 700, 121, 20)) + self.add_medium.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.add_medium.setObjectName("add_medium") + self.tabWidget.addTab(self.tab, "") + self.tab_2 = QtWidgets.QWidget() + self.tab_2.setObjectName("tab_2") + self.verticalLayoutWidget_2 = QtWidgets.QWidget(parent=self.tab_2) + self.verticalLayoutWidget_2.setGeometry(QtCore.QRect(0, 0, 1251, 721)) + self.verticalLayoutWidget_2.setObjectName("verticalLayoutWidget_2") + self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_2) + self.verticalLayout_3.setContentsMargins(0, 0, 0, 0) + self.verticalLayout_3.setObjectName("verticalLayout_3") + self.tabWidget_2 = QtWidgets.QTabWidget(parent=self.verticalLayoutWidget_2) + self.tabWidget_2.setMaximumSize(QtCore.QSize(16777215, 250)) + self.tabWidget_2.setObjectName("tabWidget_2") + self.tab_3 = QtWidgets.QWidget() + self.tab_3.setObjectName("tab_3") + self.btn_search = QtWidgets.QPushButton(parent=self.tab_3) + self.btn_search.setGeometry(QtCore.QRect(10, 180, 75, 23)) + self.btn_search.setObjectName("btn_search") + self.gridLayoutWidget = QtWidgets.QWidget(parent=self.tab_3) + self.gridLayoutWidget.setGeometry(QtCore.QRect(10, 10, 491, 161)) + self.gridLayoutWidget.setObjectName("gridLayoutWidget") + self.gridLayout_3 = QtWidgets.QGridLayout(self.gridLayoutWidget) + self.gridLayout_3.setContentsMargins(0, 0, 0, 0) + self.gridLayout_3.setObjectName("gridLayout_3") + self.label_7 = QtWidgets.QLabel(parent=self.gridLayoutWidget) + self.label_7.setObjectName("label_7") + self.gridLayout_3.addWidget(self.label_7, 0, 0, 1, 1) + self.box_erstellsemester = QtWidgets.QComboBox(parent=self.gridLayoutWidget) + self.box_erstellsemester.setEditable(True) + self.box_erstellsemester.setObjectName("box_erstellsemester") + self.gridLayout_3.addWidget(self.box_erstellsemester, 1, 3, 1, 1) + self.label_18 = QtWidgets.QLabel(parent=self.gridLayoutWidget) + self.label_18.setObjectName("label_18") + self.gridLayout_3.addWidget(self.label_18, 2, 2, 1, 1) + self.label_17 = QtWidgets.QLabel(parent=self.gridLayoutWidget) + self.label_17.setObjectName("label_17") + self.gridLayout_3.addWidget(self.label_17, 0, 2, 1, 1) + self.label_19 = QtWidgets.QLabel(parent=self.gridLayoutWidget) + self.label_19.setObjectName("label_19") + self.gridLayout_3.addWidget(self.label_19, 1, 2, 1, 1) + self.box_dauerapp = QtWidgets.QComboBox(parent=self.gridLayoutWidget) + self.box_dauerapp.setObjectName("box_dauerapp") + self.gridLayout_3.addWidget(self.box_dauerapp, 2, 3, 1, 1) + self.label_11 = QtWidgets.QLabel(parent=self.gridLayoutWidget) + self.label_11.setObjectName("label_11") + self.gridLayout_3.addWidget(self.label_11, 1, 0, 1, 1) + self.label_16 = QtWidgets.QLabel(parent=self.gridLayoutWidget) + self.label_16.setObjectName("label_16") + self.gridLayout_3.addWidget(self.label_16, 2, 0, 1, 1) + self.box_semester = QtWidgets.QComboBox(parent=self.gridLayoutWidget) + self.box_semester.setEditable(True) + self.box_semester.setObjectName("box_semester") + self.gridLayout_3.addWidget(self.box_semester, 0, 3, 1, 1) + self.box_appnrs = QtWidgets.QComboBox(parent=self.gridLayoutWidget) + self.box_appnrs.setEditable(True) + self.box_appnrs.setObjectName("box_appnrs") + self.gridLayout_3.addWidget(self.box_appnrs, 0, 1, 1, 1) + self.box_fach = QtWidgets.QComboBox(parent=self.gridLayoutWidget) + self.box_fach.setEditable(True) + self.box_fach.setObjectName("box_fach") + self.gridLayout_3.addWidget(self.box_fach, 2, 1, 1, 1) + self.box_person = QtWidgets.QComboBox(parent=self.gridLayoutWidget) + self.box_person.setEditable(True) + self.box_person.setObjectName("box_person") + self.gridLayout_3.addWidget(self.box_person, 1, 1, 1, 1) + spacerItem6 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.gridLayout_3.addItem(spacerItem6, 4, 0, 1, 1) + self.label_15 = QtWidgets.QLabel(parent=self.gridLayoutWidget) + self.label_15.setObjectName("label_15") + self.gridLayout_3.addWidget(self.label_15, 3, 0, 1, 1) + self.check_deletable = QtWidgets.QCheckBox(parent=self.gridLayoutWidget) + self.check_deletable.setText("") + self.check_deletable.setObjectName("check_deletable") + self.gridLayout_3.addWidget(self.check_deletable, 3, 1, 1, 1) + self.db_err_message = QtWidgets.QLabel(parent=self.tab_3) + self.db_err_message.setGeometry(QtCore.QRect(100, 180, 401, 23)) + self.db_err_message.setText("") + self.db_err_message.setObjectName("db_err_message") + self.tabWidget_2.addTab(self.tab_3, "") + self.tab_4 = QtWidgets.QWidget() + self.tab_4.setObjectName("tab_4") + self.tabWidget_2.addTab(self.tab_4, "") + self.verticalLayout_3.addWidget(self.tabWidget_2) + self.stackedWidget_4 = QtWidgets.QStackedWidget(parent=self.verticalLayoutWidget_2) + self.stackedWidget_4.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.stackedWidget_4.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.stackedWidget_4.setObjectName("stackedWidget_4") + self.stackedWidget_4Page1 = QtWidgets.QWidget() + self.stackedWidget_4Page1.setObjectName("stackedWidget_4Page1") + self.tabWidget_3 = QtWidgets.QTabWidget(parent=self.stackedWidget_4Page1) + self.tabWidget_3.setGeometry(QtCore.QRect(780, 10, 441, 441)) + self.tabWidget_3.setObjectName("tabWidget_3") + self.tab_6 = QtWidgets.QWidget() + self.tab_6.setObjectName("tab_6") + self.statistics_table = QtWidgets.QTableWidget(parent=self.tab_6) + self.statistics_table.setGeometry(QtCore.QRect(0, 0, 435, 191)) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.statistics_table.sizePolicy().hasHeightForWidth()) + self.statistics_table.setSizePolicy(sizePolicy) + self.statistics_table.setMaximumSize(QtCore.QSize(16777215, 191)) + self.statistics_table.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) + self.statistics_table.setAlternatingRowColors(True) + self.statistics_table.setObjectName("statistics_table") + self.statistics_table.setColumnCount(3) + self.statistics_table.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.statistics_table.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.statistics_table.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.statistics_table.setHorizontalHeaderItem(2, item) + self.statistics_table.horizontalHeader().setCascadingSectionResizes(False) + self.widget_3 = QtWidgets.QWidget(parent=self.tab_6) + self.widget_3.setGeometry(QtCore.QRect(0, 210, 431, 211)) + self.widget_3.setObjectName("widget_3") + self.tabWidget_3.addTab(self.tab_6, "") + self.tab_7 = QtWidgets.QWidget() + self.tab_7.setObjectName("tab_7") + self.tabWidget_3.addTab(self.tab_7, "") + self.widget = QtWidgets.QWidget(parent=self.stackedWidget_4Page1) + self.widget.setGeometry(QtCore.QRect(10, 10, 761, 441)) + self.widget.setObjectName("widget") + self.horizontalLayoutWidget_3 = QtWidgets.QWidget(parent=self.widget) + self.horizontalLayoutWidget_3.setGeometry(QtCore.QRect(0, 0, 761, 51)) + self.horizontalLayoutWidget_3.setObjectName("horizontalLayoutWidget_3") + self.horizontalLayout_7 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_3) + self.horizontalLayout_7.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_7.setObjectName("horizontalLayout_7") + self.btn_del_select_apparats = QtWidgets.QPushButton(parent=self.horizontalLayoutWidget_3) + self.btn_del_select_apparats.setObjectName("btn_del_select_apparats") + self.horizontalLayout_7.addWidget(self.btn_del_select_apparats) + spacerItem7 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_7.addItem(spacerItem7) + self.table = QtWidgets.QWidget(parent=self.widget) + self.table.setGeometry(QtCore.QRect(0, 50, 761, 391)) + self.table.setObjectName("table") + self.tableWidget = QtWidgets.QTableWidget(parent=self.table) + self.tableWidget.setGeometry(QtCore.QRect(0, 0, 761, 391)) + self.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) + self.tableWidget.setObjectName("tableWidget") + self.tableWidget.setColumnCount(5) + self.tableWidget.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidget.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget.setHorizontalHeaderItem(3, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidget.setHorizontalHeaderItem(4, item) + self.stackedWidget_4.addWidget(self.stackedWidget_4Page1) + self.verticalLayout_3.addWidget(self.stackedWidget_4) + self.tabWidget.addTab(self.tab_2, "") + self.tab_5 = QtWidgets.QWidget() + self.tab_5.setObjectName("tab_5") + self.tabWidget.addTab(self.tab_5, "") + self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) + self.horizontalLayout.addLayout(self.gridLayout) + self.verticalLayout.addLayout(self.horizontalLayout) + self.horizontalLayoutWidget = QtWidgets.QWidget(parent=self.centralwidget) + self.horizontalLayoutWidget.setGeometry(QtCore.QRect(1280, 360, 311, 391)) + self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget") + self.horizontalLayout_6 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget) + self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_6.setObjectName("horizontalLayout_6") + self.frame_creation_progress = QtWidgets.QFrame(parent=self.horizontalLayoutWidget) + self.frame_creation_progress.setObjectName("frame_creation_progress") + self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.frame_creation_progress) + self.verticalLayout_4.setSpacing(6) + self.verticalLayout_4.setObjectName("verticalLayout_4") + self.groupBox_2 = QtWidgets.QGroupBox(parent=self.frame_creation_progress) + self.groupBox_2.setEnabled(True) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.groupBox_2.sizePolicy().hasHeightForWidth()) + self.groupBox_2.setSizePolicy(sizePolicy) + self.groupBox_2.setObjectName("groupBox_2") + self.appdata_check = QtWidgets.QCheckBox(parent=self.groupBox_2) + self.appdata_check.setGeometry(QtCore.QRect(20, 30, 241, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setWeight(50) + self.appdata_check.setFont(font) + self.appdata_check.setObjectName("appdata_check") + self.media_check = QtWidgets.QCheckBox(parent=self.groupBox_2) + self.media_check.setGeometry(QtCore.QRect(20, 70, 241, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setWeight(50) + self.media_check.setFont(font) + self.media_check.setObjectName("media_check") + self.ids_check = QtWidgets.QCheckBox(parent=self.groupBox_2) + self.ids_check.setGeometry(QtCore.QRect(20, 140, 241, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setWeight(50) + self.ids_check.setFont(font) + self.ids_check.setObjectName("ids_check") + self.verticalLayout_4.addWidget(self.groupBox_2) + self.groupBox = QtWidgets.QGroupBox(parent=self.frame_creation_progress) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth()) + self.groupBox.setSizePolicy(sizePolicy) + self.groupBox.setObjectName("groupBox") + self.media_checked = QtWidgets.QCheckBox(parent=self.groupBox) + self.media_checked.setGeometry(QtCore.QRect(20, 30, 241, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setItalic(False) + font.setUnderline(False) + font.setWeight(50) + font.setKerning(True) + font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault) + self.media_checked.setFont(font) + self.media_checked.setObjectName("media_checked") + self.media_edited_check = QtWidgets.QCheckBox(parent=self.groupBox) + self.media_edited_check.setGeometry(QtCore.QRect(20, 70, 241, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setItalic(False) + font.setUnderline(False) + font.setWeight(50) + font.setKerning(True) + font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault) + self.media_edited_check.setFont(font) + self.media_edited_check.setObjectName("media_edited_check") + self.app_created = QtWidgets.QCheckBox(parent=self.groupBox) + self.app_created.setGeometry(QtCore.QRect(20, 110, 161, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setItalic(False) + font.setUnderline(False) + font.setWeight(50) + font.setKerning(True) + font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault) + self.app_created.setFont(font) + self.app_created.setObjectName("app_created") + self.btn_copy_adis_command = QtWidgets.QPushButton(parent=self.groupBox) + self.btn_copy_adis_command.setGeometry(QtCore.QRect(170, 120, 101, 23)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setItalic(False) + font.setUnderline(False) + font.setWeight(50) + font.setKerning(True) + font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault) + self.btn_copy_adis_command.setFont(font) + self.btn_copy_adis_command.setStatusTip("") + self.btn_copy_adis_command.setWhatsThis("") + self.btn_copy_adis_command.setAccessibleDescription("") + self.btn_copy_adis_command.setAutoFillBackground(False) + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap("/home/alexander/GitHub/Semesterapparate/ui/sounds/../../../.designer/backup/icons/information.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.btn_copy_adis_command.setIcon(icon) + self.btn_copy_adis_command.setCheckable(False) + self.btn_copy_adis_command.setChecked(False) + self.btn_copy_adis_command.setAutoDefault(False) + self.btn_copy_adis_command.setObjectName("btn_copy_adis_command") + self.verticalLayout_4.addWidget(self.groupBox) + self.horizontalLayout_6.addWidget(self.frame_creation_progress) + self.frame_2 = QtWidgets.QFrame(parent=self.centralwidget) + self.frame_2.setGeometry(QtCore.QRect(1280, 10, 301, 341)) + self.frame_2.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame_2.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame_2.setObjectName("frame_2") + self.calendarWidget = QtWidgets.QCalendarWidget(parent=self.frame_2) + self.calendarWidget.setGeometry(QtCore.QRect(0, 0, 291, 191)) + self.calendarWidget.setGridVisible(True) + self.calendarWidget.setVerticalHeaderFormat(QtWidgets.QCalendarWidget.VerticalHeaderFormat.NoVerticalHeader) + self.calendarWidget.setObjectName("calendarWidget") + self.message_frame = QtWidgets.QFrame(parent=self.frame_2) + self.message_frame.setGeometry(QtCore.QRect(0, 210, 291, 121)) + self.message_frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.message_frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.message_frame.setObjectName("message_frame") + self.label_14 = QtWidgets.QLabel(parent=self.message_frame) + self.label_14.setGeometry(QtCore.QRect(10, 10, 47, 20)) + self.label_14.setObjectName("label_14") + self.line_app_info = QtWidgets.QLineEdit(parent=self.message_frame) + self.line_app_info.setEnabled(True) + self.line_app_info.setGeometry(QtCore.QRect(60, 10, 31, 20)) + self.line_app_info.setObjectName("line_app_info") + self.message_box = QtWidgets.QTextEdit(parent=self.message_frame) + self.message_box.setGeometry(QtCore.QRect(10, 40, 271, 71)) + self.message_box.setObjectName("message_box") + self.btn_delete_message = QtWidgets.QPushButton(parent=self.message_frame) + self.btn_delete_message.setGeometry(QtCore.QRect(130, 10, 75, 23)) + self.btn_delete_message.setObjectName("btn_delete_message") + self.spin_select_message = QtWidgets.QSpinBox(parent=self.message_frame) + self.spin_select_message.setGeometry(QtCore.QRect(210, 10, 42, 22)) + self.spin_select_message.setMinimum(1) + self.spin_select_message.setObjectName("spin_select_message") + self.label_total_day_messages = QtWidgets.QLabel(parent=self.message_frame) + self.label_total_day_messages.setGeometry(QtCore.QRect(260, 10, 21, 22)) + self.label_total_day_messages.setObjectName("label_total_day_messages") + MainWindow.setCentralWidget(self.centralwidget) + self.menubar = QtWidgets.QMenuBar(parent=MainWindow) + self.menubar.setGeometry(QtCore.QRect(0, 0, 1593, 21)) + self.menubar.setObjectName("menubar") + self.menuDatei = QtWidgets.QMenu(parent=self.menubar) + self.menuDatei.setObjectName("menuDatei") + self.menuEinstellungen = QtWidgets.QMenu(parent=self.menubar) + self.menuEinstellungen.setObjectName("menuEinstellungen") + MainWindow.setMenuBar(self.menubar) + self.statusbar = QtWidgets.QStatusBar(parent=MainWindow) + self.statusbar.setObjectName("statusbar") + MainWindow.setStatusBar(self.statusbar) + self.actionBeenden = QtGui.QAction(parent=MainWindow) + self.actionBeenden.setShortcutVisibleInContextMenu(True) + self.actionBeenden.setObjectName("actionBeenden") + self.actionEinstellungen = QtGui.QAction(parent=MainWindow) + self.actionEinstellungen.setShortcutVisibleInContextMenu(True) + self.actionEinstellungen.setObjectName("actionEinstellungen") + self.menuDatei.addAction(self.actionBeenden) + self.menuEinstellungen.addAction(self.actionEinstellungen) + self.menubar.addAction(self.menuDatei.menuAction()) + self.menubar.addAction(self.menuEinstellungen.menuAction()) + + self.retranslateUi(MainWindow) + self.tabWidget.setCurrentIndex(1) + self.tabWidget_2.setCurrentIndex(0) + self.tabWidget_3.setCurrentIndex(0) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + MainWindow.setTabOrder(self.drpdwn_app_nr, self.drpdwn_prof_title) + MainWindow.setTabOrder(self.drpdwn_prof_title, self.drpdwn_prof_name) + MainWindow.setTabOrder(self.drpdwn_prof_name, self.prof_mail) + MainWindow.setTabOrder(self.prof_mail, self.prof_tel_nr) + MainWindow.setTabOrder(self.prof_tel_nr, self.app_name) + MainWindow.setTabOrder(self.app_name, self.app_fach) + MainWindow.setTabOrder(self.app_fach, self.sem_winter) + MainWindow.setTabOrder(self.sem_winter, self.sem_sommer) + MainWindow.setTabOrder(self.sem_sommer, self.sem_year) + MainWindow.setTabOrder(self.sem_year, self.check_eternal_app) + MainWindow.setTabOrder(self.check_eternal_app, self.btn_add_document) + MainWindow.setTabOrder(self.btn_add_document, self.btn_open_document) + MainWindow.setTabOrder(self.btn_open_document, self.btn_apparat_save) + MainWindow.setTabOrder(self.btn_apparat_save, self.btn_apparat_apply) + + def retranslateUi(self, MainWindow): + _translate = QtCore.QCoreApplication.translate + MainWindow.setWindowTitle(_translate("MainWindow", "Semesterapparatsmanagement")) + self.load_app.setToolTip(_translate("MainWindow", "Load the Semesterapparate from the database")) + self.load_app.setText(_translate("MainWindow", "App. aufrufen")) + self.create_new_app.setText(_translate("MainWindow", "neu. App anlegen")) + self.cancel_active_selection.setText(_translate("MainWindow", "Auswahl abbrechen")) + self.tableWidget_apparate.setSortingEnabled(True) + item = self.tableWidget_apparate.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "AppNr")) + item = self.tableWidget_apparate.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "App Name")) + item = self.tableWidget_apparate.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Professor")) + item = self.tableWidget_apparate.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "gültig bis")) + item = self.tableWidget_apparate.horizontalHeaderItem(4) + item.setText(_translate("MainWindow", "Dauerapparat")) + item = self.tableWidget_apparate.horizontalHeaderItem(5) + item.setText(_translate("MainWindow", "KontoNr")) + self.app_group_box.setTitle(_translate("MainWindow", "Apparatsdetails")) + item = self.dokument_list.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Dokumentname")) + item = self.dokument_list.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Dateityp")) + item = self.dokument_list.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Neu?")) + item = self.dokument_list.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "path")) + self.label_5.setText(_translate("MainWindow", "Apparatsname")) + self.sem_winter.setText(_translate("MainWindow", "Winter")) + self.label_4.setText(_translate("MainWindow", "Prof. Name")) + self.sem_sommer.setText(_translate("MainWindow", "Sommer")) + self.label_3.setText(_translate("MainWindow", "Prof. Titel")) + self.label_6.setText(_translate("MainWindow", "Semester")) + self.sem_year.setPlaceholderText(_translate("MainWindow", "2023")) + self.label_2.setText(_translate("MainWindow", "Apparatsnummer")) + self.btn_apparat_save.setText(_translate("MainWindow", "Speichern")) + self.btn_apparat_apply.setText(_translate("MainWindow", "Aktualisieren")) + self.check_eternal_app.setText(_translate("MainWindow", "Dauerapparat")) + self.label_8.setText(_translate("MainWindow", "Mail")) + self.label_9.setText(_translate("MainWindow", "Tel")) + self.label_10.setText(_translate("MainWindow", "Fach")) + self.mail_mand.setText(_translate("MainWindow", "*")) + self.telnr_mand.setText(_translate("MainWindow", "*")) + self.profname_mand.setText(_translate("MainWindow", "*")) + self.appname_mand.setText(_translate("MainWindow", "*")) + self.fach_mand.setText(_translate("MainWindow", "*")) + self._mand.setText(_translate("MainWindow", "*")) + self.btn_add_document.setText(_translate("MainWindow", "Dokument hinzufügen")) + self.btn_open_document.setText(_translate("MainWindow", "Dokument öffnen")) + self.check_file.setToolTip(_translate("MainWindow", "Abhängig von der Anzahl der Medien kann die Suche sehr lange dauern")) + self.check_file.setText(_translate("MainWindow", "Medien aus Dokument\n" +" hinzufügen")) + self.label_12.setText(_translate("MainWindow", "Prof-ID-aDIS")) + self.label_13.setText(_translate("MainWindow", "Apparat-ID-aDIS")) + self.check_send_mail.setText(_translate("MainWindow", "Mail senden")) + self.tableWidget_apparat_media.setSortingEnabled(True) + item = self.tableWidget_apparat_media.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Buchtitel")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Signatur")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Auflage")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "Autor")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(4) + item.setText(_translate("MainWindow", "verfügbar?")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(5) + item.setText(_translate("MainWindow", "Vorgemerkt")) + item = self.tableWidget_apparat_media.horizontalHeaderItem(6) + item.setText(_translate("MainWindow", "Link")) + self.label.setText(_translate("MainWindow", " Medienliste")) + self.chkbx_show_del_media.setText(_translate("MainWindow", "gel. Medien anzeigen")) + self.label_info.setText(_translate("MainWindow", "Medien werden hinzugefügt")) + self.progress_label.setText(_translate("MainWindow", "Medium x/y")) + self.btn_reserve.setText(_translate("MainWindow", "Vorgemertk?")) + self.add_medium.setText(_translate("MainWindow", "Medien hinzufügen")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Anlegen")) + self.btn_search.setText(_translate("MainWindow", "Suchen")) + self.label_7.setText(_translate("MainWindow", "Appnr.:")) + self.label_18.setText(_translate("MainWindow", "Dauerapp:")) + self.label_17.setText(_translate("MainWindow", "Endsemester:")) + self.label_19.setText(_translate("MainWindow", "Erstellsemester:")) + self.label_11.setText(_translate("MainWindow", "Person:")) + self.label_16.setText(_translate("MainWindow", "Fach:")) + self.label_15.setText(_translate("MainWindow", "Löschbar")) + self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_3), _translate("MainWindow", "Statistik")) + self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_4), _translate("MainWindow", "Suchen")) + item = self.statistics_table.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Semester")) + item = self.statistics_table.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Zugang")) + item = self.statistics_table.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Abgang")) + self.tabWidget_3.setTabText(self.tabWidget_3.indexOf(self.tab_6), _translate("MainWindow", "Tabelle")) + self.tabWidget_3.setTabText(self.tabWidget_3.indexOf(self.tab_7), _translate("MainWindow", "Erstellte und gelöschte Semesterapparate")) + self.btn_del_select_apparats.setText(_translate("MainWindow", "Ausgewählte Löschen")) + item = self.tableWidget.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", " ")) + item = self.tableWidget.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Apparatsname")) + item = self.tableWidget.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Apparatsnummer")) + item = self.tableWidget.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "Person")) + item = self.tableWidget.horizontalHeaderItem(4) + item.setText(_translate("MainWindow", "Fach")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Suchen / Statistik")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_5), _translate("MainWindow", "Admin")) + self.groupBox_2.setTitle(_translate("MainWindow", "Software")) + self.appdata_check.setText(_translate("MainWindow", "Apparatsdaten eingegeben")) + self.media_check.setText(_translate("MainWindow", "Medien hinzugefügt / importiert")) + self.ids_check.setText(_translate("MainWindow", "Prof-ID und Apparat-ID eingetragen")) + self.groupBox.setTitle(_translate("MainWindow", "aDIS")) + self.media_checked.setText(_translate("MainWindow", "Medien geprüft")) + self.media_edited_check.setText(_translate("MainWindow", "Medien bearbeitet")) + self.app_created.setText(_translate("MainWindow", "Apparat angelegt")) + self.btn_copy_adis_command.setToolTip(_translate("MainWindow", "Hier klicken, um die aDIS Abfrage in die Zwischenablage zu kopieren")) + self.btn_copy_adis_command.setText(_translate("MainWindow", " aDIS Abfrage")) + self.label_14.setText(_translate("MainWindow", "Apparat")) + self.btn_delete_message.setText(_translate("MainWindow", "Löschen")) + self.label_total_day_messages.setText(_translate("MainWindow", "TextLabel")) + self.menuDatei.setTitle(_translate("MainWindow", "Datei")) + self.menuEinstellungen.setTitle(_translate("MainWindow", "Bearbeiten")) + self.actionBeenden.setText(_translate("MainWindow", "Beenden")) + self.actionBeenden.setShortcut(_translate("MainWindow", "Ctrl+Q")) + self.actionEinstellungen.setText(_translate("MainWindow", "Einstellungen")) + self.actionEinstellungen.setShortcut(_translate("MainWindow", "Alt+S")) diff --git a/src/ui/untitled.ui b/src/ui/untitled.ui new file mode 100644 index 0000000..ee79033 --- /dev/null +++ b/src/ui/untitled.ui @@ -0,0 +1,692 @@ + + + MainWindow + + + + 0 + 0 + 1280 + 720 + + + + + 0 + 0 + + + + MainWindow + + + + + 0 + 0 + + + + + + 0 + 0 + 1271 + 671 + + + + + + + + + + + 0 + + + + + 0 + 0 + + + + Tab 1 + + + + + 0 + 0 + 1261 + 161 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Load the Semesterapparate from the database + + + App. aufrufen + + + + + + + neu. App anlegen + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + AppNr + + + + + App Name + + + + + Professor + + + + + Dauerapparat + + + + + + + + + + + + + + + + + + 0 + 160 + 1261 + 21 + + + + Qt::Horizontal + + + + + + 0 + 180 + 1261 + 461 + + + + + + + + Buchtitel + + + + + Autor + + + + + Auflage + + + + + Signatur + + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + Apparatsdetails + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + false + + + + + 820 + 20 + 256 + 192 + + + + + Dokumentname + + + + + Typ + + + + + + + 10 + 30 + 731 + 151 + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 110 + 50 + 69 + 22 + + + + + + + 250 + 20 + 91 + 21 + + + + + 9 + 50 + false + + + + Apparatsname + + + + + + 110 + 80 + 121 + 20 + + + + + 9 + 50 + false + + + + Nachname, Vorname + + + + + + 340 + 50 + 82 + 17 + + + + + 9 + 50 + false + + + + Winter + + + + + + 10 + 80 + 71 + 21 + + + + + 9 + 50 + false + + + + Prof. Name + + + + + + 110 + 20 + 69 + 22 + + + + + + + 340 + 20 + 113 + 20 + + + + + + + 340 + 70 + 82 + 17 + + + + + 9 + 50 + false + + + + Sommer + + + + + + 10 + 50 + 61 + 20 + + + + + 9 + 50 + false + + + + Prof. Titel + + + + + + 270 + 60 + 51 + 21 + + + + + 9 + 50 + false + + + + Semester + + + + + + 410 + 60 + 113 + 20 + + + + + 9 + 50 + false + + + + 2023 + + + + + + 10 + 20 + 101 + 21 + + + + + 9 + 50 + false + + + + Apparatsnummer + + + + + + 260 + 120 + 75 + 23 + + + + + 9 + 50 + false + + + + Speichern + + + + + + 350 + 120 + 75 + 23 + + + + + 9 + 50 + false + + + + Aktualisieren + + + + + + 340 + 90 + 101 + 17 + + + + + 9 + 50 + false + + + + Dauerapparat + + + + + + + 1100 + 40 + 131 + 25 + + + + + 9 + 50 + false + + + + Dokument hinzufügen + + + + + + 1100 + 80 + 131 + 25 + + + + + 9 + 50 + false + + + + Dokument öffnen + + + + + + 1110 + 110 + 25 + 19 + + + + ... + + + + + + 20 + 200 + 47 + 21 + + + + + 9 + 50 + false + + + + Suche + + + + + + 80 + 200 + 211 + 20 + + + + + 9 + 50 + false + + + + Buch oder Signatur + + + + + + 0 + 180 + 1259 + 18 + + + + + 11 + 75 + true + + + + Medienliste + + + + + + + + + + Tab 2 + + + + + + + + + + + + + + + 0 + 0 + 1280 + 21 + + + + + Datei + + + + + Einstellungen + + + + + + + + + + diff --git a/src/ui/untitled_ui.py b/src/ui/untitled_ui.py new file mode 100644 index 0000000..7e1b11c --- /dev/null +++ b/src/ui/untitled_ui.py @@ -0,0 +1,476 @@ +# -*- coding: utf-8 -*- + +################################################################################ +# Form generated from reading UI file 'untitled.ui' +## +# Created by: Qt User Interface Compiler version 6.5.2 +## +# WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide6.QtCore import ( + QCoreApplication, + QDate, + QDateTime, + QLocale, + QMetaObject, + QObject, + QPoint, + QRect, + QSize, + Qt, + QTime, + QUrl, +) +from PySide6.QtGui import ( + QAction, + QBrush, + QColor, + QConicalGradient, + QCursor, + QFont, + QFontDatabase, + QGradient, + QIcon, + QImage, + QKeySequence, + QLinearGradient, + QPainter, + QPalette, + QPixmap, + QRadialGradient, + QTransform, +) +from PySide6.QtWidgets import ( + QApplication, + QCheckBox, + QComboBox, + QFormLayout, + QFrame, + QGridLayout, + QGroupBox, + QHBoxLayout, + QHeaderView, + QLabel, + QLineEdit, + QMainWindow, + QMenu, + QMenuBar, + QPushButton, + QRadioButton, + QSizePolicy, + QSpacerItem, + QStatusBar, + QTableWidget, + QTableWidgetItem, + QTabWidget, + QToolButton, + QVBoxLayout, + QWidget, +) + + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + if not MainWindow.objectName(): + MainWindow.setObjectName("MainWindow") + MainWindow.resize(1280, 720) + sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth()) + MainWindow.setSizePolicy(sizePolicy) + self.centralwidget = QWidget(MainWindow) + self.centralwidget.setObjectName("centralwidget") + sizePolicy1 = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) + sizePolicy1.setHorizontalStretch(0) + sizePolicy1.setVerticalStretch(0) + sizePolicy1.setHeightForWidth( + self.centralwidget.sizePolicy().hasHeightForWidth() + ) + self.centralwidget.setSizePolicy(sizePolicy1) + self.verticalLayoutWidget = QWidget(self.centralwidget) + self.verticalLayoutWidget.setObjectName("verticalLayoutWidget") + self.verticalLayoutWidget.setGeometry(QRect(0, 0, 1271, 671)) + self.verticalLayout = QVBoxLayout(self.verticalLayoutWidget) + self.verticalLayout.setObjectName("verticalLayout") + self.verticalLayout.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout = QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.gridLayout = QGridLayout() + self.gridLayout.setObjectName("gridLayout") + self.tabWidget = QTabWidget(self.verticalLayoutWidget) + self.tabWidget.setObjectName("tabWidget") + self.tab = QWidget() + self.tab.setObjectName("tab") + sizePolicy2 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) + sizePolicy2.setHorizontalStretch(0) + sizePolicy2.setVerticalStretch(0) + sizePolicy2.setHeightForWidth(self.tab.sizePolicy().hasHeightForWidth()) + self.tab.setSizePolicy(sizePolicy2) + self.horizontalLayoutWidget_2 = QWidget(self.tab) + self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2") + self.horizontalLayoutWidget_2.setGeometry(QRect(0, 0, 1261, 161)) + self.horizontalLayout_2 = QHBoxLayout(self.horizontalLayoutWidget_2) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) + self.formLayout = QFormLayout() + self.formLayout.setObjectName("formLayout") + self.verticalLayout_2 = QVBoxLayout() + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.verticalSpacer = QSpacerItem( + 20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding + ) + + self.verticalLayout_2.addItem(self.verticalSpacer) + + self.load_app = QPushButton(self.horizontalLayoutWidget_2) + self.load_app.setObjectName("load_app") + + self.verticalLayout_2.addWidget(self.load_app) + + self.create_new_app = QPushButton(self.horizontalLayoutWidget_2) + self.create_new_app.setObjectName("create_new_app") + + self.verticalLayout_2.addWidget(self.create_new_app) + + self.verticalSpacer_2 = QSpacerItem( + 20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding + ) + + self.verticalLayout_2.addItem(self.verticalSpacer_2) + + self.formLayout.setLayout(0, QFormLayout.LabelRole, self.verticalLayout_2) + + self.tableWidget_apparate = QTableWidget(self.horizontalLayoutWidget_2) + if self.tableWidget_apparate.columnCount() < 4: + self.tableWidget_apparate.setColumnCount(4) + __qtablewidgetitem = QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(0, __qtablewidgetitem) + __qtablewidgetitem1 = QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(1, __qtablewidgetitem1) + __qtablewidgetitem2 = QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(2, __qtablewidgetitem2) + __qtablewidgetitem3 = QTableWidgetItem() + self.tableWidget_apparate.setHorizontalHeaderItem(3, __qtablewidgetitem3) + self.tableWidget_apparate.setObjectName("tableWidget_apparate") + + self.formLayout.setWidget(0, QFormLayout.FieldRole, self.tableWidget_apparate) + + self.horizontalLayout_3 = QHBoxLayout() + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + + self.formLayout.setLayout(2, QFormLayout.LabelRole, self.horizontalLayout_3) + + self.horizontalLayout_4 = QHBoxLayout() + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + + self.formLayout.setLayout(1, QFormLayout.FieldRole, self.horizontalLayout_4) + + self.horizontalLayout_2.addLayout(self.formLayout) + + self.line = QFrame(self.tab) + self.line.setObjectName("line") + self.line.setGeometry(QRect(0, 160, 1261, 21)) + self.line.setFrameShape(QFrame.HLine) + self.line.setFrameShadow(QFrame.Sunken) + self.gridLayoutWidget_2 = QWidget(self.tab) + self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2") + self.gridLayoutWidget_2.setGeometry(QRect(0, 180, 1261, 461)) + self.gridLayout_2 = QGridLayout(self.gridLayoutWidget_2) + self.gridLayout_2.setObjectName("gridLayout_2") + self.gridLayout_2.setContentsMargins(0, 0, 0, 0) + self.tableWidget_apparat_media = QTableWidget(self.gridLayoutWidget_2) + if self.tableWidget_apparat_media.columnCount() < 4: + self.tableWidget_apparat_media.setColumnCount(4) + __qtablewidgetitem4 = QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(0, __qtablewidgetitem4) + __qtablewidgetitem5 = QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(1, __qtablewidgetitem5) + __qtablewidgetitem6 = QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(2, __qtablewidgetitem6) + __qtablewidgetitem7 = QTableWidgetItem() + self.tableWidget_apparat_media.setHorizontalHeaderItem(3, __qtablewidgetitem7) + self.tableWidget_apparat_media.setObjectName("tableWidget_apparat_media") + + self.gridLayout_2.addWidget(self.tableWidget_apparat_media, 2, 0, 1, 1) + + self.app_group_box = QGroupBox(self.gridLayoutWidget_2) + self.app_group_box.setObjectName("app_group_box") + sizePolicy3 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) + sizePolicy3.setHorizontalStretch(0) + sizePolicy3.setVerticalStretch(0) + sizePolicy3.setHeightForWidth( + self.app_group_box.sizePolicy().hasHeightForWidth() + ) + self.app_group_box.setSizePolicy(sizePolicy3) + font = QFont() + font.setPointSize(12) + font.setBold(True) + self.app_group_box.setFont(font) + self.app_group_box.setAlignment( + Qt.AlignLeading | Qt.AlignLeft | Qt.AlignVCenter + ) + self.app_group_box.setCheckable(False) + self.dokument_list = QTableWidget(self.app_group_box) + if self.dokument_list.columnCount() < 2: + self.dokument_list.setColumnCount(2) + __qtablewidgetitem8 = QTableWidgetItem() + self.dokument_list.setHorizontalHeaderItem(0, __qtablewidgetitem8) + __qtablewidgetitem9 = QTableWidgetItem() + self.dokument_list.setHorizontalHeaderItem(1, __qtablewidgetitem9) + self.dokument_list.setObjectName("dokument_list") + self.dokument_list.setGeometry(QRect(820, 20, 256, 192)) + self.frame = QFrame(self.app_group_box) + self.frame.setObjectName("frame") + self.frame.setGeometry(QRect(10, 30, 731, 151)) + sizePolicy1.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth()) + self.frame.setSizePolicy(sizePolicy1) + self.frame.setFrameShape(QFrame.StyledPanel) + self.frame.setFrameShadow(QFrame.Raised) + self.drpdwn_prof_title = QComboBox(self.frame) + self.drpdwn_prof_title.setObjectName("drpdwn_prof_title") + self.drpdwn_prof_title.setGeometry(QRect(110, 50, 69, 22)) + self.label_5 = QLabel(self.frame) + self.label_5.setObjectName("label_5") + self.label_5.setGeometry(QRect(250, 20, 91, 21)) + font1 = QFont() + font1.setPointSize(9) + font1.setBold(False) + self.label_5.setFont(font1) + self.lineEdit = QLineEdit(self.frame) + self.lineEdit.setObjectName("lineEdit") + self.lineEdit.setGeometry(QRect(110, 80, 121, 20)) + self.lineEdit.setFont(font1) + self.sem_winter = QRadioButton(self.frame) + self.sem_winter.setObjectName("sem_winter") + self.sem_winter.setGeometry(QRect(340, 50, 82, 17)) + self.sem_winter.setFont(font1) + self.label_4 = QLabel(self.frame) + self.label_4.setObjectName("label_4") + self.label_4.setGeometry(QRect(10, 80, 71, 21)) + self.label_4.setFont(font1) + self.drpdwn_app_nr = QComboBox(self.frame) + self.drpdwn_app_nr.setObjectName("drpdwn_app_nr") + self.drpdwn_app_nr.setGeometry(QRect(110, 20, 69, 22)) + self.app_name = QLineEdit(self.frame) + self.app_name.setObjectName("app_name") + self.app_name.setGeometry(QRect(340, 20, 113, 20)) + self.sem_sommer = QRadioButton(self.frame) + self.sem_sommer.setObjectName("sem_sommer") + self.sem_sommer.setGeometry(QRect(340, 70, 82, 17)) + self.sem_sommer.setFont(font1) + self.label_3 = QLabel(self.frame) + self.label_3.setObjectName("label_3") + self.label_3.setGeometry(QRect(10, 50, 61, 20)) + self.label_3.setFont(font1) + self.label_6 = QLabel(self.frame) + self.label_6.setObjectName("label_6") + self.label_6.setGeometry(QRect(270, 60, 51, 21)) + self.label_6.setFont(font1) + self.sem_year = QLineEdit(self.frame) + self.sem_year.setObjectName("sem_year") + self.sem_year.setGeometry(QRect(410, 60, 113, 20)) + self.sem_year.setFont(font1) + self.label_2 = QLabel(self.frame) + self.label_2.setObjectName("label_2") + self.label_2.setGeometry(QRect(10, 20, 101, 21)) + self.label_2.setFont(font1) + self.btn_apparat_save = QPushButton(self.frame) + self.btn_apparat_save.setObjectName("btn_apparat_save") + self.btn_apparat_save.setGeometry(QRect(260, 120, 75, 23)) + self.btn_apparat_save.setFont(font1) + self.btn_apparat_apply = QPushButton(self.frame) + self.btn_apparat_apply.setObjectName("btn_apparat_apply") + self.btn_apparat_apply.setGeometry(QRect(350, 120, 75, 23)) + self.btn_apparat_apply.setFont(font1) + self.checkBox = QCheckBox(self.frame) + self.checkBox.setObjectName("checkBox") + self.checkBox.setGeometry(QRect(340, 90, 101, 17)) + self.checkBox.setFont(font1) + self.btn_add_document = QPushButton(self.app_group_box) + self.btn_add_document.setObjectName("btn_add_document") + self.btn_add_document.setGeometry(QRect(1100, 40, 131, 25)) + self.btn_add_document.setFont(font1) + self.btn_open_document = QPushButton(self.app_group_box) + self.btn_open_document.setObjectName("btn_open_document") + self.btn_open_document.setGeometry(QRect(1100, 80, 131, 25)) + self.btn_open_document.setFont(font1) + self.toolButton = QToolButton(self.app_group_box) + self.toolButton.setObjectName("toolButton") + self.toolButton.setGeometry(QRect(1110, 110, 25, 19)) + self.label_7 = QLabel(self.app_group_box) + self.label_7.setObjectName("label_7") + self.label_7.setGeometry(QRect(20, 200, 47, 21)) + self.label_7.setFont(font1) + self.lineEdit_2 = QLineEdit(self.app_group_box) + self.lineEdit_2.setObjectName("lineEdit_2") + self.lineEdit_2.setGeometry(QRect(80, 200, 211, 20)) + self.lineEdit_2.setFont(font1) + self.label = QLabel(self.app_group_box) + self.label.setObjectName("label") + self.label.setGeometry(QRect(0, 180, 1259, 18)) + font2 = QFont() + font2.setPointSize(11) + font2.setBold(True) + self.label.setFont(font2) + + self.gridLayout_2.addWidget(self.app_group_box, 1, 0, 1, 1) + + self.tabWidget.addTab(self.tab, "") + self.tab_2 = QWidget() + self.tab_2.setObjectName("tab_2") + self.tabWidget.addTab(self.tab_2, "") + + self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) + + self.horizontalLayout.addLayout(self.gridLayout) + + self.verticalLayout.addLayout(self.horizontalLayout) + + MainWindow.setCentralWidget(self.centralwidget) + self.menubar = QMenuBar(MainWindow) + self.menubar.setObjectName("menubar") + self.menubar.setGeometry(QRect(0, 0, 1280, 21)) + self.menuDatei = QMenu(self.menubar) + self.menuDatei.setObjectName("menuDatei") + self.menuEinstellungen = QMenu(self.menubar) + self.menuEinstellungen.setObjectName("menuEinstellungen") + MainWindow.setMenuBar(self.menubar) + self.statusbar = QStatusBar(MainWindow) + self.statusbar.setObjectName("statusbar") + MainWindow.setStatusBar(self.statusbar) + + self.menubar.addAction(self.menuDatei.menuAction()) + self.menubar.addAction(self.menuEinstellungen.menuAction()) + + self.retranslateUi(MainWindow) + + self.tabWidget.setCurrentIndex(0) + + QMetaObject.connectSlotsByName(MainWindow) + + # setupUi + + def retranslateUi(self, MainWindow): + MainWindow.setWindowTitle( + QCoreApplication.translate("MainWindow", "MainWindow", None) + ) + # if QT_CONFIG(tooltip) + self.load_app.setToolTip( + QCoreApplication.translate( + "MainWindow", "Load the Semesterapparate from the database", None + ) + ) + # endif // QT_CONFIG(tooltip) + self.load_app.setText( + QCoreApplication.translate("MainWindow", "App. aufrufen", None) + ) + self.create_new_app.setText( + QCoreApplication.translate("MainWindow", "neu. App anlegen", None) + ) + ___qtablewidgetitem = self.tableWidget_apparate.horizontalHeaderItem(0) + ___qtablewidgetitem.setText( + QCoreApplication.translate("MainWindow", "AppNr", None) + ) + ___qtablewidgetitem1 = self.tableWidget_apparate.horizontalHeaderItem(1) + ___qtablewidgetitem1.setText( + QCoreApplication.translate("MainWindow", "App Name", None) + ) + ___qtablewidgetitem2 = self.tableWidget_apparate.horizontalHeaderItem(2) + ___qtablewidgetitem2.setText( + QCoreApplication.translate("MainWindow", "Professor", None) + ) + ___qtablewidgetitem3 = self.tableWidget_apparate.horizontalHeaderItem(3) + ___qtablewidgetitem3.setText( + QCoreApplication.translate("MainWindow", "Dauerapparat", None) + ) + ___qtablewidgetitem4 = self.tableWidget_apparat_media.horizontalHeaderItem(0) + ___qtablewidgetitem4.setText( + QCoreApplication.translate("MainWindow", "Buchtitel", None) + ) + ___qtablewidgetitem5 = self.tableWidget_apparat_media.horizontalHeaderItem(1) + ___qtablewidgetitem5.setText( + QCoreApplication.translate("MainWindow", "Autor", None) + ) + ___qtablewidgetitem6 = self.tableWidget_apparat_media.horizontalHeaderItem(2) + ___qtablewidgetitem6.setText( + QCoreApplication.translate("MainWindow", "Auflage", None) + ) + ___qtablewidgetitem7 = self.tableWidget_apparat_media.horizontalHeaderItem(3) + ___qtablewidgetitem7.setText( + QCoreApplication.translate("MainWindow", "Signatur", None) + ) + self.app_group_box.setTitle( + QCoreApplication.translate("MainWindow", "Apparatsdetails", None) + ) + ___qtablewidgetitem8 = self.dokument_list.horizontalHeaderItem(0) + ___qtablewidgetitem8.setText( + QCoreApplication.translate("MainWindow", "Dokumentname", None) + ) + ___qtablewidgetitem9 = self.dokument_list.horizontalHeaderItem(1) + ___qtablewidgetitem9.setText( + QCoreApplication.translate("MainWindow", "Typ", None) + ) + self.label_5.setText( + QCoreApplication.translate("MainWindow", "Apparatsname", None) + ) + self.lineEdit.setPlaceholderText( + QCoreApplication.translate("MainWindow", "Nachname, Vorname", None) + ) + self.sem_winter.setText( + QCoreApplication.translate("MainWindow", "Winter", None) + ) + self.label_4.setText( + QCoreApplication.translate("MainWindow", "Prof. Name", None) + ) + self.sem_sommer.setText( + QCoreApplication.translate("MainWindow", "Sommer", None) + ) + self.label_3.setText( + QCoreApplication.translate("MainWindow", "Prof. Titel", None) + ) + self.label_6.setText(QCoreApplication.translate("MainWindow", "Semester", None)) + self.sem_year.setPlaceholderText( + QCoreApplication.translate("MainWindow", "2023", None) + ) + self.label_2.setText( + QCoreApplication.translate("MainWindow", "Apparatsnummer", None) + ) + self.btn_apparat_save.setText( + QCoreApplication.translate("MainWindow", "Speichern", None) + ) + self.btn_apparat_apply.setText( + QCoreApplication.translate("MainWindow", "Aktualisieren", None) + ) + self.checkBox.setText( + QCoreApplication.translate("MainWindow", "Dauerapparat", None) + ) + self.btn_add_document.setText( + QCoreApplication.translate("MainWindow", "Dokument hinzuf\u00fcgen", None) + ) + self.btn_open_document.setText( + QCoreApplication.translate("MainWindow", "Dokument \u00f6ffnen", None) + ) + self.toolButton.setText(QCoreApplication.translate("MainWindow", "...", None)) + self.label_7.setText(QCoreApplication.translate("MainWindow", "Suche", None)) + self.lineEdit_2.setPlaceholderText( + QCoreApplication.translate("MainWindow", "Buch oder Signatur", None) + ) + self.label.setText( + QCoreApplication.translate("MainWindow", "Medienliste", None) + ) + self.tabWidget.setTabText( + self.tabWidget.indexOf(self.tab), + QCoreApplication.translate("MainWindow", "Tab 1", None), + ) + self.tabWidget.setTabText( + self.tabWidget.indexOf(self.tab_2), + QCoreApplication.translate("MainWindow", "Tab 2", None), + ) + self.menuDatei.setTitle(QCoreApplication.translate("MainWindow", "Datei", None)) + self.menuEinstellungen.setTitle( + QCoreApplication.translate("MainWindow", "Einstellungen", None) + ) + + # retranslateUi diff --git a/src/ui/widgets/Ui_message_widget.py b/src/ui/widgets/Ui_message_widget.py new file mode 100644 index 0000000..b78daac --- /dev/null +++ b/src/ui/widgets/Ui_message_widget.py @@ -0,0 +1,67 @@ +# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\Semesterapparate\ui\widgets\message_widget.ui' +# +# Created by: PyQt6 UI code generator 6.3.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + +from src.backend.database import Database + + +class Ui_Form(object): + def setupUi(self, Form): + Form.setObjectName("Form") + Form.resize(295, 110) + self.label = QtWidgets.QLabel(Form) + self.label.setGeometry(QtCore.QRect(10, 0, 47, 21)) + self.label.setObjectName("label") + self.lineEdit = QtWidgets.QLineEdit(Form) + self.lineEdit.setEnabled(True) + self.lineEdit.setGeometry(QtCore.QRect(60, 0, 41, 20)) + self.lineEdit.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.lineEdit.setReadOnly(True) + self.lineEdit.setObjectName("lineEdit") + self.label_2 = QtWidgets.QLabel(Form) + self.label_2.setGeometry(QtCore.QRect(10, 20, 51, 21)) + self.label_2.setObjectName("label_2") + self.textEdit = QtWidgets.QTextEdit(Form) + self.textEdit.setGeometry(QtCore.QRect(10, 40, 281, 66)) + self.textEdit.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.textEdit.setInputMethodHints(QtCore.Qt.InputMethodHint.ImhNone) + self.textEdit.setReadOnly(True) + self.textEdit.setObjectName("textEdit") + self.pushButton = QtWidgets.QPushButton(Form) + self.pushButton.setGeometry(QtCore.QRect(210, 10, 75, 23)) + self.pushButton.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.pushButton.setObjectName("pushButton") + self.hidden_id = QtWidgets.QLabel(Form) + self.hidden_id.setGeometry(QtCore.QRect(140, 10, 47, 13)) + self.hidden_id.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.hidden_id.setObjectName("hidden_id") + self.hidden_id.hide() + self.delete = False + self.pushButton.clicked.connect(self.delete_message) + self.retranslateUi(Form) + QtCore.QMetaObject.connectSlotsByName(Form) + Form.setTabOrder(self.lineEdit, self.textEdit) + + def retranslateUi(self, Form): + _translate = QtCore.QCoreApplication.translate + Form.setWindowTitle(_translate("Form", "Form")) + self.label.setText(_translate("Form", "Apparat:")) + self.label_2.setText(_translate("Form", "Nachricht:")) + self.pushButton.setText(_translate("Form", "Löschen")) + self.hidden_id.setText(_translate("Form", "TextLabel")) + + def set_message(self, message: str, apparat: int, app_id: int): + self.textEdit.setText(message) + self.lineEdit.setText(str(apparat) if apparat else "Alle") + self.hidden_id.setText(str(app_id)) + + def delete_message(self): + db = Database() + print("deleting message") + db.delete_message(self.hidden_id.text()) diff --git a/src/ui/widgets/Ui_progress_overview_widget.py b/src/ui/widgets/Ui_progress_overview_widget.py new file mode 100644 index 0000000..a146656 --- /dev/null +++ b/src/ui/widgets/Ui_progress_overview_widget.py @@ -0,0 +1,149 @@ +# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\Semesterapparate\ui\widgets\progress_overview_widget.ui' +# +# Created by: PyQt6 UI code generator 6.3.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_Form(object): + def setupUi(self, Form): + Form.setObjectName("Form") + Form.resize(300, 751) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed + ) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth()) + Form.setSizePolicy(sizePolicy) + Form.setMaximumSize(QtCore.QSize(300, 751)) + self.group_software = QtWidgets.QGroupBox(Form) + self.group_software.setEnabled(True) + self.group_software.setGeometry(QtCore.QRect(10, 10, 281, 211)) + font = QtGui.QFont() + font.setPointSize(10) + font.setBold(True) + font.setWeight(75) + self.group_software.setFont(font) + self.group_software.setStatusTip("") + self.group_software.setFlat(False) + self.group_software.setCheckable(False) + self.group_software.setChecked(False) + self.group_software.setObjectName("group_software") + self.checkBox = QtWidgets.QCheckBox(self.group_software) + self.checkBox.setGeometry(QtCore.QRect(10, 20, 241, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setWeight(50) + self.checkBox.setFont(font) + self.checkBox.setObjectName("checkBox") + self.checkBox_2 = QtWidgets.QCheckBox(self.group_software) + self.checkBox_2.setGeometry(QtCore.QRect(10, 50, 241, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setWeight(50) + self.checkBox_2.setFont(font) + self.checkBox_2.setObjectName("checkBox_2") + self.checkBox_3 = QtWidgets.QCheckBox(self.group_software) + self.checkBox_3.setGeometry(QtCore.QRect(10, 130, 241, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setWeight(50) + self.checkBox_3.setFont(font) + self.checkBox_3.setObjectName("checkBox_3") + self.groupBox_2 = QtWidgets.QGroupBox(Form) + self.groupBox_2.setGeometry(QtCore.QRect(10, 220, 281, 251)) + font = QtGui.QFont() + font.setPointSize(10) + font.setBold(True) + font.setItalic(False) + font.setUnderline(False) + font.setWeight(75) + font.setKerning(True) + font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferDefault) + self.groupBox_2.setFont(font) + self.groupBox_2.setObjectName("groupBox_2") + self.checkBox_4 = QtWidgets.QCheckBox(self.groupBox_2) + self.checkBox_4.setGeometry(QtCore.QRect(10, 20, 241, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setWeight(50) + self.checkBox_4.setFont(font) + self.checkBox_4.setObjectName("checkBox_4") + self.checkBox_5 = QtWidgets.QCheckBox(self.groupBox_2) + self.checkBox_5.setGeometry(QtCore.QRect(10, 50, 241, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setWeight(50) + self.checkBox_5.setFont(font) + self.checkBox_5.setObjectName("checkBox_5") + self.checkBox_6 = QtWidgets.QCheckBox(self.groupBox_2) + self.checkBox_6.setGeometry(QtCore.QRect(10, 80, 161, 41)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setWeight(50) + self.checkBox_6.setFont(font) + self.checkBox_6.setObjectName("checkBox_6") + self.pushButton = QtWidgets.QPushButton(self.groupBox_2) + self.pushButton.setGeometry(QtCore.QRect(160, 90, 101, 23)) + font = QtGui.QFont() + font.setPointSize(8) + font.setBold(False) + font.setWeight(50) + self.pushButton.setFont(font) + self.pushButton.setStatusTip("") + self.pushButton.setWhatsThis("") + self.pushButton.setAccessibleDescription("") + self.pushButton.setAutoFillBackground(False) + icon = QtGui.QIcon() + icon.addPixmap( + QtGui.QPixmap( + "c:\\Users\\aky547\\GitHub\\Semesterapparate\\ui\\widgets\\../icons/information.png" + ), + QtGui.QIcon.Mode.Normal, + QtGui.QIcon.State.Off, + ) + self.pushButton.setIcon(icon) + self.pushButton.setCheckable(False) + self.pushButton.setChecked(False) + self.pushButton.setObjectName("pushButton") + + self.retranslateUi(Form) + QtCore.QMetaObject.connectSlotsByName(Form) + + def retranslateUi(self, Form): + _translate = QtCore.QCoreApplication.translate + Form.setWindowTitle(_translate("Form", "Form")) + self.group_software.setToolTip( + _translate( + "Form", + "Hier klicken, um die aDIS Abfrage in die Zwischenablage zu kopieren", + ) + ) + self.group_software.setTitle(_translate("Form", "Software")) + self.checkBox.setText(_translate("Form", "Apparatsdaten eingegeben")) + self.checkBox_2.setText(_translate("Form", "Medien hinzugefügt / importiert")) + self.checkBox_3.setText( + _translate("Form", "Prof-ID und Apparat-ID eingetragen") + ) + self.groupBox_2.setTitle(_translate("Form", "aDIS")) + self.checkBox_4.setText(_translate("Form", "Medien geprüft")) + self.checkBox_5.setText(_translate("Form", "Medien bearbeitet")) + self.checkBox_6.setText(_translate("Form", "Apparat angelegt")) + self.pushButton.setToolTip( + _translate( + "Form", + "Hier klicken, um die aDIS Abfrage in die Zwischenablage zu kopieren", + ) + ) + self.pushButton.setText(_translate("Form", " aDIS Abfrage")) diff --git a/src/ui/widgets/__init__.py b/src/ui/widgets/__init__.py new file mode 100644 index 0000000..c503c0e --- /dev/null +++ b/src/ui/widgets/__init__.py @@ -0,0 +1,5 @@ +__all__ = ["filepicker"] +from .collapse import StatusWidget +from .filepicker import FilePicker +from .graph import GraphWidget +from .Ui_message_widget import Ui_Form as Message_Widget diff --git a/src/ui/widgets/collapse.py b/src/ui/widgets/collapse.py new file mode 100644 index 0000000..a5fc084 --- /dev/null +++ b/src/ui/widgets/collapse.py @@ -0,0 +1,76 @@ +# import pysignal pyslot +from PyQt6.QtCore import pyqtSignal +from PyQt6.QtWidgets import ( + QApplication, + QTreeWidget, + QTreeWidgetItem, + QVBoxLayout, + QWidget, +) + + +class StatusWidget(QWidget): + person_double_clicked = pyqtSignal(str,str, int) + + def __init__(self, data, header_label: str): + super(StatusWidget, self).__init__() + + self.tree_widget = QTreeWidget() + self.tree_widget.setHeaderLabels([header_label]) + self.populate_tree(data) + self.header = header_label + layout = QVBoxLayout() + layout.addWidget(self.tree_widget) + self.setLayout(layout) + self.tree_widget.itemDoubleClicked.connect(self.on_item_double_clicked) + def on_item_double_clicked(self, item: QTreeWidgetItem, column: int): + parent_depth = 0 + parent = item.parent() + while parent: + parent_depth += 1 + parent = parent.parent() + print(parent_depth) + # Emit the person_double_clicked signal with the name of the person and the parent depth + self.person_double_clicked.emit(self.header,item.text(column), parent_depth) + + def populate_tree(self, data): + if data == {}: + return + + def __listcount(dictlist: dict[dict[str:list]]): + ret = 0 + for _, value in dictlist.items(): + for _, value2 in value.items(): + ret += len(value2) + return ret + + listitems = __listcount(data) + for action, items in data.items(): + action_item = QTreeWidgetItem( + self.tree_widget, [f"{action} ({str(listitems)})"] + ) + for person, entries in items.items(): + person_item = QTreeWidgetItem( + action_item, [f"{person} ({str(len(entries))})"] + ) + for entry in entries: + entry_item = QTreeWidgetItem(person_item, [entry]) + # Make the person entry collapsible + person_item.setExpanded(False) + + # Make the action entry collapsible + action_item.setExpanded(True) + + +if __name__ == "__main__": + import sys + + app = QApplication(sys.argv) + data = {"test": {"test2": ["test3", "test4"]}} + widget = StatusWidget(data, "test") + + widget.show() + #detect emit signal + widget.person_double_clicked.connect(lambda x: print(x)) + + sys.exit(app.exec()) diff --git a/src/ui/widgets/default_apps.py b/src/ui/widgets/default_apps.py new file mode 100644 index 0000000..b3f3a40 --- /dev/null +++ b/src/ui/widgets/default_apps.py @@ -0,0 +1,15 @@ +from PyQt6 import QtCore, QtGui, QtWidgets + + +class CollapsibleWidget(object): + pass + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class CollapsibleWidget(object): +from PyQt6 import QtCore, QtGui, QtWidgets + + +class CollapsibleWidget(object): diff --git a/src/ui/widgets/filepicker.py b/src/ui/widgets/filepicker.py new file mode 100644 index 0000000..7934787 --- /dev/null +++ b/src/ui/widgets/filepicker.py @@ -0,0 +1,29 @@ +from PyQt6.QtWidgets import QFileDialog, QApplication +from PyQt6.QtCore import QSettings +import sys + +class FilePicker: + def __init__(self): + self.settings = QSettings("PH-Freiburg", "SAP") + self.last_path = self.settings.value("last_path", "/") + self.multi_select = True + + def pick_files(self): + filepicker = QFileDialog() + filepicker.setFileMode(QFileDialog.FileMode.ExistingFiles) + filepicker.setDirectory(self.last_path) + filepicker.setOption(QFileDialog.Option.DontUseNativeDialog, True) + #enable multi select + filepicker.setOption(QFileDialog.Option.DontUseCustomDirectoryIcons, True) + + files, _ = filepicker.getOpenFileNames(caption='Open file', directory=self.last_path) + if files: + self.last_path = files[0] + self.settings.setValue("last_path", self.last_path) + return files + +if __name__ == '__main__': + app = QApplication(sys.argv) + picker = FilePicker() + files = picker.pick_files() + print(files) \ No newline at end of file diff --git a/src/ui/widgets/graph.py b/src/ui/widgets/graph.py new file mode 100644 index 0000000..75cc60c --- /dev/null +++ b/src/ui/widgets/graph.py @@ -0,0 +1,49 @@ +import matplotlib + +matplotlib.use("QtAgg") + +from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas +from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar +from matplotlib.figure import Figure +from PyQt6 import QtCore, QtWidgets + + +class graph(FigureCanvas): + def __init__(self, parent=None, width=5, height=4, dpi=100): + fig = Figure(figsize=(width, height), dpi=dpi) + self.axes = fig.add_subplot(111) + self.canvas = FigureCanvas(fig) + super().__init__(fig) + + +# display graph with multiple lines +class GraphWidget(QtWidgets.QWidget): + def __init__(self, parent=None, data=None, legend_labels=None): + super().__init__() + self.graph = graph(self, width=7, height=4.5, dpi=100) + self.graph.axes.plot(data["x"], data["y"], "r", data["x"], data["y2"], "b") + self.toolbar = NavigationToolbar(self.graph, self) + # set legend + self.graph.axes.legend(legend_labels, loc="upper left") + # set the layout + layout = QtWidgets.QVBoxLayout() + layout.addWidget(self.toolbar) + layout.addWidget(self.graph) + self.setLayout(layout) + + # def set_area(self, top=1, bottom= 0.07, left=0.1, right=0.994,hspace=0.2,wspace=0.2): + # self.graph. + + +if __name__ == "__main__": + import sys + + app = QtWidgets.QApplication(sys.argv) + data = { + "x": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + "y": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + "y2": [10, 9, 8, 7, 6, 5, 4, 3, 2, 1], + } + widget = GraphWidget(data=data, legend_labels=["+", "-"]) + widget.show() + sys.exit(app.exec()) diff --git a/src/ui/widgets/message_widget.ui b/src/ui/widgets/message_widget.ui new file mode 100644 index 0000000..c368b5c --- /dev/null +++ b/src/ui/widgets/message_widget.ui @@ -0,0 +1,119 @@ + + + Form + + + + 0 + 0 + 295 + 110 + + + + Form + + + + + 10 + 0 + 47 + 21 + + + + Apparat: + + + + + true + + + + 60 + 0 + 41 + 20 + + + + Qt::NoFocus + + + true + + + + + + 10 + 20 + 51 + 21 + + + + Nachricht: + + + + + + 10 + 40 + 281 + 66 + + + + Qt::NoFocus + + + Qt::ImhNone + + + true + + + + + + 210 + 10 + 75 + 23 + + + + Qt::NoFocus + + + Löschen + + + + + + 140 + 10 + 47 + 13 + + + + Qt::NoFocus + + + TextLabel + + + + + lineEdit + textEdit + + + + diff --git a/src/ui/widgets/progress_overview_widget.ui b/src/ui/widgets/progress_overview_widget.ui new file mode 100644 index 0000000..ee5ab84 --- /dev/null +++ b/src/ui/widgets/progress_overview_widget.ui @@ -0,0 +1,258 @@ + + + Form + + + + 0 + 0 + 300 + 751 + + + + + 0 + 0 + + + + + 300 + 751 + + + + Form + + + + true + + + + 10 + 10 + 281 + 211 + + + + + 10 + 75 + true + + + + Hier klicken, um die aDIS Abfrage in die Zwischenablage zu kopieren + + + + + + Software + + + false + + + false + + + false + + + + + 10 + 20 + 241 + 41 + + + + + 8 + 50 + false + + + + Apparatsdaten eingegeben + + + + + + 10 + 50 + 241 + 41 + + + + + 8 + 50 + false + + + + Medien hinzugefügt / importiert + + + + + + 10 + 130 + 241 + 41 + + + + + 8 + 50 + false + + + + Prof-ID und Apparat-ID eingetragen + + + + + + + 10 + 220 + 281 + 251 + + + + + 10 + 75 + false + true + false + PreferDefault + true + + + + aDIS + + + + + 10 + 20 + 241 + 41 + + + + + 8 + 50 + false + + + + Medien geprüft + + + + + + 10 + 50 + 241 + 41 + + + + + 8 + 50 + false + + + + Medien bearbeitet + + + + + + 10 + 80 + 161 + 41 + + + + + 8 + 50 + false + + + + Apparat angelegt + + + + + + 160 + 90 + 101 + 23 + + + + + 8 + 50 + false + + + + Hier klicken, um die aDIS Abfrage in die Zwischenablage zu kopieren + + + + + + + + + + + + false + + + aDIS Abfrage + + + + ../icons/information.png../icons/information.png + + + false + + + false + + + + + + + diff --git a/src/ui/widgets/progress_widget.py b/src/ui/widgets/progress_widget.py new file mode 100644 index 0000000..df14ab8 --- /dev/null +++ b/src/ui/widgets/progress_widget.py @@ -0,0 +1,16 @@ +from PyQt6 import QtCore, QtGui, QtWidgets +from Ui_progress_overview_widget import Ui_Form + + +class Progress_view(Ui_Form): + def __init__(self, MainWindow): + super().__init__() + self.setupUi(MainWindow) + self.retranslateUi(MainWindow) + self.checkBox_3.setDisabled(True) + self.pushButton.clicked.connect(self.pushButton_clicked) + + def pushButton_clicked(self): + # copies text to clipboard + clipboard = QtWidgets.QApplication.clipboard() + clipboard.setText("") diff --git a/test.py b/test.py new file mode 100644 index 0000000..e691e9e --- /dev/null +++ b/test.py @@ -0,0 +1,135 @@ +# # # # tupl = (0, 0, 0, 0, 0, 0) + + +# # # # def change_value(index: int, state: int): +# # # # global tupl +# # # # tupl = list(tupl) +# # # # print(len(tupl)) +# # # # tupl[index] = state +# # # # tupl = tuple(tupl) + + +# # # # def check_validity() -> bool: +# # # # global tupl +# # # # if all(tupl): +# # # # return True +# # # # else: +# # # # return False + + +# # # # print(tupl) +# # # # print(check_validity()) +# # # # change_value(0, 1) +# # # # for i in range(1, 6): +# # # # change_value(i, 1) +# # # # print(tupl) +# # # # print(check_validity()) +# # # import sqlite3 +# # # from codebase import Database +# # # # print(messages) + +# # # def day_to_message(messages:list[dict[str]]): +# # # print(messages) +# # # ret = [] +# # # #extract the remind_at from each message and add them to ret. If the key already exists, append the message to the list +# # # for message in messages: +# # # print(message) +# # # remind_at = message["remind_at"] +# # # if remind_at in ret: +# # # ret[remind_at].append(message) +# # # else: +# # # ret[remind_at] = [message] +# # # print(ret) +# # # if __name__ =="__man__": +# # # db = Database() + +# # # messages = db.get_messages() +# # # print(messages) +# # # print(day_to_message(messages)) + + +# # from natsort import natsorted + +# # unsorted = ["WiSe 23/24", "SoSe 23", "WiSe 21/22", "SoSe 21", "WiSe 22/23", "SoSe 22"] + +# # def custom_sort(unsorted:list[str])->list[str]: +# # """Sort a list of semesters in the format "SoSe n" and "WiSe n/n+1" in the correct order. +# # Where n == year in 2 digit format + +# # Args: +# # unsorted (list[str]): List of semesters in the format "SoSe n" and "WiSe n/n+1" + +# # Returns: +# # ret (list[str]): Sorted list in correct order +# # """ +# # #split the list into two lists, one with the summer semesters and one with the winter semesters +# # summer = natsorted([ i for i in unsorted if "SoSe" in i]) +# # winter = natsorted([i for i in unsorted if "WiSe" in i]) +# # #merge the lists entries alternately +# # ret = [] +# # for i in range(len(summer)): +# # ret.append(summer[i]) +# # ret.append(winter[i]) +# # return ret +# from typing import Any + +# def statistic_request(**kwargs:Any): + + +# if "deletable" in kwargs.keys(): +# query = f"SELECT * FROM semesterapparat WHERE deletion_status=0 AND dauer=0 AND (erstellsemester!='{kwargs['deletesemester']}' OR verlängerung_bis!='{kwargs['deletesemester']}')" +# return query + +# if "dauer" in kwargs.keys(): +# kwargs["dauer"] = kwargs["dauer"].replace("Ja", "1").replace("Nein", "0") +# query = "SELECT * FROM semesterapparat WHERE " +# for key, value in kwargs.items() if kwargs.items() is not None else {}: +# print(key, value) +# query += f"{key}='{value}' AND " +# print(query) +# #remove deletesemester part from normal query, as this will be added to the database upon deleting the apparat +# if "deletesemester" in kwargs.keys(): +# query = query.replace(f"deletesemester='{kwargs['deletesemester']}' AND ", "") +# if "endsemester" in kwargs.keys(): +# if "erstellsemester" in kwargs.keys(): +# query = query.replace(f"endsemester='{kwargs['endsemester']}' AND ", "") +# query = query.replace(f"erstellsemester='{kwargs['erstellsemester']} AND ", "xyz") +# else: +# query = query.replace(f"endsemester='{kwargs['endsemester']}' AND ", "xyz") +# print("replaced") +# query = query.replace("xyz", f"(erstellsemester='{kwargs['endsemester']}' OR verlängerung_bis='{kwargs['endsemester']}') AND ") + +# query = query[:-5].strip() +# return query +# from threads import AutoAdder +# from PyQt6 import QtWidgets +# from ui import parsed_titles_ui +# import sys +# def main(data): +# app = QtWidgets.QApplication(sys.argv) +# dialog = QtWidgets.QDialog() +# ui = parsed_titles_ui() +# ui.setupUi(dialog) +# ui.signatures = data +# ui.app_id = 3 +# ui.prof_id = 1 +# ui.toolButton.click() +# ui.populate_table() +# ui.progressBar.setMaximum(len(data)) +# ui.progressBar.setValue(0) + +# dialog.show() +# sys.exit(app.exec()) + +# if __name__ == "__main__": +# data = ['YH 6876 S344', 'YM 3500 L925', 'CU 3200 W862', 'CW 6940 W842', 'CZ 1360 M379', 'CU 3800 V445', 'CU 3100 L948', 'CU 3200 H379 (3)', 'YC 7093 K95', 'CU 8590 E34 (2)', 'MS 6410 L744 (2)+1', 'CUS778', 'Psy K 120: 125 b', 'Psy L 170: 66', 'MR 2600 M474 (12)+16', 'Psy K 760: 19', 'Psy K 110: 92', 'Psy K 400: 45 a', 'CD 20/10,6'] +# main(data) + +from src.backend.database import Database +import pickle +db = Database() + +query="SELECT * from media where id=1" +_data = db.database.execute(query).fetchall() +var = _data[0][1] +print(pickle.loads(var)) \ No newline at end of file diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/database_test.py b/test/database_test.py new file mode 100644 index 0000000..6be0a02 --- /dev/null +++ b/test/database_test.py @@ -0,0 +1,22 @@ +from src.backend.database import Database +import pickle +def test_connection(): + db=Database() + assert db.database is not None + +def test_insert(): + db=Database() + assert db.database is not None + db.create_user("test_account", "test", "test", "test") + curr_users = db.get_users() + curr_users = [x[2] for x in curr_users] + assert "test_account" in curr_users + db.delete_user("test_account") + curr_users = db.get_users() + curr_users = [x[2] for x in curr_users] + assert "test_account" not in curr_users + +def test_pickle_bookdata(): + db=Database() + assert db.database is not None + \ No newline at end of file diff --git a/test/many_webrequest_test.py b/test/many_webrequest_test.py new file mode 100644 index 0000000..d9445d4 --- /dev/null +++ b/test/many_webrequest_test.py @@ -0,0 +1,10 @@ +from test.webrequest_test import test_webdata_bibtexttransform + + +def many_test_webdata(): + test_webdata_bibtexttransform("RIS") + test_webdata_bibtexttransform("BibTeX") + test_webdata_bibtexttransform("COinS") + test_webdata_bibtexttransform("ARRAY") + test_webdata_bibtexttransform("RDS") + assert True is True \ No newline at end of file diff --git a/test/webrequest_test.py b/test/webrequest_test.py new file mode 100644 index 0000000..1924a00 --- /dev/null +++ b/test/webrequest_test.py @@ -0,0 +1,23 @@ +import pytest +from src.logic.webrequest import WebRequest +from src.logic.webrequest import BibTextTransformer +from src.logic.dataclass import BookData + +def test_webdata_bibtexttransform(source_data:str="RIS"): + request = WebRequest().get_ppn("ST 250 U42 (15) ").get_data() + assert isinstance(request, list) is True + assert len(request)>0 + model:BookData = BibTextTransformer(source_data).get_data(request).return_data() + assert model is not None + assert model.signature =="ST 250 U42 (15)" + assert model.ppn == "1693321114" + assert model.author == "Ullenboom, Christian" + assert model.link == "https://rds.ibs-bw.de/phfreiburg/link?kid=1693321114" + assert model.pages=="1246" + assert model.publisher=="Rheinwerk Computing" + + + + + + \ No newline at end of file