Compare commits

...

23 Commits
v0.1.0 ... main

Author SHA1 Message Date
Marcel Kapfer 184a5ee20b
Complete file refactoring
No code changes outside of the refactoring process.
2021-04-14 19:14:09 +02:00
Marcel Kapfer 65dc5a65e6
Fixed typo in README 2020-09-23 19:11:39 +02:00
Marcel Kapfer 56cc4308a8 Added Window Build Instructions 2020-09-11 08:01:17 +02:00
Marcel Kapfer eef51b5a43
Switch README format from Markdown to Org-Mode 2020-09-11 09:05:51 +02:00
Marcel Kapfer b69a97a47f
Better changelog formatting 2020-09-11 09:04:03 +02:00
Marcel Kapfer b54ae95452
Bump version to 0.2.0 2020-09-11 09:01:21 +02:00
Marcel Kapfer 960258eba3
Use custom close dialog
The custom close dialog provides translated buttons
2020-09-11 00:07:16 +02:00
Marcel Kapfer 7b7b92b6a3
Implement custom close dialog 2020-09-11 00:07:07 +02:00
Marcel Kapfer 97b16d1856
Add custom close dialog 2020-09-11 00:06:27 +02:00
Marcel Kapfer 02f912928f
Close without crashing 2020-09-10 23:58:09 +02:00
Marcel Kapfer dec5ccd7a8
Active "add" buttons with enter keyboard
Closes #4
2020-09-10 23:48:34 +02:00
Marcel Kapfer 38e03373b6
Focus input field after add-button and select text
Closes #7
2020-09-10 23:32:35 +02:00
Marcel Kapfer 3fe735e596
Offer clearing fields when closing code dialog
The offer is only made if the content has been copied at least once
2020-09-09 23:45:06 +02:00
Marcel Kapfer f51e5ed878
Added clear fields dialog code 2020-09-09 23:44:52 +02:00
Marcel Kapfer 371ff3fa9f
Handle clear fields menu entry 2020-09-09 23:44:27 +02:00
Marcel Kapfer ba3a575ba2
Added clear function
The clear function reset all input areas to their initial (mostly
empty) value.
2020-09-09 23:43:40 +02:00
Marcel Kapfer cb139c6fbf
Added mene item to clear fields 2020-09-09 23:42:51 +02:00
Marcel Kapfer 2b9e2292fa
Added Clear Fields Dialog 2020-09-09 23:41:42 +02:00
Marcel Kapfer 32b4c7a0f3
Fixed typo "Variantionen"
Closes #6
2020-07-06 20:15:25 +02:00
Marcel Kapfer d692958902
Fixed indentation 2020-07-06 20:11:46 +02:00
Marcel Kapfer 094dd51a78
Allow ingredients without specifying an amount
Closes #5
2020-07-06 20:07:58 +02:00
Marcel Kapfer 01f8bdd8d3
Recipe name for source url text
Closes #3
2020-07-06 20:01:18 +02:00
Marcel Kapfer 80773164aa
Display list as unordered list
Closes #1
2020-07-06 19:54:57 +02:00
18 changed files with 842 additions and 356 deletions

28
CHANGELOG.org Normal file
View File

@ -0,0 +1,28 @@
#+title: CHANGELOG
* Version 0.2.0
** Features
- It is now possible to clear/reset all input fields (cb139c6
2b9e229 ba3a575 371ff3f f51e5ed)
- Clearing all fields is now also offered when closing the code
dialog after copying the content at least once (3fe735e)
- Focus input field after acting on the corresponding add-button
and select text (38e0337)
- It is now possible to active the "add" buttons with the enter key
(dec5ccd)
** Bugfixes
- Display listings as unordered list (8077316)
- Recipe name for source URL text (01f8bdd)
- Allow ingredients without specifying an amount (094dd51)
- Fixed typo "Variantionen" (32b4c7a)
- Close without crashing (02f9129)
- Provide custom close dialog for translated buttons (97b16d1
7b7b92b 960258e)
* Version 0.1.0
- Initial release

View File

@ -59,7 +59,7 @@
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Version 0.1.0</string>
<string>Version 0.2.0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>

61
QtDesigner/ClearDialog.ui Normal file
View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ClearDialog</class>
<widget class="QDialog" name="ClearDialog">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>265</width>
<height>75</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Eingabefelder leeren</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="t_clear">
<property name="text">
<string>Sollen die Eingabefelder geleert werden?</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="l_buttons">
<item>
<widget class="QPushButton" name="b_yes">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Ja</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="b_no">
<property name="text">
<string>Nein</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

