Krita Source Code Documentation
Loading...
Searching...
No Matches
comics_project_setup_wizard.py
Go to the documentation of this file.
1"""
2SPDX-FileCopyrightText: 2017 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com>
3
4This file is part of the Comics Project Management Tools(CPMT).
5
6SPDX-License-Identifier: GPL-3.0-or-later
7"""
8
9"""
10This is a wizard that helps you set up a comics project in Krita.
11"""
12
13import json # For writing to json.
14import os # For finding the script location.
15from pathlib import Path # For reading all the files in a directory.
16import random # For selecting two random words from a list.
17try:
18 from PyQt6.QtWidgets import QWizard, QWizardPage, QHBoxLayout, QFormLayout, QLineEdit, QPushButton, QCheckBox, QLabel, QDialog, QMessageBox
19 from PyQt6.QtCore import QLocale, QUuid
20except:
21 from PyQt5.QtWidgets import QWizard, QWizardPage, QHBoxLayout, QFormLayout, QLineEdit, QPushButton, QCheckBox, QLabel, QDialog, QMessageBox
22 from PyQt5.QtCore import QLocale, QUuid
23from krita import FileDialog
24from builtins import i18n
25from . import comics_metadata_dialog
26
27"""
28The actual wizard.
29"""
30
31
33 setupDictionary = {}
34 projectDirectory = ""
35
36 def __init__(self):
37 # super().__init__(parent)
38 # Search the location of the script for the two lists that are used with the projectname generator.
39 mainP = Path(__file__).parent
40 self.generateListA = []
41 self.generateListB = []
42 if Path(mainP / "projectGenLists" / "listA.txt").exists():
43 for l in open(str(mainP / "projectGenLists" / "listA.txt"), "r"):
44 if l.isspace() == False:
45 self.generateListA.append(l.strip("\n"))
46 if Path(mainP / "projectGenLists" / "listB.txt").exists():
47 for l in open(str(mainP / "projectGenLists" / "listB.txt"), "r"):
48 if l.isspace() == False:
49 self.generateListB.append(l.strip("\n"))
50
51 def showDialog(self):
52 # Initialise the setup directory empty toavoid exceptions.
54
55 # ask for a project directory.
57
58 while self.projectDirectoryprojectDirectory == None:
59 self.projectDirectoryprojectDirectory = FileDialog.getExistingDirectory(caption=i18n("Where should the comic project go?"))
60 if os.path.exists(self.projectDirectoryprojectDirectory) is False:
61 return
62 if os.access(self.projectDirectoryprojectDirectory, os.W_OK) is False:
63 QMessageBox.warning(None, i18n("Folder cannot be used"), i18n("Krita doesn't have write access to this folder, so files cannot be made. Please choose a different folder."), QMessageBox.StandardButton.Ok)
67
68 wizard = QWizard()
69 wizard.setWindowTitle(i18n("Comic Project Setup"))
70 wizard.setOption(QWizard.WizardOption.IndependentPages, True)
71 wizard.setWizardStyle(QWizard.WizardStyle.ClassicStyle)
72
73 # Set up the UI for the wizard
74 basicsPage = QWizardPage()
75 basicsPage.setTitle(i18n("Basic Comic Project Settings"))
76 formLayout = QFormLayout()
77 basicsPage.setLayout(formLayout)
78 projectLayout = QHBoxLayout()
79 self.lnProjectName = QLineEdit()
80 basicsPage.registerField("Project Name*", self.lnProjectName)
81 self.lnProjectName.setToolTip(i18n("A Project name. This can be different from the eventual title"))
82 btnRandom = QPushButton()
83 btnRandom.setText(i18n("Generate"))
84 btnRandom.setToolTip(i18n("If you cannot come up with a project name, our highly sophisticated project name generator will serve to give a classy yet down to earth name."))
85 btnRandom.clicked.connect(self.slot_generateslot_generate)
86 projectLayout.addWidget(self.lnProjectName)
87 projectLayout.addWidget(btnRandom)
88 lnConcept = QLineEdit()
89 lnConcept.setToolTip(i18n("What is your comic about? This is mostly for your own convenience so do not worry about what it says too much."))
91 self.cmbLanguage.setToolTip(i18n("The main language the comic is in"))
92 self.cmbLanguage.setEntryToCode(str(QLocale.system().name()).split("_")[0])
94 if QLocale.system() != QLocale.c():
96 self.cmbCountry.setEntryToCode(str(QLocale.system().name()).split("_")[-1])
97 else:
98 self.cmbLanguage.setEntryToCode("en")
100 self.cmbCountry.setEntryToCode("US")
101 self.cmbLanguage.currentIndexChanged.connect(self.slot_update_countriesslot_update_countries)
103 self.chkMakeProjectDirectory = QCheckBox()
104 labelDirectory = QLabel(i18n("Make a new directory with the project name."))
105 labelDirectory.setWordWrap(True)
106 stringDirectoryTooltip = i18n("This allows you to select a generic comics project directory, in which a new folder will be made for the project using the given project name.")
107 self.chkMakeProjectDirectory.setToolTip(stringDirectoryTooltip)
108 labelDirectory.setToolTip(stringDirectoryTooltip)
109 self.chkMakeProjectDirectory.setChecked(True)
110 self.lnPagesDirectory = QLineEdit()
111 self.lnPagesDirectory.setText(i18n("pages"))
112 self.lnPagesDirectory.setToolTip(i18n("The name for the folder where the pages are contained. If it does not exist, it will be created."))
113 self.lnExportDirectory = QLineEdit()
114 self.lnExportDirectory.setText(i18n("export"))
115 self.lnExportDirectory.setToolTip(i18n("The name for the folder where the export is put. If it does not exist, it will be created."))
116 self.lnTemplateLocation = QLineEdit()
117 self.lnTemplateLocation.setText(i18n("templates"))
118 self.lnTemplateLocation.setToolTip(i18n("The name for the folder where the page templates are sought in."))
119
120 self.lnTranslationLocation = QLineEdit()
121 self.lnTranslationLocation.setText(i18n("translations"))
122 self.lnTranslationLocation.setToolTip("This is the location that POT files will be stored to and PO files will be read from.")
123 formLayout.addRow(i18n("Comic concept:"), lnConcept)
124 formLayout.addRow(i18n("Project name:"), projectLayout)
125 formLayout.addRow(i18n("Main language:"), self.cmbLanguage)
126 formLayout.addRow("", self.cmbCountry)
127
128 buttonMetaData = QPushButton(i18n("Meta Data"))
129 buttonMetaData.clicked.connect(self.slot_edit_meta_dataslot_edit_meta_data)
130
131 wizard.addPage(basicsPage)
132
133 foldersPage = QWizardPage()
134 foldersPage.setTitle(i18n("Folder names and other."))
135 folderFormLayout = QFormLayout()
136 foldersPage.setLayout(folderFormLayout)
137 folderFormLayout.addRow(i18n("Project directory:"), self.lnProjectDirectory)
138 folderFormLayout.addRow(self.chkMakeProjectDirectory, labelDirectory)
139 folderFormLayout.addRow(i18n("Pages directory"), self.lnPagesDirectory)
140 folderFormLayout.addRow(i18n("Export directory"), self.lnExportDirectory)
141 folderFormLayout.addRow(i18n("Template directory"), self.lnTemplateLocation)
142 folderFormLayout.addRow(i18n("Translation directory"), self.lnTranslationLocation)
143 folderFormLayout.addRow("", buttonMetaData)
144 wizard.addPage(foldersPage)
145
146 # Execute the wizard, and after wards...
147 if (wizard.exec()):
148
149 # First get the directories, check if the directories exist, and otherwise make them.
150 self.pagesDirectory = self.lnPagesDirectory.text()
151 self.exportDirectory = self.lnExportDirectory.text()
154 projectPath = Path(self.projectDirectoryprojectDirectory)
155
156 # Only make a project directory if the checkbox for that has been checked.
157 if self.chkMakeProjectDirectory.isChecked():
158 projectPath = projectPath / self.lnProjectName.text()
159 if projectPath.exists() is False:
160 projectPath.mkdir()
161 self.projectDirectoryprojectDirectory = str(projectPath)
162 if Path(projectPath / self.pagesDirectory).exists() is False:
163 Path(projectPath / self.pagesDirectory).mkdir()
164 if Path(projectPath / self.exportDirectory).exists() is False:
165 Path(projectPath / self.exportDirectory).mkdir()
166 if Path(projectPath / self.templateLocation).exists() is False:
167 Path(projectPath / self.templateLocation).mkdir()
168 if Path(projectPath / self.translationLocation).exists() is False:
169 Path(projectPath / self.translationLocation).mkdir()
170
171 # Then store the information into the setup diactionary.
172 self.setupDictionarysetupDictionary["projectName"] = self.lnProjectName.text()
173 self.setupDictionarysetupDictionary["concept"] = lnConcept.text()
174 self.setupDictionarysetupDictionary["language"] = str(self.cmbLanguage.codeForCurrentEntry())
175 self.setupDictionarysetupDictionary["pagesLocation"] = self.pagesDirectory
176 self.setupDictionarysetupDictionary["exportLocation"] = self.exportDirectory
177 self.setupDictionarysetupDictionary["templateLocation"] = self.templateLocation
178 self.setupDictionarysetupDictionary["translationLocation"] = self.translationLocation
179 self.setupDictionarysetupDictionary["uuid"] = QUuid.createUuid().toString()
180
181 # Finally, write the dictionary into the json file.
182 self.writeConfig()
183 """
184 This calls up the metadata dialog, for if people already have information they want to type in
185 at the setup stage. Not super likely, but the organisation and management aspect of the comic
186 manager means we should give the option to organise as smoothly as possible.
187 """
188
191 self.setupDictionarysetupDictionary["language"] = str(self.cmbLanguage.codeForCurrentEntry())
192 dialog.setConfig(self.setupDictionarysetupDictionary)
193 dialog.setConfig(self.setupDictionarysetupDictionary)
194 if (dialog.exec() == QDialog.DialogCode.Accepted):
196 self.cmbLanguage.setEntryToCode(self.setupDictionarysetupDictionary["language"])
197
198 """
199 Update the country list when the language list changes.
200 """
201
203 code = self.cmbLanguage.codeForCurrentEntry()
204 self.cmbCountry.set_country_for_locale(code)
205
206 """
207 Write the actual config to the chosen project directory.
208 """
209
210 def writeConfig(self):
211 print("CPMT: writing comic configuration...")
213 configFile = open(os.path.join(self.projectDirectoryprojectDirectory, "comicConfig.json"), "w", newline="", encoding="utf-16")
214 json.dump(self.setupDictionarysetupDictionary, configFile, indent=4, sort_keys=True, ensure_ascii=False)
215 configFile.close()
216 print("CPMT: done")
217 """
218 As you may be able to tell, the random projectname generator is hardly sophisticated.
219 It picks a word from a list of names of figures from Greek Mythology, and a name from a list
220 of vegetables and fruits and combines the two camelcased.
221 It makes for good codenames at the least.
222 """
223
224 def slot_generate(self):
225 if len(self.generateListA) > 0 and len(self.generateListB) > 0:
226 nameA = self.generateListA[random.randint(0, len(self.generateListA) - 1)]
227 nameB = self.generateListB[random.randint(0, len(self.generateListB) - 1)]
228 self.lnProjectName.setText(str(nameA.title() + nameB.title()))
static QString getExistingDirectory(QWidget *parent=nullptr, const QString &caption=QString(), const QString &directory=QString(), const QString &dialogName=QString())
Create and show a file dialog and return the name of an existing directory selected by the user.