def __init__(self, module, parent = None): rt_qt.QtGui.QWidget.__init__(self) #customize for simulation type self.beamlineType = module.beamlineType self.classDictionary = module.classDictionary self.importer = module.fileImporter self.exporter = module.fileExporter self.defaultBeamline = '' #set layout self.ui = Ui_tree(self, module) #undo/redo self.undoStack = rt_qt.QtGui.QUndoStack() #connections self.ui.workingBeamline.lengthChange.connect(self.callAfterWorkingBeamlineChanges) self.ui.workingBeamline.itemDoubleClicked.connect(self.editElement) self.ui.workingBeamline.itemPressed.connect(self.listClick) self.adv = advDialog(self) for button in self.ui.buttons + self.adv.buttons: button.clicked.connect(self.createNewElement) button.setToolTip(wordwrap(self.classDictionary[button.text()].elementDescription, 60)) if len(self.ui.advancedNames) > 0: self.ui.advanced.clicked.connect(self.adv.show) self.ui.clearBeamlineButton.clicked.connect(self.newBeam) self.ui.saveBeamlineButton.clicked.connect(self.addBeam) self.ui.treeWidget.itemClicked.connect(self.treeClick) self.ui.treeWidget.itemDoubleClicked.connect(self.treeItemDoubleClicked) self.ui.treeWidget.itemEntered.connect(self.elementTreeHovered) self.ui.treeWidget.itemExited.connect(self.elementTreeExit) self.ui.graphicsView.itemDoubleClicked.connect(self.editElement) self.ui.graphicsView.wheelZoom.connect(self.zoomPreview) self.ui.graphicsView.dragDone.connect(self.drawLengthScale) self.ui.graphicsView.horizontalScrollBar().valueChanged.connect(self.drawLengthScale) self.ui.graphicsView.verticalScrollBar().valueChanged.connect(self.drawLengthScale) self.ui.graphicsView.itemDropped.connect(self.droppedOnGraphicsWindow) self.ui.contextMenuClicked.connect(self.createContextMenu) #### Keyboard shortcuts #### # Copy element in tree widget rt_qt.QtGui.QShortcut(rt_qt.QtGui.QKeySequence.Copy, self).activated.connect(lambda : self.copyElement(self.ui.treeWidget.currentItem())) # Zooming the preview window rt_qt.QtGui.QShortcut(rt_qt.QtGui.QKeySequence.ZoomIn, self).activated.connect(lambda : self.zoomPreview(1)) rt_qt.QtGui.QShortcut(rt_qt.QtGui.QKeySequence.ZoomOut, self).activated.connect(lambda : self.zoomPreview(-1)) #text self.addToBeamClickText = self.ui.translateUTF8('Add to current beam line') self.beamlineTreeLabel = self.ui.translateUTF8('Beamlines') self.dragTargetMessage = u'Drag elements here \u2192' self.ui.label.setText(self.dragTargetMessage) self.emptyWorkingBeamlineCheck() #user interaction state if parent == None: self.parent = self self.parent.lastUsedDirectory = os.path.expanduser('~') else: self.parent = parent self.elementDictionary = OrderedDict() self.workingBeamlineName = '' self.preListSave = [] self.preListNameSave = self.workingBeamlineName self.preListLabelSave = self.ui.label.text() self.zoomScale = 1 self.drawPreviewEnabled = True # Graphical length legend for preview self.lengthLegend = []
class RbCbt(rt_qt.QtGui.QWidget): category = 'beam lines' def __init__(self, module, parent = None): rt_qt.QtGui.QWidget.__init__(self) #customize for simulation type self.beamlineType = module.beamlineType self.classDictionary = module.classDictionary self.importer = module.fileImporter self.exporter = module.fileExporter self.defaultBeamline = '' #set layout self.ui = Ui_tree(self, module) #undo/redo self.undoStack = rt_qt.QtGui.QUndoStack() #connections self.ui.workingBeamline.lengthChange.connect(self.callAfterWorkingBeamlineChanges) self.ui.workingBeamline.itemDoubleClicked.connect(self.editElement) self.ui.workingBeamline.itemPressed.connect(self.listClick) self.adv = advDialog(self) for button in self.ui.buttons + self.adv.buttons: button.clicked.connect(self.createNewElement) button.setToolTip(wordwrap(self.classDictionary[button.text()].elementDescription, 60)) if len(self.ui.advancedNames) > 0: self.ui.advanced.clicked.connect(self.adv.show) self.ui.clearBeamlineButton.clicked.connect(self.newBeam) self.ui.saveBeamlineButton.clicked.connect(self.addBeam) self.ui.treeWidget.itemClicked.connect(self.treeClick) self.ui.treeWidget.itemDoubleClicked.connect(self.treeItemDoubleClicked) self.ui.treeWidget.itemEntered.connect(self.elementTreeHovered) self.ui.treeWidget.itemExited.connect(self.elementTreeExit) self.ui.graphicsView.itemDoubleClicked.connect(self.editElement) self.ui.graphicsView.wheelZoom.connect(self.zoomPreview) self.ui.graphicsView.dragDone.connect(self.drawLengthScale) self.ui.graphicsView.horizontalScrollBar().valueChanged.connect(self.drawLengthScale) self.ui.graphicsView.verticalScrollBar().valueChanged.connect(self.drawLengthScale) self.ui.graphicsView.itemDropped.connect(self.droppedOnGraphicsWindow) self.ui.contextMenuClicked.connect(self.createContextMenu) #### Keyboard shortcuts #### # Copy element in tree widget rt_qt.QtGui.QShortcut(rt_qt.QtGui.QKeySequence.Copy, self).activated.connect(lambda : self.copyElement(self.ui.treeWidget.currentItem())) # Zooming the preview window rt_qt.QtGui.QShortcut(rt_qt.QtGui.QKeySequence.ZoomIn, self).activated.connect(lambda : self.zoomPreview(1)) rt_qt.QtGui.QShortcut(rt_qt.QtGui.QKeySequence.ZoomOut, self).activated.connect(lambda : self.zoomPreview(-1)) #text self.addToBeamClickText = self.ui.translateUTF8('Add to current beam line') self.beamlineTreeLabel = self.ui.translateUTF8('Beamlines') self.dragTargetMessage = u'Drag elements here \u2192' self.ui.label.setText(self.dragTargetMessage) self.emptyWorkingBeamlineCheck() #user interaction state if parent == None: self.parent = self self.parent.lastUsedDirectory = os.path.expanduser('~') else: self.parent = parent self.elementDictionary = OrderedDict() self.workingBeamlineName = '' self.preListSave = [] self.preListNameSave = self.workingBeamlineName self.preListLabelSave = self.ui.label.text() self.zoomScale = 1 self.drawPreviewEnabled = True # Graphical length legend for preview self.lengthLegend = [] def undo(self): self.undoStack.undo() def redo(self): self.undoStack.redo() def addToEndOfWorkingBeamLine(self, elementName, copies = None): if not copies: copies, ok = self.getNumberOfCopies(elementName) else: ok = True if ok: for i in range(copies): self.ui.workingBeamline.addItem(elementName) self.callAfterWorkingBeamlineChanges() def addReversedToEndOfWorkingBeamLine(self, elementName, copies = None): blr = self.elementDictionary[elementName].reverse() if not blr.isBeamline(): return self.elementDictionary[blr.name] = blr self.addToEndOfWorkingBeamLine(blr.name, copies) def emptyWorkingBeamlineCheck(self): isEmpty = self.ui.workingBeamline.count() == 0 self.ui.clearBeamlineButton.setDisabled(isEmpty) self.ui.saveBeamlineButton.setDisabled(isEmpty) def droppedOnGraphicsWindow(self): if self.ui.treeWidget.currentItem(): self.addToEndOfWorkingBeamLine(self.ui.treeWidget.currentItem().text(0)) def callAfterWorkingBeamlineChanges(self): self.fixWorkingBeamline() self.postListSave = self.workingBeamlineElementNames() if self.preListSave == self.postListSave: self.emptyWorkingBeamlineCheck() return self.postListNameSave = self.workingBeamlineName self.postListLabelSave = self.ui.label.text() undoAction = commandEditBeam(self) self.undoStack.push(undoAction) self.preListSave = self.postListSave self.preListNameSave = self.postListNameSave self.preListLabelSave = self.postListLabelSave def treeClick(self, item = None, column = None): # Draw element currently selected if item and item.text(column) == self.addToBeamClickText: self.addToEndOfWorkingBeamLine(item.text(0), 1) else: self.elementPreview() # Allow workingBeamline list and beamline preview to accept drops from treeWidget self.ui.workingBeamline.setDragDropMode(rt_qt.QtGui.QAbstractItemView.DropOnly) self.ui.graphicsView.setAcceptDrops(True) def treeItemDoubleClicked(self, item, column): if item and item.text(column) != self.addToBeamClickText: self.editElement(item.text(0)) def elementTreeHovered(self, item, column): if item.text(column) == self.addToBeamClickText: self.ui.treeWidget.setCursor(rt_qt.QtGui.QCursor(rt_qt.QtCore.Qt.PointingHandCursor)) else: self.elementTreeExit() def elementTreeExit(self): self.ui.treeWidget.setCursor(rt_qt.QtGui.QCursor(rt_qt.QtCore.Qt.ArrowCursor)) def listClick(self): # Draw current working beamline self.workingBeamlinePreview() # Allow workingBeamline elements to be moved around without copying self.ui.workingBeamline.setDragDropMode(rt_qt.QtGui.QAbstractItemView.InternalMove) # Don't allow drags to beamline preview self.ui.graphicsView.setAcceptDrops(False) def createContextMenu(self, name, location, globalPos): element = self.elementDictionary.get(name) mouseMenu = rt_qt.QtGui.QMenu(self) if element: if location == 'picture': menuTitle = rt_qt.QtGui.QAction(element.toolTip(), mouseMenu) menuTitle.setEnabled(False) mouseMenu.addAction(menuTitle) mouseMenu.addSeparator() mouseMenu.addAction(self.ui.translateUTF8('Edit ...'), lambda: self.editElement(element.name)) mouseMenu.addAction(self.ui.translateUTF8('New copy'), lambda: self.copyElement(element.name)) mouseMenu.addAction(self.ui.translateUTF8('Delete element'), lambda: self.deleteElement(element.name)) mouseMenu.addSeparator() if location == 'tree': mouseMenu.addAction(self.addToBeamClickText, lambda: self.addToEndOfWorkingBeamLine(element.name, 1)) mouseMenu.addAction('Add multiple copies to current beam line...', lambda: self.addToEndOfWorkingBeamLine(element.name)) if element.isBeamline(): mouseMenu.addAction('Add reversed to current beam line', lambda: self.addReversedToEndOfWorkingBeamLine(element.name, 1)) mouseMenu.addAction('Add multiple reversed to current beam line..', lambda: self.addReversedToEndOfWorkingBeamLine(element.name)) if location == 'list': if element.isBeamline(): mouseMenu.addAction(self.ui.translateUTF8('Reverse'), self.convertToReversed) mouseMenu.addAction(self.ui.translateUTF8('Add another'), self.listCopy) mouseMenu.addAction(self.ui.translateUTF8('Add multiple copies ...'), self.listMultipleCopy) mouseMenu.addAction(self.ui.translateUTF8('Remove from beam line'), self.removeFromWorkingBeamline) containingBeamlines = [] for bl in self.elementDictionary.values(): if bl.isBeamline() and bl != element: if bl.contains(element): containingBeamlines.append(bl) if containingBeamlines: mouseMenu.addSeparator() blMenu = rt_qt.QtGui.QMenu('Contained in beamlines', self) for bl in containingBeamlines: entry = rt_qt.QtGui.QAction(bl.name, self) entry.setEnabled(False) blMenu.addAction(entry) mouseMenu.addMenu(blMenu) if location == 'picture' and not self.ui.graphicsView.scene().zeroSized(): mouseMenu.addSeparator() mouseMenu.addAction(self.ui.translateUTF8('Save preview image...'), \ self.savePreviewImage) mouseMenu.addAction(self.ui.translateUTF8('Reset zoom'), self.drawElement) mouseMenu.addAction(self.ui.translateUTF8('Turn ' + ('off' if self.drawPreviewEnabled else 'on') + \ ' graphical preview'), self.toggleDrawPreview) if mouseMenu.actions(): mouseMenu.exec_(globalPos) def toggleDrawPreview(self): self.drawPreviewEnabled = not self.drawPreviewEnabled self.drawElement() def removeFromWorkingBeamline(self): row = self.ui.workingBeamline.currentRow() self.ui.workingBeamline.takeItem(row) self.callAfterWorkingBeamlineChanges() def editElement(self, name): try: selectedElement = self.elementDictionary[name] except KeyError: # Element name not found return if selectedElement.isBeamline(): self.setWorkingBeamline(selectedElement) self.callAfterWorkingBeamlineChanges() else: dialog = genDialog(selectedElement) if dialog.exec_(): data = dialog.info + dialog.more newElement = type(selectedElement)([datum[1].text() for datum in data]) undoAction = commandEditElement(self, selectedElement, newElement) self.undoStack.push(undoAction) self.elementPreview() def copyElement(self, name): # name could be text string or QTreeWidgetItem if name is None: return try: name = name.text(0) except AttributeError: pass originalElement = self.elementDictionary[name] newElement = type(originalElement)([originalElement.name] + originalElement.data[:]) copyLabel = '_Copy' copyLabelLocation = newElement.name.rfind(copyLabel) if copyLabelLocation == -1: newElement.name = newElement.name + copyLabel else: newElement.name = newElement.name[:copyLabelLocation] + copyLabel undoAction = commandLoadElements(self, [newElement]) self.undoStack.push(undoAction) def getNumberOfCopies(self, elementName): return rt_qt.QtGui.QInputDialog.getInt(self, \ "Add multiple copies", \ "Number of copies of " \ + elementName + " to add:", \ 1,1) def listMultipleCopy(self): copies, ok = self.getNumberOfCopies(self.ui.workingBeamline.currentItem().text()) if ok: for i in range(copies): self.listCopy(False) self.callAfterWorkingBeamlineChanges() def listCopy(self, postList = True): item = self.ui.workingBeamline.currentItem() row = self.ui.workingBeamline.row(item) self.ui.workingBeamline.insertItem(row, item.text()) if postList: self.callAfterWorkingBeamlineChanges() def rewriteBeamlineTree(self): # Update element list for group in self.topLevelTreeItems(): for item in itemsInGroup(group): populateTreeItem(self.addToBeamClickText, item, self.elementDictionary[item.text(0)]) self.fitColumns() # Update Working Beamline self.fixWorkingBeamline() def fitColumns(self): for i in range(self.ui.treeWidget.columnCount()): if i != 1: # don't fit Description Column self.ui.treeWidget.resizeColumnToContents(i) def createNewElement(self): typeName = self.sender().text() elementType = self.classDictionary[typeName] dialog = genDialog(elementType()) if dialog.exec_(): data = [datum[1].text() for datum in dialog.info + dialog.more] element = elementType(data) undoAction = commandLoadElements(self, [element]) self.undoStack.push(undoAction) def uniqueName(self, name): # Element name cannot match a type name lowerTypes = [elementType.lower() for elementType in self.classDictionary] while name.lower() in lowerTypes: name = name + 'X' # Element name cannot match another element's name counter = 0 baseName = name lowerNames = [elementName.lower() for elementName in self.elementDictionary] while name.lower() in lowerNames: counter += 1 name = baseName + str(counter) return name def addBeam(self): beamline = self.beamlineType() if self.workingBeamlineName: beamline.name = self.workingBeamlineName for name in self.workingBeamlineElementNames(): beamline.addElement(self.elementDictionary[name]) dialog = genDialog(beamline) if dialog.exec_(): beamline.name = dialog.info[0][1].text() if self.workingBeamlineName: oldBeam = self.elementDictionary[self.workingBeamlineName] undoAction = commandEditElement(self, oldBeam, beamline) else: undoAction = commandLoadElements(self, [beamline]) self.setWorkingBeamline() self.callAfterWorkingBeamlineChanges() self.undoStack.push(undoAction) def findElementInTreeByName(self, name): for group in self.topLevelTreeItems(): for item in itemsInGroup(group): if item.text(0) == name: return item def deleteElement(self, name): undoAction = commandDeleteElement(self, name) self.undoStack.push(undoAction) def newBeam(self): self.setWorkingBeamline() self.callAfterWorkingBeamlineChanges() def setWorkingBeamline(self, beamline = None): self.workingBeamlineName = beamline.name if (beamline and beamline.name in self.elementDictionary) else '' self.ui.label.setText(('Editing "' + self.workingBeamlineName + '"') if self.workingBeamlineName else self.dragTargetMessage) self.ui.workingBeamline.clear() if beamline: self.ui.workingBeamline.addItems([element.name for element in beamline.data]) self.emptyWorkingBeamlineCheck() self.workingBeamlinePreview() def fixWorkingBeamline(self): beamline = self.elementDictionary.get(self.workingBeamlineName) # Beamlines are constructed only from previously existing elements. # Beamlines cannot contain themselves. items = [name for name in self.workingBeamlineElementNames() if name in self.elementDictionary \ and not self.elementDictionary[name].contains(beamline)] self.ui.workingBeamline.clear() self.ui.workingBeamline.addItems(items) def elementPreview(self): try: item = self.ui.treeWidget.currentItem() self.drawElement(self.elementDictionary[item.text(0)]) except (AttributeError, KeyError): self.ui.graphicsView.scene().clear() def workingBeamlinePreview(self): bl = self.beamlineType() for name in self.workingBeamlineElementNames(): bl.addElement(self.elementDictionary[name]) self.drawElement(bl) def drawElement(self, element = None): scene = self.ui.graphicsView.scene() scene.clear() if not self.drawPreviewEnabled: return drawMessage = rt_qt.QtGui.QProgressDialog('Drawing beam line ...', 'Cancel', 0, 5, self.parent) drawMessage.setMinimumDuration(500) drawMessage.setValue(0) if element: self.lastDrawnElement = element else: element = self.lastDrawnElement element.picture(scene) sceneRect = scene.itemsBoundingRect() scene.setSceneRect(sceneRect) drawMessage.setValue(1) sx = sceneRect.width() sy = sceneRect.height() if sx == 0 or sy == 0: drawMessage.setValue(drawMessage.maximum()) return viewSize = self.ui.graphicsView.size() vx = viewSize.width() vy = viewSize.height() scale = min([vx/sx, vy/sy, 1.0]) drawMessage.setValue(2) self.ui.graphicsView.resetTransform() drawMessage.setValue(3) self.ui.graphicsView.scale(scale, scale) drawMessage.setValue(4) self.zoomScale = scale self.drawLengthScale() drawMessage.setValue(drawMessage.maximum()) def visibleSceneRect(self): viewportRect = rt_qt.QtCore.QRect(0,0,self.ui.graphicsView.viewport().width(), self.ui.graphicsView.viewport().height()) return self.ui.graphicsView.mapToScene(viewportRect).boundingRect() def drawLengthScale(self): if self.ui.graphicsView.scene() is None or len(self.ui.graphicsView.scene().items()) == 0: return self.removeLengthScale() vis = self.visibleSceneRect() # Determine a reasonable length to display length = 1.0 # meter widthFraction = 0.25 # maximum length of legend w.r.t. preview window resolution = self.classDictionary.values()[0]().getResolution() while length*resolution < float(vis.width())*widthFraction: length = length*10.0 while length*resolution > float(vis.width())*widthFraction: length = length/10.0 textItem = rt_qt.QtGui.QGraphicsTextItem(displayWithUnitsNumber(length, 'm')) pixLength = int(length*resolution) if pixLength < 1: return # line showing length given by textItem try: rightEnd = rt_qt.QtCore.QPoint(vis.right()-vis.width()/10, vis.bottom()-vis.height()/10) except OverflowError: self.zoomPreview(1) return leftEnd = rightEnd - rt_qt.QtCore.QPoint(pixLength,0) self.lengthLegend.append(rt_qt.QtGui.QGraphicsLineItem(leftEnd.x(), leftEnd.y(), rightEnd.x(), rightEnd.y())) endHeight = int(20.0/self.zoomScale) # constant-height despite zooming if endHeight <= 0: self.zoomPreview(-1) return # left upright bracket self.lengthLegend.append(rt_qt.QtGui.QGraphicsLineItem(leftEnd.x(), leftEnd.y()+endHeight, leftEnd.x(), leftEnd.y()-endHeight)) # right upright bracket self.lengthLegend.append(rt_qt.QtGui.QGraphicsLineItem(rightEnd.x(), rightEnd.y()+endHeight, rightEnd.x(), rightEnd.y()-endHeight)) # Scale textItem so it always appears the same size textItem.translate(rightEnd.x(), rightEnd.y() - textItem.boundingRect().height()/(2*self.zoomScale)) textItem.scale(1.0/self.zoomScale, 1.0/self.zoomScale) self.lengthLegend.append(textItem) for item in self.lengthLegend: self.ui.graphicsView.scene().addItem(item) def removeLengthScale(self): for item in self.lengthLegend: if item in self.ui.graphicsView.scene().items(): self.ui.graphicsView.scene().removeItem(item) self.lengthLegend = [] def zoomPreview(self, wheelClicks): scale = 1.2**wheelClicks self.zoomScale = self.zoomScale*scale self.ui.graphicsView.setTransformationAnchor(rt_qt.QtGui.QGraphicsView.AnchorUnderMouse) self.ui.graphicsView.scale(scale, scale) self.ui.graphicsView.setTransformationAnchor(rt_qt.QtGui.QGraphicsView.NoAnchor) self.drawLengthScale() def savePreviewImage(self): imageSuffixes = ['png', 'jpg', 'bmp', 'ppm', 'tiff', 'xbm', 'xpm'] fileName = getSaveFileName(self, imageSuffixes) if not fileName: return fileExtension = os.path.splitext(fileName)[1] self.parent.lastUsedDirectory = os.path.dirname(fileName) view = self.ui.graphicsView questionBox = rt_qt.QtGui.QMessageBox(rt_qt.QtGui.QMessageBox.Question, 'RadTrack', 'Render entire beamline or just the viewable portion?') responses = [questionBox.addButton(text , rt_qt.QtGui.QMessageBox.ActionRole) for text in ['Entire Beamline', 'Viewable Portion']] questionBox.exec_() if questionBox.clickedButton() == responses[0]: boundingRectangle = view.scene().itemsBoundingRect() else: boundingRectangle = self.visibleSceneRect() # reduce image size if either dimension is larger than maxImageDimension maxImageDimension = 2**14 - 1 sceneSize = max([boundingRectangle.width(), boundingRectangle.height()])*self.zoomScale scale = min([1.0, maxImageDimension/sceneSize]) self.zoomScale = self.zoomScale*scale view.setTransformationAnchor(rt_qt.QtGui.QGraphicsView.AnchorViewCenter) view.scale(scale, scale) view.setTransformationAnchor(rt_qt.QtGui.QGraphicsView.NoAnchor) try: progress = rt_qt.QtGui.QProgressDialog('Creating Image ...', 'Cancel', 0, 6, self) progress.setMinimumDuration(0) progress.setValue(0) image = rt_qt.QtGui.QImage((boundingRectangle.size()*self.zoomScale).toSize(), rt_qt.QtGui.QImage.Format_ARGB32_Premultiplied) if progress.wasCanceled(): return progress.setValue(1) progress.setLabelText('Filling Background ...') if fileExtension in ['png', 'tiff', 'xpm']: image.fill(rt_qt.QtGui.QColor('transparent')) else: image.fill(rt_qt.QtGui.QColor('white')) if progress.wasCanceled(): return progress.setValue(2) progress.setLabelText('Creating Painter ...') painter = rt_qt.QtGui.QPainter(image) if progress.wasCanceled(): return progress.setValue(3) progress.setLabelText('Rendering Image ...') view.scene().render(painter, rt_qt.QtCore.QRectF(), boundingRectangle) if progress.wasCanceled(): return progress.setValue(4) progress.setLabelText('Saving Image ...') if not image.save(fileName): rt_qt.QtGui.QMessageBox(rt_qt.QtGui.QMessageBox.Warning, 'RadTrack', "Image (" + fileName + ") was not saved.").exec_() progress.reset() return finally: progress.setLabelText('Deleting Painter ...') progress.setValue(5) try: del painter except Exception: pass progress.setValue(6) self.drawLengthScale() def convertToReversed(self): beamlineName = self.ui.workingBeamline.currentItem().text() reversedBeamline = self.elementDictionary[beamlineName].reverse() if not reversedBeamline.isBeamline(): return self.elementDictionary[reversedBeamline.name] = reversedBeamline self.ui.workingBeamline.currentItem().setText(reversedBeamline.name) self.callAfterWorkingBeamlineChanges() def topLevelTreeItems(self): return [self.ui.treeWidget.topLevelItem(i) for i in range(self.ui.treeWidget.topLevelItemCount())] def workingBeamlineElementNames(self): return [self.ui.workingBeamline.item(i).text() for i in range(self.ui.workingBeamline.count())] def importFile(self, fileName): ignoreMissingImportFiles = False try: importedData = self.importer(fileName) except IOError as e: rt_qt.QtGui.QMessageBox(rt_qt.QtGui.QMessageBox.Warning, 'RadTrack', e.message).exec_() return if importedData: newElements, defaultBeamline = importedData if newElements: undoAction = commandLoadElements(self, newElements.values()) self.undoStack.push(undoAction) if defaultBeamline: self.defaultBeamline = defaultBeamline # Copy files referenced by the elements into the current working directory for element in [e for e in newElements.values() if not e.isBeamline()]: for parameter in element.inputFileParameters: index = element.parameterNames.index(parameter) if element.data[index]: path = os.path.join(os.path.dirname(fileName), element.data[index]) try: shutil.copy2(path, self.parent.sessionDirectory) except IOError: if not ignoreMissingImportFiles: box = rt_qt.QtGui.QMessageBox(rt_qt.QtGui.QMessageBox.Warning, 'Missing File Reference', 'The file "' + path.replace('\\', '/') + '" specified by element "' + \ element.name + '" cannot be found.\n\n' +\ 'Do you wish to ignore future warnings of this type?', rt_qt.QtGui.QMessageBox.Yes | rt_qt.QtGui.QMessageBox.No, self) box.exec_() if box.standardButton(box.clickedButton()) == rt_qt.QtGui.QMessageBox.Yes: ignoreMissingImportFiles = True def exportToFile(self, outputFileName = None): if not outputFileName: getSaveFileName(self) if not outputFileName: return # User cancelled self.exporter(outputFileName, self.elementDictionary, self.defaultBeamline) def closeEvent(self, event): # Large pictures seem to crash python on exiting RadTrack, # so clear the picture before exiting. self.ui.graphicsView.scene().clear() rt_qt.QtGui.QWidget.closeEvent(self, event)