61
QtDesigner/CloseDialog.ui Normal file
View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CloseDialog</class>
<widget class="QDialog" name="CloseDialog">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>313</width>
<height>75</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Programm schließen</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="t_close">
<property name="text">
<string>Soll das Programm wirklich geschlossen werden?</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="l_buttons">
<item>
<widget class="QPushButton" name="b_yes">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Ja</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="b_no">
<property name="text">
<string>Nein</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -98,13 +98,6 @@
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLineEdit" name="e_url">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="l_recipe_name">
<property name="text">
@ -150,6 +143,13 @@
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLineEdit" name="e_url">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
@ -200,6 +200,9 @@
<property name="text">
<string>Hinzufügen</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
@ -314,6 +317,9 @@
<property name="text">
<string>Hinzufügen</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
@ -386,6 +392,9 @@
<property name="text">
<string>Hinzufügen</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
@ -435,6 +444,9 @@
<property name="text">
<string>Hinzufügen</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
@ -510,6 +522,9 @@
<property name="text">
<string>Hinzufügen</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
@ -585,6 +600,9 @@
<property name="text">
<string>Hinzufügen</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
@ -634,7 +652,7 @@
</widget>
<widget class="QWidget" name="t_variations">
<attribute name="title">
<string>Variantionen</string>
<string>Variationen</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
@ -660,6 +678,9 @@
<property name="text">
<string>Hinzufügen</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
@ -735,6 +756,9 @@
<property name="text">
<string>Hinzufügen</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
@ -792,19 +816,26 @@
<x>0</x>
<y>0</y>
<width>800</width>
<height>30</height>
<height>28</height>
</rect>
</property>
<widget class="QMenu" name="menuMen">
<property name="title">
<string>Me&amp;nü</string>
</property>
<addaction name="ma_clear_fields"/>
<addaction name="separator"/>
<addaction name="ma_information"/>
<addaction name="separator"/>
<addaction name="ma_close"/>
</widget>
<addaction name="menuMen"/>
</widget>
<action name="ma_clear_fields">
<property name="text">
<string>Eingaben löschen</string>
</property>
</action>
<action name="ma_close">
<property name="text">
<string>&amp;Schließen</string>
@ -823,22 +854,52 @@
<tabstop>e_rating_overall</tabstop>
<tabstop>e_url</tabstop>
<tabstop>e_category</tabstop>
<tabstop>b_category_add</tabstop>
<tabstop>v_categories</tabstop>
<tabstop>b_category_remove</tabstop>
<tabstop>e_ingredient</tabstop>
<tabstop>c_heading</tabstop>
<tabstop>e_amount</tabstop>
<tabstop>b_ingredient_add</tabstop>
<tabstop>v_ingredients</tabstop>
<tabstop>b_ingredient_remove</tabstop>
<tabstop>e_utensil</tabstop>
<tabstop>b_utensil_add</tabstop>
<tabstop>v_utensils</tabstop>
<tabstop>b_utensil_remove</tabstop>
<tabstop>e_step</tabstop>
<tabstop>b_step_add</tabstop>
<tabstop>v_steps</tabstop>
<tabstop>b_step_edit</tabstop>
<tabstop>b_step_replace</tabstop>
<tabstop>b_step_remove</tabstop>
<tabstop>e_note</tabstop>
<tabstop>b_note_add</tabstop>
<tabstop>v_notes</tabstop>
<tabstop>b_note_edit</tabstop>
<tabstop>b_note_replace</tabstop>
<tabstop>b_note_remove</tabstop>
<tabstop>e_tip</tabstop>
<tabstop>b_tip_add</tabstop>
<tabstop>v_tips</tabstop>
<tabstop>b_tip_edit</tabstop>
<tabstop>b_tip_replace</tabstop>
<tabstop>b_tip_remove</tabstop>
<tabstop>e_variation</tabstop>
<tabstop>b_variation_add</tabstop>
<tabstop>v_variations</tabstop>
<tabstop>b_variation_edit</tabstop>
<tabstop>b_variation_replace</tabstop>
<tabstop>b_variation_remove</tabstop>
<tabstop>e_rating</tabstop>
<tabstop>b_rating_add</tabstop>
<tabstop>v_ratings</tabstop>
<tabstop>b_rating_edit</tabstop>
<tabstop>b_rating_replace</tabstop>
<tabstop>b_rating_remove</tabstop>
<tabstop>b_create</tabstop>
<tabstop>tabWidget</tabstop>
<tabstop>b_cancel</tabstop>
</tabstops>
<resources/>
<connections/>

View File

