10 Commits
4.0 ... 4.0.1

40 changed files with 532 additions and 1085 deletions

View File

@@ -0,0 +1,9 @@
next-version: 4.0.1
mode: ContinuousDeployment
assembly-versioning-scheme: MajorMinorPatch
assembly-file-versioning-scheme: MajorMinorPatch
branches:
main:
regex: ^main$
increment: Patch

BIN
.gitea/readme/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View File

@@ -0,0 +1,34 @@
name: Analyze code
on:
push:
branches:
- "dev"
paths:
- "src**"
- "requirements.txt"
pull_request:
branches:
- "dev"
- "main"
paths:
- "src**"
- "requirements.txt"
jobs:
analyze:
name: Analyze code
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pylint
- name: Analysing the code with pylint
run: pylint --exit-zero $(git ls-files 'src/*.pyw')

View File

@@ -0,0 +1,77 @@
name: Analyze code and publish app
on:
push:
branches:
- "main"
paths:
- "src**"
- "requirements.txt"
jobs:
analyze:
name: Analyze code
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.8"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pylint
- name: Analysing the code with pylint
run: pylint --exit-zero $(git ls-files 'src/*.pyw')
publish:
name: Publish script
needs: analyze
steps:
- name: Checkout
uses: actions/checkout@v6.0.2
with:
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 10.0.x
- name: Setup GitVersion
uses: gittools/actions/gitversion/setup@v4.2.0
with:
versionSpec: 6.4.x
- name: Determine version
uses: gittools/actions/gitversion/execute@v4.2.0
id: gitversion
with:
configFilePath: ./.gitea/config/gitversion.yml
- name: Replace version
run: sed -i 's/WIP/${{steps.gitversion.outputs.SemVer}}/g' ./src/configs/config.cfg
- name: Create package root directory
run: |
mkdir package
mkdir package/generator_csv
cp -r src/* package/generator_csv/
cp requirements.txt package/requirements.txt
- name: Create .TAR.GZ archive
uses: ksm2/archive-action@v1
with:
format: "tar.gz"
name: generator_csv_${{steps.gitversion.outputs.SemVer}}
root-directory: "package"
- name: Create .ZIP archive
uses: ksm2/archive-action@v1
with:
format: "zip"
name: generator_csv_${{steps.gitversion.outputs.SemVer}}
root-directory: "package"
- name: Create Release
uses: akkuman/gitea-release-action@v1
with:
tag_name: ${{steps.gitversion.outputs.SemVer}}
name: ${{steps.gitversion.outputs.SemVer}}
files: |-
generator_csv_${{steps.gitversion.outputs.SemVer}}.tar.gz
generator_csv_${{steps.gitversion.outputs.SemVer}}.zip

160
.gitignore vendored Normal file
View File

@@ -0,0 +1,160 @@
# 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/

18
LICENSE Normal file
View File

@@ -0,0 +1,18 @@
MIT License
Copyright (c) 2020 Mateusz Skoczek
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 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.

60
README.md Normal file
View File

@@ -0,0 +1,60 @@
<p align="center"><img src=".gitea/readme/icon.png"/></p>
<h1 align="center">Generator CSV</h1>
<h3 align="center"><b>Students and teachers data file structure converter for Microsoft 365 Admin Center.</b></h3>
<p align="center">Generator CSV was written using Python and Tkinter library. This project was implemented as part of the Microsoft 365 rollout at my high school (ZSP Sobolew).</p>
<p align="center"><img width="50%" src=".gitea/readme/screenshot.png"/></p>
---
## Informations
> [!IMPORTANT]
> App is no longer maintained, but should work properly
> [!NOTE]
> The application only supports the Polish language because it was written for my school and one of the requirements was that it be easy to use for people who do not speak English. Since there are no plans to further develop the application, support for other languages is not planned. Detailed documentation (Wiki) is also in Polish. I leave the repository mainly as a sample of my skills (or at least their state as of 2020).
> [!NOTE]
> Polska wersja README znajduje się w Wiki
## Features
- Converting students and teachers data from one format (e.g. electronic school journal) to another (data format required by Microsoft 365 Admin Center)
- File format presets
- Highly customizable file generation
- Ability to change apperance of UI
## Installation
Download latest package version from <a href="https://repos.mateuszskoczek.com/MateuszSkoczek/GeneratorCSV/releases">Releases</a> tab, unpack, install requirements and you good to go
**Requirements**
- Python installed
- PIP packages:
- `pillow==9.0.1`
- `tk`
You can also use `requirements.txt` file to install PIP dependencies
```
pip install -r requirements.txt
```
## Usage
```
python generator_csv
```
## Attribution
You can copy this repository and create your own version of the app freely. However, it would be nice if you included URL to this repository in the description to your repository or in README file.
**Other sources:**
- Icon by <a href="icons8.com">Icons8</a>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

View File

@@ -1,115 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<link rel = "stylesheet" type = "text/css" href = "content.css">
<meta charset = "utf-8">
<link rel = "shortcut icon" href = "../assets/documentation-page/icon.ico">
<title>Generator CSV</title>
</head>
<body>
<p id = "about-program-image">
<br>
<br>
<br>
<br>
<img src = '../assets/documentation-page/about-program/icon.png'>
<br>
<br>
<br>
<br>
</p>
<h1>
Generator CSV
</h1>
<p id = "about-program-main-text">
Wersja 4.0 (Build 20254)
</p>
<p id = "about-program-text-centered">
<br>
© styczeń 2019 - wrzesień 2020<br>
<br>
Mateusz Skoczek<br>
<br>
dla ZSP Sobolew<br>
</p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<hr>
<br>
<h2>Historia wersji</h2>
<p id = 'about-program-changelog-main-version'>Wersja 1.0</p>
<br>
<ul>
<li>Pierwsza wersja programu składająca się z 4 części</li>
</ul>
<br>
<br>
<br>
<p id = 'about-program-changelog-main-version'>Wersja 2.0</p>
<br>
<ul>
<li>Podstawowy tekstowy interfejs</li>
<li>Scalenie programu w jeden</li>
<li>Aktualizacja formatu plików z danymi</li>
<li>Wstępne przystosowanie do działania w czteroletnim liceum i w trzyletniej szkole branżowej</li>
<li>Aktualizacja kodowania</li>
</ul>
<br>
<br>
<br>
<p id = 'about-program-changelog-main-version'>Wersja 3.0</p>
<br>
<ul>
<li>Wprowadzenie pełnego graficznego interfejsu w środowisku tkinter</li>
<li>Wstępne obsługiwanie wyjątków</li>
<li>Przeniesienie modułów do oddzielnego pliku</li>
<li>Stworzenie pliku 'format.py' ze skryptem przetwarzającym dane - przystosowanie programu do ewentualnych zmian w formacie plików z danymi</li>
<li>Przeniesienie ukrytych ustawień do pliku 'config.cfg'</li>
</ul>
<br>
<br>
<br>
<p id = 'about-program-changelog-main-version'>Wersja 3.0.1</p>
<br>
<ul>
<li>Poprawka błędu - pole 3 i 4 nie mają już przypisanej tej samej zmiennej tekstowej</li>
<li>Przydzielenie wersji, autorów, tytułu programu i lat pracy do zmiennych globalnych środowiska graficznego</li>
</ul>
<br>
<br>
<br>
<p id = 'about-program-changelog-main-version'>Wersja 4.0 (work in progress)</p>
<br>
<ul>
<li>Skompliowanie pliku programu do formatu .exe</li>
<li>Przeprojektowanie kodu programu</li>
<li>Nowy interfejs programu</li>
<li>Dodanie ustawień</li>
<li>Dodanie możliwości ręcznego zmieniania wyglądu programu</li>
<li>Wprowadzenie systemu format presetów zamiast pliku 'format.py'</li>
<li>Możliwość zmiany nazwy plików wyjściowych i uniezależnienie ich lokalizacji od siebie</li>
<li>Usunięcie konsoli w tle</li>
<li>Stworzenie strony w HTMLu zawierającej instrukcję, dokumentację, informacje o programie i changelog</li>
<li>Wiele innych mniejszych zmian</li>
</ul>
<br>
<br>
<br>
</body>
</html>

View File

@@ -1,104 +0,0 @@
h1 {
color: #C0C0C0;
font-family: 'Segoe UI';
font-size: 35px;
text-align: center;
}
h2 {
color: #C0C0C0;
font-family: 'Segoe UI';
font-size: 25px;
text-align: center;
}
h5 {
color: #C0C0C0;
font-family: 'Segoe UI';
font-size: 15px;
}
p {
color: #C0C0C0;
font-family: 'Segoe UI';
}
#description-text {
color: #C0C0C0;
font-family: 'Segoe UI';
font-size: 17px;
line-height: 25px;
text-align: center;
}
#description-image {
text-align: center;
}
#about-program-image {
text-align: center;
}
#about-program-main-text {
color: #C0C0C0;
font-family: 'Segoe UI';
font-size: 17px;
line-height: 25px;
text-align: center;
}
#about-program-text-centered {
text-align: center;
}
#about-program-changelog-main-version {
color: #C0C0C0;
font-family: 'Segoe UI';
font-size: 17px;
font-weight: 600;
}
td {
color: #C0C0C0;
font-family: 'Segoe UI';
}
th {
color: #C0C0C0;
font-family: 'Segoe UI';
}
.accordion {
background-color: #333842;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
text-align: left;
border: none;
outline: none;
transition: 0.4s;
color: #C0C0C0;
font-size: 18px;
font-family: 'Segoe UI';
}
.active, .accordion:hover {
background-color: #3a3f4b;
}
.panel {
padding: 0 18px;
background-color: #2e313b;
display: none;
overflow: hidden;
}
li {
color: #C0C0C0;
font-family: 'Segoe UI';
}
code {
color: #C0C0C0;
font-size: large;
}

View File

@@ -1,18 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<link rel = "stylesheet" type = "text/css" href = "content.css">
<meta charset = "utf-8">
<link rel = "shortcut icon" href = "../assets/documentation-page/icon.ico">
<title>Generator CSV</title>
</head>
<body>
<p id = "description-text">Program "Generator CSV" służy do przetwarzania plików danymi uczniów/nauczycieli i generowania plików wyjściowych w formacie pozwalającym na import danych na stronie szkoły oraz portal.office.com</p>
<br>
<br>
<p id = "description-image"><img width = '60%' src = '../assets/documentation-page/description/generator-csv.png'><br></p>
<p id = "description-image"><img width = '60%' src = '../assets/documentation-page/description/format-danych.png'><br></p>
<p id = "description-image"><img width = '60%' src = '../assets/documentation-page/description/ustawienia.png'><br></p>
<p id = "description-image"><img width = '60%' src = '../assets/documentation-page/description/o-programie.png'><br></p>
</body>
</html>

View File

@@ -1,30 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<link rel = "stylesheet" type = "text/css" href = "main.css">
<meta charset = "utf-8">
<link rel = "shortcut icon" href = "../assets/documentation-page/icon.ico">
<title>Generator CSV</title>
</head>
<body>
<div id = "outer">
<header>
<img id = "header-image" src = "../assets/documentation-page/icon.png">
<div id = "header-text">
<p>GENERATOR CSV</p>
</div>
<nav>
<ul id = "menu-ul">
<li id = "menu-li"><a href = "description.html" target = "content">Opis</a></li>
<li id = "menu-li"><a href = "instruction.html" target = "content">Instrukcja</a></li>
<li id = "menu-li"><a href = "program_documentation.html" target = "content">Dokumentacja</a></li>
<li id = "menu-li"><a href = "about_program.html" target = "content">O programie</a></li>
</ul>
</nav>
</header>
<section>
<iframe name = "content" src = "description.html"></iframe>
</section>
</div>
</body>
</html>

View File

@@ -1,163 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<link rel = "stylesheet" type = "text/css" href = "content.css">
<meta charset = "utf-8">
<link rel = "shortcut icon" href = "../assets/documentation-page/icon.ico">
<title>Generator CSV</title>
</head>
<body>
<button class="accordion"><b>Tworzenie/edytowanie format presetu dla danego pliku źródłowego</b></button>
<div class="panel">
<p>Dane dla przykładu:</p>
<img src = '../assets/documentation-page/instruction/example-input-data.png'><br>
<p>W praktyce układ danych wygląda tak (* - nieznaczące dla programu dane):</p>
<p>[imię] [nazwisko]<br>[klasa] [szkoła]<br>[login], [haslo*]</p>
<p>Uruchom program i otwórz zakładkę FORMAT DANYCH. W pierwszej kolejności należy nadać nazwę presetowi formatu w polu zaznaczonym poniżej lub wybrać preset już istniejący z listy rozwijanej</p>
<img width = '700px' src = '../assets/documentation-page/instruction/input-name.png'><br>
<p> Aby przejśc do edycji presetu należy wcisnąć przycisk WCZYTAJ</p>
<br>
<h5>Typ osoby</h5>
<p>Wybierz odpowiednią opcję w zależności od tego jakich osób dane znajdują się w pliku wejściowym</p>
<h5>Separator pomiędzy danymi</h5>
<p>W tym polu należy wpisać znaki, które oddzielają zbiór danych pojeńczych osób. Jeżeli zbiór danych odziela znak końca wiersza (wciśnięcie ENTER) należy wpisać &ltenter&gt (ilość zależna od ilości znaków końca wiersza). Niedozwolone znaki to litery, cyfry oraz * i \. Dla przykładowych danych będzie to "<u>&ltenter&gt&ltenter&gt</u>"</p>
<h5>Separator pomiędzy wierszami</h5>
<p>W tym polu należy wpisać znaki, które oddzielają wiersze. Zazwyczaj jest to jeden znak końca wiersza. Jeżeli wiersze odziela znak końca wiersza (wciśnięcie ENTER) należy wpisać &ltenter&gt (ilość zależna od ilości znaków końca wiersza). Niedozwolone znaki to litery, cyfry oraz * i \. Dla przykładowych danych będzie to "<b>&ltenter&gt</b>"</p>
<h5>Separatory pomiędzy danymi</h5>
<p>W tym polu należy wpisać znaki, które oddzielają pojedyńcze dane. Każdy kolejny separator musi być zapisany w następnej linijce. Jeżeli dane odziela znak końca wiersza (wciśnięcie ENTER) należy wpisać &ltenter&gt (ilość zależna od ilości znaków końca wiersza). Niedozwolone znaki to litery, cyfry oraz * i \. Dla przykładowych danych będzie to (znaki są podkreślone aby je wyróżnić):<br>"""<br><u>,<br></u><br>"""</p>
<h5>Prawa kolumna - pozycja danych w zbiorze</h5>
<p>W tej sekcji należy dla każdego typu danych ustawić jego położenie w zbiorze. Typy SZKOŁA i KLASA nie są istotne jeżeli w sekcji TYP OSOBY zosła zaznaczona opcja Nauczyciele. Dla przykładowych danych uczniów bedzie to:</p>
<table>
<tr>
<th></th>
<th>Wiersz</th>
<th>Pozycja<br>w wierszu</th>
</tr>
<tr>
<td>Login</td>
<td>3</td>
<td>1</td>
</tr>
<tr>
<td>Imię</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>Nazwisko</td>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>Szkoła</td>
<td>2</td>
<td>2</td>
</tr>
<tr>
<td>Klasa</td>
<td>2</td>
<td>1</td>
</tr>
</table>
<h5>Prawa kolumna - Kodowanie</h5>
<p>W tym polu należy wybrać kodowanie pliku wejściowego.</p>
<br>
<p><b>Aby zapisać preset należy wcisnąć przycisk ZAPISZ. Aby anulować tworzenie należy wcisnąć przycisk Anuluj</b></p>
</div>
<button class="accordion"><b>Edycja ustawień ogólnych</b></button>
<div class="panel">
<p>Uruchom program i przejdź do zakładki USTAWIENIA.</p>
<br>
<h5>Kodowanie wyjściowe dla pliku poczty</h5>
<p>W tym polu należy wybrać kodowanie, w jakim ma być zapisany plik csv z danymi uczniów do importu w panelu administracyjnym serwisu szkoły</p>
<h5>Kodowanie wyjściowe dla pliku office</h5>
<p>W tym polu należy wybrać kodowanie, w jakim ma być zapisany plik csv z danymi uczniów do importu w panelu administracyjnym serwisu portal.office.com</p>
<h5>Domena (używana w mailu)</h5>
<p>W tym polu należy wpisać domenę serwisu szkoły. Będzie ona używana w mailu każdego uzytkownika. Przykład: jan.kowalski2023a@<b>losobolew.pl</b></p>
<h5>Quota (MB)</h5>
<p>W tym polu należy wpisać ilość miejsca (w megabajtach) przeznaczoną dla każdego użytkownika na przechowywanie maili. Te dane są używane w pliku wyjściowym poczty. Przykład: jan.kowalski2023a@losobolew.pl,1234567u:JK,<b>500</b></p>
<h5>Kraj (zapisany w danych na office)</h5>
<p>W tym polu należy wpisać nazwę kraju zamieszkania użytkowników. Będzie ona wykorzystywana w pliku wyjściowym office oraz widoczna w profilu użytkownika w serwisie office. Przykład: jan.kowalski2023a@losobolew.pl,Jan,Kowalski,Jan Kowalski,uczeń,1b LO,,,,,,,,,<b>Rzeczpospolita Polska</b></p>
<h5>Nagłówek dla pliku wyjściowego poczty</h5>
<p>Jeżeli chcesz aby w pierwszej linii pliku wyjściowego dla poczty znajdował się nagłowek, zaznacz opcję "Umieść w pliku". Zawartość nagłówka można edytować w polu tekstowym po lewej.</p>
<h5>Nagłówek dla pliku wyjściowego office</h5>
<p>Jeżeli chcesz aby w pierwszej linii pliku wyjściowego dla office znajdował się nagłowek, zaznacz opcję "Umieść w pliku". Zawartość nagłówka można edytować w polu tekstowym po lewej.</p>
<h5>Rozpoczęcie roku szkolnego (DD | MM)</h5>
<p>W tych polach należy wpisać datę rozpoczęcia roku szkolnego (z reguły). W pierwszym polu (po lewo) należy wpisać dzień, a w drugim (po prawo) miesiąc. Te dane są używane do obliczania roku w znaczniku klasy (przykłądowy znacznik klasy: 2023a). W przypadku generowania plików na nowy rok szkolny przed jego rozpoczęciem, należy wprowadzić datę dzisiejszą lub wcześniejszą.</p>
<h5>Dane o szkołach</h5>
<p>W tym polu należy wprowadzić dane każdej szkoły w zespole szkół (po jednej szkole w linijce). Wymagane są trzy "kolumny danych". Są one odzielone znakami "<u>|</u>".<br>W pierwszej kolumnie należy wpisać oznaczenie szkoły (dowolne bez spacji, najlepiej jak najkrótsze). Te dane będą używane w znaczniku klasy, jeżeli w trzeciej kolumnie została wybrana opcja "1".<br>W drugiej kolmnie należy wpisać liczbę klas w danej szkole. Te dane używane są do obliczenia roku w znaczniku klasy.<br>W trzeciej kolumnie można wybrać opcję "1" lub "0" (Prawda/Fałsz). Wybierz "1" jeżeli chcesz, aby w znaczniku klasy znajdowało się oznaczenie szkoły (przykład: 2023bs). Wybierz "0" jeżeli chcesz, aby w znaczniku klasy znajdowała się litera klasy (przykład: 2023a).</p>
<br>
<p><b>Aby zapisać ustawienia należy wcisnąć przycisk ZAPISZ. Aby anulować zmiany wciśnij przycisk Anuluj</b></p>
</div>
<button class="accordion"><b>Generowanie plików wyjściowych</b></button>
<div class="panel">
<h5>Krok 1</h5>
<p>W pierwszej kolejności należy przygotować pliki wejściowe oraz stworzyć presety formatu dla tych plików, według instrukcji w sekcji "Tworzenie/edytowanie format presetu dla danego pliku źródłowego" (jednego presetu formatu można używac do kilku plików jeżeli pliki mają ten sam format i to samo kodowanie)</p>
<h5>Krok 2</h5>
<p>Przejdź do zakładki GENERATOR CSV. Możesz przetworzyć naraz 4 pliki wejściowe. Dla każdego pliku należy wybrać jego lokalizację (wpisać ją w polu, oznaczonym kolorem czerwonym na poniższym zdjęciu, lub otworzyć okno wyboru lokalizacji za pomocą przycisku "Przeglądaj" i tam wybrać plik. Następnie należy wybrać preset formatu, odpowiedni dla pliku wejściowego, w polu oznaczonym kolorem zielonym na poniższym zdjęciu.</p>
<img width = '700px' src = '../assets/documentation-page/instruction/generate-input-file-settings.png'><br>
<h5>Krok 3</h5>
<p>Wybierz lokalizację zapisu pliku wyjściowego dla serwisu szkoły, wpisując lokalizację wraz z nazwą pliku w polu, oznaczonym kolorem czerwonym na poniższym zdjęciu, lub otwierając okno wyboru lokalizacji za pomocą przycisku "Przeglądaj" obok tego pola i tam wybierając plik.<br>Wybierz lokalizację zapisu pliku wyjściowego dla serwisu portal.office.com, wpisując lokalizację wraz z nazwą pliku w polu, oznaczonym kolorem zielonym na poniższym zdjęciu, lub otwierając okno wyboru lokalizacji za pomocą przycisku "Przeglądaj" obok tego pola i tam wybierając plik.</p>
<img width = '700px' src = '../assets/documentation-page/instruction/generate-output-file-settings.png'><br>
<h5>Krok 4</h5>
<p>Aby rozpocząć generowanie wciśnij przycisk START i potwierdź komunikat. Pliki wyjściowe zostaną zapisane w wybranych lokalizacjach. Przed importem upewnij się że w plikach nie występują błędy.</p>
</div>
<button class="accordion"><b>Usuwanie presetów formatu</b></button>
<div class="panel">
<h5>Krok 1</h5>
<p>Uruchom program i przejdź do zakładki USTAWIENIA.</p>
<h5>Krok 2</h5>
<p>Naciśnij przycisk "Zarządzaj presetami formatu".</p>
<h5>Krok 3</h5>
<p>Zaznacz presety formatu które chcesz usunąć.</p>
<h5>Krok 4</h5>
<p>Naciśnij przycisk "Usuń zaznaczone"</p>
</div>
<button class="accordion"><b>Przywracanie domyślnych ustawień ogólnych programu</b></button>
<div class="panel">
<h5>Krok 1</h5>
<p>Uruchom program i przejdź do zakładki USTAWIENIA.</p>
<h5>Krok 2</h5>
<p>Naciśnij przycisk "Przywróć domyślne ustawienia ogólne". Po potwierdzeniu i ponownym uruchomieniu programu, ustawienia zostaną przywrócone do ustawień fabrycznych.</p>
</div>
<button class="accordion"><b>Przywracanie domyślnego wyglądu programu</b></button>
<div class="panel">
<h5>Krok 1</h5>
<p>Uruchom program i przejdź do zakładki USTAWIENIA.</p>
<h5>Krok 2</h5>
<p>Naciśnij przycisk "Przywróć domyślne ustawienia wyglądu". Po potwierdzeniu i ponownym uruchomieniu programu, wygląd zostanie przywrócony do ustawień fabrycznych.</p>
</div>
<button class="accordion"><b>Zaawansowana edycja ustawień programu i wyglądu</b></button>
<div class="panel">
<h5>Krok 1</h5>
<p>Otwórz menu start i wpisz "%appdata%"</p>
<h5>Krok 2</h5>
<p>Przejdź do folderu "Generator CSV"</p>
<h5>Krok 3</h5>
<p>Za ustawienia programu odpowiedzialny jest plik "config.cfg", a za wygląd plik "style.cfg". Użyj dowolnego edytora plików tekstowych, do edycji tych plików. Więcej informacji o tych plikach znajduje się w Dokumentacji technicznej.<br>Aby przywrócić te pliki do stanu fabrycznego wykonaj kroki z sekcji odpowiednio "Przywracanie domyślnych ustawień ogólnych programu" lub "Przywracanie domyślnego wyglądu programu"</p>
</div>
<script>
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
}
</script>
</body>
</html>

View File

@@ -1,80 +0,0 @@
body, html{
background-color: #21242D;
margin: 0px;
height: 100%;
width: 100%;
}
header {
width: 100%;
position: sticky;
}
#header-image {
background-color: #333842;
width: 100px;
height: 100px;
float: left;
padding: 25px;
}
#header-text {
background-color: #333842;
overflow: auto;
line-height: 40px;
font-family: 'Segoe UI';
color: #C0C0C0;
font-size: 30px;
padding: 25px;
}
nav {
width: 100%;
}
#menu-ul {
width: 100%;
height: 50px;
padding: 0;
margin: 0;
list-style: none;
}
#menu-li a {
display: block;
float: left;
text-align: center;
font-family: 'Segoe UI';
margin-right: 0.05%;
margin-left: 0.05%;
font-size: 20px;
width: 24.9%;
line-height: 50px;
text-decoration: none;
color: #C0C0C0;
background-color: #2e313b;
}
#menu-li a:hover {
color: #C0C0C0;
background: #333842;
}
section {
width: 100%;
}
iframe {
float: left;
width: 100%;
border: none;
height: calc(100% - 220px);
overflow: scroll;
position: absolute;
}

View File

@@ -1,388 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<link rel = "stylesheet" type = "text/css" href = "content.css">
<meta charset = "utf-8">
<link rel = "shortcut icon" href = "../assets/documentation-page/icon.ico">
<title>Generator CSV</title>
</head>
<body>
<button class="accordion"><b>generator.pyw - WPROWADZENIE</b></button>
<div class="panel">
<p>Aby móc uruchomić aplikację w wersji developerskiej należy pobrać Pythona (wersja zalecana: 3.8.5) oraz wymagane biblioteki (wymienione w sekcji 'generator.pyw - Import bibliotek')</p>
</div>
<button class="accordion"><b>generator.pyw - Import bibliotek</b></button>
<div class="panel">
<p>
<b>Biblioteki główne</b><br>
<br>
W tej sekcji importowane są wszystkie biblioteki niezwiązane z interfejsem graficznych<br>
<ul>
<li>sys (SS) - używana tylko do zamykania programu</li>
<li>os (OS) - odpowiedzialna za polecenia w terminalu</li>
<li>time (TM) - używana do pobierania aktualnej daty i czasu</li>
<li>codecs (CD) - odpowiedzialna za otwieranie i czytanie plików w odpowiednim kodowaniu</li>
<li>pathlib (PT) - używana tylko do pozyskania ścieżki katalogu APPDATA</li>
<li>shutil (SU) - odpowiedzialna za operacje na plikach i folderach</li>
</ul>
</p>
<p>
<br>
<b>Biblioteki interfejsu graficznego</b><br>
<br>
W tej sekcji importowane są wszystkie biblioteki związane z interfejsem graficznym
<br>
<ul>
<li>tkinter (TK) - główne środowisko budowy interfejsu graficznego</li>
<ul>
<li>ttk (TKttk) - biblioteka odpowiedzialna za kontrolki i ich wygląd</li>
<li>messagebox (TKmsb) - biblioteka odpowiedzialna za wyświetlanie komunikatów dialogowych</li>
<li>filedialog (TKfld) - biblioteka odpowiedzialna za wyświetlanie okien wyboru plików</li>
</ul>
<li>PIL (PL), (PLitk), (PLimg) - biblioteka odpowiedzialna za wyświetlanie obrazów</li>
</ul>
</p>
</div>
<button class="accordion"><b>generator.pyw - Główne zmienne globalne</b></button>
<div class="panel">
<p>
<b>Informacje o programie</b><br>
<br>
<code>programName</code> - Zmienna definująca nazwę programu<br>
<code>programVersion</code> - Zmienna definiująca główną wersję programu<br>
<code>programVersionStage</code> - Zmienna definiująca etap rozwoju programu. Wersja stabilna definiowana jest przez pusty string<br>
<code>programVersionBuild</code> - Zmienna definiująca numer buildu programu. Zapisany jest on w formacie '[ostatnie dwie cyfry roku][numer dnia w roku]'<br>
<code>programCustomer</code> - Zmienna definiująca nazwę organizacji zlecającej stworzenie programu<br>
<code>programAuthors</code> - Lista zawierająca nazwy osób rozwijających program.<br>
<code>programToW</code> - Lista zawierająca informacje na temat czasu rozwoju programu. Format: ['miesiąc rozpoczęcia prac', 'rok rozpoczęcia prac', 'aktualny dla rozwoju danej wersji miesiąc', 'aktualny dla rozwoju danej wersji rok']<br>
<br>
<br>
<b>Dozwolone kodowanie plików</b><br>
<br>
<code>allowedCoding</code> - Lista zawierająca wspierane kodowania plików. Są one wyświetlane w rozwijanych listach wyboru kodowania pliku.<br>
<br>
<br>
<b>Dozwolone znaki</b><br>
<br>
<code>allowedCharactersInSeparator</code> - Lista zawierająca znaki które można wpisać w pola dotyczące separatorów osób, linii i danych<br>
<br>
<br>
<b>Katalog APPDATA</b><br>
<br>
<code>appdataPath</code> - zmienna definiująca ścieżkę do folderu %appdata%
</p>
</div>
<button class="accordion"><b>generator.pyw - Okna dialogowe</b></button>
<div class="panel">
<p>
<b>Lista komunikatów</b><br>
<br>
Słownik <code>MSGlist</code> zawiera listę komunikatów. Format: '[kod dialogowy]' : '[komunikat]'. Kod dialogowy składa się z [jednoznakowego znacznika rodzaju okna dialogowego][czterocyfrowego numeru komunikatu]<br>
<br>
<br>
<b><i>Rodzaje okien dialogowych:</i></b>
<ul>
<li>E - komunikaty błędów</li>
<li>I - komunikaty informacyjne</li>
<li>W - komunikaty ostrzegające</li>
<li>A - komunikaty zapytania</li>
</ul>
</p>
<p>
<br>
<b>Funkcja odpowiedzialna za wywoływanie komunikatów dialogowych</b><br>
<br>
Wywoływanie funkcji: <code>MSG(</code>[kod dialogowy]<code>,</code>[<code>True</code> - Zakończ działanie programu po zamknięciu okna dialogowego/<code>False</code> - Kontynuuj działanie programu po zamknięciu okna dialogowego]<code>,</code>[dodatkowe informacje wyświetlane w komunikacie - <b>opcjonalnie</b>]<code>)</code><br>
<br>
<code>
try:<br>
optionalInfo[0]<br>
except:<br>
optionalInfo = ['']<br>
</code>
Sprawdza czy zostały wpisane 'dodatkowe informacje wyświetlane w komunikacie' i jeżeli nie, definiuje listę, w której znajduje się pusty string (ma to na celu uniknięcia błędu podczas próby wywołania dodatkowych informacji przez dalszą część funkcji)<br>
<br>
<code>
if code[0] == 'E/I/W':<br>
TKmsb.showerror/showinfo/showwarning('</code>[tytuł komunikatu]<code>', '%s\n%s' % (MSGlist[code], optionalInfo[0]))<br>
</code>
Wywoływanie danego rodzaju komunikatu na podstawie jednoznakowego znacznika rodzaju okna dialogowego.<br>
<br>
<code>
if terminate:<br>
SS.exit(0)<br>
</code>
Zakończenie działania programu po zamknięciu okna dialogowego, jeżeli została ustawiona opdowiednia opcja.<br>
<br>
<code>
elif code[0] == 'A':<br>
if TKmsb.askokcancel('Pytanie', '%s\n%s' % (MSGlist[code], optionalInfo[0])):<br>
return True<br>
else:<br>
return False<br>
</code>
Funkcja zwraca wartość boolean w przypadku wywołania komunikatu zapytania
</p>
</div>
<button class="accordion"><b>generator.pyw - Sprawdzanie katalogu programu w APPDATA</b></button>
<div class="panel">
<p>
Klasa <code>checkAppdata</code> odpowiedzialna jest za sprawdzenie poprawności i, w razie potrzeby, doprowadzenie go do stanu poprawności.
<br>
<br>
<b>Główna funkcja programu</b><br>
<br>
1. Czy w folderze %appdata% istnieje folder programu (Generator CSV)?<br>
Jeżeli nie istnieje, uruchamiana jest funckja <code>__buildAppdata</code> (odpowiedzialna za zbudowanie całości katalogu programu).<br>
2. Czy w folderze programu istnieje plik 'version' (przechowuje on numer buildu programu, w którym został zbudowany katalog programu)?<br>
Jeżeli nie istnieje, uruchamiane jest okno dialogowe zapytania z pytaniem czy pozwolić na zresetowanie katalogu programu i kontynuować ładowanie programu<br>
3. Czy numer buildu programu w pliku 'version' jest zgodny z numerem buildu zawartym w zmiennej <code>VAR.programVersionBuild</code><br>
Jeżeli nie, uruchamiane jest okno dialogowe zapytania z pytaniem czy pozwolić na zresetowanie katalogu programu i kontynuować ładowanie programu<br>
Jeżeli tak, sprawdzane są poszczególne pliki i foldery które powinny być zawarte w folderze, i jeżeli któryś plik/folder nie znajduje się w folderze, wywołuje się funkcje mające na celu przywrócenie/utworzenie tych plików/folderów (odpowiednio: <code>__restoreCFG</code> dla plików konfiguracyjnych, <code>__createFormatPresetsDir</code> dla folderu przechowującego format presety)<br>
<br>
<br>
<b>Budowanie katalogu programu</b> (<code>__buildAppdata</code>)<br>
<br>
Funkcja ta, jest odpowiedzialna za zbudowanie całości katalogu programu w folderze %appdata%.<br>
1. Tworzenie katalogu 'Generator CSV'<br>
2. Tworzenie pliku 'version' i zapisanie w nim numeru buildu.<br>
3. Inicjacja funkcji <code>__restoreCFG</code> (w celu skopiowania pliku 'config.cfg' z głównego katalogu programu do katalogu 'Generator CSV' w folderze %appdata%).<br>
4. Inicjacja funkcji <code>__restoreCFG</code> (w celu skopiowania pliku 'style.cfg' z głównego katalogu programu do katalogu 'Generator CSV' w folderze %appdata%).<br>
5. Inicjacja funkcji <code>__createFormatPresetsDir</code> (w celu stworzenia folderu 'format-presets' przechowującego format presety)<br>
<br>
<br>
<b>Resetowanie katalogu programu</b> (<code>__resetAppdata</code>)<br>
<br>
Funkcja ta, jest odpowiedzialna za przywrócenie katalogu programu w folderze %appdata% do stanu podstawowego oraz stworzenie kopii zapasowej starego katalogu.<br>
1. W przypadku gdy w katalogu istnieje jeszcze starsza kopia zapasowa folderu, kopia ta jest usuwana.<br>
2. Nazwa katalogu programu jest zmieniana na taką z dopiskiem '_old'.<br>
3. Inicjacja funkcji <code>__buildAppdata</code> w celu zbudowania nowego katalogu programu<br>
4. Skopiowanie katalogu 'Generator CSV_old' do nowego katalogu 'Generator CSV'<br>
<br>
<br>
<b>Przywracanie plików konfiguracyjnych</b> (<code>__restoreCFG</code>)<br>
<br>
Funkcja ta, jest odpowiedzialna za skopiowanie pliku konfiguracyjnego (.cfg) o danej nazwie z głównego katalogu programu do katalogu programu w folderze %appdata%<br>
<br>
<br>
<b>Tworzenie katalogu przechowującego format presety</b> (<code>__createFormatPresetsDir</code>)<br>
<br>
Funkcja ta, jest odpowiedzialna za utworzenie folderu 'format-presets', przechowującego format presety, w katalogu programu w folderze %appdata%
</p>
</div>
<button class="accordion"><b>generator.pyw - Ładowanie głównego pliku konfiguracyjnego 'config.cfg'</b></button>
<div class="panel">
<p>
Klasa <code>CFG</code> odpowiedzialna jest za zarządzanie plikiem konfiguracyjnym 'config.cfg'<br>
<br>
<br>
<b>Odczytywanie pojedyńczej zmiennej z pliku</b> (<code>R</code>)<br>
<br>
Funkcja ta, jest odpowiedzialna za odczytanie zawartości danego recordu i sprawdzenie jego poprawności<br>
1. Inicjacja funkcji <code>__checkIfFileExist</code> w celu sprawdzenia czy plik 'config.cfg' istnieje<br>
2. Zczytanie i zapisanie wszystkich danych z pliku 'config.cfg' do słownika <code>content</code> w formacie: 'nazwa zmiennej' : ['zmienna', 'typ zmiennej']<br>
3. Inicjacja funckji <code>__checkIfRecordExist</code> w celu sprawdzenia czy w słowniku <code>content</code> znajduje się żądany record<br>
4. Inicjacja, odpowiedniej dla typu zmiennej, funkcji mającej na celu sprawdzenie jej poprawności i jej przetworzenie<br>
5. Funkcja zwraca wartość zmiennej.<br>
<br>
<br>
<b>Zapisywanie zmian w pliku</b> (<code>W</code>)<br>
<br>
Funkcja ta jest odpowiedzialna za sprawdzenie, przetworzenie i zapisanie zmian w pliku konfiguracyjnych.<br>
1. Inicjacja funkcji <code>__checkIfFileExist</code> w celu sprawdzenia czy plik 'config.cfg' istnieje<br>
2. Zczytanie i zapisanie wszystkich danych z pliku 'config.cfg' do słownika <code>content</code> w formacie: 'nazwa zmiennej' : ['zmienna', 'typ zmiennej']<br>
3. Inicjacja, odpowiedniej dla typu zmiennej, funkcji mającej na celu sprawdzenie jej poprawności i jej przetworzenie, dla każdego recordu ze słownika <code>changes</code><br>
4. Nadpisanie zmiennej ze słownika content, wartością <code>var</code>.<br>
5. Zapisanie zawartości słownika <code>content</code> w pliku 'config.cfg'<br>
6. Funkcja zwraca <code>True</code> jeżeli operacja została wykonana pomyślnie lub <code>False</code> jeżeli wystąpił błąd<br>
<br>
<br>
<b>Funkcje sprawdzające istnienie</b><br>
<br>
<code>__checkIfFileExist</code> - funkcja sprawdza czy plik istnieje i możliwe jest jego nadpisanie (w przypadku zapisu)<br>
<code>__checkIfRecordExist</code> - funkcja sprawdza czy <code>record</code> istnieje w słowniku <code>content</code><br>
<br>
<br>
<b>Funkcje sprawdzające poprawność recordu</b><br>
<br>
Funkcje te odpowiadają za sprawdzenie poprawności zmiennej i w razie potrzeby przetwarzają ją na pożądaną formę.
</p>
</div>
<button class="accordion"><b>generator.pyw - Ładowanie pliku konfiguracyjnego stylu 'style.cfg'</b></button>
<div class="panel">
<p>
Klasa <code>GUI</code> odpowiedzialna jest za zarządzanie plikiem konfiguracyjnym 'style.cfg'<br>
<br>
<br>
<b>Odczytywanie pojedyńczej zmiennej z pliku</b> (<code>R</code>)<br>
<br>
Funkcja ta, jest odpowiedzialna za odczytanie zawartości danego recordu i sprawdzenie jego poprawności<br>
1. Inicjacja funkcji <code>__checkIfFileExist</code> w celu sprawdzenia czy plik 'style.cfg' istnieje<br>
2. Zczytanie i zapisanie wszystkich danych z pliku 'style.cfg' do słownika <code>content</code> w formacie: 'nazwa zmiennej' : ['zmienna', 'typ zmiennej']<br>
3. Inicjacja funkcji <code>__checkIfRecordExist</code> w celu sprawdzenia czy w słowniku <code>content</code> znajduje się żądany record<br>
4. Inicjacja, odpowiedniej dla typu zmiennej, funkcji mającej na celu sprawdzenie jej poprawności i jej przetworzenie<br>
Funkcja zwraca wartość zmiennej.<br>
<br>
<br>
<b>Funkcje sprawdzające istnienie</b><br>
<br>
<code>__checkIfFileExist</code> - funkcja sprawdza czy plik istnieje<br>
<code>__checkIfRecordExist</code> - funkcja sprawdza czy <code>record</code> istnieje w słowniku <code>content</code><br>
<br>
<br>
<b>Funkcje sprawdzające poprawność recordu</b><br>
<br>
Funkcje te odpowiadają za sprawdzenie poprawności zmiennej i w razie potrzeby przetwarzają ją na pożądaną formę.
</p>
</div>
<button class="accordion"><b>generator.pyw - Zarządzanie plikami formatu</b></button>
<div class="panel">
<p>
Klasa <code>FMT</code> odpowiedzialna jest za zarządzanie plikami formatu (.fmt)<br>
<br>
<br>
<b>Odczytywanie pojedyńczej zmiennej z pliku</b> (<code>R</code>)<br>
<br>
Funkcja ta, jest odpowiedzialna za odczytanie zawartości danego recordu i sprawdzenie jego poprawności<br>
1. Inicjacja funkcji <code>__checkIfFolderExist</code> w celu sprawdzenia czy folder 'format-presets' istnieje<br>
2. Sprawdzenie czy podany plik formatu (<code>preset</code>) znajduje się w folderze 'format-presets' (funkcja <code>getList</code> zwraca listę plików formatu w folderze 'format-presets')<br>
Jeżeli nie, wartość zmiennej jest wybierana ze słownika <code>content</code> (zawierającego podstawowe wartości zmiennych)<br>
Jeżeli tak:
3. Zczytanie i zapisanie wszystkich danych z wybranego pliku formatu do słownika <code>content</code> w formacie: 'nazwa zmiennej' : ['zmienna', 'typ zmiennej']<br>
4. Inicjacja funkcji <code>__checkIfRecordExist</code> w celu sprawdzenia czy w słowniku <code>content</code> znajduje się żądany record<br>
5. Inicjacja, odpowiedniej dla typu zmiennej, funkcji mającej na celu sprawdzenie jej poprawności i jej przetworzenie<br>
Funkcja zwraca wartość zmiennej.<br>
<br>
<br>
<b>Zapisywanie zmian w pliku</b> (<code>W</code>)<br>
<br>
Funkcja ta jest odpowiedzialna za sprawdzenie, przetworzenie i zapisanie zmian w pliku konfiguracyjnych.<br>
1. Inicjacja funkcji <code>__checkIfFolderExist</code> w celu sprawdzenia czy folder 'format-presets' istnieje<br>
2. Sprawdzenie czy podany plik formatu (<code>preset</code>) znajduje się w folderze 'format-presets' (funkcja <code>getList</code> zwraca listę plików formatu w folderze 'format-presets')<br>
Jeżeli nie, tworzony jest słownik <code>content</code> z zawartością podstawową
Jeżeli tak: Zczytanie i zapisanie wszystkich danych z wybranego pliku formatu do słownika <code>content</code> w formacie: 'nazwa zmiennej' : ['zmienna', 'typ zmiennej']<br>
3. Inicjacja, odpowiedniej dla typu zmiennej, funkcji mającej na celu sprawdzenie jej poprawności i jej przetworzenie, dla każdego recordu ze słownika <code>changes</code><br>
4. Nadpisanie zmiennej ze słownika content, wartością <code>var</code>.<br>
5. Zapisanie zawartości słownika <code>content</code> w pliku 'config.cfg'<br>
6. Funkcja zwraca <code>True</code> jeżeli operacja została wykonana pomyślnie lub <code>False</code> jeżeli wystąpił błąd<br>
<br>
<br>
<b>Funkcja zwracająca listę presetów</b> (<code>getList</code>)<br>
<br>
Funkcja ta odpowiedzialna jest za stworzenie listy plików .fmt w folderze 'format-presets' oraz za jej zwrócenie.<br>
<br>
<br>
<b>Funkcje sprawdzające istnienie</b><br>
<br>
<code>__checkIfFolderExist</code> - funkcja sprawdza czy folder 'format-presets' istnieje (inicjuje <code>checkAppdata</code>)<br>
<code>__checkIfRecordExist</code> - funkcja sprawdza czy <code>record</code> istnieje w słowniku <code>content</code><br>
<br>
<br>
<b>Funkcje sprawdzające poprawność recordu</b><br>
<br>
Funkcje te odpowiadają za sprawdzenie poprawności zmiennej i w razie potrzeby przetwarzają ją na pożądaną formę.
</p>
</div>
<button class="accordion"><b>generator.pyw - Przetwarzanie plików</b></button>
<div class="panel">
<p>
Klasa <code>dataProcess</code> odpowiedzialna za przetwarzanie plików wejściowych i generowanie plików wyjściowych<br>
<br>
<br>
<b>Główna funkcja klasy</b> (<code>start</code>)<br>
<br>
Funkcja ta odpowiedzialna za zainicjowanie kolejnych funkcji w odpowiedniej kolejności oraz zwrócenie informacji o błędach lub pomyślnym wykonaniu polecenia<br>
1. Inicjacja funkcji <code>__checkIfAtLeastOneInputFileIsFilled</code> w celu sprawdzenia czy przynajmniej jedno pole plików wejściowych zostało wypełnione<br>
2. Inicjacja funkcji <code>__checkIfInputFilesIsReadable</code> w celu sprawdzenia czy pliki wejściowe, do których ścieżki zostały podane, są możliwe do odczytania<br>
3. Inicjacja funkcji <code>__checkIfInputFilesFormatPresetsExist</code> w celu sprawdzenia czy format presety, które zostały wybrane, istnieją<br>
4. Inicjacja funkcji <code>__getData</code> w celu zebrania danych z plików wejściowych<br>
5. Dla każdego zbioru danych - <code>for x in data</code> (dla każdej osoby), inicjacja funkcji <code>__checkLogin</code>, <code>__checkFname</code>, <code>__checkLname</code>, oraz dla uczniów <code>__checkSchool</code>, <code>__checkClass</code>, w celu sprawdzenia poprawności danych<br>
6. Inicjacja funkcji <code>__processData</code> w celu przetworzenia danych w linie gotowe do zapisania w plikach wyjściowych<br>
7. Inicjacja funkcji <code>__checkIfCreatingOutputFilesIsPossible</code> w celu sprawdzenia czy możliwe jest utworzenie plików wyjściowych<br>
8. Inicjacja funkcji <code>__saveData</code> w celu zapisania danych w plikach wyjściowych<br>
Funkcja zwraca listę zawierającą zmienne boolean potwierdzające w którym momencie zakończyło się wykonywanie funkcji (z powodu błędu lub pomyślnego ukończenia operacji)<br>
<br>
<br>
<b>Funkcje sprawdzające istnienie</b>
<br>
<code>__checkIfAtLeastOneInputFileIsFilled</code> - sprawdza czy przynajmniej jedno pole plików wejściowych zostało wypełnione oraz zwraca dane z wypełnionych pól<br>
<code>__checkIfInputFilesIsReadable</code> - sprawdza czy pliki wejściowe są możliwe do odczytania<br>
<code>__checkIfInputFilesFormatPresetsExist</code> - sprawdza czy wybrane format presety istnieją<br>
<code>__checkIfCreatingOutputFilesIsPossible</code> - sprawdza czy utworzenie plików wyjściowych jest możliwe<br>
<br>
<br>
<b>Funkcje sprawdzające poprawność</b>
<br>
Funkcje te sprawdzają poprawność określonych typów danych.
<br>
<br>
<b>Wyodrębnienie danych z plików</b> (<code>__getData</code>)<br>
<br>
Funkcja odpowiedzialna jest za wyodrębnienie danych z pliku (<code>path</code>) na podstawie określonego format presetu (<code>format</code>)
Dla każdego zbioru ścieżek plików wejściowych i format presetów (<code>for x in input</code>):<br>
1. Pobranie danych z pliku formatu (za pomocą funkcji <code>FMT.R</code>)<br>
2. Pobranie zawartości z pliku wyjściowego i podzielenie ich na zbiory danych pojedyńczych osób (<code>.split(personseparator)</code>)<br>
Dla każdego zbioru danych pojedyńczych osób (<code>for x in file</code>):<br>
3. Dzielenie zbioru danych na linie (<code>x.split(linesSeparator)</code>)<br>
4. Dla każdej linii: dzielenie danych na pojedyńcze segmenty separatorami z listy <code>dataSeparators</code><br>
5. Wyodrębnienie wymaganych danych ze zbioru<br>
6. Dodanie danych pojedyńczej osoby do listy <code>data</code><br>
<br>
<br>
<b>Przetworzenie danych</b> (<code>__processData</code>)<br>
<br>
Funkcja odpowiedzialna jest za przetworzenie danych w linie gotowe do zapisania w plikach wyjściowych<br>
Funkcja zwraca listę <code>[mailData, officeData]</code><br>
<br>
<br>
<b>Zapisanie danych</b> (<code>__saveData</code>)<br>
<br>
Funkcja odpowiedzialna jest za zapisanie danych w plikach wyjściowych dla poczty i dla office
</p>
</div>
<button class="accordion"><b>generator.pyw - GUI</b></button>
<div class="panel">
<p>
Klasa <code>GUI</code> odpowiada za interfejs programu<br>
<br>
<br>
<b>1. Główna funkcja programu</b><br>
<br>
- Stworzenie okna<br>
- Inicjacja styli kontrolek<br>
- Kontrolki<br>
<br>
<br>
<b>Akcje przycisków</b><br>
<br>
Funkcje inicjowane przez naciśnięcie przycisków
</p>
</div>
<script>
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
}
</script>
</body>
</html>

BIN
icon.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

2
requirements.txt Normal file
View File

@@ -0,0 +1,2 @@
pillow==9.0.1
tk

View File

@@ -1,15 +1,3 @@
"""
# Generator CSV
# Wersja 4.0
# Autorzy: Mateusz Skoczek
# styczeń 2019 - wrzesień 2020
# dla ZSP Sobolew
"""
# ------------------------------------- # Import bibliotek # ------------------------------------ #
# Biblioteki główne
@@ -19,7 +7,7 @@ import time as TM
import codecs as CD
import pathlib as PT
import shutil as SU
import webbrowser as WB
# Biblioteki interfejsu graficznego
import tkinter as TK
@@ -39,9 +27,8 @@ from PIL import Image as PLimg
class VAR:
# Informacje o programie
programName = 'Generator CSV'
programVersion = '4.0'
programVersionStage = ''
programVersionBuild = '20254'
programVersionBuild = '26000'
programCustomer = 'ZSP Sobolew'
programAuthors = ['Mateusz Skoczek']
programToW = ['styczeń', '2019', 'wrzesień', '2020']
@@ -80,7 +67,6 @@ MSGlist = {
'E0013' : 'Nie można utworzyć plików wejściowych',
'E0014' : 'Nie można zapisać plików wejściowych',
'E0015' : 'Nie można usunąć wybranych format presetów',
'E0016' : 'Nie można uruchomić pliku instrukcji (documentation/index.html)',
'E0017' : 'Nie można zapisać pliku formatu',
'A0001' : 'Czy chcesz zapisać? Zostanie utworzony nowy plik',
'A0002' : 'Czy chcesz zapisać? Plik zostanie nadpisany',
@@ -197,7 +183,7 @@ class checkAppdata:
# Przywracanie plików konfiguracyjnych
def __restoreCFG(self, configFileName):
try:
SU.copy(('configs\%s.cfg' % configFileName), str(VAR.appdataPath) + ('\Generator CSV\%s.cfg' % configFileName))
SU.copy(OS.path.join(OS.path.dirname(OS.path.abspath(__file__)), ('configs\%s.cfg' % configFileName)), str(VAR.appdataPath) + ('\Generator CSV\%s.cfg' % configFileName))
except Exception as exceptInfo:
MSG('E0001', True, exceptInfo)
@@ -690,6 +676,7 @@ class GUI:
return [True, var]
def __checkP(self, record, var):
var = OS.path.join(OS.path.dirname(OS.path.abspath(__file__)), var.replace("/","\\"))
try:
check = open(var)
except:
@@ -1310,11 +1297,11 @@ class mainWindow:
def __init__(self, master):
# Okno
self.master = master
master.title('%s %s %s' % (VAR.programName, VAR.programVersion, VAR.programVersionStage))
master.title('%s %s %s' % (VAR.programName, CFG.R('version'), VAR.programVersionStage))
master.geometry('%ix%i' % (GUI.R('windowWidth'), GUI.R('windowHeight')))
master.resizable(width = GUI.R('windowWidthResizable'), height = GUI.R('windowHeightResizable'))
master.configure(bg = GUI.R('windowMainBG'))
master.iconbitmap(GUI.R('mainIcon'))
master.iconbitmap(OS.path.join(OS.path.dirname(OS.path.abspath(__file__)), GUI.R('mainIcon')))
@@ -2826,7 +2813,7 @@ class mainWindow:
# Wersja programu
self.aboutInfoProgramNameLabel = TKttk.Label(self.aboutInfoFrame)
self.aboutInfoProgramNameLabel.config(style = 'label1.TLabel')
self.aboutInfoProgramNameLabel.config(text = 'Wersja %s %s (Build %s)' % (VAR.programVersion, VAR.programVersionStage, VAR.programVersionBuild))
self.aboutInfoProgramNameLabel.config(text = 'Wersja %s %s (Build %s)' % (CFG.R('version'), VAR.programVersionStage, VAR.programVersionBuild))
self.aboutInfoProgramNameLabel.pack()
# (3) Pozostałe informacje ##############
@@ -3207,7 +3194,7 @@ class mainWindow:
self.ZPFWindow.geometry('%ix%i' % (GUI.R('ZPFWindowWidth'), GUI.R('ZPFWindowHeight')))
self.ZPFWindow.resizable(width = GUI.R('ZPFWindowWidthResizable'), height = GUI.R('ZPFWindowHeightResizable'))
self.ZPFWindow.configure(bg = GUI.R('ZPFWindowMainBG'))
self.ZPFWindow.iconbitmap(GUI.R('mainIcon'))
self.ZPFWindow.iconbitmap(OS.path.join(OS.path.dirname(OS.path.abspath(__file__)), GUI.R('mainIcon')))
# Wybór format presetu - listbox
self.selectFPListbox = TK.Listbox(self.ZPFWindow)
@@ -3231,10 +3218,7 @@ class mainWindow:
self.deleteSelectedFPButton.pack(fill = TK.X, padx = 6, pady = 6)
def aboutInstructionButtonAction(self):
try:
OS.startfile('documentation\index.html')
except Exception as exceptInfo:
MSG('E0016', False, exceptInfo)
WB.open("https://repos.mateuszskoczek.com/MateuszSkoczek/GeneratorCSV/wiki", new = 2, autoraise = True)

BIN
src/assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 426 B

After

Width:  |  Height:  |  Size: 426 B

View File

Before

Width:  |  Height:  |  Size: 623 B

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,12 +1,13 @@
secret(S) = entersecretstringhere
mailOutputCoding(Sc) = utf-8
officeOutputCoding(Sc) = utf-8
domain(S) = losobolew.pl
quota(I) = 500
country(S) = Rzeczypospolita Polska
schoolData(MSAs) = [LO, 4, 0]|[BS, 3, 1]
schoolyearStart(D) = 01.09.* *:*:*
ifHeadlineInMail(B) = 0
headlineInMail(S) = mailHeadline
ifHeadlineInOffice(B) = 0
version(S) = WIP
secret(S) = entersecretstringhere
mailOutputCoding(Sc) = utf-8
officeOutputCoding(Sc) = utf-8
domain(S) = losobolew.pl
quota(I) = 500
country(S) = Rzeczypospolita Polska
schoolData(MSAs) = [LO, 4, 0]|[BS, 3, 1]
schoolyearStart(D) = 01.09.* *:*:*
ifHeadlineInMail(B) = 0
headlineInMail(S) = mailHeadline
ifHeadlineInOffice(B) = 0
headlineInOffice(S) = officeHeadline

View File

@@ -1,152 +1,152 @@
windowWidth(I) = 1200
windowHeight(I) = 720
windowWidthResizable(B) = 0
windowHeightResizable(B) = 0
windowMainBG(C) = #21242D
mainIcon(P) = icon.ico
mainMenuBG(C) = #21242D
mainMenuPosition(FAposition) = wn
tabFramesBorderWidth(I) = 0
unselectedTabBG(C) = #21242D
menuTabsBorderWidth(I) = 0
menuTabsPadding(I) = 10
selectedTabBG(C) = #333842
disabledTabBG(C) = #333842
tabFrameBG(C) = #21242D
headerFont(F) = Segoe UI;15
headerBG(C) = #333842
headerTextColor(C) = #C0C0C0
headerPadding(I) = 10
headerTextAnchor(FAanchor) = center
contentTabFrameBG(C) = #21242D
layoutFrameBG(C) = #21242D
label1BG(C) = #21242D
label1TextColor(C) = #C0C0C0
label1Font(F) = Segoe UI;10
label2BG(C) = #21242D
label2TextColor(C) = #C0C0C0
label2Font(F) = Segoe UI;9
label3BG(C) = #21242D
label3TextColor(C) = #C0C0C0
label3Font(F) = Segoe UI;7
label4BG(C) = #21242D
label4TextColor(C) = #C0C0C0
label4Font(F) = Segoe UI;25
combobox1ArrowColor(C) = #C0C0C0
combobox1ButtonColor(C) = #333842
combobox1BorderColor(C) = #21242D
combobox1FieldBackground(C) = #333842
combobox1TextColor(C) = #C0C0C0
combobox1Relief(FArelief) = flat
combobox1BorderWidth(I) = 0
combobox1Padding(I) = 5
combobox1ListBoxBackground(C) = #333842
combobox1ListBoxForeground(C) = #C0C0C0
combobox1ListBoxSelectBackground(C) = #737373
combobox1ListBoxSelectForeground(C) = #FFFFFF
combobox2ArrowColor(C) = #C0C0C0
combobox2ButtonColor(C) = #333842
combobox2BorderColor(C) = #21242D
combobox2FieldBackground(C) = #333842
combobox2TextColor(C) = #C0C0C0
combobox2Relief(FArelief) = flat
combobox2BorderWidth(I) = 0
combobox2Padding(I) = 7
combobox2ListBoxBackground(C) = #333842
combobox2ListBoxForeground(C) = #C0C0C0
combobox2ListBoxSelectBackground(C) = #737373
combobox2ListBoxSelectForeground(C) = #FFFFFF
button1TextAnchor(FAanchor) = center
button1Background(C) = #333842
button1Foreground(C) = #C0C0C0
button1Padding(I) = 4
separator1BG(C) = #21242D
spinbox1ArrowColor(C) = #C0C0C0
spinbox1FieldBackground(C) = #333842
spinbox1Relief(FArelief) = flat
spinbox1BorderWidth(I) = 0
spinbox1TextColor(C) = #C0C0C0
spinbox1ButtonColor(C) = #333842
spinbox1Padding(I) = 7
entry1FieldBackground(C) = #333842
entry1Relief(FArelief) = flat
entry1BorderWidth(I) = 0
entry1Padding(I) = 7
entry1TextColor(C) = #C0C0C0
iconTabIcon(P) = assets/tab-icons/icon.png
tabIconsSize(I) = 30
generateTabIcon(P) = assets/tab-icons/generate.png
headerFill(FAfill) = x
tabFramePadding(I) = 10
contentTabFrameFill(FAfill) = both
contentTabFrameExpand(I) = 1
outsidelayoutFramesPadX(I) = 6
GIFFrameSeparators(I) = 16
generateFilesLabelWidth(I) = 15
generateFilesLabelAnchor(FAanchor) = center
generateInputFilesPadding(I) = 6
generateHorizontalSeparatorPadY(I) = 10
generateOutputFilesPadding(I) = 6
generateStartButtonPadding(I) = 10
generateStartButtonPadY(I) = 6
formatTabIcon(P) = assets/tab-icons/format.png
loadingListPadX(I) = 12
loadingButtonWidth(I) = 15
formatHorizontalSeparatorPadY(I) = 10
formatVerticalSeparatorPadY(I) = 10
EPOSTypeFramePadY(I) = 0
EPOSPersonSeparatorFramePadY(I) = 0
EPOSRowSeparatorFramePadY(I) = 0
EPOSDataSeparatorFramePadY(I) = 7
EPOSLabelWidth(I) = 30
EPOSLabelAnchor(FAanchor) = center
radiobutton1Background(C) = #21242D
radiobutton1TextColor(C) = #C0C0C0
radiobutton1IndicatorBackground(C) = #21242D
checkbutton1Background(C) = #21242D
checkbutton1TextColor(C) = #C0C0C0
checkbutton1IndicatorBackground(C) = #21242D
text1Background(C) = #333842
text1TextColor(C) = #C0C0C0
text1Relief(FArelief) = flat
EPDataLocalizationPadX(I) = 6
EPDataLocalizationPadY(I) = 6
editingPresetButtonsPadY(I) = 6
editingPresetSaveButtonWidth(I) = 25
editingPresetCancelButtonWidth(I) = 25
settingsTabIcon(P) = assets/tab-icons/settings.png
settingsHorizontalSeparatorPadY(I) = 10
settingsVerticalSeparatorPadY(I) = 10
settingsCodeLabelWidth(I) = 35
settingsCodeLabelAnchor(FAanchor) = w
settingsOtherLabelWidth(I) = 35
settingsOtherLabelAnchor(FAanchor) = w
settingsHeadlineLabelWidth(I) = 35
settingsHeadlineLabelAnchor(FAanchor) = w
settingsSchoolDataLabelAnchor(FAanchor) = center
settingsButtonsPadY(I) = 6
settingsButtonSaveWidth(I) = 20
settingsButtonCancelWidth(I) = 15
settingsButtonPDUOWidth(I) = 35
settingsButtonPDUWWidth(I) = 35
settingsButtonZPFWidth(I) = 35
aboutTabIcon(P) = assets/tab-icons/about.png
button2TextAnchor(FAanchor) = center
button2Background(C) = #21242D
button2Padding(I) = 0
aboutLogoButtonImg(P) = assets/icon.png
aboutLogoButtonImgSize(I) = 250
aboutInstructionButtonWidth(I) = 25
aboutOtherInfoFramePadX(I) = 10
ZPFWindowWidth(I) = 500
ZPFWindowHeight(I) = 400
ZPFWindowWidthResizable(B) = 0
ZPFWindowHeightResizable(B) = 0
ZPFWindowMainBG(C) = #21242D
listbox1BG(C) = #333842
listbox1TextColor(C) = #C0C0C0
listbox1Relief(FArelief) = flat
listbox1BorderWidth(I) = 0
listbox1ActiveStyle(FAactivestyle) = none
listbox1HighlightThickness(I) = 0
windowWidth(I) = 1200
windowHeight(I) = 720
windowWidthResizable(B) = 0
windowHeightResizable(B) = 0
windowMainBG(C) = #21242D
mainIcon(P) = icon.ico
mainMenuBG(C) = #21242D
mainMenuPosition(FAposition) = wn
tabFramesBorderWidth(I) = 0
unselectedTabBG(C) = #21242D
menuTabsBorderWidth(I) = 0
menuTabsPadding(I) = 10
selectedTabBG(C) = #333842
disabledTabBG(C) = #333842
tabFrameBG(C) = #21242D
headerFont(F) = Segoe UI;15
headerBG(C) = #333842
headerTextColor(C) = #C0C0C0
headerPadding(I) = 10
headerTextAnchor(FAanchor) = center
contentTabFrameBG(C) = #21242D
layoutFrameBG(C) = #21242D
label1BG(C) = #21242D
label1TextColor(C) = #C0C0C0
label1Font(F) = Segoe UI;10
label2BG(C) = #21242D
label2TextColor(C) = #C0C0C0
label2Font(F) = Segoe UI;9
label3BG(C) = #21242D
label3TextColor(C) = #C0C0C0
label3Font(F) = Segoe UI;7
label4BG(C) = #21242D
label4TextColor(C) = #C0C0C0
label4Font(F) = Segoe UI;25
combobox1ArrowColor(C) = #C0C0C0
combobox1ButtonColor(C) = #333842
combobox1BorderColor(C) = #21242D
combobox1FieldBackground(C) = #333842
combobox1TextColor(C) = #C0C0C0
combobox1Relief(FArelief) = flat
combobox1BorderWidth(I) = 0
combobox1Padding(I) = 5
combobox1ListBoxBackground(C) = #333842
combobox1ListBoxForeground(C) = #C0C0C0
combobox1ListBoxSelectBackground(C) = #737373
combobox1ListBoxSelectForeground(C) = #FFFFFF
combobox2ArrowColor(C) = #C0C0C0
combobox2ButtonColor(C) = #333842
combobox2BorderColor(C) = #21242D
combobox2FieldBackground(C) = #333842
combobox2TextColor(C) = #C0C0C0
combobox2Relief(FArelief) = flat
combobox2BorderWidth(I) = 0
combobox2Padding(I) = 7
combobox2ListBoxBackground(C) = #333842
combobox2ListBoxForeground(C) = #C0C0C0
combobox2ListBoxSelectBackground(C) = #737373
combobox2ListBoxSelectForeground(C) = #FFFFFF
button1TextAnchor(FAanchor) = center
button1Background(C) = #333842
button1Foreground(C) = #C0C0C0
button1Padding(I) = 4
separator1BG(C) = #21242D
spinbox1ArrowColor(C) = #C0C0C0
spinbox1FieldBackground(C) = #333842
spinbox1Relief(FArelief) = flat
spinbox1BorderWidth(I) = 0
spinbox1TextColor(C) = #C0C0C0
spinbox1ButtonColor(C) = #333842
spinbox1Padding(I) = 7
entry1FieldBackground(C) = #333842
entry1Relief(FArelief) = flat
entry1BorderWidth(I) = 0
entry1Padding(I) = 7
entry1TextColor(C) = #C0C0C0
iconTabIcon(P) = assets/tab-icons/icon.png
tabIconsSize(I) = 30
generateTabIcon(P) = assets/tab-icons/generate.png
headerFill(FAfill) = x
tabFramePadding(I) = 10
contentTabFrameFill(FAfill) = both
contentTabFrameExpand(I) = 1
outsidelayoutFramesPadX(I) = 6
GIFFrameSeparators(I) = 16
generateFilesLabelWidth(I) = 15
generateFilesLabelAnchor(FAanchor) = center
generateInputFilesPadding(I) = 6
generateHorizontalSeparatorPadY(I) = 10
generateOutputFilesPadding(I) = 6
generateStartButtonPadding(I) = 10
generateStartButtonPadY(I) = 6
formatTabIcon(P) = assets/tab-icons/format.png
loadingListPadX(I) = 12
loadingButtonWidth(I) = 15
formatHorizontalSeparatorPadY(I) = 10
formatVerticalSeparatorPadY(I) = 10
EPOSTypeFramePadY(I) = 0
EPOSPersonSeparatorFramePadY(I) = 0
EPOSRowSeparatorFramePadY(I) = 0
EPOSDataSeparatorFramePadY(I) = 7
EPOSLabelWidth(I) = 30
EPOSLabelAnchor(FAanchor) = center
radiobutton1Background(C) = #21242D
radiobutton1TextColor(C) = #C0C0C0
radiobutton1IndicatorBackground(C) = #21242D
checkbutton1Background(C) = #21242D
checkbutton1TextColor(C) = #C0C0C0
checkbutton1IndicatorBackground(C) = #21242D
text1Background(C) = #333842
text1TextColor(C) = #C0C0C0
text1Relief(FArelief) = flat
EPDataLocalizationPadX(I) = 6
EPDataLocalizationPadY(I) = 6
editingPresetButtonsPadY(I) = 6
editingPresetSaveButtonWidth(I) = 25
editingPresetCancelButtonWidth(I) = 25
settingsTabIcon(P) = assets/tab-icons/settings.png
settingsHorizontalSeparatorPadY(I) = 10
settingsVerticalSeparatorPadY(I) = 10
settingsCodeLabelWidth(I) = 35
settingsCodeLabelAnchor(FAanchor) = w
settingsOtherLabelWidth(I) = 35
settingsOtherLabelAnchor(FAanchor) = w
settingsHeadlineLabelWidth(I) = 35
settingsHeadlineLabelAnchor(FAanchor) = w
settingsSchoolDataLabelAnchor(FAanchor) = center
settingsButtonsPadY(I) = 6
settingsButtonSaveWidth(I) = 20
settingsButtonCancelWidth(I) = 15
settingsButtonPDUOWidth(I) = 35
settingsButtonPDUWWidth(I) = 35
settingsButtonZPFWidth(I) = 35
aboutTabIcon(P) = assets/tab-icons/about.png
button2TextAnchor(FAanchor) = center
button2Background(C) = #21242D
button2Padding(I) = 0
aboutLogoButtonImg(P) = assets/icon.png
aboutLogoButtonImgSize(I) = 250
aboutInstructionButtonWidth(I) = 25
aboutOtherInfoFramePadX(I) = 10
ZPFWindowWidth(I) = 500
ZPFWindowHeight(I) = 400
ZPFWindowWidthResizable(B) = 0
ZPFWindowHeightResizable(B) = 0
ZPFWindowMainBG(C) = #21242D
listbox1BG(C) = #333842
listbox1TextColor(C) = #C0C0C0
listbox1Relief(FArelief) = flat
listbox1BorderWidth(I) = 0
listbox1ActiveStyle(FAactivestyle) = none
listbox1HighlightThickness(I) = 0
listbox1SelectBG(C) = #4F4F4F

BIN
src/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB