source: dassmodus/trunk/dassmodus/dassmodus/dassModus.py

Last change on this file was 961, checked in by pstorz, on Oct 18, 2011 at 5:09:06 PM

added templates dir

  • Property svn:executable set to *
File size: 51.8 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# $Id: dassmodus.py 11432 2010-11-01 19:20:55Z pstorz $
5
6
7from PyQt4 import QtGui, QtCore
8from PyQt4.QtCore import *
9from PyQt4.QtGui import *
10from functools import partial
11
12import dassmodus.ui.schedule
13import dassmodus.ui.onlinehelpdialog
14import dassmodus.ui.messagesdialog
15import dassmodus.ui.listselectdialog
16import dassmodus.ui.baseconfwizard
17import dassmodus.ui.fetchDCdialog
18import dassmodus.ui.integrityCheckDialog
19import dassmodus.ui.newdatacenterwizard
20import dassmodus.ui.deploywizard
21
22from nosferatu.bacresources import *
23from nosferatu.prettynames import PrettyNames
24#from nosferatu.directive import *
25#from nosferatu import configrules
26
27import logging
28
29logging.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
35import sys
36import os
37import re
38import platform
39#import glob
40
41from dassmodus.ui.mainwindow import Ui_MainWindow as Dlg
42import re
43
44import xmlrpclib
45
46import dassmodus.dragndrop
47
48import dassmodus.ui.qt_resources # for the icons
49
50TEMPLATES_PATH = '/usr/share/dassmodus/templates' # DC templates for new datacenter wizard
51
52'''
53find where our executable script is called from,as the templates dir is relative to that.
54As we are running as py2exe on windows, we have to make these efforts:
55see http://www.py2exe.org/index.cgi/WhereAmI
56'''
57def 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
64def 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
72DASSMODUS_PATH = module_path()
73
74RXP_DATE = re.compile('.*\((.*)\)')
75
76#from nosferatu.directive import *
77
78__version__ = 0.1
79
80__revision__ = "$Rev: 11441 $".replace('$','').replace('Rev: ','.')
81
82
83datestring = "$Date: 2011-02-10 15:00:43 +0100 (Do, 10 Feb 2011) $".replace('$','').replace('Date: ','')
84m = RXP_DATE.match(datestring)
85__date__ = '(' + m.group(1) + ')'
86
87
88
89
90INTERNALLY_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 ])
105BOOL_ITEMS = set([
106 'store_bool',
107 'store_runscript_bool',
108 ])
109
110logging.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
116logger = logging.getLogger("vanHelsing")
117logger.setLevel(logging.DEBUG)
118
119
120
121logger.debug(QApplication.translate('Main','Started Main Program'))
122
123
124
125OUTPUTDIR = '/etc/bacula/'
126#INPUTDIR = '/etc/bacula/'
127INPUTDIR = ':/'
128
129
130#Configurations = [] # global list of configuration objects
131Datacenters = []
132
133#proxy = xmlrpclib.ServerProxy("http://bacula-devel:8000/")
134class 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
222class StorageItemCheckbox(QCheckBox):
223 def __init__(self, storageItem, label):
224 QCheckBox.__init__(self,label)
225 self.storageItem = storageItem
226
227class StorageItemLineEdit(QLineEdit):
228 def __init__(self, parentWidget, storageItem):
229 QCheckBox.__init__(self, parentWidget)
230 self.storageItem = storageItem
231
232
233class StorageItemCombobox(QComboBox):
234 def __init__(self, storageItem):
235 QComboBox.__init__(self)
236 self.storageItem = storageItem
237
238class 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
260class 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
269class ResItemTableWidgetItem(QTableWidgetItem):
270 def __init__(self, ResItem):
271 self.ResItem = ResItem
272 QTableWidgetItem.__init__(self)
273
274class 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
288class 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 &copy; 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
1380def 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
1403if __name__ == "__main__":
1404 sys.exit(main())
1405
1406
Note: See TracBrowser for help on using the repository browser.