class DSBrowser(QWidget): """browser for datastorage databases Nodes are identified by a string, containing fields separated by '|'. - first filed is a capital letter: 'R'oot, 'P'roject, sensor'G'roup, 'S'ensor and 'C'hart - second field is the database folder - third filed is the path of the node in the database - for charts the fourth field is the chart name (third is path of sensorgroup in this case) """ def __init__(self): QWidget.__init__(self) self.layout = QVBoxLayout(self) self.layout.setSpacing(0) self.layout.setMargin(0) self.toolBar = QFrame(self) self.toolBarLayout = QHBoxLayout(self.toolBar) self.toolBarLayout.setMargin(2) self.toolBarLayout.setSpacing(2) self.layout.addWidget(self.toolBar) self.loadButton = QToolButton(self.toolBar) self.loadButton.setText(QCoreApplication.translate('DataStorageBrowser', 'Open...')) self.loadButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.fileOpen))) self.loadButton.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Open a datastorage database')) self.toolBarLayout.addWidget(self.loadButton) self.connect(self.loadButton, SIGNAL('pressed()'), self.loadDatabase) self.dropButton = QToolButton(self.toolBar) self.dropButton.setText(QCoreApplication.translate('DataStorageBrowser', 'Close All')) self.dropButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.clear))) self.dropButton.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Drop all open databases')) self.toolBarLayout.addWidget(self.dropButton) self.connect(self.dropButton, SIGNAL('pressed()'), self.dropDatabases) self.dropButton.setEnabled(False) self.toolBarLayout.addStretch(100) self.splitter = QSplitter(self) self.splitter.setOrientation(Qt.Vertical) self.treeView = QTreeView(self.splitter) self.treeView.setAlternatingRowColors(True) self.treeView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.treeView.setContextMenuPolicy(Qt.CustomContextMenu) self.treeView.setAutoExpandDelay(500) self.textBrowser = QTextBrowser(self.splitter) self.layout.addWidget(self.splitter) self.splitter.setStretchFactor(0, 60) self.splitter.setStretchFactor(1, 40) self.model = DSModel() self.treeView.setModel(self.model) self.treeView.setSortingEnabled(True) self.treeView.expandAll() self.connect(self.treeView.selectionModel(), SIGNAL("currentChanged(QModelIndex, QModelIndex)"), self.showItem) self.connect(self.treeView, SIGNAL("doubleClicked(QModelIndex)"), self.itemAction) self.connect(self.treeView, SIGNAL("customContextMenuRequested(QPoint)"), self.showContextMenu) self.selectedNode = None self.selectedMI = None def loadDatabase(self, dn=None): """load a database""" if not dn: dn = QFileDialog.getExistingDirectory(self, QCoreApplication.translate('DataStorageBrowser', "Select a folder containing a datastorage database"), SimuVis4.Globals.defaultFolder) if not dn.isEmpty(): dn = unicode(dn) SimuVis4.Globals.defaultFolder = dn else: return self.model.addDatabase(dn) self.treeView.expandToDepth(1) def dropDatabases(self): # FIXME: implement it pass def showItem(self, mi, pr): """show the item at model index mi""" t, n = self.model.dsNode(mi) txt = "" if t == 'R': # FIXME: no metadata? txt = rootInfo.substitute(name=n.name, title=escape(n.title), folder=n.h5dir, projects=len(n)) # + formatMetaData(n) elif t == 'P': txt = projectInfo.substitute(name=n.name, title=escape(n.title), groups=len(n)) + formatMetaData(n) elif t == 'G': txt = groupInfo.substitute(name=n.name, title=escape(n.title), sensors=len(n), charts=len(n.charts)) + formatMetaData(n) elif t == 'S': txt = sensorInfo.substitute(name=n.name, title=escape(n.title), start=n.timegrid.start, stop=n.timegrid.stop, step=n.timegrid.step, length=n.datalen()) + formatMetaData(n) elif t == 'C': txt = chartInfo.substitute(name=n.name) self.textBrowser.setText(txt) def itemAction(self, mi): """default action (on doubleclick) for item at model index mi""" t, n = self.model.dsNode(mi) if t == 'R': pass elif t == 'P': pass elif t == 'G': pass elif t == 'S': print n self.showQwtPlot(n) elif t == 'C': self.showMplChart(n) def showContextMenu(self, pos): """show context menu for item at pos""" mi = self.treeView.indexAt(pos) t, n = self.model.dsNode(mi) self.selectedNode = n self.selectedMI = mi m = QMenu() if t in 'RPGS': p = m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Edit metadata'), self.editMetadata) if t == 'R': pass elif t == 'P': pass elif t == 'G': m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Add Chart'), self.newChart) elif t == 'S': m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Plot (Qwt)'), self.showQwtPlot) elif t == 'C': m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Show'), self.showMplChart) m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Delete'), self.deleteItem) a = m.exec_(self.treeView.mapToGlobal(pos)) def showMplChart(self, node=None): if node is None: node = self.selectedNode showChartMplWindow(node, maximized=showChartMaximized) def showQwtPlot(self, node=None): if node is None: node = self.selectedNode showQwtPlotWindow(node, maximized=showChartMaximized) def editMetadata(self, node=None): if node is None: node = self.selectedNode editMetadata(node) def newChart(self, mi=None): """add a chart to sensorgroup at mi using the wizard""" if mi is None: mi = self.selectedMI showNewChartWizard(self.model, mi) def deleteItem(self, mi=None): """delete the item at mi""" if mi is None: mi = self.selectedMI self.model.deleteItem(mi)
class DSBrowser(QWidget): """browser for datastorage databases Nodes are identified by a string, containing fields separated by '|'. - first filed is a capital letter: 'R'oot, 'P'roject, sensor'G'roup, 'S'ensor and 'C'hart - second field is the database folder - third filed is the path of the node in the database - for charts the fourth field is the chart name (third is path of sensorgroup in this case) """ def __init__(self): QWidget.__init__(self) self.layout = QVBoxLayout(self) self.layout.setSpacing(0) self.layout.setMargin(0) self.toolBar = QFrame(self) self.toolBarLayout = QHBoxLayout(self.toolBar) self.toolBarLayout.setMargin(2) self.toolBarLayout.setSpacing(2) self.layout.addWidget(self.toolBar) self.loadButton = QToolButton(self.toolBar) self.loadButton.setText(QCoreApplication.translate("DataStorageBrowser", "Open...")) self.loadButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.fileOpen))) self.loadButton.setToolTip(QCoreApplication.translate("DataStorageBrowser", "Open a datastorage database")) self.toolBarLayout.addWidget(self.loadButton) self.connect(self.loadButton, SIGNAL("pressed()"), self.loadDatabase) self.expandButton = QToolButton(self.toolBar) self.expandButton.setText("Expand/Collapse") self.expandButton.setIcon(QIcon(QPixmap(Icons.exp_col))) self.expandButton.setToolTip( QCoreApplication.translate("DataStorageBrowser", "Expand or collapse the whole tree") ) self.toolBarLayout.addWidget(self.expandButton) self.connect(self.expandButton, SIGNAL("pressed()"), self.expandCollapseAll) self.searchInput = MyLineEdit(self.toolBar) self.searchInput.setText(QCoreApplication.translate("DataStorageBrowser", "Enter search text here")) self.searchInput.setToolTip( QCoreApplication.translate( "DataStorageBrowser", "Enter search text using wildcards here, press ENTER again to go to next match!" ) ) self.toolBarLayout.addWidget(self.searchInput, 100) self.connect(self.searchInput, SIGNAL("returnPressed()"), self.searchItem) self.helpButton = QToolButton(self.toolBar) self.helpButton.setText(QCoreApplication.translate("DataStorageBrowser", "Help")) self.helpButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.help))) self.helpButton.setToolTip(QCoreApplication.translate("DataStorageBrowser", "Show help for DataStorageBrowser")) self.toolBarLayout.addWidget(self.helpButton) self.connect(self.helpButton, SIGNAL("pressed()"), self.showHelp) self.splitter = QSplitter(self) self.splitter.setOrientation(Qt.Vertical) self.treeView = QTreeView(self.splitter) self.treeView.setAlternatingRowColors(True) self.treeView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.treeView.setContextMenuPolicy(Qt.CustomContextMenu) self.treeView.setAutoExpandDelay(500) self.textBrowser = QTextBrowser(self.splitter) self.layout.addWidget(self.splitter) self.splitter.setStretchFactor(0, 60) self.splitter.setStretchFactor(1, 40) self.model = DSModel() self.treeView.setModel(self.model) self.treeView.setSortingEnabled(True) self.treeView.expandAll() self.connect(self.treeView.selectionModel(), SIGNAL("currentChanged(QModelIndex, QModelIndex)"), self.showItem) self.connect(self.treeView, SIGNAL("doubleClicked(QModelIndex)"), self.itemAction) self.connect(self.treeView, SIGNAL("customContextMenuRequested(QPoint)"), self.showContextMenu) self.selectedNode = None self.selectedMI = None self.searchText = "" self.searchResults = [] self.collExpand = SimuVis4.Misc.Switcher() self.statusBar = SimuVis4.Globals.mainWin.statusBar() def loadDatabase(self, dn=None): """load a database""" if not dn: dn = QFileDialog.getExistingDirectory( self, QCoreApplication.translate("DataStorageBrowser", "Select a folder containing a datastorage database"), SimuVis4.Globals.defaultFolder, ) if not dn.isEmpty(): dn = unicode(dn) SimuVis4.Globals.defaultFolder = dn else: return self.model.addDatabase(dn) self.treeView.collapseAll() self.treeView.expandToDepth(SimuVis4.Globals.config.getint("datastoragebrowser", "expand_tree_depth")) self.treeView.resizeColumnToContents(0) def showHelp(self): SimuVis4.HelpBrowser.showHelp("/plugin/DataStorageBrowser/index.html") def showItem(self, mi, pr): """show the item at model index mi""" t, n = self.model.dsNode(mi) txt = "" if t == "R": txt = rootInfo.substitute( name=n.name, title=escape(n.title), folder=n.h5dir, projects=len(n) ) + formatMetaData(n) elif t == "P": txt = projectInfo.substitute( name=n.name, path=escape(n.parent.name), title=escape(n.title), groups=len(n) ) + formatMetaData(n) elif t == "G": txt = groupInfo.substitute( name=n.name, path="/".join(n.path.split("/")[:-1]), title=escape(n.title), sensors=len(n), charts=len(n.getCharts()), start=formatTime(n.timegrid.start), stop=formatTime(n.timegrid.stop), step=n.timegrid.step, timezone=n.timegrid.timezone, ) + formatMetaData(n) elif t == "S": txt = sensorInfo.substitute( name=n.name, path="/".join(n.path.split("/")[:-1]), title=escape(n.title), start=formatTime(n.timegrid.start), stop=formatTime(n.timegrid.stop), step=n.timegrid.step, length=n.datalen(), timezone=n.timegrid.timezone, ) + formatMetaData(n) elif t == "C": txt = chartInfo.substitute(name=n.name, path=n.sensorgroup.path) self.textBrowser.setText(txt) msg = ": ".join(str(self.model.itemFromIndex(mi).data().toString()).split("|")[1:]) self.statusBar.showMessage(msg, 5000) def searchItem(self): """execute the search and highlight the (next) result""" txt = str(self.searchInput.text()) if txt != self.searchText: self.searchText = txt tmp = self.model.findItems( txt, Qt.MatchFixedString | Qt.MatchContains | Qt.MatchWildcard | Qt.MatchRecursive ) self.searchList = [i.index() for i in tmp] if self.searchList: mi = self.searchList.pop() self.treeView.setCurrentIndex(mi) self.treeView.expand(mi) self.treeView.scrollTo(mi) else: QMessageBox.information( self, QCoreApplication.translate("DataStorageBrowser", "No (more) matches!"), QCoreApplication.translate( "DataStorageBrowser", "No (more) matches found! Change you search text and try again!" ), ) self.searchText = "" def expandCollapseAll(self): if self.collExpand(): self.treeView.collapseAll() else: self.treeView.expandAll() def itemAction(self, mi): """default action (on doubleclick) for item at model index mi""" t, n = self.model.dsNode(mi) if t == "S": if qwtPlotWindowActive(): self.addToQwtPlot(n) else: self.showQwtPlot(n) elif t == "C": self.showChart(n) def showContextMenu(self, pos): """show context menu for item at pos""" mi = self.treeView.indexAt(pos) t, n = self.model.dsNode(mi) self.selectedNode = n self.selectedMI = mi m = QMenu() if t == "R": m.addAction(QCoreApplication.translate("DataStorageBrowser", "Close"), self.closeDatabase) m.addAction(QCoreApplication.translate("DataStorageBrowser", "Reload"), self.reloadDatabase) elif t == "P": m.addAction(QCoreApplication.translate("DataStorageBrowser", "New sensorgroup"), self.newSensorGroup) elif t == "G": nCharts = len(n.getCharts()) if nCharts > 0: txt = str(QCoreApplication.translate("DataStorageBrowser", "Show all charts (%d)")) % nCharts m.addAction(txt, self.showAllCharts) m.addAction( QCoreApplication.translate("DataStorageBrowser", "Save all charts as images"), self.saveAllChartImages, ) m.addAction(QCoreApplication.translate("DataStorageBrowser", "Add chart"), self.newChart) m.addAction(QCoreApplication.translate("DataStorageBrowser", "Add/update data"), self.importFiles) m.addAction(QCoreApplication.translate("DataStorageBrowser", "Export data"), self.exportSensors) elif t == "S": m.addAction(QCoreApplication.translate("DataStorageBrowser", "New plot (Qwt)"), self.showQwtPlot) if qwtPlotWindowActive(): m.addAction(QCoreApplication.translate("DataStorageBrowser", "Add to plot (Qwt)"), self.addToQwtPlot) elif t == "C": m.addAction(QCoreApplication.translate("DataStorageBrowser", "Show"), self.showChart) m.addAction(QCoreApplication.translate("DataStorageBrowser", "Delete"), self.deleteItem) if t in "RPGS": m.addSeparator() m.addAction(QCoreApplication.translate("DataStorageBrowser", "Edit metadata"), self.editMetadata) a = m.exec_(self.treeView.mapToGlobal(pos)) def newSensorGroup(self, mi=None): if mi is None: mi = self.selectedMI newSensorGroup(self.model, mi) def showChart(self, ch=None): if ch is None: ch = self.selectedNode showChartWindow(ch, maximized=showChartMaximized) def importFiles(self, mi=None): if mi is None: mi = self.selectedMI importFiles(self.model, mi) def showAllCharts(self, sg=None): if sg is None: sg = self.selectedNode showAllChartWindows(sg, maximized=showChartMaximized) def saveAllChartImages(self, sg=None): if sg is None: sg = self.selectedNode saveAllChartImages(sg) def exportSensors(self, sg=None): if sg is None: sg = self.selectedNode exportSensors(sg) def showQwtPlot(self, se=None): if se is None: se = self.selectedNode showQwtPlotWindow(se, maximized=showChartMaximized) def addToQwtPlot(self, se=None): if se is None: se = self.selectedNode addToQwtPlotWindow(se) def editMetadata(self, node=None): if node is None: node = self.selectedNode editMetadata(node) def closeDatabase(self, mi=None): if mi is None: mi = self.selectedMI self.model.closeDatabase(mi) def reloadDatabase(self, mi=None): if mi is None: mi = self.selectedMI dbPath = self.model.dsFolder(mi) self.model.closeDatabase(mi) self.loadDatabase(dbPath) def newChart(self, mi=None): """add a chart to sensorgroup at mi using the wizard""" if mi is None: mi = self.selectedMI showNewChartWizard(self.model, mi, self) def deleteItem(self, mi=None): """delete the item at mi""" if mi is None: mi = self.selectedMI self.model.deleteItem(mi)
class DSBrowser(QWidget): """browser for datastorage databases Nodes are identified by a string, containing fields separated by '|'. - first filed is a capital letter: 'R'oot, 'P'roject, sensor'G'roup, 'S'ensor and 'C'hart - second field is the database folder - third filed is the path of the node in the database - for charts the fourth field is the chart name (third is path of sensorgroup in this case) """ def __init__(self): QWidget.__init__(self) self.layout = QVBoxLayout(self) self.layout.setSpacing(0) self.layout.setMargin(0) self.toolBar = QFrame(self) self.toolBarLayout = QHBoxLayout(self.toolBar) self.toolBarLayout.setMargin(2) self.toolBarLayout.setSpacing(2) self.layout.addWidget(self.toolBar) self.loadButton = QToolButton(self.toolBar) self.loadButton.setText(QCoreApplication.translate('DataStorageBrowser', 'Open...')) self.loadButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.fileOpen))) self.loadButton.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Open a datastorage database')) self.toolBarLayout.addWidget(self.loadButton) self.connect(self.loadButton, SIGNAL('pressed()'), self.loadDatabase) self.expandButton = QToolButton(self.toolBar) self.expandButton.setText('Expand/Collapse') self.expandButton.setIcon(QIcon(QPixmap(Icons.exp_col))) self.expandButton.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Expand or collapse the whole tree')) self.toolBarLayout.addWidget(self.expandButton) self.connect(self.expandButton, SIGNAL('pressed()'), self.expandCollapseAll) self.searchInput = QLineEdit(self.toolBar) self.searchInput.setText(QCoreApplication.translate('DataStorageBrowser', 'Enter search text here')) self.searchInput.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Enter search text using wildcards here, press ENTER again to go to next match!')) self.toolBarLayout.addWidget(self.searchInput, 100) self.connect(self.searchInput, SIGNAL('returnPressed()'), self.searchItem) self.helpButton = QToolButton(self.toolBar) self.helpButton.setText(QCoreApplication.translate('DataStorageBrowser', 'Help')) self.helpButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.help))) self.helpButton.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Show help for DataStorageBrowser')) self.toolBarLayout.addWidget(self.helpButton) self.connect(self.helpButton, SIGNAL('pressed()'), self.showHelp) self.splitter = QSplitter(self) self.splitter.setOrientation(Qt.Vertical) self.treeView = QTreeView(self.splitter) self.treeView.setAlternatingRowColors(True) self.treeView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.treeView.setContextMenuPolicy(Qt.CustomContextMenu) self.treeView.setAutoExpandDelay(500) self.textBrowser = QTextBrowser(self.splitter) self.layout.addWidget(self.splitter) self.splitter.setStretchFactor(0, 60) self.splitter.setStretchFactor(1, 40) self.model = DSModel() self.treeView.setModel(self.model) self.treeView.setSortingEnabled(True) self.treeView.expandAll() self.connect(self.treeView.selectionModel(), SIGNAL("currentChanged(QModelIndex, QModelIndex)"), self.showItem) self.connect(self.treeView, SIGNAL("doubleClicked(QModelIndex)"), self.itemAction) self.connect(self.treeView, SIGNAL("customContextMenuRequested(QPoint)"), self.showContextMenu) self.selectedNode = None self.selectedMI = None self.searchText = '' self.searchResults = [] self.collExpand = SimuVis4.Misc.Switcher() def loadDatabase(self, dn=None): """load a database""" if not dn: dn = QFileDialog.getExistingDirectory(self, QCoreApplication.translate('DataStorageBrowser', "Select a folder containing a datastorage database"), SimuVis4.Globals.defaultFolder) if not dn.isEmpty(): dn = unicode(dn) SimuVis4.Globals.defaultFolder = dn else: return self.model.addDatabase(dn) self.treeView.expandToDepth(1) self.treeView.resizeColumnToContents(0) def showHelp(self): SimuVis4.HelpBrowser.showHelp('/plugin/DataStorageBrowser/index.html') def showItem(self, mi, pr): """show the item at model index mi""" t, n = self.model.dsNode(mi) txt = "" if t == 'R': # FIXME: no metadata? txt = rootInfo.substitute(name=n.name, title=escape(n.title), folder=n.h5dir, projects=len(n)) + formatMetaData(n) elif t == 'P': txt = projectInfo.substitute(name=n.name, path=escape(n.parent.name), title=escape(n.title), groups=len(n)) + formatMetaData(n) elif t == 'G': txt = groupInfo.substitute(name=n.name, path='/'.join(n.path.split('/')[:-1]), title=escape(n.title), sensors=len(n), charts=len(n.charts)) + formatMetaData(n) elif t == 'S': txt = sensorInfo.substitute(name=n.name, path='/'.join(n.path.split('/')[:-1]), title=escape(n.title), start=n.timegrid.start, stop=n.timegrid.stop, step=n.timegrid.step, length=n.datalen()) + formatMetaData(n) elif t == 'C': txt = chartInfo.substitute(name=n.name, path=n.sensorgroup.path) self.textBrowser.setText(txt) def searchItem(self): """execute the search and highlight the (next) result""" txt = str(self.searchInput.text()) if txt != self.searchText: self.searchText = txt tmp = self.model.findItems(txt, Qt.MatchFixedString | Qt.MatchContains | Qt.MatchWildcard | Qt.MatchRecursive) self.searchList = [i.index() for i in tmp] if self.searchList: mi = self.searchList.pop() self.treeView.setCurrentIndex(mi) self.treeView.expand(mi) self.treeView.scrollTo(mi) else: QMessageBox.information(self, QCoreApplication.translate('DataStorageBrowser', 'No (more) matches!'), QCoreApplication.translate('DataStorageBrowser', 'No (more) matches found! Change you search criteria and try again!')) self.searchText = '' def expandCollapseAll(self): if self.collExpand(): self.treeView.collapseAll() else: self.treeView.expandAll() def itemAction(self, mi): """default action (on doubleclick) for item at model index mi""" t, n = self.model.dsNode(mi) if t == 'R': pass elif t == 'P': pass elif t == 'G': pass elif t == 'S': self.showQwtPlot(n) elif t == 'C': self.showMplChart(n) def showContextMenu(self, pos): """show context menu for item at pos""" mi = self.treeView.indexAt(pos) t, n = self.model.dsNode(mi) self.selectedNode = n self.selectedMI = mi m = QMenu() if t == 'R': m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Close'), self.closeDatabase) elif t == 'P': pass elif t == 'G': nCharts = len(n.charts) if nCharts > 0: txt = str(QCoreApplication.translate('DataStorageBrowser', 'Show all Charts (%d)')) % nCharts m.addAction(txt, self.showAllCharts) m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Add Chart'), self.newChart) elif t == 'S': m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Plot (Qwt)'), self.showQwtPlot) elif t == 'C': m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Show'), self.showMplChart) m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Delete'), self.deleteItem) if t in 'RPGS': m.addSeparator() m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Edit metadata'), self.editMetadata) a = m.exec_(self.treeView.mapToGlobal(pos)) def showMplChart(self, node=None): if node is None: node = self.selectedNode showChartMplWindow(node, maximized=showChartMaximized) def showAllCharts(self, node=None): if node is None: node = self.selectedNode for chart in node.charts.values(): showChartMplWindow(chart, maximized=showChartMaximized) def showQwtPlot(self, node=None): if node is None: node = self.selectedNode showQwtPlotWindow(node, maximized=showChartMaximized) def editMetadata(self, node=None): if node is None: node = self.selectedNode editMetadata(node) def closeDatabase(self, mi=None): if mi is None: mi = self.selectedMI self.model.closeDatabase(mi) def newChart(self, mi=None): """add a chart to sensorgroup at mi using the wizard""" if mi is None: mi = self.selectedMI showNewChartWizard(self.model, mi) def deleteItem(self, mi=None): """delete the item at mi""" if mi is None: mi = self.selectedMI self.model.deleteItem(mi)