|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2013 - 2017 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 |
|
83 self.typeComboBox.addItems([ |
|
84 self.tr("FreeDesktop Standard .desktop"), |
|
85 self.tr("KDE Plasma MetaData .desktop"), |
|
86 self.tr("Ubuntu Unity QuickList .desktop"), |
|
87 ]) |
|
88 |
|
89 self.kdeCategoryComboBox.addItems([ |
|
90 '', 'Application Launchers', 'Accessibility', 'Astronomy', |
|
91 'Date and Time', 'Development Tools', 'Education', 'Environment', |
|
92 'Examples', 'File System', 'Fun and Games', 'Graphics', |
|
93 'Language', 'Mapping', 'Multimedia', 'Online Services', |
|
94 'System Information', 'Utilities', 'Windows and Tasks', |
|
95 'Miscelaneous', |
|
96 ]) |
|
97 |
|
98 self.kdeApiComboBox.addItems([ |
|
99 'Python', 'Javascript', 'Ruby', 'C++', 'HTML5', 'QML' |
|
100 ]) |
|
101 |
|
102 self.kdeEncodingComboBox.addItems(sorted(Utilities.supportedCodecs)) |
|
103 self.kdeEncodingComboBox.setCurrentIndex( |
|
104 self.kdeEncodingComboBox.findText("utf-8")) |
|
105 |
|
106 projectOpen = e5App().getObject("Project").isOpen() |
|
107 self.projectButton.setEnabled(projectOpen) |
|
108 |
|
109 icon = UI.PixmapCache.getIcon("listSelection.png") |
|
110 self.categoriesButton.setIcon(icon) |
|
111 self.onlyShowButton.setIcon(icon) |
|
112 self.notShowButton.setIcon(icon) |
|
113 |
|
114 def getCode(self): |
|
115 """ |
|
116 Public method to get the source code. |
|
117 |
|
118 @return generated code (string) |
|
119 """ |
|
120 # step 1: standard desktop entries |
|
121 code = [ |
|
122 '[Desktop Entry]', |
|
123 'Type=' + self.typeEdit.text(), |
|
124 ] |
|
125 if self.versionEdit.text(): |
|
126 code.append('Version=' + self.versionEdit.text()) |
|
127 code.append('Name=' + self.nameEdit.text()) |
|
128 if self.genericNameEdit.text(): |
|
129 code.append('GenericName=' + self.genericNameEdit.text()) |
|
130 if self.commentEdit.text(): |
|
131 code.append('Comment=' + self.commentEdit.text()) |
|
132 if self.iconFileEdit.text(): |
|
133 code.append('Icon=' + self.iconFileEdit.text()) |
|
134 if self.onlyShowEdit.text(): |
|
135 code.append('OnlyShowIn=' + self.onlyShowEdit.text()) |
|
136 if self.notShowEdit.text(): |
|
137 code.append('NotShowIn=' + self.notShowEdit.text()) |
|
138 if self.tryExecEdit.text(): |
|
139 code.append('TryExec=' + self.tryExecEdit.text()) |
|
140 if self.execEdit.text(): |
|
141 code.append('Exec=' + self.execEdit.text()) |
|
142 if self.pathEdit.text(): |
|
143 code.append('Path=' + self.pathEdit.text()) |
|
144 if self.terminalCheckBox.isChecked(): |
|
145 code.append('Terminal=true') |
|
146 if self.actionsEdit.text(): |
|
147 code.append('Actions=' + self.actionsEdit.text()) |
|
148 if self.mimetypeEdit.text(): |
|
149 code.append('MimeType=' + self.mimetypeEdit.text()) |
|
150 if self.categoriesEdit.text(): |
|
151 code.append('Categories=' + self.categoriesEdit.text()) |
|
152 |
|
153 # step 2a: KDE Plasma entries |
|
154 if self.typeComboBox.currentIndex() == 1: |
|
155 if self.kdeEncodingComboBox.currentText(): |
|
156 code.append('Encoding=' + |
|
157 self.kdeEncodingComboBox.currentText()) |
|
158 if self.kdeServiceTypeEdit.text(): |
|
159 code.append('ServiceTypes=' + |
|
160 self.kdeServiceTypeEdit.text()) |
|
161 if self.kdeApiComboBox.currentText(): |
|
162 code.append('X-Plasma-API=' + |
|
163 self.kdeApiComboBox.currentText()) |
|
164 if self.kdeMainScriptEdit.text(): |
|
165 code.append('X-Plasma-MainScript=' + |
|
166 self.kdeMainScriptEdit.text()) |
|
167 if self.kdeAuthorEdit.text(): |
|
168 code.append('X-KDE-PluginInfo-Author=' + |
|
169 self.kdeAuthorEdit.text()) |
|
170 if self.kdeEmailEdit.text(): |
|
171 code.append('X-KDE-PluginInfo-Email=' + |
|
172 self.kdeEmailEdit.text()) |
|
173 if self.kdeNameEdit.text(): |
|
174 code.append('X-KDE-PluginInfo-Name=' + |
|
175 self.kdeNameEdit.text()) |
|
176 if self.kdeVersionEdit.text(): |
|
177 code.append('X-KDE-PluginInfo-Version=' + |
|
178 self.kdeVersionEdit.text()) |
|
179 if self.kdeWebsiteEdit.text(): |
|
180 code.append('X-KDE-PluginInfo-Website=' + |
|
181 self.kdeWebsiteEdit.text()) |
|
182 if self.kdeCategoryComboBox.currentText(): |
|
183 code.append('X-KDE-PluginInfo-Category=' + |
|
184 self.kdeCategoryComboBox.currentText()) |
|
185 if self.kdeDependsEdit.text(): |
|
186 code.append('X-KDE-PluginInfo-Depends=' + |
|
187 self.kdeDependsEdit.text()) |
|
188 if self.kdeLicensEdit.text(): |
|
189 code.append('X-KDE-PluginInfo-License=' + |
|
190 self.kdeLicensEdit.text()) |
|
191 if self.kdeEnabledDefaultCheckBox.isChecked(): |
|
192 code.append('X-KDE-PluginInfo-EnabledByDefault=true') |
|
193 |
|
194 # step 2b: Unity entries |
|
195 if self.typeComboBox.currentIndex() == 2: |
|
196 if self.unityShortcutsEdit.text(): |
|
197 code.append('X-Ayatana-Desktop-Shortcuts=' + |
|
198 self.unityShortcutsEdit.text()) |
|
199 |
|
200 # step 3: action entries |
|
201 actions = [act for act in self.actionsEdit.text().split(";") if act] |
|
202 for act in actions: |
|
203 code.append('') |
|
204 code.append('[Desktop Action {0}]'.format(act)) |
|
205 code.append('Name={0}'.format(act)) |
|
206 code.append('Icon=<Icon Path>') |
|
207 code.append('Exec=<Executable command>') |
|
208 |
|
209 # step 4: add empty last line |
|
210 code.append('') |
|
211 |
|
212 return os.linesep.join(code) |
|
213 |
|
214 def __checkOK(self): |
|
215 """ |
|
216 Private slot to check, if the OK button should be enabled. |
|
217 """ |
|
218 enable = bool(self.nameEdit.text()) and bool(self.typeEdit.text()) |
|
219 if bool(self.onlyShowEdit.text()) and bool(self.notShowEdit.text()): |
|
220 enable = False |
|
221 self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable) |
|
222 |
|
223 @pyqtSlot(int) |
|
224 def on_typeComboBox_currentIndexChanged(self, index): |
|
225 """ |
|
226 Private slot to handle a change of the .desktop type. |
|
227 |
|
228 @param index index of the selected entry (integer) |
|
229 """ |
|
230 self.dataTabWidget.setTabEnabled(1, index == 1) |
|
231 self.dataTabWidget.setTabEnabled(2, index == 2) |
|
232 |
|
233 @pyqtSlot() |
|
234 def on_projectButton_clicked(self): |
|
235 """ |
|
236 Private slot to populate some fields with data retrieved from the |
|
237 current project. |
|
238 """ |
|
239 project = e5App().getObject("Project") |
|
240 |
|
241 self.nameEdit.setText(project.getProjectName()) |
|
242 self.genericNameEdit.setText(project.getProjectName()) |
|
243 self.kdeNameEdit.setText(project.getProjectName()) |
|
244 try: |
|
245 self.kdeVersionEdit.setText(project.getProjectVersion()) |
|
246 self.kdeAuthorEdit.setText(project.getProjectAuthor()) |
|
247 self.kdeEmailEdit.setText(project.getProjectAuthorEmail()) |
|
248 except AttributeError: |
|
249 self.kdeVersionEdit.setText(project.pdata["VERSION"][0]) |
|
250 self.kdeAuthorEdit.setText(project.pdata["AUTHOR"][0]) |
|
251 self.kdeEmailEdit.setText(project.pdata["EMAIL"][0]) |
|
252 mainscript = project.getMainScript(True) |
|
253 if mainscript: |
|
254 self.kdeMainScriptEdit.setText(mainscript) |
|
255 self.execEdit.setText(mainscript) |
|
256 self.tryExecEdit.setText(mainscript) |
|
257 |
|
258 # prevent overwriting of entries by disabling the button |
|
259 self.projectButton.setEnabled(False) |
|
260 |
|
261 @pyqtSlot() |
|
262 def on_categoriesButton_clicked(self): |
|
263 """ |
|
264 Private slot to select the categories. |
|
265 """ |
|
266 from .DotDesktopListSelectionDialog import \ |
|
267 DotDesktopListSelectionDialog |
|
268 dlg = DotDesktopListSelectionDialog( |
|
269 self.__mainCategories, |
|
270 self.categoriesEdit.text(), ";", |
|
271 subEntries=self.__subCategories, |
|
272 allowMultiMain=False) |
|
273 if dlg.exec_() == QDialog.Accepted: |
|
274 categories = dlg.getData(";", True) |
|
275 self.categoriesEdit.setText(categories) |
|
276 |
|
277 @pyqtSlot(str) |
|
278 def on_onlyShowEdit_textChanged(self, txt): |
|
279 """ |
|
280 Private slot to check the contents of the onlyShowEdit field. |
|
281 |
|
282 @param txt text of the entry field (string) |
|
283 """ |
|
284 self.__checkOK() |
|
285 if bool(self.onlyShowEdit.text()) and bool(self.notShowEdit.text()): |
|
286 E5MessageBox.critical( |
|
287 self, |
|
288 self.tr(".desktop Wizard"), |
|
289 self.tr("""Only one of 'Only Show In' or """ |
|
290 """ 'Not Show In' allowed.""")) |
|
291 |
|
292 @pyqtSlot() |
|
293 def on_onlyShowButton_clicked(self): |
|
294 """ |
|
295 Private slot to select the OnlyShowIn environments. |
|
296 """ |
|
297 from .DotDesktopListSelectionDialog import \ |
|
298 DotDesktopListSelectionDialog |
|
299 dlg = DotDesktopListSelectionDialog( |
|
300 self.__showinEnvironments, |
|
301 self.onlyShowEdit.text(), ";") |
|
302 if dlg.exec_() == QDialog.Accepted: |
|
303 environments = dlg.getData(";", True) |
|
304 self.onlyShowEdit.setText(environments) |
|
305 |
|
306 @pyqtSlot(str) |
|
307 def on_notShowEdit_textChanged(self, txt): |
|
308 """ |
|
309 Private slot to check the contents of the notShowEdit field. |
|
310 |
|
311 @param txt text of the entry field (string) |
|
312 """ |
|
313 self.__checkOK() |
|
314 if bool(self.onlyShowEdit.text()) and bool(self.notShowEdit.text()): |
|
315 E5MessageBox.critical( |
|
316 self, |
|
317 self.tr(".desktop Wizard"), |
|
318 self.tr("""Only one of 'Only Show In' or """ |
|
319 """ 'Not Show In' allowed.""")) |
|
320 |
|
321 @pyqtSlot() |
|
322 def on_notShowButton_clicked(self): |
|
323 """ |
|
324 Private slot to select the NotShowIn environments. |
|
325 """ |
|
326 from .DotDesktopListSelectionDialog import \ |
|
327 DotDesktopListSelectionDialog |
|
328 dlg = DotDesktopListSelectionDialog( |
|
329 self.__showinEnvironments, |
|
330 self.notShowEdit.text(), ";") |
|
331 if dlg.exec_() == QDialog.Accepted: |
|
332 environments = dlg.getData(";", True) |
|
333 self.notShowEdit.setText(environments) |
|
334 |
|
335 @pyqtSlot(str) |
|
336 def on_typeEdit_textChanged(self, txt): |
|
337 """ |
|
338 Private slot to check, if the typeEdit field is empty. |
|
339 |
|
340 @param txt text of the entry field (string) |
|
341 """ |
|
342 self.__checkOK() |
|
343 |
|
344 @pyqtSlot(str) |
|
345 def on_nameEdit_textChanged(self, txt): |
|
346 """ |
|
347 Private slot to check, if the nameEdit field is empty. |
|
348 |
|
349 @param txt text of the entry field (string) |
|
350 """ |
|
351 self.__checkOK() |