|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2013 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the .desktop wizard dialog. |
|
8 """ |
|
9 |
|
10 from __future__ import unicode_literals |
|
11 |
|
12 import os |
|
13 |
|
14 from PyQt5.QtCore import pyqtSlot |
|
15 from PyQt5.QtWidgets import QDialog, QDialogButtonBox |
|
16 |
|
17 from E5Gui.E5Application import e5App |
|
18 from E5Gui import E5MessageBox |
|
19 |
|
20 from .Ui_DotDesktopWizardDialog import Ui_DotDesktopWizardDialog |
|
21 |
|
22 import Utilities |
|
23 import UI.PixmapCache |
|
24 |
|
25 |
|
26 class DotDesktopWizardDialog(QDialog, Ui_DotDesktopWizardDialog): |
|
27 """ |
|
28 Class implementing the .desktop wizard dialog. |
|
29 """ |
|
30 def __init__(self, parent=None): |
|
31 """ |
|
32 Constructor |
|
33 |
|
34 @param parent reference to the parent widget (QWidget) |
|
35 """ |
|
36 super(DotDesktopWizardDialog, self).__init__(parent) |
|
37 self.setupUi(self) |
|
38 |
|
39 self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) |
|
40 |
|
41 self.__mainCategories = [ |
|
42 'AudioVideo', 'Audio', 'Video', 'Development', 'Education', |
|
43 'Game', 'Graphics', 'Network', 'Office', 'Science', 'Settings', |
|
44 'System', 'Utility', |
|
45 ] |
|
46 |
|
47 self.__subCategories = [ |
|
48 'Building', 'Debugger', 'IDE', 'GUIDesigner', 'Profiling', |
|
49 'RevisionControl', 'Translation', 'Calendar', 'ContactManagement', |
|
50 'Database', 'Dictionary', 'Chart', 'Email', 'Finance', 'FlowChart', |
|
51 'PDA', 'ProjectManagement', 'Presentation', 'Spreadsheet', |
|
52 'WordProcessor', '2DGraphics', 'VectorGraphics', 'RasterGraphics', |
|
53 '3DGraphics', 'Scanning', 'OCR', 'Photography', 'Publishing', |
|
54 'Viewer', 'TextTools', 'DesktopSettings', 'HardwareSettings', |
|
55 'Printing', 'PackageManager', 'Dialup', 'InstantMessaging', 'Chat', |
|
56 'IRCClient', 'Feed', 'FileTransfer', 'HamRadio', 'News', 'P2P', |
|
57 'RemoteAccess', 'Telephony', 'TelephonyTools', 'VideoConference', |
|
58 'WebBrowser', 'WebDevelopment', 'Midi', 'Mixer', 'Sequencer', |
|
59 'Tuner', 'TV', 'AudioVideoEditing', 'Player', 'Recorder', |
|
60 'DiscBurning', 'ActionGame', 'AdventureGame', 'ArcadeGame', |
|
61 'BoardGame', 'BlocksGame', 'CardGame', 'KidsGame', 'LogicGame', |
|
62 'RolePlaying', 'Shooter', 'Simulation', 'SportsGame', |
|
63 'StrategyGame', 'Art', 'Construction', 'Music', 'Languages', |
|
64 'ArtificialIntelligence', 'Astronomy', 'Biology', 'Chemistry', |
|
65 'ComputerScience', 'DataVisualization', 'Economy', 'Electricity', |
|
66 'Geography', 'Geology', 'Geoscience', 'History', 'Humanities', |
|
67 'ImageProcessing', 'Literature', 'Maps', 'Math', |
|
68 'NumericalAnalysis', 'MedicalSoftware', 'Physics', 'Robotics', |
|
69 'Spirituality', 'Sports', 'ParallelComputing', 'Amusement', |
|
70 'Archiving', 'Compression', 'Electronics', 'Emulator', |
|
71 'Engineering', 'FileTools', 'FileManager', 'TerminalEmulator', |
|
72 'Filesystem', 'Monitor', 'Security', 'Accessibility', 'Calculator', |
|
73 'Clock', 'TextEditor', 'Documentation', 'Adult', 'Core', 'KDE', |
|
74 'GNOME', 'XFCE', 'GTK', 'Qt', 'Motif', 'Java', 'ConsoleOnly', |
|
75 ] |
|
76 |
|
77 self.__showinEnvironments = [ |
|
78 'GNOME', 'KDE', 'LXDE', 'LXQt', 'MATE', 'Razor', 'ROX', 'TDE', |
|
79 'Unity', 'XFCE', 'EDE', 'Cinnamon', 'Pantheon', 'Old', |
|
80 ] |
|
81 |
|
82 self.typeComboBox.addItems([ |
|
83 self.tr("FreeDesktop Standard .desktop"), |
|
84 self.tr("KDE Plasma MetaData .desktop"), |
|
85 self.tr("Ubuntu Unity QuickList .desktop"), |
|
86 ]) |
|
87 |
|
88 self.kdeCategoryComboBox.addItems([ |
|
89 '', 'Application Launchers', 'Accessibility', 'Astronomy', |
|
90 'Date and Time', 'Development Tools', 'Education', 'Environment', |
|
91 'Examples', 'File System', 'Fun and Games', 'Graphics', |
|
92 'Language', 'Mapping', 'Multimedia', 'Online Services', |
|
93 'System Information', 'Utilities', 'Windows and Tasks', |
|
94 'Miscelaneous', |
|
95 ]) |
|
96 |
|
97 self.kdeApiComboBox.addItems([ |
|
98 'Python', 'Javascript', 'Ruby', 'C++', 'HTML5', 'QML' |
|
99 ]) |
|
100 |
|
101 self.kdeEncodingComboBox.addItems(sorted(Utilities.supportedCodecs)) |
|
102 self.kdeEncodingComboBox.setCurrentIndex( |
|
103 self.kdeEncodingComboBox.findText("utf-8")) |
|
104 |
|
105 projectOpen = e5App().getObject("Project").isOpen() |
|
106 self.projectButton.setEnabled(projectOpen) |
|
107 |
|
108 icon = UI.PixmapCache.getIcon("listSelection.png") |
|
109 self.categoriesButton.setIcon(icon) |
|
110 self.onlyShowButton.setIcon(icon) |
|
111 self.notShowButton.setIcon(icon) |
|
112 |
|
113 def getCode(self): |
|
114 """ |
|
115 Public method to get the source code. |
|
116 |
|
117 @return generated code (string) |
|
118 """ |
|
119 # step 1: standard desktop entries |
|
120 code = [ |
|
121 '[Desktop Entry]', |
|
122 'Type=' + self.typeEdit.text(), |
|
123 ] |
|
124 if self.versionEdit.text(): |
|
125 code.append('Version=' + self.versionEdit.text()) |
|
126 code.append('Name=' + self.nameEdit.text()) |
|
127 if self.genericNameEdit.text(): |
|
128 code.append('GenericName=' + self.genericNameEdit.text()) |
|
129 if self.commentEdit.text(): |
|
130 code.append('Comment=' + self.commentEdit.text()) |
|
131 if self.iconFileEdit.text(): |
|
132 code.append('Icon=' + self.iconFileEdit.text()) |
|
133 if self.onlyShowEdit.text(): |
|
134 code.append('OnlyShowIn=' + self.onlyShowEdit.text()) |
|
135 if self.notShowEdit.text(): |
|
136 code.append('NotShowIn=' + self.notShowEdit.text()) |
|
137 if self.tryExecEdit.text(): |
|
138 code.append('TryExec=' + self.tryExecEdit.text()) |
|
139 if self.execEdit.text(): |
|
140 code.append('Exec=' + self.execEdit.text()) |
|
141 if self.pathEdit.text(): |
|
142 code.append('Path=' + self.pathEdit.text()) |
|
143 if self.terminalCheckBox.isChecked(): |
|
144 code.append('Terminal=true') |
|
145 if self.actionsEdit.text(): |
|
146 code.append('Actions=' + self.actionsEdit.text()) |
|
147 if self.mimetypeEdit.text(): |
|
148 code.append('MimeType=' + self.mimetypeEdit.text()) |
|
149 if self.categoriesEdit.text(): |
|
150 code.append('Categories=' + self.categoriesEdit.text()) |
|
151 |
|
152 # step 2a: KDE Plasma entries |
|
153 if self.typeComboBox.currentIndex() == 1: |
|
154 if self.kdeEncodingComboBox.currentText(): |
|
155 code.append('Encoding=' + |
|
156 self.kdeEncodingComboBox.currentText()) |
|
157 if self.kdeServiceTypeEdit.text(): |
|
158 code.append('ServiceTypes=' + |
|
159 self.kdeServiceTypeEdit.text()) |
|
160 if self.kdeApiComboBox.currentText(): |
|
161 code.append('X-Plasma-API=' + |
|
162 self.kdeApiComboBox.currentText()) |
|
163 if self.kdeMainScriptEdit.text(): |
|
164 code.append('X-Plasma-MainScript=' + |
|
165 self.kdeMainScriptEdit.text()) |
|
166 if self.kdeAuthorEdit.text(): |
|
167 code.append('X-KDE-PluginInfo-Author=' + |
|
168 self.kdeAuthorEdit.text()) |
|
169 if self.kdeEmailEdit.text(): |
|
170 code.append('X-KDE-PluginInfo-Email=' + |
|
171 self.kdeEmailEdit.text()) |
|
172 if self.kdeNameEdit.text(): |
|
173 code.append('X-KDE-PluginInfo-Name=' + |
|
174 self.kdeNameEdit.text()) |
|
175 if self.kdeVersionEdit.text(): |
|
176 code.append('X-KDE-PluginInfo-Version=' + |
|
177 self.kdeVersionEdit.text()) |
|
178 if self.kdeWebsiteEdit.text(): |
|
179 code.append('X-KDE-PluginInfo-Website=' + |
|
180 self.kdeWebsiteEdit.text()) |
|
181 if self.kdeCategoryComboBox.currentText(): |
|
182 code.append('X-KDE-PluginInfo-Category=' + |
|
183 self.kdeCategoryComboBox.currentText()) |
|
184 if self.kdeDependsEdit.text(): |
|
185 code.append('X-KDE-PluginInfo-Depends=' + |
|
186 self.kdeDependsEdit.text()) |
|
187 if self.kdeLicensEdit.text(): |
|
188 code.append('X-KDE-PluginInfo-License=' + |
|
189 self.kdeLicensEdit.text()) |
|
190 if self.kdeEnabledDefaultCheckBox.isChecked(): |
|
191 code.append('X-KDE-PluginInfo-EnabledByDefault=true') |
|
192 |
|
193 # step 2b: Unity entries |
|
194 if self.typeComboBox.currentIndex() == 2: |
|
195 if self.unityShortcutsEdit.text(): |
|
196 code.append('X-Ayatana-Desktop-Shortcuts=' + |
|
197 self.unityShortcutsEdit.text()) |
|
198 |
|
199 # step 3: action entries |
|
200 actions = [act for act in self.actionsEdit.text().split(";") if act] |
|
201 for act in actions: |
|
202 code.append('') |
|
203 code.append('[Desktop Action {0}]'.format(act)) |
|
204 code.append('Name={0}'.format(act)) |
|
205 code.append('Icon=<Icon Path>') |
|
206 code.append('Exec=<Executable command>') |
|
207 |
|
208 # step 4: add empty last line |
|
209 code.append('') |
|
210 |
|
211 return os.linesep.join(code) |
|
212 |
|
213 def __checkOK(self): |
|
214 """ |
|
215 Private slot to check, if the OK button should be enabled. |
|
216 """ |
|
217 enable = bool(self.nameEdit.text()) and bool(self.typeEdit.text()) |
|
218 if bool(self.onlyShowEdit.text()) and bool(self.notShowEdit.text()): |
|
219 enable = False |
|
220 self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable) |
|
221 |
|
222 @pyqtSlot(int) |
|
223 def on_typeComboBox_currentIndexChanged(self, index): |
|
224 """ |
|
225 Private slot to handle a change of the .desktop type. |
|
226 |
|
227 @param index index of the selected entry (integer) |
|
228 """ |
|
229 self.dataTabWidget.setTabEnabled(1, index == 1) |
|
230 self.dataTabWidget.setTabEnabled(2, index == 2) |
|
231 |
|
232 @pyqtSlot() |
|
233 def on_projectButton_clicked(self): |
|
234 """ |
|
235 Private slot to populate some fields with data retrieved from the |
|
236 current project. |
|
237 """ |
|
238 project = e5App().getObject("Project") |
|
239 |
|
240 self.nameEdit.setText(project.getProjectName()) |
|
241 self.genericNameEdit.setText(project.getProjectName()) |
|
242 self.kdeNameEdit.setText(project.getProjectName()) |
|
243 try: |
|
244 self.kdeVersionEdit.setText(project.getProjectVersion()) |
|
245 self.kdeAuthorEdit.setText(project.getProjectAuthor()) |
|
246 self.kdeEmailEdit.setText(project.getProjectAuthorEmail()) |
|
247 except AttributeError: |
|
248 self.kdeVersionEdit.setText(project.pdata["VERSION"][0]) |
|
249 self.kdeAuthorEdit.setText(project.pdata["AUTHOR"][0]) |
|
250 self.kdeEmailEdit.setText(project.pdata["EMAIL"][0]) |
|
251 mainscript = project.getMainScript(True) |
|
252 if mainscript: |
|
253 self.kdeMainScriptEdit.setText(mainscript) |
|
254 self.execEdit.setText(mainscript) |
|
255 self.tryExecEdit.setText(mainscript) |
|
256 |
|
257 # prevent overwriting of entries by disabling the button |
|
258 self.projectButton.setEnabled(False) |
|
259 |
|
260 @pyqtSlot() |
|
261 def on_categoriesButton_clicked(self): |
|
262 """ |
|
263 Private slot to select the categories. |
|
264 """ |
|
265 from .DotDesktopListSelectionDialog import \ |
|
266 DotDesktopListSelectionDialog |
|
267 dlg = DotDesktopListSelectionDialog( |
|
268 self.__mainCategories, |
|
269 self.categoriesEdit.text(), ";", |
|
270 subEntries=self.__subCategories, |
|
271 allowMultiMain=False) |
|
272 if dlg.exec_() == QDialog.Accepted: |
|
273 categories = dlg.getData(";", True) |
|
274 self.categoriesEdit.setText(categories) |
|
275 |
|
276 @pyqtSlot(str) |
|
277 def on_onlyShowEdit_textChanged(self, txt): |
|
278 """ |
|
279 Private slot to check the contents of the onlyShowEdit field. |
|
280 |
|
281 @param txt text of the entry field (string) |
|
282 """ |
|
283 self.__checkOK() |
|
284 if bool(self.onlyShowEdit.text()) and bool(self.notShowEdit.text()): |
|
285 E5MessageBox.critical( |
|
286 self, |
|
287 self.tr(".desktop Wizard"), |
|
288 self.tr("""Only one of 'Only Show In' or """ |
|
289 """ 'Not Show In' allowed.""")) |
|
290 |
|
291 @pyqtSlot() |
|
292 def on_onlyShowButton_clicked(self): |
|
293 """ |
|
294 Private slot to select the OnlyShowIn environments. |
|
295 """ |
|
296 from .DotDesktopListSelectionDialog import \ |
|
297 DotDesktopListSelectionDialog |
|
298 dlg = DotDesktopListSelectionDialog( |
|
299 self.__showinEnvironments, |
|
300 self.onlyShowEdit.text(), ";") |
|
301 if dlg.exec_() == QDialog.Accepted: |
|
302 environments = dlg.getData(";", True) |
|
303 self.onlyShowEdit.setText(environments) |
|
304 |
|
305 @pyqtSlot(str) |
|
306 def on_notShowEdit_textChanged(self, txt): |
|
307 """ |
|
308 Private slot to check the contents of the notShowEdit field. |
|
309 |
|
310 @param txt text of the entry field (string) |
|
311 """ |
|
312 self.__checkOK() |
|
313 if bool(self.onlyShowEdit.text()) and bool(self.notShowEdit.text()): |
|
314 E5MessageBox.critical( |
|
315 self, |
|
316 self.tr(".desktop Wizard"), |
|
317 self.tr("""Only one of 'Only Show In' or """ |
|
318 """ 'Not Show In' allowed.""")) |
|
319 |
|
320 @pyqtSlot() |
|
321 def on_notShowButton_clicked(self): |
|
322 """ |
|
323 Private slot to select the NotShowIn environments. |
|
324 """ |
|
325 from .DotDesktopListSelectionDialog import \ |
|
326 DotDesktopListSelectionDialog |
|
327 dlg = DotDesktopListSelectionDialog( |
|
328 self.__showinEnvironments, |
|
329 self.notShowEdit.text(), ";") |
|
330 if dlg.exec_() == QDialog.Accepted: |
|
331 environments = dlg.getData(";", True) |
|
332 self.notShowEdit.setText(environments) |
|
333 |
|
334 @pyqtSlot(str) |
|
335 def on_typeEdit_textChanged(self, txt): |
|
336 """ |
|
337 Private slot to check, if the typeEdit field is empty. |
|
338 |
|
339 @param txt text of the entry field (string) |
|
340 """ |
|
341 self.__checkOK() |
|
342 |
|
343 @pyqtSlot(str) |
|
344 def on_nameEdit_textChanged(self, txt): |
|
345 """ |
|
346 Private slot to check, if the nameEdit field is empty. |
|
347 |
|
348 @param txt text of the entry field (string) |
|
349 """ |
|
350 self.__checkOK() |