@ -1,5 +0,0 @@
# WikiCookBook
WikiCookBook is a simple graphical editor for creating MoinMoin wiki pages for recips.
It is based on [Python](https://www.python.org), [Qt](https://www.qt.io/) and [PyQt](https://www.riverbankcomputing.com/software/pyqt/intro).

22
README.org Normal file
View File

@ -0,0 +1,22 @@
#+title: WikiCookBook
WikiCookBook is a simple graphical editor for creating MoinMoin wiki pages for recipes.
It is based on [[https://www.python.org][Python]], [[https://www.qt.io/][QT]] and [[https://www.riverbankcomputing.com/software/pyqt/intro][PyQt]].
* Building
** Microsoft Windows
Building in Microsoft Windows happens with pyinstaller. Here the complete process.
#+BEGIN_SRC shell
git clone git@git.mmk2410.org:mmk2410/wikicookbook
cd wikicookbook
python -m venv venv
.\venv\Scripts\activate.bat
pip install -r requirements.txt
.\venv\Scripts\pyinstaller.exe --onefile --windowed wikicookbook.py
#+END_SRC
The result can the be found in the =dist= directory.

View File

@ -114,7 +114,7 @@ class Recipe():
code.append(writer.table_cell(self.servings, f"{style_info_contentrow} {style_info_content}"))
code.append(writer.table_cell(self.time, style_info_content))
code.append(writer.table_cell("🟢" * self.rating + "" * (5 - self.rating), style_info_content))
code.append(writer.table_cell(writer.link("Quelle", self.url), style_info_content))
code.append(writer.table_cell(writer.link(self.name, self.url), style_info_content))
code.append(writer.table_row_end())
code.append(writer.newline())
code.append(writer.linebreak())
@ -176,7 +176,7 @@ class Recipe():
code.append(writer.table_row_end())
for item in items:
code.append(writer.olitem(item))
code.append(writer.ulitem(item))
code.append(writer.newline())
return code

View File

@ -2,15 +2,16 @@
# Form implementation generated from reading ui file 'ui_about_dialog.ui'
#
# Created by: PyQt5 UI code generator 5.14.2
# Created by: PyQt5 UI code generator 5.15.0
#
# WARNING! All changes made in this file will be lost!
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_About(object):
class AboutDialog(object):
def setupUi(self, About):
About.setObjectName("About")
About.resize(400, 300)
@ -70,7 +71,7 @@ class Ui_About(object):
About.setWindowTitle(_translate("About", "About"))
self.l_title.setText(_translate("About", "WikiCookBook"))
self.l_description.setText(_translate("About", "A graphical editor for creating cookbook entries using the MoinMoin wiki syntax"))
self.label.setText(_translate("About", "Version 0.1.0"))
self.label.setText(_translate("About", "Version 0.2.0"))
self.l_basedon.setText(_translate("About", "<html><head/><body><p>Based on <a href=\"https://www.python.org/\"><span style=\" text-decoration: underline; color:#4c6b8a;\">Python</span></a> and <a href=\"https://www.riverbankcomputing.com/software/pyqt/intro\"><span style=\" text-decoration: underline; color:#4c6b8a;\">PyQt</span></a>.</p></body></html>"))
self.l_copyright.setText(_translate("About", "<html><head/><body><p>2020 © Marcel Kapfer (opensource@mmk2410.org)<br/>Licensed under GPLv3</p></body></html>"))
self.l_sourcecode.setText(_translate("About", "<html><head/><body><p>Sourcecode available at<br/><a href=\"https://git.mmk2410.org/mmk2410/wikicookbook\"><span style=\" text-decoration: underline; color:#4c6b8a;\">git.mmk2410.org/mmk2410/wikicookbook</span></a></p></body></html>"))

View File

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_clear_dialog.ui'
#
# Created by: PyQt5 UI code generator 5.15.0
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class ClearDialog(object):
def setupUi(self, ClearDialog):
ClearDialog.setObjectName("ClearDialog")
ClearDialog.setWindowModality(QtCore.Qt.ApplicationModal)
ClearDialog.resize(265, 75)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(ClearDialog.sizePolicy().hasHeightForWidth())
ClearDialog.setSizePolicy(sizePolicy)
self.verticalLayout = QtWidgets.QVBoxLayout(ClearDialog)
self.verticalLayout.setObjectName("verticalLayout")
self.t_clear = QtWidgets.QLabel(ClearDialog)
self.t_clear.setObjectName("t_clear")
self.verticalLayout.addWidget(self.t_clear)
self.l_buttons = QtWidgets.QHBoxLayout()
self.l_buttons.setObjectName("l_buttons")
self.b_yes = QtWidgets.QPushButton(ClearDialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.b_yes.sizePolicy().hasHeightForWidth())
self.b_yes.setSizePolicy(sizePolicy)
self.b_yes.setObjectName("b_yes")
self.l_buttons.addWidget(self.b_yes)
self.b_no = QtWidgets.QPushButton(ClearDialog)
self.b_no.setObjectName("b_no")
self.l_buttons.addWidget(self.b_no)
self.verticalLayout.addLayout(self.l_buttons)
self.retranslateUi(ClearDialog)
QtCore.QMetaObject.connectSlotsByName(ClearDialog)
def retranslateUi(self, ClearDialog):
_translate = QtCore.QCoreApplication.translate
ClearDialog.setWindowTitle(_translate("ClearDialog", "Eingabefelder leeren"))
self.t_clear.setText(_translate("ClearDialog", "Sollen die Eingabefelder geleert werden?"))
self.b_yes.setText(_translate("ClearDialog", "Ja"))
self.b_no.setText(_translate("ClearDialog", "Nein"))

View File

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_close_dialog.ui'
#
# Created by: PyQt5 UI code generator 5.15.0
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class CloseDialog(object):
def setupUi(self, CloseDialog):
CloseDialog.setObjectName("CloseDialog")
CloseDialog.setWindowModality(QtCore.Qt.ApplicationModal)
CloseDialog.resize(313, 75)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(CloseDialog.sizePolicy().hasHeightForWidth())
CloseDialog.setSizePolicy(sizePolicy)
self.verticalLayout = QtWidgets.QVBoxLayout(CloseDialog)
self.verticalLayout.setObjectName("verticalLayout")
self.t_close = QtWidgets.QLabel(CloseDialog)
self.t_close.setObjectName("t_close")
self.verticalLayout.addWidget(self.t_close)
self.l_buttons = QtWidgets.QHBoxLayout()
self.l_buttons.setObjectName("l_buttons")
self.b_yes = QtWidgets.QPushButton(CloseDialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.b_yes.sizePolicy().hasHeightForWidth())
self.b_yes.setSizePolicy(sizePolicy)
self.b_yes.setObjectName("b_yes")
self.l_buttons.addWidget(self.b_yes)
self.b_no = QtWidgets.QPushButton(CloseDialog)
self.b_no.setObjectName("b_no")
self.l_buttons.addWidget(self.b_no)
self.verticalLayout.addLayout(self.l_buttons)
self.retranslateUi(CloseDialog)
QtCore.QMetaObject.connectSlotsByName(CloseDialog)
def retranslateUi(self, CloseDialog):
_translate = QtCore.QCoreApplication.translate
CloseDialog.setWindowTitle(_translate("CloseDialog", "Programm schließen"))
self.t_close.setText(_translate("CloseDialog", "Soll das Programm wirklich geschlossen werden?"))
self.b_yes.setText(_translate("CloseDialog", "Ja"))
self.b_no.setText(_translate("CloseDialog", "Nein"))

View File

@ -10,13 +10,13 @@
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_WikiCode(object):
def setupUi(self, WikiCode):
WikiCode.setObjectName("WikiCode")
WikiCode.resize(530, 643)
self.verticalLayout_2 = QtWidgets.QVBoxLayout(WikiCode)
class CodeDialog(object):
def setupUi(self, CodeDialog):
CodeDialog.setObjectName("CodeDialog")
CodeDialog.resize(530, 643)
self.verticalLayout_2 = QtWidgets.QVBoxLayout(CodeDialog)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.e_code = QtWidgets.QPlainTextEdit(WikiCode)
self.e_code = QtWidgets.QPlainTextEdit(CodeDialog)
font = QtGui.QFont()
font.setFamily("Monospace")
self.e_code.setFont(font)
@ -27,19 +27,19 @@ class Ui_WikiCode(object):
self.horizontalLayout.setObjectName("horizontalLayout")
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.b_copy = QtWidgets.QPushButton(WikiCode)
self.b_copy = QtWidgets.QPushButton(CodeDialog)
self.b_copy.setObjectName("b_copy")
self.horizontalLayout.addWidget(self.b_copy)
self.b_close = QtWidgets.QPushButton(WikiCode)
self.b_close = QtWidgets.QPushButton(CodeDialog)
self.b_close.setObjectName("b_close")
self.horizontalLayout.addWidget(self.b_close)
self.verticalLayout_2.addLayout(self.horizontalLayout)
self.retranslateUi(WikiCode)
QtCore.QMetaObject.connectSlotsByName(WikiCode)
self.retranslateUi(CodeDialog)
QtCore.QMetaObject.connectSlotsByName(CodeDialog)
def retranslateUi(self, WikiCode):
def retranslateUi(self, CodeDialog):
_translate = QtCore.QCoreApplication.translate
WikiCode.setWindowTitle(_translate("WikiCode", "WikiCode"))
self.b_copy.setText(_translate("WikiCode", "Kopieren"))
self.b_close.setText(_translate("WikiCode", "Schließen"))
CodeDialog.setWindowTitle(_translate("CodeDialog", "CodeDialog"))
self.b_copy.setText(_translate("CodeDialog", "Kopieren"))
self.b_close.setText(_translate("CodeDialog", "Schließen"))

View File

@ -2,15 +2,16 @@
# Form implementation generated from reading ui file 'ui_mainwindow.ui'
#
# Created by: PyQt5 UI code generator 5.14.2
# Created by: PyQt5 UI code generator 5.15.0
#
# WARNING! All changes made in this file will be lost!
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
class MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 620)
@ -49,10 +50,6 @@ class Ui_MainWindow(object):
self.e_servings.setText("")
self.e_servings.setObjectName("e_servings")
self.y_basics.addWidget(self.e_servings, 1, 1, 1, 1)
self.e_url = QtWidgets.QLineEdit(self.t_basics)
self.e_url.setText("")
self.e_url.setObjectName("e_url")
self.y_basics.addWidget(self.e_url, 2, 3, 1, 1)
self.l_recipe_name = QtWidgets.QLabel(self.t_basics)
self.l_recipe_name.setObjectName("l_recipe_name")
self.y_basics.addWidget(self.l_recipe_name, 0, 0, 1, 1)
@ -75,6 +72,10 @@ class Ui_MainWindow(object):
self.e_rating_overall.setProperty("value", 3)
self.e_rating_overall.setObjectName("e_rating_overall")
self.y_basics.addWidget(self.e_rating_overall, 2, 1, 1, 1)
self.e_url = QtWidgets.QLineEdit(self.t_basics)
self.e_url.setText("")
self.e_url.setObjectName("e_url")
self.y_basics.addWidget(self.e_url, 2, 3, 1, 1)
self.verticalLayout_9.addLayout(self.y_basics)
self.horizontalLayout_16 = QtWidgets.QHBoxLayout()
self.horizontalLayout_16.setObjectName("horizontalLayout_16")
@ -100,6 +101,7 @@ class Ui_MainWindow(object):
self.b_category_remove.setObjectName("b_category_remove")
self.horizontalLayout_15.addWidget(self.b_category_remove)
self.b_category_add = QtWidgets.QPushButton(self.t_basics)
self.b_category_add.setAutoDefault(True)
self.b_category_add.setObjectName("b_category_add")
self.horizontalLayout_15.addWidget(self.b_category_add)
self.verticalLayout_8.addLayout(self.horizontalLayout_15)
@ -153,6 +155,7 @@ class Ui_MainWindow(object):
self.b_ingredient_remove.setObjectName("b_ingredient_remove")
self.horizontalLayout_13.addWidget(self.b_ingredient_remove)
self.b_ingredient_add = QtWidgets.QPushButton(self.t_ingredients)
self.b_ingredient_add.setAutoDefault(True)
self.b_ingredient_add.setObjectName("b_ingredient_add")
self.horizontalLayout_13.addWidget(self.b_ingredient_add)
self.verticalLayout_7.addLayout(self.horizontalLayout_13)
@ -186,6 +189,7 @@ class Ui_MainWindow(object):
self.b_utensil_remove.setObjectName("b_utensil_remove")
self.horizontalLayout_12.addWidget(self.b_utensil_remove)
self.b_utensil_add = QtWidgets.QPushButton(self.t_utensils)
self.b_utensil_add.setAutoDefault(True)
self.b_utensil_add.setObjectName("b_utensil_add")
self.horizontalLayout_12.addWidget(self.b_utensil_add)
self.verticalLayout_6.addLayout(self.horizontalLayout_12)
@ -205,6 +209,7 @@ class Ui_MainWindow(object):
spacerItem7 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_9.addItem(spacerItem7)
self.b_step_add = QtWidgets.QPushButton(self.t_steps)
self.b_step_add.setAutoDefault(True)
self.b_step_add.setObjectName("b_step_add")
self.horizontalLayout_9.addWidget(self.b_step_add)
self.verticalLayout_5.addLayout(self.horizontalLayout_9)
@ -238,6 +243,7 @@ class Ui_MainWindow(object):
spacerItem9 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_7.addItem(spacerItem9)
self.b_note_add = QtWidgets.QPushButton(self.t_notes)
self.b_note_add.setAutoDefault(True)
self.b_note_add.setObjectName("b_note_add")
self.horizontalLayout_7.addWidget(self.b_note_add)
self.verticalLayout_4.addLayout(self.horizontalLayout_7)
@ -271,6 +277,7 @@ class Ui_MainWindow(object):
spacerItem11 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_5.addItem(spacerItem11)
self.b_tip_add = QtWidgets.QPushButton(self.t_tips)
self.b_tip_add.setAutoDefault(True)
self.b_tip_add.setObjectName("b_tip_add")
self.horizontalLayout_5.addWidget(self.b_tip_add)
self.verticalLayout_2.addLayout(self.horizontalLayout_5)
@ -304,6 +311,7 @@ class Ui_MainWindow(object):
spacerItem13 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_3.addItem(spacerItem13)
self.b_variation_add = QtWidgets.QPushButton(self.t_variations)
self.b_variation_add.setAutoDefault(True)
self.b_variation_add.setObjectName("b_variation_add")
self.horizontalLayout_3.addWidget(self.b_variation_add)
self.verticalLayout_3.addLayout(self.horizontalLayout_3)
@ -337,6 +345,7 @@ class Ui_MainWindow(object):
spacerItem15 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(spacerItem15)
self.b_rating_add = QtWidgets.QPushButton(self.t_rating)
self.b_rating_add.setAutoDefault(True)
self.b_rating_add.setObjectName("b_rating_add")
self.horizontalLayout_2.addWidget(self.b_rating_add)
self.verticalLayout.addLayout(self.horizontalLayout_2)
@ -361,15 +370,19 @@ class Ui_MainWindow(object):
self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menuBar = QtWidgets.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 800, 30))
self.menuBar.setGeometry(QtCore.QRect(0, 0, 800, 28))
self.menuBar.setObjectName("menuBar")
self.menuMen = QtWidgets.QMenu(self.menuBar)
self.menuMen.setObjectName("menuMen")
MainWindow.setMenuBar(self.menuBar)
self.ma_clear_fields = QtWidgets.QAction(MainWindow)
self.ma_clear_fields.setObjectName("ma_clear_fields")
self.ma_close = QtWidgets.QAction(MainWindow)
self.ma_close.setObjectName("ma_close")
self.ma_information = QtWidgets.QAction(MainWindow)
self.ma_information.setObjectName("ma_information")
self.menuMen.addAction(self.ma_clear_fields)
self.menuMen.addSeparator()
self.menuMen.addAction(self.ma_information)
self.menuMen.addSeparator()
self.menuMen.addAction(self.ma_close)
@ -383,22 +396,52 @@ class Ui_MainWindow(object):
MainWindow.setTabOrder(self.e_time, self.e_rating_overall)
MainWindow.setTabOrder(self.e_rating_overall, self.e_url)
MainWindow.setTabOrder(self.e_url, self.e_category)
MainWindow.setTabOrder(self.e_category, self.e_ingredient)
MainWindow.setTabOrder(self.e_category, self.b_category_add)
MainWindow.setTabOrder(self.b_category_add, self.v_categories)
MainWindow.setTabOrder(self.v_categories, self.b_category_remove)
MainWindow.setTabOrder(self.b_category_remove, self.e_ingredient)
MainWindow.setTabOrder(self.e_ingredient, self.c_heading)
MainWindow.setTabOrder(self.c_heading, self.e_amount)
MainWindow.setTabOrder(self.e_amount, self.v_ingredients)
MainWindow.setTabOrder(self.v_ingredients, self.e_utensil)
MainWindow.setTabOrder(self.e_utensil, self.v_utensils)
MainWindow.setTabOrder(self.v_utensils, self.e_step)
MainWindow.setTabOrder(self.e_step, self.v_steps)
MainWindow.setTabOrder(self.v_steps, self.e_note)
MainWindow.setTabOrder(self.e_note, self.v_notes)
MainWindow.setTabOrder(self.v_notes, self.e_tip)
MainWindow.setTabOrder(self.e_tip, self.v_tips)
MainWindow.setTabOrder(self.v_tips, self.e_variation)
MainWindow.setTabOrder(self.e_variation, self.v_variations)
MainWindow.setTabOrder(self.v_variations, self.e_rating)
MainWindow.setTabOrder(self.e_rating, self.v_ratings)
MainWindow.setTabOrder(self.e_amount, self.b_ingredient_add)
MainWindow.setTabOrder(self.b_ingredient_add, self.v_ingredients)
MainWindow.setTabOrder(self.v_ingredients, self.b_ingredient_remove)
MainWindow.setTabOrder(self.b_ingredient_remove, self.e_utensil)
MainWindow.setTabOrder(self.e_utensil, self.b_utensil_add)
MainWindow.setTabOrder(self.b_utensil_add, self.v_utensils)
MainWindow.setTabOrder(self.v_utensils, self.b_utensil_remove)
MainWindow.setTabOrder(self.b_utensil_remove, self.e_step)
MainWindow.setTabOrder(self.e_step, self.b_step_add)
MainWindow.setTabOrder(self.b_step_add, self.v_steps)
MainWindow.setTabOrder(self.v_steps, self.b_step_edit)
MainWindow.setTabOrder(self.b_step_edit, self.b_step_replace)
MainWindow.setTabOrder(self.b_step_replace, self.b_step_remove)
MainWindow.setTabOrder(self.b_step_remove, self.e_note)
MainWindow.setTabOrder(self.e_note, self.b_note_add)
MainWindow.setTabOrder(self.b_note_add, self.v_notes)
MainWindow.setTabOrder(self.v_notes, self.b_note_edit)
MainWindow.setTabOrder(self.b_note_edit, self.b_note_replace)
MainWindow.setTabOrder(self.b_note_replace, self.b_note_remove)
MainWindow.setTabOrder(self.b_note_remove, self.e_tip)
MainWindow.setTabOrder(self.e_tip, self.b_tip_add)
MainWindow.setTabOrder(self.b_tip_add, self.v_tips)
MainWindow.setTabOrder(self.v_tips, self.b_tip_edit)
MainWindow.setTabOrder(self.b_tip_edit, self.b_tip_replace)
MainWindow.setTabOrder(self.b_tip_replace, self.b_tip_remove)
MainWindow.setTabOrder(self.b_tip_remove, self.e_variation)
MainWindow.setTabOrder(self.e_variation, self.b_variation_add)
MainWindow.setTabOrder(self.b_variation_add, self.v_variations)
MainWindow.setTabOrder(self.v_variations, self.b_variation_edit)
MainWindow.setTabOrder(self.b_variation_edit, self.b_variation_replace)
MainWindow.setTabOrder(self.b_variation_replace, self.b_variation_remove)
MainWindow.setTabOrder(self.b_variation_remove, self.e_rating)
MainWindow.setTabOrder(self.e_rating, self.b_rating_add)
MainWindow.setTabOrder(self.b_rating_add, self.v_ratings)
MainWindow.setTabOrder(self.v_ratings, self.b_rating_edit)
MainWindow.setTabOrder(self.b_rating_edit, self.b_rating_replace)
MainWindow.setTabOrder(self.b_rating_replace, self.b_rating_remove)
MainWindow.setTabOrder(self.b_rating_remove, self.b_create)
MainWindow.setTabOrder(self.b_create, self.tabWidget)
MainWindow.setTabOrder(self.tabWidget, self.b_cancel)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
@ -447,12 +490,13 @@ class Ui_MainWindow(object):
self.b_variation_edit.setText(_translate("MainWindow", "Bearbeiten"))
self.b_variation_replace.setText(_translate("MainWindow", "Ersetzen"))
self.b_variation_remove.setText(_translate("MainWindow", "Entfernen"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.t_variations), _translate("MainWindow", "Variantionen"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.t_variations), _translate("MainWindow", "Variationen"))
self.b_rating_add.setText(_translate("MainWindow", "Hinzufügen"))
self.b_rating_edit.setText(_translate("MainWindow", "Bearbeiten"))
self.b_rating_replace.setText(_translate("MainWindow", "Ersetzen"))
self.b_rating_remove.setText(_translate("MainWindow", "Entfernen"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.t_rating), _translate("MainWindow", "Bewertung"))
self.menuMen.setTitle(_translate("MainWindow", "Me&nü"))
self.ma_clear_fields.setText(_translate("MainWindow", "Eingaben löschen"))
self.ma_close.setText(_translate("MainWindow", "&Schließen"))
self.ma_information.setText(_translate("MainWindow", "Informationen"))

