1 | #!/usr/bin/env python
|
---|
2 | # -*- coding: utf-8 -*-
|
---|
3 | #
|
---|
4 | # $Id: dassmodus.py 11432 2010-11-01 19:20:55Z pstorz $
|
---|
5 |
|
---|
6 |
|
---|
7 | from PyQt4 import QtGui, QtCore
|
---|
8 | from PyQt4.QtCore import *
|
---|
9 | from PyQt4.QtGui import *
|
---|
10 | from functools import partial
|
---|
11 |
|
---|
12 | import dassmodus.ui.schedule
|
---|
13 | import dassmodus.ui.onlinehelpdialog
|
---|
14 | import dassmodus.ui.messagesdialog
|
---|
15 | import dassmodus.ui.listselectdialog
|
---|
16 | import dassmodus.ui.baseconfwizard
|
---|
17 | import dassmodus.ui.fetchDCdialog
|
---|
18 | import dassmodus.ui.integrityCheckDialog
|
---|
19 | import dassmodus.ui.newdatacenterwizard
|
---|
20 | import dassmodus.ui.deploywizard
|
---|
21 |
|
---|
22 | from nosferatu.bacresources import *
|
---|
23 | from nosferatu.prettynames import PrettyNames
|
---|
24 | #from nosferatu.directive import *
|
---|
25 | #from nosferatu import configrules
|
---|
26 |
|
---|
27 | import logging
|
---|
28 |
|
---|
29 | logging.basicConfig(level=logging.DEBUG,
|
---|
30 | format='%(asctime)s %(levelname)s \t (%(module)s:%(lineno)d) %(message)s ',
|
---|
31 | #filename='vanHelsing.log',
|
---|
32 | filemode='w')
|
---|
33 |
|
---|
34 |
|
---|
35 | import sys
|
---|
36 | import os
|
---|
37 | import re
|
---|
38 | import platform
|
---|
39 | #import glob
|
---|
40 |
|
---|
41 | from dassmodus.ui.mainwindow import Ui_MainWindow as Dlg
|
---|
42 | import re
|
---|
43 |
|
---|
44 | import xmlrpclib
|
---|
45 |
|
---|
46 | import dassmodus.dragndrop
|
---|
47 |
|
---|
48 | import dassmodus.ui.qt_resources # for the icons
|
---|
49 |
|
---|
50 | TEMPLATES_PATH = '/usr/share/dassmodus/templates' # DC templates for new datacenter wizard
|
---|
51 |
|
---|
52 | '''
|
---|
53 | find where our executable script is called from,as the templates dir is relative to that.
|
---|
54 | As we are running as py2exe on windows, we have to make these efforts:
|
---|
55 | see http://www.py2exe.org/index.cgi/WhereAmI
|
---|
56 | '''
|
---|
57 | def we_are_frozen():
|
---|
58 | """Returns whether we are frozen via py2exe.
|
---|
59 | This will affect how we find out where we are located."""
|
---|
60 |
|
---|
61 | return hasattr(sys, "frozen")
|
---|
62 |
|
---|
63 |
|
---|
64 | def module_path():
|
---|
65 | """ This will get us the program's directory,
|
---|
66 | even if we are frozen using py2exe"""
|
---|
67 |
|
---|
68 | if we_are_frozen():
|
---|
69 | return os.path.dirname(unicode(sys.executable, sys.getfilesystemencoding( )))
|
---|
70 | return os.path.dirname(unicode(__file__, sys.getfilesystemencoding( )))
|
---|
71 |
|
---|
72 | DASSMODUS_PATH = module_path()
|
---|
73 |
|
---|
74 | RXP_DATE = re.compile('.*\((.*)\)')
|
---|
75 |
|
---|
76 | #from nosferatu.directive import *
|
---|
77 |
|
---|
78 | __version__ = 0.1
|
---|
79 |
|
---|
80 | __revision__ = "$Rev: 11441 $".replace('$','').replace('Rev: ','.')
|
---|
81 |
|
---|
82 |
|
---|
83 | datestring = "$Date: 2011-02-10 15:00:43 +0100 (Do, 10 Feb 2011) $".replace('$','').replace('Date: ','')
|
---|
84 | m = RXP_DATE.match(datestring)
|
---|
85 | __date__ = '(' + m.group(1) + ')'
|
---|
86 |
|
---|
87 |
|
---|
88 |
|
---|
89 |
|
---|
90 | INTERNALLY_REFERENCED_ITEMS = set(['fileset',
|
---|
91 | 'client' ,
|
---|
92 | 'catalog',
|
---|
93 | 'messages',
|
---|
94 | 'schedule',
|
---|
95 | 'storage',
|
---|
96 | 'jobdefs',
|
---|
97 | 'pool',
|
---|
98 | 'incrementalbackuppool',
|
---|
99 | 'fullbackuppool',
|
---|
100 | 'differentialbackuppool',
|
---|
101 | 'job',
|
---|
102 | 'basejob',
|
---|
103 | 'device',
|
---|
104 | ])
|
---|
105 | BOOL_ITEMS = set([
|
---|
106 | 'store_bool',
|
---|
107 | 'store_runscript_bool',
|
---|
108 | ])
|
---|
109 |
|
---|
110 | logging.basicConfig(level=logging.DEBUG,
|
---|
111 | format='%(asctime)s %(levelname)s \t (%(module)s:%(lineno)d) %(message)s ',
|
---|
112 | filename='dassModus.log',
|
---|
113 | filemode='w')
|
---|
114 |
|
---|
115 | # create logger
|
---|
116 | logger = logging.getLogger("vanHelsing")
|
---|
117 | logger.setLevel(logging.DEBUG)
|
---|
118 |
|
---|
119 |
|
---|
120 |
|
---|
121 | logger.debug(QApplication.translate('Main','Started Main Program'))
|
---|
122 |
|
---|
123 |
|
---|
124 |
|
---|
125 | OUTPUTDIR = '/etc/bacula/'
|
---|
126 | #INPUTDIR = '/etc/bacula/'
|
---|
127 | INPUTDIR = ':/'
|
---|
128 |
|
---|
129 |
|
---|
130 | #Configurations = [] # global list of configuration objects
|
---|
131 | Datacenters = []
|
---|
132 |
|
---|
133 | #proxy = xmlrpclib.ServerProxy("http://bacula-devel:8000/")
|
---|
134 | class SafeTransportWithCert(xmlrpclib.SafeTransport):
|
---|
135 | # __cert_file = DFLT_CERTFILE
|
---|
136 | # __key_file = DFLT_KEYFILE
|
---|
137 | __cert_file = 'certs/client-cert.pem' # Replace with your PEM formatted key file
|
---|
138 | __key_file = 'certs/client-cert.pem' # Replace with your PEM formatted certificate file
|
---|
139 |
|
---|
140 | def make_connection(self,host):
|
---|
141 | host_with_cert = (host, {
|
---|
142 | 'key_file' : self.__key_file,
|
---|
143 | 'cert_file' : self.__cert_file
|
---|
144 | } )
|
---|
145 | return xmlrpclib.SafeTransport.make_connection(
|
---|
146 | self,host_with_cert)
|
---|
147 |
|
---|
148 |
|
---|
149 |
|
---|
150 | #server_url = 'https://bacula-devel:4443'
|
---|
151 | #transport = SafeTransportWithCert()
|
---|
152 | #proxy = xmlrpclib.ServerProxy(server_url,
|
---|
153 | # transport = transport)
|
---|
154 |
|
---|
155 | #print proxy.get_lsscsi()
|
---|
156 |
|
---|
157 | #name = 'bacula-sd.conf'
|
---|
158 | #filename = INPUTDIR + name
|
---|
159 | #outfile = OUTPUTDIR + name
|
---|
160 | #configstring = open(filename).read()
|
---|
161 | #sdconf = StorageDaemonConfig(configstring)
|
---|
162 | #writefile = open(outfile,'w')
|
---|
163 | #writefile.write(str(sdconf))
|
---|
164 |
|
---|
165 |
|
---|
166 | #name = ('bacula-fd.conf')
|
---|
167 | #filename = INPUTDIR + name
|
---|
168 | #outfile = OUTPUTDIR + name
|
---|
169 | #configstring = open(filename).read()
|
---|
170 | #fdconf = FileDaemonConfig(configstring)
|
---|
171 |
|
---|
172 |
|
---|
173 | #writefile = open(outfile,'w')
|
---|
174 | #writefile.write(str(fdconf))
|
---|
175 |
|
---|
176 |
|
---|
177 | #name = ('bconsole.conf')
|
---|
178 | #filename = INPUTDIR + name
|
---|
179 | #outfile = OUTPUTDIR + name
|
---|
180 |
|
---|
181 | #readfile = open(filename)
|
---|
182 | #configstring = readfile.read()
|
---|
183 | #conconf = ConsoleConfig(configstring)
|
---|
184 | #readfile.close()
|
---|
185 |
|
---|
186 | #writefile = open(outfile,'w')
|
---|
187 | #writefile.write(str(conconf))
|
---|
188 |
|
---|
189 |
|
---|
190 |
|
---|
191 | #name = 'bacula-dir.conf'
|
---|
192 | #filename = INPUTDIR + name
|
---|
193 | #outfile = OUTPUTDIR + name
|
---|
194 | #configstring = open(filename).read()
|
---|
195 | #dirconf = DirectorConfig(configstring)
|
---|
196 |
|
---|
197 |
|
---|
198 | #Configurations.append(dirconf)
|
---|
199 | #Configurations.append(sdconf)
|
---|
200 | #Configurations.append(fdconf)
|
---|
201 | #Configurations.append(conconf)
|
---|
202 | #writefile = open(outfile,'w')
|
---|
203 | #writefile.write(str(dirconf))
|
---|
204 |
|
---|
205 | #print dirconf
|
---|
206 |
|
---|
207 |
|
---|
208 |
|
---|
209 | #def bind(objectName, propertyName, type):
|
---|
210 | #
|
---|
211 | # def getter(self):
|
---|
212 | # return type(self.findChild(QObject, objectName).property(propertyName).toPyObject())
|
---|
213 | #
|
---|
214 | # def setter(self, value):
|
---|
215 | # self.findChild(QObject, objectName).setProperty(propertyName, QVariant(value))
|
---|
216 | #
|
---|
217 | # return property(getter, setter)
|
---|
218 | #
|
---|
219 |
|
---|
220 |
|
---|
221 |
|
---|
222 | class StorageItemCheckbox(QCheckBox):
|
---|
223 | def __init__(self, storageItem, label):
|
---|
224 | QCheckBox.__init__(self,label)
|
---|
225 | self.storageItem = storageItem
|
---|
226 |
|
---|
227 | class StorageItemLineEdit(QLineEdit):
|
---|
228 | def __init__(self, parentWidget, storageItem):
|
---|
229 | QCheckBox.__init__(self, parentWidget)
|
---|
230 | self.storageItem = storageItem
|
---|
231 |
|
---|
232 |
|
---|
233 | class StorageItemCombobox(QComboBox):
|
---|
234 | def __init__(self, storageItem):
|
---|
235 | QComboBox.__init__(self)
|
---|
236 | self.storageItem = storageItem
|
---|
237 |
|
---|
238 | class ResourceTreeWidgetItem(QTreeWidgetItem):
|
---|
239 | itemsList = [] # class variable
|
---|
240 | def __init__(self, Resource, headerlist):
|
---|
241 | self.Resource = Resource
|
---|
242 | #print "type:" , type(headerlist),"headerlist:" , headerlist
|
---|
243 |
|
---|
244 | self.itemsList.append(self)
|
---|
245 |
|
---|
246 | QTreeWidgetItem.__init__(self, headerlist)
|
---|
247 |
|
---|
248 | #TODO: Why does the treeview not use the standard fontsize?
|
---|
249 | #col = 0
|
---|
250 | #f = self.font(col)
|
---|
251 | #f.setPixelSize(14)
|
---|
252 | #self.setFont(col,f)
|
---|
253 | #col=1
|
---|
254 | #f = self.font(col)
|
---|
255 | #f.setBold(True)
|
---|
256 | #f.setPixelSize(14)
|
---|
257 | #self.setFont(col,f)
|
---|
258 | # fontsize end
|
---|
259 |
|
---|
260 | class ResourceListWidgetItem(QListWidgetItem):
|
---|
261 | def __init__(self, Resource):
|
---|
262 | self.Resource = Resource
|
---|
263 | QListWidgetItem.__init__(self,self.Resource.resourcetype+ ' ' +
|
---|
264 | self.Resource.getName())
|
---|
265 | #self.Resource.items_dict['name'].storage.value)
|
---|
266 | icon = QtGui.QIcon(":/icons/" + self.Resource.resourcetype + ".png")
|
---|
267 | self.setIcon(icon)
|
---|
268 |
|
---|
269 | class ResItemTableWidgetItem(QTableWidgetItem):
|
---|
270 | def __init__(self, ResItem):
|
---|
271 | self.ResItem = ResItem
|
---|
272 | QTableWidgetItem.__init__(self)
|
---|
273 |
|
---|
274 | class StorageItemPushButton(QPushButton):
|
---|
275 | def __init__(self, storageItem):
|
---|
276 | QPushButton.__init__(self)
|
---|
277 | self.storageItem = storageItem
|
---|
278 |
|
---|
279 | #class VHTreeWidget(QtGui.QTreeWidget):
|
---|
280 | # def __init__(self, parent):
|
---|
281 | # super(VHTreeWidget, self).__init__(parent)
|
---|
282 |
|
---|
283 |
|
---|
284 |
|
---|
285 |
|
---|
286 | #self.treeWidget = QtGui.QTreeWidget(self.verticalLayoutWidget_3)
|
---|
287 |
|
---|
288 | class MeinDialog(QtGui.QMainWindow, Dlg):
|
---|
289 |
|
---|
290 | def __init__(self):
|
---|
291 | QtGui.QDialog.__init__(self)
|
---|
292 | self.setupUi(self)
|
---|
293 | self.gridwidgets = []
|
---|
294 | self.onlinehelpdialog = dassmodus.ui.onlinehelpdialog.OnlinehelpDialog(self)
|
---|
295 |
|
---|
296 | # restore the applications settings
|
---|
297 | settings = QSettings()
|
---|
298 | #size = settings.value("MainWindows/Size",
|
---|
299 | # QVariant(QSize(600,500))).toSize()
|
---|
300 | #
|
---|
301 | #self.resize(size)
|
---|
302 | ##self.restoreGeometry(settings.value("Geometry").toByteArray())
|
---|
303 | #position = settings.value("MainWindow/Position",
|
---|
304 | # QVariant(QPoint(0,0))).toPoint()
|
---|
305 | #self.move(position)
|
---|
306 | #self.restoreState(settings.value("Mainwindow/State").toByteArray())
|
---|
307 |
|
---|
308 |
|
---|
309 | self.restoreGeometry(settings.value("Geometry").toByteArray())
|
---|
310 | self.onlinehelpdialog.restoreGeometry(settings.value("HelpWindowsGeometry").toByteArray())
|
---|
311 |
|
---|
312 | # restoring state end
|
---|
313 |
|
---|
314 |
|
---|
315 |
|
---|
316 |
|
---|
317 |
|
---|
318 |
|
---|
319 |
|
---|
320 | # statusbar
|
---|
321 | self.statusLabel = QLabel()
|
---|
322 | self.statusLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
|
---|
323 | self.statusBar.setSizeGripEnabled(False)
|
---|
324 | self.statusBar.addPermanentWidget(self.statusLabel)
|
---|
325 | self.statusPB = QProgressBar(self.statusBar)
|
---|
326 | self.statusPB.setMaximumWidth(200)
|
---|
327 | self.statusPB.setTextVisible(True)
|
---|
328 | self.statusBar.addPermanentWidget(self.statusPB)
|
---|
329 |
|
---|
330 | self.statusPB.setMinimum(0)
|
---|
331 | self.statusPB.setMaximum(10)
|
---|
332 |
|
---|
333 | self.statusBar.showMessage(self.tr("Welcome to the bacula configuration program"), 5000)
|
---|
334 |
|
---|
335 |
|
---|
336 |
|
---|
337 | #self.configsToTreeWidget()
|
---|
338 | #self.dirconfRoot = self.addConfigToTreeWidget(dirconf)
|
---|
339 | #self.sdconfRoot = self.addConfigToTreeWidget(sdconf)
|
---|
340 | #self.addConfigToTreeWidget(fdconf)
|
---|
341 | #self.addConfigToTreeWidget(conconf)
|
---|
342 | self.treeWidget.setMouseTracking(True)
|
---|
343 | self.treeWidget.setColumnCount(3)
|
---|
344 | self.treeWidget.resizeColumnToContents(0)
|
---|
345 | self.treeWidget.setAlternatingRowColors(False)
|
---|
346 |
|
---|
347 | self.treeWidget.sortByColumn(0, Qt.AscendingOrder)
|
---|
348 |
|
---|
349 |
|
---|
350 |
|
---|
351 | #self.treeWidget = VHTreeWidget(self.verticalLayoutWidget_3)
|
---|
352 | self.verticalLayout_3.addWidget(self.treeWidget)
|
---|
353 |
|
---|
354 |
|
---|
355 |
|
---|
356 |
|
---|
357 | #self.textEdit.setText('hallo')
|
---|
358 | #<print "started"
|
---|
359 | # signale connecten
|
---|
360 |
|
---|
361 | self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu)
|
---|
362 | self.connect(self.treeWidget,
|
---|
363 | QtCore.SIGNAL("customContextMenuRequested(const QPoint &)")
|
---|
364 | ,self.menuContextTree)
|
---|
365 |
|
---|
366 | self.connect(self.treeWidget,
|
---|
367 | QtCore.SIGNAL("itemClicked(QTreeWidgetItem *,int)"),
|
---|
368 | self.onTreeItemClick)
|
---|
369 | self.connect(self.treeWidget,
|
---|
370 | QtCore.SIGNAL("currentItemChanged (QTreeWidgetItem *,QTreeWidgetItem *)"),
|
---|
371 | self.onTreeItemClick)
|
---|
372 |
|
---|
373 | self.modifyAction(self.actionSave, None, None, self.tr("save a local configuration file"), False)
|
---|
374 | self.connect(self.actionSave, SIGNAL("triggered()"), self.onSave)
|
---|
375 |
|
---|
376 | self.modifyAction(self.actionOpen, None, 'open', self.tr("load a local datacenter file"), False)
|
---|
377 | self.connect(self.actionOpen, SIGNAL("triggered()"), self.onActionOpen)
|
---|
378 | self.toolBar.addAction(self.actionOpen)
|
---|
379 |
|
---|
380 | self.modifyAction(self.actionFetch, None, 'repository', self.tr("fetch a configuration file from a server"), False)
|
---|
381 | self.connect(self.actionFetch, SIGNAL("triggered()"), self.onActionFetch)
|
---|
382 | self.toolBar.addAction(self.actionFetch)
|
---|
383 |
|
---|
384 | self.modifyAction(self.actionOpenHelp, None, 'help-contextual', self.tr("open the contextsensitive help window"), False)
|
---|
385 | self.connect(self.actionOpenHelp, SIGNAL("triggered()"), self.onOpenHelp)
|
---|
386 | self.toolBar.addAction(self.actionOpenHelp)
|
---|
387 |
|
---|
388 | self.modifyAction(self.actionCommit_to_server, None, None, self.tr("commmit a configuration file on a server"), False)
|
---|
389 | self.connect(self.actionCommit_to_server, SIGNAL("triggered()"), self.onActionCommit)
|
---|
390 |
|
---|
391 | self.modifyAction(self.actionQuit_2, None, None, self.tr("quit program"), False)
|
---|
392 | self.connect(self.actionQuit_2, SIGNAL("triggered()"), self.close)
|
---|
393 |
|
---|
394 | self.modifyAction(self.actionNew_Datacenter, None, 'datacenter_new', self.tr("create new Datacenter"), False)
|
---|
395 | self.connect(self.actionNew_Datacenter, SIGNAL("triggered()"), self.onActionNewDatacenter)
|
---|
396 | self.toolBar.addAction(self.actionNew_Datacenter)
|
---|
397 |
|
---|
398 |
|
---|
399 | self.modifyAction(self.actionAbout, None, None, self.tr("information about the program"), False)
|
---|
400 | self.statusBar.addAction(self.actionAbout)
|
---|
401 | self.toolBar.addAction(self.actionAbout)
|
---|
402 |
|
---|
403 | self.connect(self.actionAbout, SIGNAL("triggered()"), self.onActionAbout)
|
---|
404 |
|
---|
405 | self.treeWidget.setHeaderLabels([self.tr('Resourcetype'),self.tr('Name'),self.tr('Ref.')])
|
---|
406 |
|
---|
407 |
|
---|
408 | self.connect(self.referencesListWidget,
|
---|
409 | SIGNAL("itemDoubleClicked(QListWidgetItem *)"),
|
---|
410 | self.onReferenceItemDoubleClicked
|
---|
411 | )
|
---|
412 | self.onlinehelpdialog.show()
|
---|
413 | # delete widgets from form
|
---|
414 | #self.label.setParent(None)
|
---|
415 | #self.textEdit.setParent(None)
|
---|
416 |
|
---|
417 | def okToQuit(self):
|
---|
418 | reply = QMessageBox.question(self,
|
---|
419 | self.tr("close dassModus"),
|
---|
420 | self.tr("Do you really want to quit"),
|
---|
421 | QMessageBox.Yes|QMessageBox.No | QMessageBox.Cancel)
|
---|
422 | if reply != QMessageBox.Yes:
|
---|
423 | return False
|
---|
424 | else:
|
---|
425 | return True
|
---|
426 |
|
---|
427 | def closeEvent(self, event):
|
---|
428 | if self.okToQuit():
|
---|
429 | settings = QSettings()
|
---|
430 | settings.setValue("Geometry",QVariant(self.saveGeometry()))
|
---|
431 | settings.setValue("HelpWindowsGeometry",QVariant(self.onlinehelpdialog.saveGeometry()))
|
---|
432 | #settings.setValue("MainWindow/Size", QVariant(self.size()))
|
---|
433 | #settings.setValue("MainWindow/Position", QVariant(self.pos()))
|
---|
434 | #settings.setValue("Mainwindow/State", QVariant(self.saveState()))
|
---|
435 | else:
|
---|
436 | event.ignore()
|
---|
437 |
|
---|
438 |
|
---|
439 |
|
---|
440 |
|
---|
441 |
|
---|
442 | def modifyAction(self, action, shortcut=None, icon=None,
|
---|
443 | tip=None, checkable=False ):
|
---|
444 | if icon is not None:
|
---|
445 | action.setIcon(QIcon(":/icons/%s.png" % icon))
|
---|
446 | if shortcut is not None:
|
---|
447 | action.setShortcut(shortcut)
|
---|
448 | if tip is not None:
|
---|
449 | action.setToolTip(tip)
|
---|
450 | action.setStatusTip(tip)
|
---|
451 | if checkable:
|
---|
452 | action.setCheckable(True)
|
---|
453 | return action
|
---|
454 |
|
---|
455 | def onOpenHelp(self):
|
---|
456 | self.onlinehelpdialog.show()
|
---|
457 |
|
---|
458 | def onActionAbout(self):
|
---|
459 | """Show about box"""
|
---|
460 | # TODO: do the Translation for this, maybe use QString (see PyQtBook, Page 515)s
|
---|
461 | QMessageBox.about(self,"About dassModus",
|
---|
462 | u"""
|
---|
463 | <b>dassModus v %s</b>
|
---|
464 | <p>
|
---|
465 | A GUI program to configure Bacula
|
---|
466 | <p>Copyright © 2010-2011 <a href="http://www.dass-it.de/">dass IT GmbH</a><br>
|
---|
467 | <a href="http://www.dass-it.de/">http://www.dass-it.de</a>
|
---|
468 | <p>Händelstraße 25-29<br>
|
---|
469 | 50674 Köln <br>
|
---|
470 | Germany <br>
|
---|
471 | Phone: +49 221 3 56 56 66-0 <br>
|
---|
472 | <p>
|
---|
473 | Python %s - Qt %s - PyQt %s on %s
|
---|
474 | """ % (str(__version__) + __revision__ + '<br>' + __date__, platform.python_version(),
|
---|
475 | QT_VERSION_STR, PYQT_VERSION_STR, platform.system()
|
---|
476 | )
|
---|
477 | )
|
---|
478 |
|
---|
479 | def onActionDeployConfig(self, Resource):
|
---|
480 | server_url = 'https://bacula-old:4443'
|
---|
481 | transport = SafeTransportWithCert()
|
---|
482 | proxy = xmlrpclib.ServerProxy(server_url,
|
---|
483 | transport = transport)
|
---|
484 |
|
---|
485 | deploywizard = dassmodus.ui.deploywizard.deploywizard(proxy, str(Resource),Resource.longname, self )
|
---|
486 | deploywizard.exec_()
|
---|
487 |
|
---|
488 |
|
---|
489 | #server_url = 'https://bacula-old:4443'
|
---|
490 | #transport = SafeTransportWithCert()
|
---|
491 | #proxy = xmlrpclib.ServerProxy(server_url,
|
---|
492 | # transport = transport)
|
---|
493 | #OLD_CONFIG = proxy.get_conf('dir')
|
---|
494 | #proxy.set_conf('dir',str(Resource))
|
---|
495 | #print proxy.reload_director()
|
---|
496 |
|
---|
497 |
|
---|
498 | def onActionFetch(self):
|
---|
499 | availableDCs = proxy.list_datacenters()
|
---|
500 | DCdialog = dassmodus.ui.fetchDCdialog.FetchDCDialog( datacenterlist = availableDCs )
|
---|
501 |
|
---|
502 | if DCdialog.exec_():
|
---|
503 | selectedDC = unicode( DCdialog.listWidget.selectedItems()[0].text() )
|
---|
504 | DCdata = proxy.get_datacenter(selectedDC).data
|
---|
505 |
|
---|
506 | #TODO: write this to a temporary file, open this file
|
---|
507 |
|
---|
508 | #print availableDCs
|
---|
509 | # configstring = proxy.get_dirdconf()
|
---|
510 | # print "configstring:", configstring
|
---|
511 | # print str(configstring)
|
---|
512 | # dirconf = DirectorConfig(str(configstring))
|
---|
513 | # Configurations.append(dirconf)
|
---|
514 | # self.rebuildTreeWidget()
|
---|
515 |
|
---|
516 | def onActionCheckIntegrity(self, Resource):
|
---|
517 | '''
|
---|
518 | call the Datacenters own integrity checks and display the output
|
---|
519 | '''
|
---|
520 | dc = Resource
|
---|
521 | intcheckdlg = dassmodus.ui.integrityCheckDialog.IntegrityCheckDialog(self,dc.checkFileDaemonsIntegrity())
|
---|
522 | intcheckdlg.show()
|
---|
523 | #print dc.checkFileDaemonsIntegrity()
|
---|
524 | #print dc.checkStorageDaemonsIntegrity()
|
---|
525 |
|
---|
526 | def onActionNewDatacenter(self):
|
---|
527 | wizard = dassmodus.ui.newdatacenterwizard.newdatacenterwizard(TEMPLATES_PATH)
|
---|
528 | if wizard.exec_():
|
---|
529 | self.openDatacenterFile(wizard.filename)
|
---|
530 |
|
---|
531 | def onActionCommit(self):
|
---|
532 | #configstring = Configurations[0]
|
---|
533 | #print unicode(configstring)
|
---|
534 | #proxy.set_dirdconf(unicode(configstring))
|
---|
535 | pass
|
---|
536 |
|
---|
537 | def onRunentryEdit(self):
|
---|
538 | #print "onRunEntryEdi called"
|
---|
539 | #print self.sender().storageItem.runentry
|
---|
540 | rune = self.sender().storageItem.runentry
|
---|
541 | parentcfg = self.sender().storageItem.parentitem.parentresource.parentconfig
|
---|
542 |
|
---|
543 | dialog = dassmodus.ui.schedule.RunentryDialog(self,
|
---|
544 | runentry=rune,
|
---|
545 | parentconfig=parentcfg
|
---|
546 | )
|
---|
547 |
|
---|
548 | # get parent config to be able to find valid pools, storages, etc. to fill in comboboxes
|
---|
549 |
|
---|
550 |
|
---|
551 | if dialog.exec_():
|
---|
552 | print "yes" + str(self.sender().storageItem.runentry)
|
---|
553 | #else:
|
---|
554 | # print "no"
|
---|
555 |
|
---|
556 | def onMessageEntryEdit(self):
|
---|
557 | mesgDict = self.sender().storageItem.messageDict
|
---|
558 | dialog = dassmodus.ui.messagesdialog.MessagesDialog(self,
|
---|
559 | messagesTypesDict=mesgDict)
|
---|
560 | if dialog.exec_():
|
---|
561 | print "yes"# + str(self.sender().storageItem.runentry)
|
---|
562 | else:
|
---|
563 | print "no"
|
---|
564 |
|
---|
565 | def onAclEntryEdit(self):
|
---|
566 | sender = self.sender()
|
---|
567 | aclname = sender.storageItem.parentitem.name
|
---|
568 | if aclname == 'commandacl':
|
---|
569 | for cmd in commands.keys():
|
---|
570 | if not cmd in sender.storageItem.ACLDict:
|
---|
571 | sender.storageItem.ACLDict[cmd] = False
|
---|
572 | else:
|
---|
573 | parentconfig = self.sender().storageItem.parentitem.parentresource.parentconfig
|
---|
574 | aclresourcename = aclname.lower().replace('acl','') # FilesetACL -> fileset
|
---|
575 | availableresources = parentconfig.getResourcesListByResType(aclresourcename)
|
---|
576 | #cfgdict = {}
|
---|
577 | for res in availableresources:
|
---|
578 | #if not res.items_dict['name'].storage.value in sender.storageItem.ACLDict:
|
---|
579 | if not res.getName() in sender.storageItem.ACLDict:
|
---|
580 | sender.storageItem.ACLDict[res.getName()] = False
|
---|
581 |
|
---|
582 |
|
---|
583 | dialog = dassmodus.ui.listselectdialog.ListSelectDialog(self,
|
---|
584 | configDict = sender.storageItem.ACLDict,
|
---|
585 | title = 'Edit %s' % (aclname) )
|
---|
586 |
|
---|
587 |
|
---|
588 | #sender.storageItem.setValue(str(sender.storageItem))
|
---|
589 |
|
---|
590 | #.setValue( unicode(self.sender().text() ) )
|
---|
591 |
|
---|
592 | if dialog.exec_():
|
---|
593 | print "yes"# + str(self.sender().storageItem.runentry)
|
---|
594 | sender.storageItem.__ACLDict2value__()
|
---|
595 | else:
|
---|
596 | print "no"
|
---|
597 |
|
---|
598 | def processEventsCallback(self, info = None):
|
---|
599 | QtGui.QApplication.processEvents()
|
---|
600 | if info:
|
---|
601 | self.statusBar.showMessage(info)
|
---|
602 |
|
---|
603 |
|
---|
604 |
|
---|
605 |
|
---|
606 | def onActionOpen(self):
|
---|
607 |
|
---|
608 | #fd = QFileDialog(self)
|
---|
609 | #fd.setFileMode(QFileDialog.Directory)
|
---|
610 | filename = unicode(QFileDialog.getOpenFileName(self
|
---|
611 | ,self.tr('Open Datacenter file')
|
---|
612 | ,''
|
---|
613 | ,self.tr('dassModus datacenter .dmdz files (*.dmdz)'))
|
---|
614 | )
|
---|
615 |
|
---|
616 |
|
---|
617 | if filename:
|
---|
618 | self.openDatacenterFile(filename)
|
---|
619 |
|
---|
620 | # self.statusPB.setMinimum(0)
|
---|
621 | # self.statusPB.setMaximum(0)
|
---|
622 | #
|
---|
623 | # dc = DataCenter(filename, self.processEventsCallback )
|
---|
624 | # Datacenters.append(dc)
|
---|
625 | #
|
---|
626 | # self.statusPB.setMaximum(100)
|
---|
627 | #
|
---|
628 | # self.updateReferenceInformation()
|
---|
629 | # self.rebuildTreeWidget()
|
---|
630 | # self.treeWidget.expandToDepth(0)
|
---|
631 | # self.treeWidget.resizeColumnToContents(0)
|
---|
632 | # self.treeWidget.resizeColumnToContents(1)
|
---|
633 | #
|
---|
634 | # #self.statusPB.setEnabled(False)
|
---|
635 | # #pd.close()
|
---|
636 | # self.statusBar.clearMessage()
|
---|
637 | # self.statusPB.setMaximum(100)
|
---|
638 | # self.statusPB.setMinimum(0)
|
---|
639 |
|
---|
640 | def openDatacenterFile(self,filename):
|
---|
641 |
|
---|
642 | self.statusPB.setMinimum(0)
|
---|
643 | self.statusPB.setMaximum(0)
|
---|
644 |
|
---|
645 | dc = DataCenter(filename, self.processEventsCallback )
|
---|
646 | Datacenters.append(dc)
|
---|
647 |
|
---|
648 | self.statusPB.setMaximum(100)
|
---|
649 |
|
---|
650 | self.updateReferenceInformation()
|
---|
651 | self.rebuildTreeWidget()
|
---|
652 | self.treeWidget.expandToDepth(0)
|
---|
653 | self.treeWidget.resizeColumnToContents(0)
|
---|
654 | self.treeWidget.resizeColumnToContents(1)
|
---|
655 |
|
---|
656 | #self.statusPB.setEnabled(False)
|
---|
657 | #pd.close()
|
---|
658 | self.statusBar.clearMessage()
|
---|
659 | self.statusPB.setMaximum(100)
|
---|
660 | self.statusPB.setMinimum(0)
|
---|
661 |
|
---|
662 |
|
---|
663 | def datacentersToTreeWidget(self):
|
---|
664 |
|
---|
665 | dcs_to_create = set(Datacenters)
|
---|
666 | dc2treewidgetitem = {}
|
---|
667 | # check if there is already a toplevel item for this dc
|
---|
668 | for dc in Datacenters:
|
---|
669 | count = self.treeWidget.topLevelItemCount()
|
---|
670 | for i in range(count):
|
---|
671 | tli = self.treeWidget.topLevelItem(i)
|
---|
672 | if tli.Resource == dc:
|
---|
673 | dcs_to_create.remove(dc)
|
---|
674 | dc2treewidgetitem[dc] = tli
|
---|
675 |
|
---|
676 | # only add top treewidget for not existing datacenters
|
---|
677 | for dc in Datacenters:
|
---|
678 | #root = self.addDatacenterToTreeWidget(config)
|
---|
679 | if dc in dcs_to_create:
|
---|
680 | dcTWI = QTreeWidgetItem([self.tr('Datacenter'), unicode(dc.name)])
|
---|
681 | dcTWI.Resource = dc
|
---|
682 | icon = QtGui.QIcon(":/icons/datacenter.png")
|
---|
683 | dcTWI.setIcon(0,icon)
|
---|
684 | # TODO: why does treewidget not use standard fontsize?
|
---|
685 | #col = 0
|
---|
686 | #f = dcTWI.font(col)
|
---|
687 | #f.setPixelSize(14)
|
---|
688 | #dcTWI.setFont(col,f)
|
---|
689 | #col = 1
|
---|
690 | #f = dcTWI.font(col)
|
---|
691 | ## f.setBold(True)
|
---|
692 | #f.setPixelSize(14)
|
---|
693 | #dcTWI.setFont(col,f)
|
---|
694 | #font end
|
---|
695 | self.treeWidget.addTopLevelItem(dcTWI)
|
---|
696 | else:
|
---|
697 | dcTWI = dc2treewidgetitem[dc]
|
---|
698 |
|
---|
699 | for config in list(dc.directors) + list(dc.filedaemons) + list(dc.storagedaemons) + list(dc.consoles):
|
---|
700 | self.addConfigToDc(config, dcTWI)
|
---|
701 |
|
---|
702 | def addDatacenterToTreeWidget(self):
|
---|
703 | #parent = ResourceTreeWidgetItem(Resource,[Resource.__class__.__name__, name])
|
---|
704 | #self.treeWidget.expandAll()
|
---|
705 | pass
|
---|
706 |
|
---|
707 |
|
---|
708 | def menuContextTree(self, point):
|
---|
709 | # Infos about the node selected.
|
---|
710 | index = self.treeWidget.indexAt(point)
|
---|
711 | if not index.isValid():
|
---|
712 | return
|
---|
713 | item = self.treeWidget.itemAt(point)
|
---|
714 | name = item.text(0) # The text of the node.
|
---|
715 | resource = item.Resource
|
---|
716 | # We build the menu.
|
---|
717 | menu=QtGui.QMenu(self)
|
---|
718 | #action=menu.addAction(name)
|
---|
719 | print "Contextmenu for:" + name + ':'
|
---|
720 |
|
---|
721 | if name == PrettyNames['client']:
|
---|
722 | actionCreateFDConfig = menu.addAction(self.tr("create FiledaemonConfig from ") + name)
|
---|
723 | self.connect(actionCreateFDConfig, SIGNAL("triggered()"),
|
---|
724 | partial(self.onActionCreateFDConfig, resource ) )
|
---|
725 |
|
---|
726 |
|
---|
727 | if hasattr(resource, 'validitemsset'):
|
---|
728 | for r in resource.validitemsset:
|
---|
729 | if r in MULTIPLE_ALLOWED_ITEMS_SET:
|
---|
730 | icon = QtGui.QIcon(":/icons/" + r + ".png")
|
---|
731 | actionAdd=menu.addAction(icon,'add' + PrettyNames[r])
|
---|
732 | actionAdd.setObjectName(r)
|
---|
733 | self.connect(actionAdd, SIGNAL("triggered()"), partial( self.onActionAdd, resource, r ) )
|
---|
734 |
|
---|
735 | elif hasattr(resource, 'validresourcesset'):
|
---|
736 | for r in resource.validresourcesset:
|
---|
737 | if r in MULTIPLE_RESOURCES_IN_DIRD:
|
---|
738 | icon = QtGui.QIcon(":/icons/" + r + ".png")
|
---|
739 | actionAdd=menu.addAction(icon, self.tr('add ') + PrettyNames[r])
|
---|
740 | actionAdd.setObjectName(r)
|
---|
741 | self.connect(actionAdd, SIGNAL("triggered()"), partial( self.onActionAdd, resource, r ) )
|
---|
742 |
|
---|
743 | # import a client snippet from the abcd
|
---|
744 | if name == 'DirectorConfig':
|
---|
745 | actionImportSnippet = menu.addAction( icon, 'import client snippet from autoconfiguration' )
|
---|
746 | self.connect(actionImportSnippet, SIGNAL("triggered()"), partial( self.onImportSnippet, resource) )
|
---|
747 |
|
---|
748 | # deploy configuration to director
|
---|
749 | actionDeployConfig = menu.addAction( icon, 'deploy configuration....' )
|
---|
750 | self.connect(actionDeployConfig, SIGNAL("triggered()"), partial( self.onActionDeployConfig, resource) )
|
---|
751 |
|
---|
752 |
|
---|
753 | if name == 'Datacenter':
|
---|
754 | # TODO: icons for these menu entries
|
---|
755 | actionCheckIntegrity = menu.addAction(self.tr("check integrity of Datacenter"))
|
---|
756 | self.connect(actionCheckIntegrity, SIGNAL("triggered()"),
|
---|
757 | partial(self.onActionCheckIntegrity, resource ) )
|
---|
758 |
|
---|
759 | actionSaveDatacenter = menu.addAction(self.tr("save Datacenter (") + resource.filename + ')')
|
---|
760 | self.connect(actionSaveDatacenter, SIGNAL("triggered()"),
|
---|
761 | partial(self.onActionSaveDc, resource ) )
|
---|
762 |
|
---|
763 | actionSaveDatacenterAs = menu.addAction(self.tr("save Datacenter as"))
|
---|
764 | self.connect(actionSaveDatacenterAs, SIGNAL("triggered()"),
|
---|
765 | partial(self.onActionSaveDcAs, resource ) )
|
---|
766 |
|
---|
767 |
|
---|
768 | menu.addSeparator()
|
---|
769 |
|
---|
770 | actionImportConfigurationFile = menu.addAction(self.tr("Import existing configuration file"))
|
---|
771 | self.connect(actionImportConfigurationFile, SIGNAL("triggered()"),
|
---|
772 | partial(self.onActionImportConfigFile, resource ) )
|
---|
773 |
|
---|
774 | actionExport = menu.addAction(self.tr("export ") + name)
|
---|
775 | self.connect(actionExport, SIGNAL("triggered()"),
|
---|
776 | partial(self.onActionExport, resource ) )
|
---|
777 |
|
---|
778 |
|
---|
779 | menu.addSeparator()
|
---|
780 | actionDelete = menu.addAction(self.tr("delete ") + name)
|
---|
781 | self.connect(actionDelete, SIGNAL("triggered()"),
|
---|
782 | partial(self.onActionDelete, resource ) )
|
---|
783 |
|
---|
784 |
|
---|
785 | menu.exec_(QtGui.QCursor.pos())
|
---|
786 |
|
---|
787 | def onActionImportConfigFile(self, datacenter):
|
---|
788 | filename = unicode(QFileDialog.getOpenFileName(self
|
---|
789 | ,self.tr('Import bacula configuration file')
|
---|
790 | ,''
|
---|
791 | ,self.tr('bacula configuration files (*.conf)'))
|
---|
792 | )
|
---|
793 | if filename:
|
---|
794 | print "open filename" + filename
|
---|
795 |
|
---|
796 | if filename.find('-fd.conf') != -1:
|
---|
797 | datacenter.importConfigurationFile(filename, 'filedaemon')
|
---|
798 |
|
---|
799 | elif filename.find('-sd.conf') != -1:
|
---|
800 | datacenter.importConfigurationFile(filename, 'storagedaemon')
|
---|
801 | elif filename.find('-dir.conf') != -1:
|
---|
802 | datacenter.importConfigurationFile(filename, 'director')
|
---|
803 | elif filename.find('bconsole.conf') != -1:
|
---|
804 | datacenter.importConfigurationFile(filename, 'console')
|
---|
805 | else:
|
---|
806 | # TODO: QMessageBox Error
|
---|
807 | QMessageBox.warning(self,
|
---|
808 | self.tr('Warning'),
|
---|
809 | self.tr('did not recognize the file format of file ' + filename)
|
---|
810 | )
|
---|
811 | self.datacentersToTreeWidget()
|
---|
812 | '''
|
---|
813 | TODO: ask for filetype (dir, fd, sd, console) or try all and look if it works?
|
---|
814 | '''
|
---|
815 |
|
---|
816 |
|
---|
817 |
|
---|
818 | def onActionExport(self, resource):
|
---|
819 | filename = unicode(QFileDialog.getSaveFileName(self
|
---|
820 | ,self.tr('Export configuration file')
|
---|
821 | ,resource.getName().strip('"')+'.conf'
|
---|
822 | )
|
---|
823 | )
|
---|
824 | if filename:
|
---|
825 | f = open(filename,'w')
|
---|
826 | f.write(str(resource))
|
---|
827 | f.close()
|
---|
828 |
|
---|
829 |
|
---|
830 |
|
---|
831 | def onActionSaveDcAs(self ,datacenter):
|
---|
832 | filename = unicode(QFileDialog.getSaveFileName(self
|
---|
833 | ,self.tr('save datacenter file as...')
|
---|
834 | ,datacenter.getName().strip('"')+'.dmdz'
|
---|
835 | )
|
---|
836 | )
|
---|
837 | if filename:
|
---|
838 | datacenter.setFileName(filename)
|
---|
839 | datacenter.safeDatacenter()
|
---|
840 |
|
---|
841 | def onActionSaveDc(self ,datacenter):
|
---|
842 | datacenter.safeDatacenter()
|
---|
843 |
|
---|
844 |
|
---|
845 | def onImportSnippet(self, resource):
|
---|
846 | filename = unicode(QFileDialog.getOpenFileName(self
|
---|
847 | ,self.tr('Import bacula client snippet from autoconfiguration daemon')
|
---|
848 | ,''
|
---|
849 | ,self.tr('bacula client configuration snippets (*.snippet)'))
|
---|
850 | )
|
---|
851 | if filename:
|
---|
852 | f = open(filename,'r')
|
---|
853 | snippet = f.read()
|
---|
854 | f.close()
|
---|
855 | #newres = resource.createResource('client')
|
---|
856 | resource.parse_configfile(snippet, None)
|
---|
857 | self.rebuildTreeWidget()
|
---|
858 |
|
---|
859 | def onActionAdd(self, resource, resname):
|
---|
860 |
|
---|
861 | newres = resource.createResource(resname)
|
---|
862 | wizard = dassmodus.ui.baseconfwizard.baseconfigwizard(newres,resource)
|
---|
863 | if wizard.exec_():
|
---|
864 | print "ok"
|
---|
865 | else:
|
---|
866 | resource.deleteResource(newres)
|
---|
867 | self.rebuildTreeWidget()
|
---|
868 | #self.sender().storageItem.setValue( unicode(self.sender().currentText() ) )
|
---|
869 |
|
---|
870 | def onActionDelete(self, resource):
|
---|
871 | print self.tr("deleting ") , resource
|
---|
872 | if hasattr(resource,'parentconfig'): # resource?
|
---|
873 | resource.parentconfig.deleteResource(resource)
|
---|
874 | del resource
|
---|
875 |
|
---|
876 | elif hasattr(resource,'parentdatacenter'): # resource?
|
---|
877 | resource.parentdatacenter.deleteConfiguration(resource)
|
---|
878 | #del resource
|
---|
879 |
|
---|
880 | else:
|
---|
881 | print "help me"
|
---|
882 | # BaculaConfig TODO!
|
---|
883 | #Configurations.remove(resource)
|
---|
884 | # del resource
|
---|
885 |
|
---|
886 | self.treeWidget.clear() # TODO: better remove the corresponding treewidgetitem
|
---|
887 | self.rebuildTreeWidget()
|
---|
888 |
|
---|
889 | def onActionCreateFDConfig(self, dirClient):
|
---|
890 | print self.tr("creating FD Config from ") , dirClient
|
---|
891 | newFdConfig = FileDaemonConfig('')
|
---|
892 | dirClient.parentconfig.parentdatacenter.filedaemons.add(newFdConfig)
|
---|
893 | newFdConfig.createFdConfigFromDirClient(dirClient) # copy relevant info from dirClient entry
|
---|
894 | #newFdConfig.filename = os.getcwd()+ newFdConfig.name +'-fd.conf'
|
---|
895 | newFdConfig.filename = os.getcwd()+ '/' + newFdConfig.name +'-fd.conf'
|
---|
896 | self.rebuildTreeWidget()
|
---|
897 |
|
---|
898 |
|
---|
899 |
|
---|
900 |
|
---|
901 | #def newClient(self):
|
---|
902 | # newres = dirconf.createResource('client')
|
---|
903 | # newres.items_dict['name'].storage.setValue('newclient')
|
---|
904 | # self.addResourcesToTreeWidget(self.dirconfRoot, [newres])
|
---|
905 | #
|
---|
906 | #def newJobDefs(self):
|
---|
907 | # newres = dirconf.createResource('jobdefs')
|
---|
908 | # newres.items_dict['name'].storage.setValue('newJobDefs')
|
---|
909 | # self.addResourcesToTreeWidget(self.dirconfRoot, [newres])
|
---|
910 | #
|
---|
911 | #def newDirector(self):
|
---|
912 | # newres = dirconf.createResource('director')
|
---|
913 | # newres.items_dict['name'].storage.setValue('newDirector')
|
---|
914 | # self.addResourcesToTreeWidget(self.dirconfRoot, [newres])
|
---|
915 |
|
---|
916 | def onSave(self):
|
---|
917 | for dc in Datacenters:
|
---|
918 | dc.writeDatacenter('/tmp/')
|
---|
919 |
|
---|
920 | #for conf in Configurations:a
|
---|
921 | # print "writing "+ conf.filename
|
---|
922 | # writefile = open(conf.filename,'w')
|
---|
923 | # #writefile = open(outfile,'w')
|
---|
924 | # writefile.write(str(conf))
|
---|
925 | # #print str(dirconf)
|
---|
926 | # writefile.close()
|
---|
927 |
|
---|
928 | def onTreeItemClick(self, item):
|
---|
929 |
|
---|
930 | #print item.Resource.onlinehelpURL
|
---|
931 | if hasattr(item,'Resource'):
|
---|
932 | if hasattr(item.Resource,'onlinehelpURL'):
|
---|
933 | self.onlinehelpdialog.loadURL(item.Resource.onlinehelpURL)
|
---|
934 |
|
---|
935 | if self.textEdit.isVisible(): # only create the config file if output is visible
|
---|
936 | self.textEdit.setText(unicode(item.Resource))
|
---|
937 |
|
---|
938 | self.addConfigItemsToItemsGroup(item.Resource)
|
---|
939 | self.updateReferencesItemsList(item.Resource)
|
---|
940 |
|
---|
941 | # TODO: this does not work (why?)
|
---|
942 | #if hasattr(item.Resource,'filename'):
|
---|
943 | # self.statusBar.showMessage(item.Resource.filename, 5000)
|
---|
944 |
|
---|
945 |
|
---|
946 |
|
---|
947 | #def onPushButton(self):
|
---|
948 | # print "PushButton"
|
---|
949 | # self.addConfigToTreeWidget(dirconf,None)
|
---|
950 | # #self.addDictToTreeWidget(myNewResDict,None)
|
---|
951 |
|
---|
952 | def rebuildTreeWidget(self):
|
---|
953 |
|
---|
954 | #self.treeWidget.clear()
|
---|
955 |
|
---|
956 | self.datacentersToTreeWidget()
|
---|
957 |
|
---|
958 | #self.configsToTreeWidget()
|
---|
959 |
|
---|
960 | #self.treeWidget.expandToDepth(0)
|
---|
961 | #self.treeWidget.resizeColumnToContents(0)
|
---|
962 | #self.treeWidget.resizeColumnToContents(1)
|
---|
963 | self.treeWidget.setAlternatingRowColors(False)
|
---|
964 | self.treeWidget.sortByColumn(0, Qt.AscendingOrder)
|
---|
965 | #self.treeWidget.expandAll()
|
---|
966 |
|
---|
967 | def addResourcesToTreeWidget( self, parentTreeItem, Resources ):
|
---|
968 | # check if we already have a treewidgetitem for this resource
|
---|
969 | resources2treewidgetitem = {}
|
---|
970 | resources_to_create = set(Resources)
|
---|
971 | # check if there is already a sibling item for this resource
|
---|
972 | #QtGui.QTreeWidgetItem.
|
---|
973 | count = parentTreeItem.childCount()
|
---|
974 | #print count
|
---|
975 | for res in Resources: # all resources
|
---|
976 | for i in range(count): # iterate over all siblings
|
---|
977 | tli = parentTreeItem.child(i)
|
---|
978 | if tli.Resource == res: # is there already a sibling representing res?
|
---|
979 | resources_to_create.remove(res)
|
---|
980 | resources2treewidgetitem[res]= tli
|
---|
981 |
|
---|
982 |
|
---|
983 | #logger.info(str(resources_to_create))
|
---|
984 | for res in Resources: # some Resources do not have a name (include, exclude, options...s)
|
---|
985 | try:
|
---|
986 | name = res.getName()
|
---|
987 | #name = res.items_dict['name'].storage.value.strip('"')
|
---|
988 | except:
|
---|
989 | name = ' ' # no name
|
---|
990 |
|
---|
991 | refcount = len(res.reflist)
|
---|
992 | # only add treewidget for not existing resources
|
---|
993 | if res in resources_to_create:
|
---|
994 | mytreeitem = ResourceTreeWidgetItem( res, [ PrettyNames[res.resourcetype], unicode(name), str(refcount)] )
|
---|
995 | parentTreeItem.addChild(mytreeitem)
|
---|
996 | icon = QtGui.QIcon(":/icons/" + res.resourcetype + ".png")
|
---|
997 | mytreeitem.setIcon(0,icon)
|
---|
998 | else:
|
---|
999 | mytreeitem = resources2treewidgetitem[res]
|
---|
1000 |
|
---|
1001 | self.addResourcesToTreeWidget(mytreeitem, res.resources)
|
---|
1002 |
|
---|
1003 |
|
---|
1004 |
|
---|
1005 | def addConfigToTreeWidget(self,Resource):
|
---|
1006 | name = Resource.getName()
|
---|
1007 | #parent = ResourceTreeWidgetItem(Resource,[Resource.__class__.__name__, name, Resource.filename])
|
---|
1008 | parent = ResourceTreeWidgetItem(Resource,[Resource.__class__.__name__, unicode(name)] )
|
---|
1009 |
|
---|
1010 | parent.setStatusTip(0,QtCore.QString(Resource.filename))
|
---|
1011 | #parent.setToolTip(0,QtCore.QString(Resource.filename))
|
---|
1012 | #parent.setWhatsThis(0,QtCore.QString(Resource.filename))
|
---|
1013 | icon = QtGui.QIcon(":/icons/config.png")
|
---|
1014 | parent.setIcon(0,icon)
|
---|
1015 | #if Resource.__class__.__name__ == 'DirectorConfig':
|
---|
1016 | # self.resGroupingTreeItems = {} # which resource types are grouped under DirectorConfig?
|
---|
1017 |
|
---|
1018 | self.treeWidget.addTopLevelItem(parent)
|
---|
1019 | self.addResourcesToTreeWidget(parent, Resource.resources)
|
---|
1020 | return parent
|
---|
1021 |
|
---|
1022 |
|
---|
1023 | def addConfigToDc(self, Resource, DcTreeWidgetItem):
|
---|
1024 |
|
---|
1025 | parent = None
|
---|
1026 | count = DcTreeWidgetItem.childCount()
|
---|
1027 | #QtGui.QTreeWidgetItem.child(int)
|
---|
1028 | for i in range (count):
|
---|
1029 | if DcTreeWidgetItem.child(i).Resource == Resource:
|
---|
1030 | parent = DcTreeWidgetItem.child(i)
|
---|
1031 |
|
---|
1032 | if not parent:
|
---|
1033 | name = Resource.getName().strip('"') # remove quotation marks
|
---|
1034 | #parent = ResourceTreeWidgetItem(Resource,[Resource.__class__.__name__, name, Resource.filename])
|
---|
1035 | parent = ResourceTreeWidgetItem(Resource,[Resource.__class__.__name__, unicode(name) ])
|
---|
1036 |
|
---|
1037 | parent.setStatusTip(0,QtCore.QString(Resource.filename))
|
---|
1038 | #parent.setToolTip(0,QtCore.QString(Resource.filename))
|
---|
1039 | #parent.setWhatsThis(0,QtCore.QString(Resource.filename))
|
---|
1040 | #icon = QtGui.QIcon(":/icons/config.png")
|
---|
1041 | #print Resource.__class__.__name__.replace('Config','').lower()
|
---|
1042 | icon = QtGui.QIcon(":/icons/" + Resource.__class__.__name__.replace('Config','').lower() +".png")
|
---|
1043 |
|
---|
1044 | parent.setIcon(0,icon)
|
---|
1045 | #if Resource.__class__.__name__ == 'DirectorConfig':
|
---|
1046 | # self.resGroupingTreeItems = {} # which resource types are grouped under DirectorConfig?
|
---|
1047 | DcTreeWidgetItem.addChild(parent)
|
---|
1048 | #self.treeWidget.addTopLevelItem(parent)
|
---|
1049 | self.addResourcesToTreeWidget(parent, Resource.resources)
|
---|
1050 | return parent
|
---|
1051 |
|
---|
1052 |
|
---|
1053 |
|
---|
1054 |
|
---|
1055 |
|
---|
1056 |
|
---|
1057 |
|
---|
1058 |
|
---|
1059 |
|
---|
1060 |
|
---|
1061 |
|
---|
1062 | def onCheckboxChecked(self):
|
---|
1063 | print "checkbox was checked by:" , self.sender().objectName() , "to:" , self.sender().isChecked()
|
---|
1064 | self.sender().storageItem.setValue( self.sender().isChecked() )
|
---|
1065 |
|
---|
1066 | def onComboboxChanged(self):
|
---|
1067 | print "combobox was changed by:" , self.sender().objectName() , "to:" , self.sender().currentText()
|
---|
1068 | self.sender().storageItem.setValue( unicode(self.sender().currentText() ) )
|
---|
1069 |
|
---|
1070 | def onLineEditChanged(self):
|
---|
1071 | print "LineEdit was changed by:" , self.sender().objectName() , "to:" , self.sender().text()
|
---|
1072 | self.sender().storageItem.setValue( unicode(self.sender().text() ) )
|
---|
1073 |
|
---|
1074 | def onReferenceItemDoubleClicked(self,item):
|
---|
1075 | print "RefItemClicked:" , ":" , item.text(), item.Resource
|
---|
1076 | for ResTreeItem in ResourceTreeWidgetItem.itemsList:
|
---|
1077 | if ResTreeItem.Resource == item.Resource:
|
---|
1078 | self.treeWidget.setCurrentItem(ResTreeItem)
|
---|
1079 | #TODO: Find the right TreeWidgetItem and activate it
|
---|
1080 |
|
---|
1081 | def onFileListItemDoubleClicked(self,item):
|
---|
1082 | print "FileItemClicked:" , ":" , item.text()
|
---|
1083 | item.editItem(item)
|
---|
1084 |
|
---|
1085 | #for ResTreeItem in ResourceTreeWidgetItem.itemsList:
|
---|
1086 | # if ResTreeItem.Resource == item.Resource:
|
---|
1087 | # self.treeWidget.setCurrentItem(ResTreeItem)
|
---|
1088 |
|
---|
1089 |
|
---|
1090 | def updateReferenceInformation(self):
|
---|
1091 | """
|
---|
1092 | iterate over all resources and update the
|
---|
1093 | reference information accordingly
|
---|
1094 | """
|
---|
1095 | for dc in Datacenters:
|
---|
1096 | for config in list(dc.directors) + list(dc.filedaemons) + list(dc.storagedaemons) + list(dc.consoles):
|
---|
1097 | for res in config.resources:
|
---|
1098 | reflist = config.getReferencingResourcesListForResource(res)
|
---|
1099 | res.reflist = reflist
|
---|
1100 | #print '\n',res.resourcetype, res.items_dict['name'].storage.value,"is referenced", len(reflist),"times:"
|
---|
1101 | #for refres in reflist:
|
---|
1102 | # print refres.resourcetype, refres.items_dict['name'].storage.value
|
---|
1103 |
|
---|
1104 | def updateReferencesItemsList(self,Resource):
|
---|
1105 | self.referencesListWidget.clear()
|
---|
1106 | for r in Resource.reflist:
|
---|
1107 | #icon = QtGui.QIcon(":/icons/" + r.resourcetype + ".png")
|
---|
1108 | ListWidgetItem = ResourceListWidgetItem(r)
|
---|
1109 | #QtGui.QListWidgetItem(r.resourcetype+ ' ' + r.items_dict['name'].storage.value)
|
---|
1110 | #ListWidgetItem.setIcon(icon)
|
---|
1111 | self.referencesListWidget.addItem(ListWidgetItem)
|
---|
1112 |
|
---|
1113 |
|
---|
1114 |
|
---|
1115 | def addConfigItemsToItemsGroup(self,Resource):
|
---|
1116 |
|
---|
1117 | #cleanup widgets
|
---|
1118 | for widget in self.gridwidgets:
|
---|
1119 | self.gridLayout_2.removeWidget(widget)
|
---|
1120 | widget.setParent(None)
|
---|
1121 | self.gridwidgets = []
|
---|
1122 | #TODO: do this depending on the type, ignore for Configs
|
---|
1123 | if not hasattr(Resource,'items'):
|
---|
1124 | return
|
---|
1125 |
|
---|
1126 | row = 0
|
---|
1127 |
|
---|
1128 | # special treatment of file entries
|
---|
1129 | if Resource.shortname == 'include': # is the same as exclude
|
---|
1130 | newlabel = QtGui.QLabel(self.scrollAreaWidgetContents)
|
---|
1131 | newlabel.setText('Files')
|
---|
1132 | self.gridLayout_2.addWidget(newlabel, row, 0, 1, 1)
|
---|
1133 | self.gridwidgets.append(newlabel)
|
---|
1134 |
|
---|
1135 | filelistWidget = dassmodus.dragndrop.DnDListWidget()
|
---|
1136 | self.gridwidgets.append(filelistWidget)
|
---|
1137 | self.gridLayout_2.addWidget(filelistWidget, row, 1, 1, 1)
|
---|
1138 | for f in Resource.getItemsListByItemName('file'):
|
---|
1139 | if f.print_item():
|
---|
1140 | fileListWidgetItem = QtGui.QListWidgetItem(unicode(f.storage.value).rstrip('"').lstrip('"'))
|
---|
1141 |
|
---|
1142 | self.connect( filelistWidget,
|
---|
1143 | SIGNAL("itemDoubleClicked(QListWidgetItem *)"),
|
---|
1144 | self.onFileListItemDoubleClicked
|
---|
1145 | )
|
---|
1146 | #print Resource.items_dict
|
---|
1147 | icon = QIcon(":/icons/" + Resource.resourcetype + "file.png")
|
---|
1148 | fileListWidgetItem.setIcon(icon)
|
---|
1149 | filelistWidget.addItem(fileListWidgetItem)
|
---|
1150 | row += 1
|
---|
1151 |
|
---|
1152 | #TODO: create a ListWidget on the fileset level containing both include and exclude with +/- icons
|
---|
1153 | # in order to view all included and excluded things at once
|
---|
1154 |
|
---|
1155 |
|
---|
1156 |
|
---|
1157 |
|
---|
1158 |
|
---|
1159 | for item in Resource.items:
|
---|
1160 |
|
---|
1161 | if item.name == 'file':
|
---|
1162 | continue
|
---|
1163 | # clear
|
---|
1164 |
|
---|
1165 | # items manually added to horizontallayout
|
---|
1166 |
|
---|
1167 | if item.print_item() or self.showAllCheckBox.isChecked(): # only print configured or required items
|
---|
1168 |
|
---|
1169 | newlabel = QtGui.QLabel(self.scrollAreaWidgetContents)
|
---|
1170 | labeltext = PrettyNames[item.name]
|
---|
1171 | # show job items that are inherited from jobdefs
|
---|
1172 | if hasattr(item.parentresource,'shortname') and item.parentresource.shortname == 'job':
|
---|
1173 | jobdef = False
|
---|
1174 | jobdefname = item.parentresource.getItemValue('jobdefs')
|
---|
1175 | #jobdefname = item.parentresource.items_dict['jobdefs'].storage.value
|
---|
1176 |
|
---|
1177 | if jobdefname is not None:
|
---|
1178 | print "jobdefs is set:" + str(jobdefname)
|
---|
1179 | jobdef = True
|
---|
1180 |
|
---|
1181 | else:
|
---|
1182 | print "jobdefs is not set:" + str(item.parentresource.items_dict['jobdefs'].storage)
|
---|
1183 | jobdef = False
|
---|
1184 |
|
---|
1185 | if jobdef and item.storage.value == item.defaultvalue:
|
---|
1186 | jobdefs = item.parentresource.parentconfig.getResourceByName( jobdefname )
|
---|
1187 | if jobdefs.items_dict[item.name].storage.value != jobdefs.items_dict[item.name].defaultvalue:
|
---|
1188 | #print '>' + jobdefs.items_dict[item.name].storage.value + '<'
|
---|
1189 | #labeltext = PrettyNames[item.name] + ' (' + jobdefname + '->' + jobdefs.items_dict[item.name].storage.value + ' )'
|
---|
1190 | #labeltext = PrettyNames[item.name] + ' (' + jobdefs.items_dict[item.name].storage.value + ')'
|
---|
1191 | labeltext = PrettyNames[item.name] + ' (' + jobdefs.getName() + ')'
|
---|
1192 |
|
---|
1193 | newlabel.setText(labeltext)
|
---|
1194 |
|
---|
1195 | self.gridLayout_2.addWidget(newlabel, row, 0, 1, 1)
|
---|
1196 | self.gridwidgets.append(newlabel)
|
---|
1197 |
|
---|
1198 | font = QtGui.QFont()
|
---|
1199 |
|
---|
1200 | # bold means: item will be printed
|
---|
1201 | if item.print_item():
|
---|
1202 | font.setWeight(75)
|
---|
1203 | font.setBold(True)
|
---|
1204 | newlabel.setFont(font)
|
---|
1205 | newlabel.setToolTip(self.tr('item will be printed'))
|
---|
1206 |
|
---|
1207 | # Italic means: item is required
|
---|
1208 | if item.required:
|
---|
1209 | font.setWeight(50)
|
---|
1210 | font.setItalic(True)
|
---|
1211 | font.setUnderline(True)
|
---|
1212 | newlabel.setFont(font)
|
---|
1213 | newlabel.setToolTip(self.tr('item is required'))
|
---|
1214 |
|
---|
1215 | if item.storage.__class__.__name__ in BOOL_ITEMS:
|
---|
1216 | newcheckbox = StorageItemCheckbox(item.storage, unicode(item.storage.value))
|
---|
1217 |
|
---|
1218 | #newcheckbox = QtGui.QCheckBox(str(item.storage.value))
|
---|
1219 | self.gridLayout_2.addWidget(newcheckbox, row, 1, 1, 1)
|
---|
1220 | newcheckbox.setObjectName(item.name)
|
---|
1221 |
|
---|
1222 | newcheckbox.setChecked( bool(item.storage.value) )
|
---|
1223 | self.gridwidgets.append(newcheckbox)
|
---|
1224 |
|
---|
1225 | self.connect( newcheckbox,
|
---|
1226 | SIGNAL("toggled(bool)"),
|
---|
1227 | self.onCheckboxChecked )
|
---|
1228 |
|
---|
1229 |
|
---|
1230 | elif item.name == 'run': # Schedule "Run" entries
|
---|
1231 | # 'String input'
|
---|
1232 | newlineedit = StorageItemLineEdit(self.scrollAreaWidgetContents,
|
---|
1233 | item.storage)#QtGui.QLineEdit(self.scrollAreaWidgetContents)
|
---|
1234 | newlineedit.setText(unicode(item.storage.value))
|
---|
1235 |
|
---|
1236 | self.gridLayout_2.addWidget(newlineedit, row, 1, 1, 1)
|
---|
1237 | self.gridwidgets.append(newlineedit)
|
---|
1238 | self.connect( newlineedit,
|
---|
1239 | SIGNAL("returnPressed()"),
|
---|
1240 | self.onLineEditChanged )
|
---|
1241 | self.connect( newlineedit,
|
---|
1242 | SIGNAL("editingFinished()"),
|
---|
1243 | self.onLineEditChanged )
|
---|
1244 |
|
---|
1245 | # add a Button to edit the run entry (with own dialog)
|
---|
1246 | newbutton = StorageItemPushButton(item.storage)
|
---|
1247 | newbutton.setText(self.tr('Edit...'))
|
---|
1248 | self.gridwidgets.append(newbutton)
|
---|
1249 |
|
---|
1250 | self.gridLayout_2.addWidget(newbutton, row, 2, 1, 1)
|
---|
1251 | self.connect( newbutton,
|
---|
1252 | SIGNAL("clicked()"),
|
---|
1253 | self.onRunentryEdit )
|
---|
1254 |
|
---|
1255 |
|
---|
1256 |
|
---|
1257 | elif item.name in INTERNALLY_REFERENCED_ITEMS:
|
---|
1258 | newcombobox = StorageItemCombobox(item.storage)
|
---|
1259 | newcombobox.setObjectName(item.name)
|
---|
1260 | #QtGui.QComboBox()
|
---|
1261 |
|
---|
1262 | newcombobox.addItem(unicode(item.storage.value))
|
---|
1263 | #newcombobox.addItem(unicode(item.storage.value.strip('"')))
|
---|
1264 | #QtGui.QComboBox.currentIndexChanged(*types name=str)
|
---|
1265 |
|
---|
1266 | restype = item.name
|
---|
1267 | if restype.endswith('pool'):
|
---|
1268 | restype = 'pool'
|
---|
1269 | if restype.endswith('job'):
|
---|
1270 | restype = 'job'
|
---|
1271 |
|
---|
1272 | for r in Resource.parentconfig.getResourcesListByResType(restype):
|
---|
1273 | if newcombobox.findText(QString(r.getName())) == -1:
|
---|
1274 | newcombobox.addItem(r.getName())
|
---|
1275 | #newcombobox.addItem(r.items_dict['name'].storage.value)
|
---|
1276 | #newcombobox.setText(str(item.storage.value))
|
---|
1277 | self.gridLayout_2.addWidget(newcombobox, row, 1, 1, 1)
|
---|
1278 | self.gridwidgets.append(newcombobox)
|
---|
1279 |
|
---|
1280 | self.connect( newcombobox,
|
---|
1281 | SIGNAL("currentIndexChanged(int)"),
|
---|
1282 | self.onComboboxChanged )
|
---|
1283 |
|
---|
1284 | elif len(item.storage.possiblevalues) > 0: # do we have predefined possible values?
|
---|
1285 | #print item.storage.__class__.__name__
|
---|
1286 | newcombobox = StorageItemCombobox(item.storage)#QtGui.QComboBox()
|
---|
1287 | newcombobox.setObjectName(item.name)
|
---|
1288 |
|
---|
1289 |
|
---|
1290 | for v in item.storage.possiblevalues:
|
---|
1291 | newcombobox.addItem(PrettyNames[v.lower().replace(' ','')])
|
---|
1292 |
|
---|
1293 | self.gridLayout_2.addWidget(newcombobox, row, 1, 1, 1)
|
---|
1294 | self.gridwidgets.append(newcombobox)
|
---|
1295 |
|
---|
1296 | if item.storage.value is None:
|
---|
1297 | newcombobox.addItem('unconfigured')
|
---|
1298 | newcombobox.setCurrentIndex(newcombobox.findText('unconfigured'))
|
---|
1299 |
|
---|
1300 | elif item.storage.value is True:
|
---|
1301 | #newcombobox.addItem('Yes')
|
---|
1302 | newcombobox.setCurrentIndex(newcombobox.findText('Yes'))
|
---|
1303 |
|
---|
1304 | elif item.storage.value is False:
|
---|
1305 | #newcombobox.addItem('No')
|
---|
1306 | newcombobox.setCurrentIndex(newcombobox.findText('No'))
|
---|
1307 |
|
---|
1308 | else:
|
---|
1309 | newcombobox.setCurrentIndex(
|
---|
1310 | newcombobox.findText(unicode(item.storage.value).lower().replace(' ','') ))
|
---|
1311 |
|
---|
1312 |
|
---|
1313 | self.connect( newcombobox,
|
---|
1314 | SIGNAL("currentIndexChanged(int)"),
|
---|
1315 | self.onComboboxChanged )
|
---|
1316 |
|
---|
1317 | else:
|
---|
1318 | # 'String input'
|
---|
1319 | newlineedit = StorageItemLineEdit(self.scrollAreaWidgetContents, item.storage)#QtGui.QLineEdit(self.scrollAreaWidgetContents)
|
---|
1320 |
|
---|
1321 | #newlineedit.setText(str(item.storage.value))
|
---|
1322 | newlineedit.setText(unicode(item.storage))
|
---|
1323 |
|
---|
1324 | self.gridLayout_2.addWidget(newlineedit, row, 1, 1, 1)
|
---|
1325 | self.gridwidgets.append(newlineedit)
|
---|
1326 |
|
---|
1327 | self.connect( newlineedit,
|
---|
1328 | SIGNAL("returnPressed()"),
|
---|
1329 | self.onLineEditChanged )
|
---|
1330 | self.connect( newlineedit,
|
---|
1331 | SIGNAL("editingFinished()"),
|
---|
1332 | self.onLineEditChanged )
|
---|
1333 |
|
---|
1334 |
|
---|
1335 | if item.storage.__class__.__name__ == 'store_msgs': # messages items
|
---|
1336 | #print "found store_msgs"
|
---|
1337 | # add a Button to edit the run entry (with own dialog)
|
---|
1338 | newbutton = StorageItemPushButton(item.storage)
|
---|
1339 | newbutton.setText('Edit...')
|
---|
1340 | self.gridwidgets.append(newbutton)
|
---|
1341 |
|
---|
1342 | self.gridLayout_2.addWidget(newbutton, row, 2, 1, 1)
|
---|
1343 | self.connect( newbutton,
|
---|
1344 | SIGNAL("clicked()"),
|
---|
1345 | self.onMessageEntryEdit )
|
---|
1346 |
|
---|
1347 | elif item.storage.__class__.__name__.endswith('acl'): # acl items
|
---|
1348 | #print "found store_msgs"
|
---|
1349 | # add a Button to edit the run entry (with own dialog)
|
---|
1350 | newbutton = StorageItemPushButton(item.storage)
|
---|
1351 | newbutton.setText('Edit...')
|
---|
1352 | self.gridwidgets.append(newbutton)
|
---|
1353 |
|
---|
1354 | self.gridLayout_2.addWidget(newbutton, row, 2, 1, 1)
|
---|
1355 | self.connect( newbutton,
|
---|
1356 | SIGNAL("clicked()"),
|
---|
1357 | self.onAclEntryEdit )
|
---|
1358 |
|
---|
1359 | # write the default value after the configured value
|
---|
1360 | if item.defaultvalue:
|
---|
1361 | requiredlabel = QtGui.QLabel(self.scrollAreaWidgetContents)
|
---|
1362 | requiredlabel.setText('('+str(item.defaultvalue)+')')
|
---|
1363 | self.gridLayout_2.addWidget(requiredlabel, row, 2, 1, 1)
|
---|
1364 | self.gridwidgets.append(requiredlabel)
|
---|
1365 |
|
---|
1366 |
|
---|
1367 | row += 1
|
---|
1368 |
|
---|
1369 |
|
---|
1370 |
|
---|
1371 |
|
---|
1372 |
|
---|
1373 |
|
---|
1374 | # create logger
|
---|
1375 | #logger = logging.getLogger("vanHelsing")
|
---|
1376 | #print FS_option_kw
|
---|
1377 |
|
---|
1378 |
|
---|
1379 |
|
---|
1380 | def main():
|
---|
1381 |
|
---|
1382 | print "started in directory " + DASSMODUS_PATH
|
---|
1383 | app = QtGui.QApplication(sys.argv)
|
---|
1384 | locale = QLocale.system().name()
|
---|
1385 | qtTranslator = QTranslator()
|
---|
1386 | if qtTranslator.load("qt_" + locale, ":/"):
|
---|
1387 | app.installTranslator(qtTranslator)
|
---|
1388 | appTranslator = QTranslator()
|
---|
1389 | if appTranslator.load("dassModus_" + locale + ":/"):
|
---|
1390 | app.installTranslator(appTranslator)
|
---|
1391 |
|
---|
1392 |
|
---|
1393 | app.setOrganizationDomain("dass-it.de")
|
---|
1394 | app.setOrganizationName("dassIT GmbH")
|
---|
1395 | app.setApplicationName("dassModus")
|
---|
1396 | app.setWindowIcon(QIcon(":/icons/DassModusLogo/logo300.png"))
|
---|
1397 | dialog = MeinDialog()
|
---|
1398 | dialog.show()
|
---|
1399 | dialog.onActionAbout()
|
---|
1400 | sys.exit(app.exec_())
|
---|
1401 |
|
---|
1402 |
|
---|
1403 | if __name__ == "__main__":
|
---|
1404 | sys.exit(main())
|
---|
1405 |
|
---|
1406 |
|
---|