View File

@ -0,0 +1,5 @@
from .AboutDialog import AboutDialog
from .ClearDialog import ClearDialog
from .CloseDialog import CloseDialog
from .CodeDialog import CodeDialog
from .MainWindow import MainWindow

View File

@ -0,0 +1,382 @@
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox, QTableWidgetItem, QDialog
import WikiCookBook.UI as UI
from WikiCookBook.Model.Recipe import Recipe
from WikiCookBook.Writer.MoinMoinWriter import MoinMoinWriter
class AboutDialog(QDialog, UI.AboutDialog):
def __init__(self, *args, **kwargs):
super(AboutDialog, self).__init__(*args, **kwargs)
self.setupUi(self)
self.b_close.clicked.connect(self.close)
self.show()
class CloseDialog(QDialog, UI.CloseDialog):
def __init__(self, *args, **kwargs):
super(CloseDialog, self).__init__(*args, **kwargs)
self.setupUi(self)
self.b_yes.clicked.connect(self.accept)
self.b_no.clicked.connect(self.reject)
self.show()
class ClearDialog(QDialog, UI.ClearDialog):
def __init__(self, *args, **kwargs):
super(ClearDialog, self).__init__(*args, **kwargs)
self.setupUi(self)
self.b_yes.clicked.connect(self.accept)
self.b_no.clicked.connect(self.reject)
self.show()
class CodeDialog(QDialog, UI.CodeDialog):
def __init__(self, code, *args, **kwargs):
super(CodeDialog, self).__init__(*args, **kwargs)
self.setupUi(self)
self.copied = False
self.e_code.setPlainText(code)
self.b_close.clicked.connect(self.clear_fields)
self.b_copy.clicked.connect(self.copy)
self.show()
def copy(self):
self.e_code.selectAll()
self.e_code.copy()
self.copied = True
def clear_fields(self):
"""
Show the clear fields dialog if the code was at least copied once.
"""
if self.copied:
dialog = ClearDialog()
dialog.rejected.connect(self.reject)
dialog.accepted.connect(self.accept)
dialog.exec_()
else:
self.close()
class MainWindow(QMainWindow, UI.MainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.setupUi(self)
# Connect close actions
self.b_cancel.clicked.connect(self.ask_close)
self.ma_close.triggered.connect(self.ask_close)
# Connect other menu actions
self.ma_information.triggered.connect(self.about)
self.ma_clear_fields.triggered.connect(self.clear_fields)
# Conncect recipe name typing
self.e_recipe_name.textChanged.connect(self.updateTitle)
# Handle categories
self.b_category_add.clicked.connect(self.category_add)
self.e_category.returnPressed.connect(self.category_add)
self.b_category_remove.clicked.connect(self.category_remove)
# Handle ingredients
self.b_ingredient_add.clicked.connect(self.ingredient_add)
self.b_ingredient_remove.clicked.connect(self.ingredient_remove)
# Handle utensils
self.b_utensil_add.clicked.connect(self.utensil_add)
self.e_utensil.returnPressed.connect(self.utensil_add)
self.b_utensil_remove.clicked.connect(self.utensil_remove)
# Handle steps
self.b_step_add.clicked.connect(self.step_add)
self.b_step_edit.clicked.connect(self.step_edit)
self.b_step_replace.clicked.connect(self.step_replace)
self.b_step_remove.clicked.connect(self.step_remove)
# Handle notes
self.b_note_add.clicked.connect(self.note_add)
self.b_note_edit.clicked.connect(self.note_edit)
self.b_note_replace.clicked.connect(self.note_replace)
self.b_note_remove.clicked.connect(self.note_remove)
# Handle tips
self.b_tip_add.clicked.connect(self.tip_add)
self.b_tip_edit.clicked.connect(self.tip_edit)
self.b_tip_replace.clicked.connect(self.tip_replace)
self.b_tip_remove.clicked.connect(self.tip_remove)
# Handle variations
self.b_variation_add.clicked.connect(self.variation_add)
self.b_variation_edit.clicked.connect(self.variation_edit)
self.b_variation_replace.clicked.connect(self.variation_replace)
self.b_variation_remove.clicked.connect(self.variation_remove)
# Handle ratings
self.b_rating_add.clicked.connect(self.rating_add)
self.b_rating_edit.clicked.connect(self.rating_edit)
self.b_rating_replace.clicked.connect(self.rating_replace)
self.b_rating_remove.clicked.connect(self.rating_remove)
# Handle recipe creation
self.b_create.clicked.connect(self.create_recipe)
self.show()
def updateTitle(self):
"""
Update the window title so it contains the name of the current recipe.
"""
current_recipe_name = self.e_recipe_name.text()
if current_recipe_name:
self.setWindowTitle(f"{current_recipe_name} - WikiCookBook")
else:
self.setWindowTitle("WikiCookBook")
def category_add(self):
if self.e_category.text():
self.v_categories.addItem(f"Kategorie{self.e_category.text()}")
self.e_category.setFocus()
self.e_category.selectAll()
def category_remove(self):
self.v_categories.takeItem(self.v_categories.currentRow())
def ingredient_add(self):
if self.e_ingredient.text():
if self.c_heading.checkState() == 2:
current_amount = QTableWidgetItem("----------")
else:
current_amount = QTableWidgetItem(self.e_amount.text())
current_ingredient = QTableWidgetItem(self.e_ingredient.text())
self.v_ingredients.setRowCount(self.v_ingredients.rowCount() + 1)
self.v_ingredients.setItem(self.v_ingredients.rowCount() - 1, 0, current_amount)
self.v_ingredients.setItem(self.v_ingredients.rowCount() - 1, 1, current_ingredient)
self.e_ingredient.setFocus()
self.e_ingredient.selectAll()
def ingredient_remove(self):
self.v_ingredients.removeRow(self.v_ingredients.currentRow())
def utensil_add(self):
if self.e_utensil.text():
self.v_utensils.addItem(self.e_utensil.text())
self.e_utensil.setFocus()
self.e_utensil.selectAll()
def utensil_remove(self):
self.v_utensils.takeItem(self.v_utensils.currentRow())
def step_add(self):
if self.e_step.toPlainText():
self.v_steps.addItem(self.e_step.toPlainText())
self.e_step.setFocus()
self.e_step.selectAll()
def step_edit(self):
if self.v_steps.count() > 0:
self.e_step.setText(self.v_steps.currentItem().text())
def step_replace(self):
if self.e_step.toPlainText() and self.v_steps.count() > 0:
self.v_steps.currentItem().setText(self.e_step.toPlainText())
def step_remove(self):
self.v_steps.takeItem(self.v_steps.currentRow())
def note_add(self):
if self.e_note.toPlainText():
self.v_notes.addItem(self.e_note.toPlainText())
self.e_note.setFocus()
self.e_note.selectAll()
def note_edit(self):
if self.v_notes.count() > 0:
self.e_note.setText(self.v_notes.currentItem().text())
def note_replace(self):
if self.e_note.toPlainText() and self.v_notes.count() > 0:
self.v_notes.currentItem().setText(self.e_note.toPlainText())
def note_remove(self):
self.v_notes.takeItem(self.v_notes.currentRow())
def tip_add(self):
if self.e_tip.toPlainText():
self.v_tips.addItem(self.e_tip.toPlainText())
self.e_tip.setFocus()
self.e_tip.selectAll()
def tip_edit(self):
if self.v_tips.count() > 0:
self.e_tip.setText(self.v_tips.currentItem().text())
def tip_replace(self):
if self.e_tip.toPlainText() and self.v_tips.count() > 0:
self.v_tips.currentItem().setText(self.e_tip.toPlainText())
def tip_remove(self):
self.v_tips.takeItem(self.v_tips.currentRow())
def variation_add(self):
if self.e_variation.toPlainText():
self.v_variations.addItem(self.e_variation.toPlainText())
self.e_variation.setFocus()
self.e_variation.selectAll()
def variation_edit(self):
if self.v_variations.count() > 0:
self.e_variation.setText(self.v_variations.currentItem().text())
def variation_replace(self):
if self.e_variation.toPlainText() and self.v_variations.count() > 0:
self.v_variations.currentItem().setText(self.e_variation.toPlainText())
def variation_remove(self):
self.v_variations.takeItem(self.v_variations.currentRow())
def rating_add(self):
if self.e_rating.toPlainText():
self.v_ratings.addItem(self.e_rating.toPlainText())
self.e_rating.setFocus()
self.e_rating.selectAll()
def rating_edit(self):
if self.v_ratings.count() > 0:
self.e_rating.setText(self.v_ratings.currentItem().text())
def rating_replace(self):
if self.e_rating.toPlainText() and self.v_ratings.count() > 0:
self.v_ratings.currentItem().setText(self.e_rating.toPlainText())
def rating_remove(self):
self.v_ratings.takeItem(self.v_ratings.currentRow())
def create_recipe(self):
current_recipe = Recipe(self.e_recipe_name.text(),
self.e_servings.text(),
self.e_time.text(),
self.e_rating_overall.value(),
self.e_url.text())
# Categories
for row in range(self.v_categories.count()):
current_recipe.add_category(self.v_categories.item(row).text())
# Ingredients
for row in range(self.v_ingredients.rowCount()):
current_recipe.add_ingredient(
self.v_ingredients.item(row, 0).text(),
self.v_ingredients.item(row, 1).text()
)
# Utensils
for row in range(self.v_utensils.count()):
current_recipe.add_utensil(self.v_utensils.item(row).text())
# Steps
for row in range(self.v_steps.count()):
current_recipe.add_step(self.v_steps.item(row).text())
# Notes
for row in range(self.v_notes.count()):
current_recipe.add_note(self.v_notes.item(row).text())
# Tips
for row in range(self.v_tips.count()):
current_recipe.add_tip(self.v_tips.item(row).text())
# Variations
for row in range(self.v_variations.count()):
current_recipe.add_variation(self.v_variations.item(row).text())
# Ratings
for row in range(self.v_ratings.count()):
current_recipe.add_rating(self.v_ratings.item(row).text())
writer = MoinMoinWriter()
code = current_recipe.wikicode(writer)
dialog = CodeDialog(code)
dialog.accepted.connect(self.clear)
dialog.exec_()
def clear(self):
"""
Clear all fields
"""
# Tab: Basics
self.e_recipe_name.setText("")
self.e_servings.setText("")
self.e_time.setText("")
self.e_rating_overall.setValue(3)
self.e_url.setText("")
self.e_category.setText("")
self.v_categories.clear()
# Tab: Ingredients
self.e_ingredient.setText("")
self.e_amount.setText("")
self.c_heading.setChecked(False)
self.v_ingredients.clear()
# Tab: Utensils
self.e_utensil.setText("")
self.v_utensils.clear()
# Tab: Steps
self.e_step.setText("")
self.v_steps.clear()
# Tab: Notes
self.e_note.setText("")
self.v_notes.clear()
# Tab: Tips
self.e_tip.setText("")
self.v_tips.clear()
# Tab: Variations
self.e_variation.setText("")
self.v_variations.clear()
# Tab: Ratings
self.e_rating.setText("")
self.v_ratings.clear()
def clear_fields(self):
"""
Show the clear fields dialog.
"""
dialog = ClearDialog()
dialog.accepted.connect(self.clear)
dialog.exec_()
def about(self):
"""
Show an about dialog.
"""
dialog = AboutDialog()
dialog.exec_()
def ask_close(self):
"""
Close the application. A warning is shown before.
"""
dialog = CloseDialog()
dialog.accepted.connect(self.close)
dialog.exec_()
def main():
app = QApplication([])
app.setApplicationName("WikiCookBook")
window = MainWindow()
return app.exec_()

318
wikicookbook.py Normal file → Executable file
View File

@ -1,304 +1,26 @@
#!/usr/bin/python
#!/usr/bin/env python3
"""
WikiCookBook
# Copyright (C) 2020-2021 Marcel Kapfer <opensource@mmk2410.org>
#
# This file is part of WikiCookBook.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
Easily enter recipes and export them to beautiful wiki pages.
Copyright (C) 2020 Marcel Kapfer <opensource@mmk2410.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
"""Launcher for WikiCookBook"""
import sys
import recipe
from writer.MoinMoinWriter import MoinMoinWriter
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox, QTableWidgetItem, QDialog
from ui_mainwindow import Ui_MainWindow
from ui_code_dialog import Ui_WikiCode
from ui_about_dialog import Ui_About
class AboutDialog(QDialog, Ui_About):
def __init__(self, *args, **kwargs):
super(AboutDialog, self).__init__(*args, **kwargs)
self.setupUi(self)
self.b_close.clicked.connect(self.close)
self.show()
class WikiCodeDialog(QDialog, Ui_WikiCode):
def __init__(self, code, *args, **kwargs):
super(WikiCodeDialog, self).__init__(*args, **kwargs)
self.setupUi(self)
self.e_code.setPlainText(code)
self.b_close.clicked.connect(self.close)
self.b_copy.clicked.connect(self.copy)
self.show()
def copy(self):
self.e_code.selectAll()
self.e_code.copy()
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.setupUi(self)
# Connect close actions
self.b_cancel.clicked.connect(self.close)
self.ma_close.triggered.connect(self.close)
# Connect about action
self.ma_information.triggered.connect(self.about)
# Conncect recipe name typing
self.e_recipe_name.textChanged.connect(self.updateTitle)
# Handle categories
self.b_category_add.clicked.connect(self.category_add)
self.e_category.returnPressed.connect(self.category_add)
self.b_category_remove.clicked.connect(self.category_remove)
# Handle ingredients
self.b_ingredient_add.clicked.connect(self.ingredient_add)
self.b_ingredient_remove.clicked.connect(self.ingredient_remove)
# Handle utensils
self.b_utensil_add.clicked.connect(self.utensil_add)
self.e_utensil.returnPressed.connect(self.utensil_add)
self.b_utensil_remove.clicked.connect(self.utensil_remove)
# Handle steps
self.b_step_add.clicked.connect(self.step_add)
self.b_step_edit.clicked.connect(self.step_edit)
self.b_step_replace.clicked.connect(self.step_replace)
self.b_step_remove.clicked.connect(self.step_remove)
# Handle notes
self.b_note_add.clicked.connect(self.note_add)
self.b_note_edit.clicked.connect(self.note_edit)
self.b_note_replace.clicked.connect(self.note_replace)
self.b_note_remove.clicked.connect(self.note_remove)
# Handle tips
self.b_tip_add.clicked.connect(self.tip_add)
self.b_tip_edit.clicked.connect(self.tip_edit)
self.b_tip_replace.clicked.connect(self.tip_replace)
self.b_tip_remove.clicked.connect(self.tip_remove)
# Handle variations
self.b_variation_add.clicked.connect(self.variation_add)
self.b_variation_edit.clicked.connect(self.variation_edit)
self.b_variation_replace.clicked.connect(self.variation_replace)
self.b_variation_remove.clicked.connect(self.variation_remove)
# Handle ratings
self.b_rating_add.clicked.connect(self.rating_add)
self.b_rating_edit.clicked.connect(self.rating_edit)
self.b_rating_replace.clicked.connect(self.rating_replace)
self.b_rating_remove.clicked.connect(self.rating_remove)
# Handle recipe creation
self.b_create.clicked.connect(self.create_recipe)
self.show()
def updateTitle(self):
"""
Update the window title so it contains the name of the current recipe.
"""
current_recipe_name = self.e_recipe_name.text()
if current_recipe_name:
self.setWindowTitle(f"{current_recipe_name} - WikiCookBook")
else:
self.setWindowTitle("WikiCookBook")
def category_add(self):
if self.e_category.text():
self.v_categories.addItem(f"Kategorie{self.e_category.text()}")
def category_remove(self):
self.v_categories.takeItem(self.v_categories.currentRow())
def ingredient_add(self):
if self.c_heading.checkState() == 2 or self.e_amount.text():
if self.e_ingredient.text():
if self.c_heading.checkState() == 2:
current_amount = QTableWidgetItem("----------")
else:
current_amount = QTableWidgetItem(self.e_amount.text())
current_ingredient = QTableWidgetItem(self.e_ingredient.text())
self.v_ingredients.setRowCount(self.v_ingredients.rowCount() + 1)
self.v_ingredients.setItem(self.v_ingredients.rowCount() - 1, 0, current_amount)
self.v_ingredients.setItem(self.v_ingredients.rowCount() - 1, 1, current_ingredient)
def ingredient_remove(self):
self.v_ingredients.removeRow(self.v_ingredients.currentRow())
def utensil_add(self):
if self.e_utensil.text():
self.v_utensils.addItem(self.e_utensil.text())
def utensil_remove(self):
self.v_utensils.takeItem(self.v_utensils.currentRow())
def step_add(self):
if self.e_step.toPlainText():
self.v_steps.addItem(self.e_step.toPlainText())
def step_edit(self):
if self.v_steps.count() > 0:
self.e_step.setText(self.v_steps.currentItem().text())
def step_replace(self):
if self.e_step.toPlainText() and self.v_steps.count() > 0:
self.v_steps.currentItem().setText(self.e_step.toPlainText())
def step_remove(self):
self.v_steps.takeItem(self.v_steps.currentRow())
def note_add(self):
if self.e_note.toPlainText():
self.v_notes.addItem(self.e_note.toPlainText())
def note_edit(self):
if self.v_notes.count() > 0:
self.e_note.setText(self.v_notes.currentItem().text())
def note_replace(self):
if self.e_note.toPlainText() and self.v_notes.count() > 0:
self.v_notes.currentItem().setText(self.e_note.toPlainText())
def note_remove(self):
self.v_notes.takeItem(self.v_notes.currentRow())
def tip_add(self):
if self.e_tip.toPlainText():
self.v_tips.addItem(self.e_tip.toPlainText())
def tip_edit(self):
if self.v_tips.count() > 0:
self.e_tip.setText(self.v_tips.currentItem().text())
def tip_replace(self):
if self.e_tip.toPlainText() and self.v_tips.count() > 0:
self.v_tips.currentItem().setText(self.e_tip.toPlainText())
def tip_remove(self):
self.v_tips.takeItem(self.v_tips.currentRow())
def variation_add(self):
if self.e_variation.toPlainText():
self.v_variations.addItem(self.e_variation.toPlainText())
def variation_edit(self):
if self.v_variations.count() > 0:
self.e_variation.setText(self.v_variations.currentItem().text())
def variation_replace(self):
if self.e_variation.toPlainText() and self.v_variations.count() > 0:
self.v_variations.currentItem().setText(self.e_variation.toPlainText())
def variation_remove(self):
self.v_variations.takeItem(self.v_variations.currentRow())
def rating_add(self):
if self.e_rating.toPlainText():
self.v_ratings.addItem(self.e_rating.toPlainText())
def rating_edit(self):
if self.v_ratings.count() > 0:
self.e_rating.setText(self.v_ratings.currentItem().text())
def rating_replace(self):
if self.e_rating.toPlainText() and self.v_ratings.count() > 0:
self.v_ratings.currentItem().setText(self.e_rating.toPlainText())
def rating_remove(self):
self.v_ratings.takeItem(self.v_ratings.currentRow())
def create_recipe(self):
current_recipe = recipe.Recipe(self.e_recipe_name.text(),
self.e_servings.text(),
self.e_time.text(),
self.e_rating_overall.value(),
self.e_url.text())
# Categories
for row in range(self.v_categories.count()):
current_recipe.add_category(self.v_categories.item(row).text())
# Ingredients
for row in range(self.v_ingredients.rowCount()):
current_recipe.add_ingredient(
self.v_ingredients.item(row, 0).text(),
self.v_ingredients.item(row, 1).text()
)
# Utensils
for row in range(self.v_utensils.count()):
current_recipe.add_utensil(self.v_utensils.item(row).text())
# Steps
for row in range(self.v_steps.count()):
current_recipe.add_step(self.v_steps.item(row).text())
# Notes
for row in range(self.v_notes.count()):
current_recipe.add_note(self.v_notes.item(row).text())
# Tips
for row in range(self.v_tips.count()):
current_recipe.add_tip(self.v_tips.item(row).text())
# Variations
for row in range(self.v_variations.count()):
current_recipe.add_variation(self.v_variations.item(row).text())
# Ratings
for row in range(self.v_ratings.count()):
current_recipe.add_rating(self.v_ratings.item(row).text())
writer = MoinMoinWriter()
code = current_recipe.wikicode(writer)
dialog = WikiCodeDialog(code)
dialog.exec_()
def about(self):
"""
Show an about dialog.
"""
dialog = AboutDialog()
dialog.exec_()
def close(self):
"""
Close the application. A warning is shown before.
"""
reply = QMessageBox.question(self, "Sicher?",
"Möchten Sie wirklich schließen?",
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
super.close()
import WikiCookBook.wikicookbook
if __name__ == "__main__":
app = QApplication([])
app.setApplicationName("WikiCookBook")
window = MainWindow()
sys.exit(app.exec_())
sys.exit(WikiCookBook.wikicookbook.main())