class NgspiceWidget(QtGui.QWidget): """ This Class creates NgSpice Window """ def __init__(self, command, projPath): QtGui.QWidget.__init__(self) self.obj_appconfig = Appconfig() self.process = QtCore.QProcess(self) self.terminal = QtGui.QWidget(self) self.layout = QtGui.QVBoxLayout(self) self.layout.addWidget(self.terminal) print "Argument to ngspice command : ", command print "\nngspice simulation starts : \n" if platform.system() == 'Linux': self.command = "cd " + projPath + " && ngspice " + command console_output = os.popen(self.command).read() self.obj_appconfig.print_info("NgSpice output: " + console_output) self.obj_appconfig.proc_dict[ self.obj_appconfig.current_project['ProjectName']].append( self.process.pid()) elif platform.system() == 'Windows': tempdir = os.getcwd() projPath = self.obj_appconfig.current_project["ProjectName"] os.chdir(projPath) self.command = "ngspice " + command self.process.start(self.command) os.chdir(tempdir) print "\n simulation finished"
class OpenProjectInfo(QtGui.QWidget): """ This class is called when User click on Open Project Button """ def __init__(self): super(OpenProjectInfo, self).__init__() self.obj_validation = Validation() def body(self): self.obj_Appconfig = Appconfig() self.openDir = self.obj_Appconfig.default_workspace["workspace"] #print "default workspace is now 1", self.openDir self.projDir = QtGui.QFileDialog.getExistingDirectory( self, "open", self.openDir) if self.obj_validation.validateOpenproj(self.projDir) == True: #print "Pass open project test" #self.obj_Appconfig = Appconfig() self.obj_Appconfig.current_project['ProjectName'] = str( self.projDir) if os.path.isdir(self.projDir): print "true" for dirs, subdirs, filelist in os.walk( self.obj_Appconfig.current_project["ProjectName"]): directory = dirs files = filelist self.obj_Appconfig.project_explorer[dirs] = filelist json.dump(self.obj_Appconfig.project_explorer, open(self.obj_Appconfig.dictPath, 'w')) self.obj_Appconfig.print_info('Open Project called') self.obj_Appconfig.print_info('Current Project is ' + self.projDir) return dirs, filelist else: #print "Failed open project test" self.obj_Appconfig.print_error( "The project doesn't contain .proj file. Please select the proper directory else you won't be able to perform any operation" ) reply = QtGui.QMessageBox.critical( None, "Error Message", '''<b> Error: The project doesn't contain .proj file.</b><br/> <b>Please select the proper project directory else you won't be able to perform any operation</b>''', QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel) if reply == QtGui.QMessageBox.Ok: self.body() self.obj_Appconfig.print_info('Open Project called') self.obj_Appconfig.print_info('Current Project is ' + self.projDir) elif reply == QtGui.QMessageBox.Cancel: self.obj_Appconfig.print_info('No Project opened') else: pass
class OpenProjectInfo(QtGui.QWidget): """ This class is called when User click on Open Project Button """ def __init__(self): super(OpenProjectInfo, self).__init__() self.obj_validation = Validation() def body(self): self.obj_Appconfig = Appconfig() self.openDir = self.obj_Appconfig.default_workspace["workspace"] #print "default workspace is now 1", self.openDir self.projDir=QtGui.QFileDialog.getExistingDirectory(self,"open",self.openDir) if self.obj_validation.validateOpenproj(self.projDir) == True: #print "Pass open project test" #self.obj_Appconfig = Appconfig() self.obj_Appconfig.current_project['ProjectName'] = str(self.projDir) if os.path.isdir(self.projDir): print "true" for dirs, subdirs, filelist in os.walk(self.obj_Appconfig.current_project["ProjectName"]): directory = dirs files = filelist self.obj_Appconfig.project_explorer[dirs] = filelist json.dump(self.obj_Appconfig.project_explorer, open(self.obj_Appconfig.dictPath,'w')) self.obj_Appconfig.print_info('Open Project called') self.obj_Appconfig.print_info('Current Project is ' + self.projDir) return dirs, filelist else: #print "Failed open project test" self.obj_Appconfig.print_error("The project doesn't contain .proj file. Please select the proper directory else you won't be able to perform any operation") reply = QtGui.QMessageBox.critical(None, "Error Message",'''<b> Error: The project doesn't contain .proj file.</b><br/> <b>Please select the proper project directory else you won't be able to perform any operation</b>''',QtGui.QMessageBox.Ok|QtGui.QMessageBox.Cancel) if reply == QtGui.QMessageBox.Ok: self.body() self.obj_Appconfig.print_info('Open Project called') self.obj_Appconfig.print_info('Current Project is ' + self.projDir) elif reply == QtGui.QMessageBox.Cancel: self.obj_Appconfig.print_info('No Project opened') else: pass
class ProjectExplorer(QtWidgets.QWidget): """ This class contains function: - One work as a constructor(__init__). - For saving data. - for renaming project. - for refreshing project. - for removing project. """ def __init__(self): """ This method is doing following tasks: - Working as a constructor for class ProjectExplorer. - view of project explorer area. """ QtWidgets.QWidget.__init__(self) self.obj_appconfig = Appconfig() self.obj_validation = Validation() self.treewidget = QtWidgets.QTreeWidget() self.window = QtWidgets.QVBoxLayout() header = QtWidgets.QTreeWidgetItem(["Projects", "path"]) self.treewidget.setHeaderItem(header) self.treewidget.setColumnHidden(1, True) # CSS init_path = '../../' if os.name == 'nt': init_path = '' self.treewidget.setStyleSheet(" \ QTreeView { border-radius: 15px; border: 1px \ solid gray; padding: 5px; width: 200px; height: 150px; }\ QTreeView::branch:has-siblings:!adjoins-item { \ border-image: url(" + init_path + "images/vline.png) 0;} \ QTreeView::branch:has-siblings:adjoins-item { \ border-image: url(" + init_path + "images/branch-more.png) 0; } \ QTreeView::branch:!has-children:!has-siblings:adjoins-item { \ border-image: url(" + init_path + "images/branch-end.png) 0; } \ QTreeView::branch:has-children:!has-siblings:closed, \ QTreeView::branch:closed:has-children:has-siblings { \ border-image: none; \ image: url(" + init_path + "images/branch-closed.png); } \ QTreeView::branch:open:has-children:!has-siblings, \ QTreeView::branch:open:has-children:has-siblings { \ border-image: none; \ image: url(" + init_path + "images/branch-open.png); } \ ") for parents, children in list( self.obj_appconfig.project_explorer.items()): os.path.join(parents) if os.path.exists(parents): pathlist = parents.split(os.sep) parentnode = QtWidgets.QTreeWidgetItem(self.treewidget, [pathlist[-1], parents]) for files in children: QtWidgets.QTreeWidgetItem( parentnode, [files, os.path.join(parents, files)]) self.window.addWidget(self.treewidget) self.treewidget.doubleClicked.connect(self.openProject) self.treewidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.treewidget.customContextMenuRequested.connect(self.openMenu) self.setLayout(self.window) self.show() def addTreeNode(self, parents, children): os.path.join(parents) pathlist = parents.split(os.sep) parentnode = QtWidgets.QTreeWidgetItem(self.treewidget, [pathlist[-1], parents]) for files in children: QtWidgets.QTreeWidgetItem( parentnode, [files, os.path.join(parents, files)]) (self.obj_appconfig.proc_dict[ self.obj_appconfig.current_project['ProjectName']]) = [] (self.obj_appconfig.dock_dict[ self.obj_appconfig.current_project['ProjectName']]) = [] def openMenu(self, position): indexes = self.treewidget.selectedIndexes() if len(indexes) > 0: level = 0 index = indexes[0] while index.parent().isValid(): index = index.parent() level += 1 menu = QtWidgets.QMenu() if level == 0: renameProject = menu.addAction(self.tr("Rename Project")) renameProject.triggered.connect(self.renameProject) deleteproject = menu.addAction(self.tr("Remove Project")) deleteproject.triggered.connect(self.removeProject) refreshproject = menu.addAction(self.tr("Refresh")) refreshproject.triggered.connect(self.refreshProject) elif level == 1: openfile = menu.addAction(self.tr("Open")) openfile.triggered.connect(self.openProject) menu.exec_(self.treewidget.viewport().mapToGlobal(position)) def openProject(self): self.indexItem = self.treewidget.currentIndex() filename = str(self.indexItem.data()) self.filePath = str( self.indexItem.sibling(self.indexItem.row(), 1).data()) self.obj_appconfig.print_info('The current project is ' + self.filePath) self.textwindow = QtWidgets.QWidget() self.textwindow.setMinimumSize(600, 500) self.textwindow.setGeometry(QtCore.QRect(400, 150, 400, 400)) self.textwindow.setWindowTitle(filename) self.text = QtWidgets.QTextEdit() self.save = QtWidgets.QPushButton('Save and Exit') self.save.setDisabled(True) self.windowgrid = QtWidgets.QGridLayout() if (os.path.isfile(str(self.filePath))): self.fopen = open(str(self.filePath), 'r') lines = self.fopen.read() self.text.setText(lines) self.text.textChanged.connect(self.enable_save) vbox_main = QtWidgets.QVBoxLayout(self.textwindow) vbox_main.addWidget(self.text) vbox_main.addWidget(self.save) self.save.clicked.connect(self.save_data) self.textwindow.show() else: self.obj_appconfig.current_project["ProjectName"] = str( self.filePath) (self.obj_appconfig.proc_dict[ self.obj_appconfig.current_project['ProjectName']]) = [] if (self.obj_appconfig.current_project['ProjectName'] not in self.obj_appconfig.dock_dict): (self.obj_appconfig.dock_dict[ self.obj_appconfig.current_project['ProjectName']]) = [] def enable_save(self): """This function enables save button option.""" self.save.setEnabled(True) def save_data(self): """ This function saves data before it closes the given file. It first opens file in write-mode, write operation is performed, \ closes that file and then it closes window. """ self.fopen = open(self.filePath, 'w') self.fopen.write(self.text.toPlainText()) self.fopen.close() self.textwindow.close() def removeProject(self): """ This function removes the project in explorer area by right \ clicking on project and selecting remove option. """ self.indexItem = self.treewidget.currentIndex() filePath = str(self.indexItem.sibling(self.indexItem.row(), 1).data()) self.int = self.indexItem.row() self.treewidget.takeTopLevelItem(self.int) if self.obj_appconfig.current_project["ProjectName"] == filePath: self.obj_appconfig.current_project["ProjectName"] = None del self.obj_appconfig.project_explorer[filePath] json.dump(self.obj_appconfig.project_explorer, open(self.obj_appconfig.dictPath["path"], 'w')) def refreshProject(self, filePath=None): """ This function refresh the project in explorer area by right \ clicking on project and selecting refresh option. """ if not filePath or filePath is None: self.indexItem = self.treewidget.currentIndex() filePath = str( self.indexItem.sibling(self.indexItem.row(), 1).data()) if os.path.exists(filePath): filelistnew = os.listdir(os.path.join(filePath)) parentnode = self.treewidget.currentItem() count = parentnode.childCount() for i in range(count): for items in self.treewidget.selectedItems(): items.removeChild(items.child(0)) for files in filelistnew: QtWidgets.QTreeWidgetItem( parentnode, [files, os.path.join(filePath, files)]) self.obj_appconfig.project_explorer[filePath] = filelistnew json.dump(self.obj_appconfig.project_explorer, open(self.obj_appconfig.dictPath["path"], 'w')) return True else: print("Selected project not found") print("==================") msg = QtWidgets.QErrorMessage(self) msg.setModal(True) msg.setWindowTitle("Error Message") msg.showMessage('Selected project does not exist.') msg.exec_() return False def renameProject(self): """ This function renames the project present in project explorer area. It validates first: - If project names is not empty. - Project name does not contain spaces between them. - Project name is different between what it was earlier. - Project name should not exist. After project name is changed, it recreates the project explorer tree. """ self.indexItem = self.treewidget.currentIndex() self.baseFileName = str(self.indexItem.data()) filePath = str(self.indexItem.sibling(self.indexItem.row(), 1).data()) newBaseFileName, ok = QtWidgets.QInputDialog.getText( self, 'Rename Project', 'Project Name:', QtWidgets.QLineEdit.Normal, self.baseFileName) if ok and newBaseFileName: newBaseFileName = str(newBaseFileName) if not newBaseFileName.strip(): print("Project name cannot be empty") print("==================") msg = QtWidgets.QErrorMessage(self) msg.setModal(True) msg.setWindowTitle("Error Message") msg.showMessage('The project name cannot be empty') msg.exec_() elif self.baseFileName == newBaseFileName: print("Project name has to be different") print("==================") msg = QtWidgets.QErrorMessage(self) msg.setModal(True) msg.setWindowTitle("Error Message") msg.showMessage('The project name has to be different') msg.exec_() elif self.refreshProject(filePath): projectPath = None projectFiles = None for parents, children in list( self.obj_appconfig.project_explorer.items()): if filePath == parents: if os.path.exists(parents): projectPath, projectFiles = parents, children break self.workspace = \ self.obj_appconfig.default_workspace['workspace'] newBaseFileName = str(newBaseFileName).rstrip().lstrip() projDir = os.path.join(self.workspace, str(newBaseFileName)) reply = self.obj_validation.validateNewproj(str(projDir)) if not (projectPath and projectFiles): print("Selected project not found") print("Project Path :", projectPath) print("Project Files :", projectFiles) print("==================") msg = QtWidgets.QErrorMessage(self) msg.setModal(True) msg.setWindowTitle("Error Message") msg.showMessage('Selected project does not exist.') msg.exec_() elif reply == "VALID": # rename project folder updatedProjectFiles = [] updatedProjectPath = newBaseFileName.join( projectPath.rsplit(self.baseFileName, 1)) print("Renaming " + projectPath + " to " + updatedProjectPath) # rename project folder try: os.rename(projectPath, updatedProjectPath) except BaseException as e: msg = QtWidgets.QErrorMessage(self) msg.setModal(True) msg.setWindowTitle("Error Message") msg.showMessage(str(e)) msg.exec_() return # rename files matching project name try: for projectFile in projectFiles: if self.baseFileName in projectFile: oldFilePath = os.path.join( updatedProjectPath, projectFile) projectFile = projectFile.replace( self.baseFileName, newBaseFileName, 1) newFilePath = os.path.join( updatedProjectPath, projectFile) print("Renaming " + oldFilePath + " to " + newFilePath) os.rename(oldFilePath, newFilePath) updatedProjectFiles.append(projectFile) except BaseException as e: print("==================") print("Error! Revert renaming project") # Revert updatedProjectFiles for projectFile in updatedProjectFiles: newFilePath = os.path.join(updatedProjectPath, projectFile) projectFile = projectFile.replace( newBaseFileName, self.baseFileName, 1) oldFilePath = os.path.join(updatedProjectPath, projectFile) os.rename(newFilePath, oldFilePath) # Revert project folder name os.rename(updatedProjectPath, projectPath) print("==================") msg = QtWidgets.QErrorMessage(self) msg.setModal(True) msg.setWindowTitle("Error Message") msg.showMessage(str(e)) msg.exec_() return # update project_explorer dictionary del self.obj_appconfig.project_explorer[projectPath] self.obj_appconfig.project_explorer[updatedProjectPath] = \ updatedProjectFiles # save project_explorer dictionary on disk json.dump(self.obj_appconfig.project_explorer, open(self.obj_appconfig.dictPath["path"], 'w')) # recreate project explorer tree self.treewidget.clear() for parent, children in \ self.obj_appconfig.project_explorer.items(): if os.path.exists(parent): self.addTreeNode(parent, children) elif reply == "CHECKEXIST": print("Project name already exists.") print("==========================") msg = QtWidgets.QErrorMessage(self) msg.setModal(True) msg.setWindowTitle("Error Message") msg.showMessage( 'The project "' + newBaseFileName + '" already exist. Please select a different name or' + ' delete existing project') msg.exec_() elif reply == "CHECKNAME": print("Name can not contain space between them") print("===========================") msg = QtWidgets.QErrorMessage(self) msg.setModal(True) msg.setWindowTitle("Error Message") msg.showMessage('The project name should not ' + 'contain space between them') msg.exec_()
class OpenModelicaEditor(QtGui.QWidget): def __init__(self, dir=None): QtGui.QWidget.__init__(self) self.obj_validation = Validation() self.obj_appconfig = Appconfig() self.projDir = dir self.projName = os.path.basename(self.projDir) self.ngspiceNetlist = os.path.join(self.projDir, self.projName + ".cir.out") self.modelicaNetlist = os.path.join(self.projDir, self.projName + ".mo") self.map_json = Appconfig.modelica_map_json self.grid = QtGui.QGridLayout() self.FileEdit = QtGui.QLineEdit() self.FileEdit.setText(self.ngspiceNetlist) self.grid.addWidget(self.FileEdit, 0, 0) self.browsebtn = QtGui.QPushButton("Browse") self.browsebtn.clicked.connect(self.browseFile) self.grid.addWidget(self.browsebtn, 0, 1) self.convertbtn = QtGui.QPushButton("Convert") self.convertbtn.clicked.connect(self.callConverter) self.grid.addWidget(self.convertbtn, 2, 1) self.loadOMbtn = QtGui.QPushButton("Load OMEdit") self.loadOMbtn.clicked.connect(self.callOMEdit) self.grid.addWidget(self.loadOMbtn, 3, 1) # self.setGeometry(300, 300, 350, 300) self.setLayout(self.grid) self.show() def browseFile(self): self.ngspiceNetlist = QtGui.QFileDialog.getOpenFileName( self, 'Open Ngspice Netlist', BROWSE_LOCATION) self.FileEdit.setText(self.ngspiceNetlist) def callConverter(self): dir_name = os.path.dirname(os.path.realpath(self.ngspiceNetlist)) # file_basename = os.path.basename(self.ngspiceNetlist) cwd = os.getcwd() os.chdir(dir_name) obj_NgMoConverter = NgMoConverter(self.map_json) try: # Getting all the require information lines = obj_NgMoConverter.readNetlist(self.ngspiceNetlist) # print("Complete Lines of Ngspice netlist : " + # "lines ---------------->", lines) optionInfo, schematicInfo = \ obj_NgMoConverter.separateNetlistInfo(lines) # print("All option details like analysis,subckt,.ic,.model :" + # "OptionInfo------------------->", optionInfo) # print("Schematic connection info :schematicInfo", schematicInfo) modelName, modelInfo, subcktName, paramInfo, transInfo,\ inbuiltModelDict = ( obj_NgMoConverter.addModel(optionInfo) ) # print("Name of Model : " + # "modelName-------------------->", modelName) # print("Model Information : " + # "modelInfo--------------------->", modelInfo) # print("Subcircuit Name : " + # "subcktName------------------------>", subcktName) # print("Parameter Information : " + # "paramInfo---------------------->", paramInfo) # print("InBuilt Model ---------------------->", inbuiltModelDict) modelicaParamInit = obj_NgMoConverter.processParam(paramInfo) # print("Make modelicaParamInit from paramInfo : " + # "processParamInit------------->", modelicaParamInit) compInfo, plotInfo = obj_NgMoConverter.separatePlot(schematicInfo) # print("Plot info like plot,print etc :plotInfo",plotInfo) IfMOS = '0' for eachline in compInfo: # words = eachline.split() if eachline[0] == 'm': IfMOS = '1' break subOptionInfo = [] subSchemInfo = [] if len(subcktName) > 0: # subOptionInfo = [] # subSchemInfo = [] for eachsub in subcktName: filename_temp = eachsub + '.sub' data = obj_NgMoConverter.readNetlist(filename_temp) # print "Data---------->",data subOptionInfo, subSchemInfo = ( obj_NgMoConverter.separateNetlistInfo(data)) for eachline in subSchemInfo: # words = eachline.split() if eachline[0] == 'm': IfMOS = '1' break # print("Subcircuit OptionInfo :" + # "subOptionInfo------------------->", subOptionInfo) # print("Subcircuit Schematic Info :" + # "subSchemInfo-------------------->", subSchemInfo) node, nodeDic, pinInit, pinProtectedInit = \ obj_NgMoConverter.nodeSeparate( compInfo, '0', [], subcktName, [] ) # print("All nodes in the netlist :node---------------->", node) # print("NodeDic which will be used for modelica :" + # "nodeDic------------->", nodeDic) # print("PinInit-------------->", pinInit) # print("pinProtectedInit----------->", pinProtectedInit) modelicaCompInit, numNodesSub = obj_NgMoConverter.compInit( compInfo, node, modelInfo, subcktName, dir_name, transInfo, inbuiltModelDict) # print("ModelicaComponents :" + # "modelicaCompInit----------->", modelicaCompInit) # print("SubcktNumNodes :" + # "numNodesSub---------------->", numNodesSub) connInfo = obj_NgMoConverter.connectInfo(compInfo, node, nodeDic, numNodesSub, subcktName) # print("ConnInfo------------------>", connInfo) # After Sub Ckt Func if len(subcktName) > 0: data, subOptionInfo, subSchemInfo, subModel, subModelInfo,\ subsubName, subParamInfo, modelicaSubCompInit,\ modelicaSubParam, nodeSubInterface, nodeSub, nodeDicSub,\ pinInitSub, connSubInfo = ( obj_NgMoConverter.procesSubckt( subcktName, numNodesSub, dir_name ) ) # Adding 'numNodesSub' by Fahim # Creating Final Output file fileDir = os.path.dirname(self.ngspiceNetlist) newfile = os.path.basename(self.ngspiceNetlist) newfilename = os.path.join(fileDir, newfile.split('.')[0]) outfile = newfilename + ".mo" out = open(outfile, "w") out.writelines('model ' + os.path.basename(newfilename)) out.writelines('\n') if IfMOS == '0': out.writelines('import Modelica.Electrical.*;') elif IfMOS == '1': out.writelines('import BondLib.Electrical.*;') # out.writelines('import Modelica.Electrical.*;') out.writelines('\n') for eachline in modelicaParamInit: if len(paramInfo) == 0: continue else: out.writelines(eachline) out.writelines('\n') for eachline in modelicaCompInit: if len(compInfo) == 0: continue else: out.writelines(eachline) out.writelines('\n') out.writelines('protected') out.writelines('\n') out.writelines(pinInit) out.writelines('\n') out.writelines('equation') out.writelines('\n') for eachline in connInfo: if len(connInfo) == 0: continue else: out.writelines(eachline) out.writelines('\n') out.writelines('end ' + os.path.basename(newfilename) + ';') out.writelines('\n') out.close() os.chdir(cwd) self.msg = QtGui.QMessageBox() self.msg.setText( "Ngspice netlist successfully converted to OpenModelica " + "netlist") self.obj_appconfig.print_info( "Ngspice netlist successfully converted to OpenModelica " + "netlist") self.msg.exec_() except BaseException as e: traceback.print_exc() print("================") self.msg = QtGui.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle("Conversion Error") self.msg.showMessage( 'Unable to convert Ngspice netlist to Modelica netlist. ' + 'Check the netlist : ' + repr(e)) def callOMEdit(self): if self.obj_validation.validateTool("OMEdit"): self.cmd2 = "OMEdit " + self.modelicaNetlist self.obj_workThread2 = Worker.WorkerThread(self.cmd2) self.obj_workThread2.start() print("OMEdit called") self.obj_appconfig.print_info("OMEdit called") else: self.msg = QtGui.QMessageBox() self.msgContent = ( "There was an error while opening OMEdit.<br/>" "Please make sure OpenModelica is installed in your" " system.<br/>" "To install it on Linux : Go to <a href=" "https://www.openmodelica.org/download/download-linux" ">OpenModelica Linux</a> and install nightly build" " release.<br/>" "To install it on Windows : Go to <a href=" "https://www.openmodelica.org/download/download-windows" ">OpenModelica Windows</a> and install latest version.<br/>") self.msg.setTextFormat(QtCore.Qt.RichText) self.msg.setText(self.msgContent) self.msg.setWindowTitle("Missing OpenModelica") self.obj_appconfig.print_info(self.msgContent) self.msg.exec_()
class plotWindow(QtGui.QMainWindow): def __init__(self,fpath,projectName): QtGui.QMainWindow.__init__(self) self.fpath = fpath#+".cir.out" self.projectName = projectName self.obj_appconfig = Appconfig() print "Path : ",self.fpath print "Project Name : ",self.projectName self.obj_appconfig.print_info('Ngspice simulation is called : ' + self.fpath) self.obj_appconfig.print_info('PythonPlotting is called : ' + self.fpath) self.combo = [] self.combo1 = [] self.combo1_rev = [] #Creating Frame self.createMainFrame() def createMainFrame(self): self.mainFrame = QtGui.QWidget() self.dpi = 100 self.fig = Figure((7.0, 7.0), dpi=self.dpi) #Creating Canvas which will figure self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self.mainFrame) self.axes = self.fig.add_subplot(111) self.navToolBar = NavigationToolbar(self.canvas, self.mainFrame) #LeftVbox hold navigation tool bar and canvas self.left_vbox = QtGui.QVBoxLayout() self.left_vbox.addWidget(self.navToolBar) self.left_vbox.addWidget(self.canvas) #right VBOX is main Layout which hold right grid(bottom part) and top grid(top part) self.right_vbox = QtGui.QVBoxLayout() self.right_grid = QtGui.QGridLayout() self.top_grid = QtGui.QGridLayout() #Get DataExtraction Details self.obj_dataext = DataExtraction() self.plotType = self.obj_dataext.openFile(self.fpath) self.obj_dataext.computeAxes() self.a = self.obj_dataext.numVals() self.chkbox=[] ########### Generating list of colors : self.full_colors = ['r','b','g','y','c','m','k']#,(0.4,0.5,0.2),(0.1,0.4,0.9),(0.4,0.9,0.2),(0.9,0.4,0.9)] self.color = [] for i in range(0,self.a[0]-1): if i%7 == 0: self.color.append(self.full_colors[0]) elif (i-1)%7 == 0: self.color.append(self.full_colors[1]) elif (i-2)%7 == 0: self.color.append(self.full_colors[2]) elif (i-3)%7 == 0: self.color.append(self.full_colors[3]) elif (i-4)%7 == 0: self.color.append(self.full_colors[4]) elif (i-5)%7 == 0: self.color.append(self.full_colors[5]) elif (i-6)%7 == 0: self.color.append(self.full_colors[6]) ###########Color generation ends here #Total number of voltage source self.volts_length = self.a[1] self.analysisType = QtGui.QLabel() self.top_grid.addWidget(self.analysisType,0,0) self.listNode = QtGui.QLabel() self.top_grid.addWidget(self.listNode,1,0) self.listBranch = QtGui.QLabel() self.top_grid.addWidget(self.listBranch,self.a[1]+2,0) for i in range(0,self.a[1]):#a[0]-1 self.chkbox.append(QtGui.QCheckBox(self.obj_dataext.NBList[i])) self.chkbox[i].setStyleSheet('color') self.chkbox[i].setToolTip('<b>Check To Plot</b>' ) self.top_grid.addWidget(self.chkbox[i],i+2,0) self.colorLab = QtGui.QLabel() self.colorLab.setText('____') self.colorLab.setStyleSheet(self.colorName(self.color[i])+'; font-weight = bold;') self.top_grid.addWidget(self.colorLab,i+2,1) for i in range(self.a[1],self.a[0]-1):#a[0]-1 self.chkbox.append(QtGui.QCheckBox(self.obj_dataext.NBList[i])) self.chkbox[i].setToolTip('<b>Check To Plot</b>' ) self.top_grid.addWidget(self.chkbox[i],i+3,0) self.colorLab = QtGui.QLabel() self.colorLab.setText('____') self.colorLab.setStyleSheet(self.colorName(self.color[i])+'; font-weight = bold;') self.top_grid.addWidget(self.colorLab,i+3,1) self.clear = QtGui.QPushButton("Clear") self.warnning = QtGui.QLabel() self.funcName = QtGui.QLabel() self.funcExample = QtGui.QLabel() self.plotbtn = QtGui.QPushButton("Plot") self.plotbtn.setToolTip('<b>Press</b> to Plot' ) self.text = QtGui.QLineEdit() self.funcLabel = QtGui.QLabel() self.palette1 = QtGui.QPalette() self.palette2 = QtGui.QPalette() self.plotfuncbtn = QtGui.QPushButton("Plot Function") self.plotfuncbtn.setToolTip('<b>Press</b> to Plot the function' ) self.palette1.setColor(QtGui.QPalette.Foreground,QtCore.Qt.blue) self.palette2.setColor(QtGui.QPalette.Foreground,QtCore.Qt.red) self.funcName.setPalette(self.palette1) self.funcExample.setPalette(self.palette2) self.right_vbox.addLayout(self.top_grid) self.right_vbox.addWidget(self.plotbtn) self.right_grid.addWidget(self.funcLabel,1,0) self.right_grid.addWidget(self.text,1,1) self.right_grid.addWidget(self.plotfuncbtn,2,1) self.right_grid.addWidget(self.clear,2,0) self.right_grid.addWidget(self.warnning,3,0) self.right_grid.addWidget(self.funcName,4,0) self.right_grid.addWidget(self.funcExample,4,1) self.right_vbox.addLayout(self.right_grid) self.hbox = QtGui.QHBoxLayout() self.hbox.addLayout(self.left_vbox) self.hbox.addLayout(self.right_vbox) self.widget = QtGui.QWidget() self.widget.setLayout(self.hbox)#finalvbox self.scrollArea = QtGui.QScrollArea() self.scrollArea.setWidgetResizable(True) self.scrollArea.setWidget(self.widget) self.finalhbox = QtGui.QHBoxLayout() self.finalhbox.addWidget(self.scrollArea) self.mainFrame.setLayout(self.finalhbox) self.showMaximized() self.listNode.setText("<font color='indigo'>List of Nodes:</font>") self.listBranch.setText("<font color='indigo'>List of Branches:</font>") self.funcLabel.setText("<font color='indigo'>Function:</font>") self.funcName.setText("<font color='indigo'>Examples:</font>\ <br><br>Addition:<br>Subtraction:<br>Multiplication:<br>Division:<br>Comparison:") self.funcExample.setText("\n\nV(1) + V(2)\nV(1) - V(2)\nV(1) * V(2)\nV(1) / V(2)\nV(1) vs V(2)") #Connecting to plot and clear function self.connect(self.clear,QtCore.SIGNAL('clicked()'),self.pushedClear) self.connect(self.plotfuncbtn,QtCore.SIGNAL('clicked()'), self.pushedPlotFunc) if self.plotType[0]==0: self.analysisType.setText("<b>AC Analysis</b>") if self.plotType[1]==1: self.connect(self.plotbtn, QtCore.SIGNAL('clicked()'), self.onPush_decade) else: self.connect(self.plotbtn, QtCore.SIGNAL('clicked()'), self.onPush_ac) elif self.plotType[0]==1: self.analysisType.setText("<b>Transient Analysis</b>") self.connect(self.plotbtn, QtCore.SIGNAL('clicked()'), self.onPush_trans) else: self.analysisType.setText("<b>DC Analysis</b>") self.connect(self.plotbtn, QtCore.SIGNAL('clicked()'), self.onPush_dc) self.setCentralWidget(self.mainFrame) def pushedClear(self): #print "Calling Clear Canvas function" self.text.clear() self.axes.cla() self.canvas.draw() QtCore.SLOT('quit()') def pushedPlotFunc(self): #print "Calling Plot function" self.parts = str(self.text.text()) self.parts = self.parts.split(" ") #print "Parts :",self.parts if self.parts[len(self.parts)-1] == '': self.parts = self.parts[0:-1] self.values = self.parts self.comboAll = [] self.axes.cla() self.plotType2 = self.obj_dataext.openFile(self.fpath) if len(self.parts) <= 2: self.warnning.setText("Too few arguments!\nRefer syntax below!") QtGui.QMessageBox.about(self, "Warning!!", "Too Few Arguments/SYNTAX Error!\n Refer Examples") else: self.warnning.setText("") a = [] finalResult = [] p = 0 for i in range(len(self.parts)): #print "I",i if i%2 == 0: #print "I'm in:" for j in range(len(self.obj_dataext.NBList)): if self.parts[i]==self.obj_dataext.NBList[j]: #print "I got you:",self.parts[i] a.append(j) if len(a) != len(self.parts)//2 + 1: QtGui.QMessageBox.about(self, "Warning!!", "One of the operands doesn't belong to the above list of Nodes!!") for i in a: self.comboAll.append(self.obj_dataext.y[i]) for i in range(len(a)): if a[i] == len(self.obj_dataext.NBList): QtGui.QMessageBox.about(self, "Warning!!", "One of the operands doesn't belong to the above list!!") self.warnning.setText("<font color='red'>To Err Is Human!<br>One of the operands doesn't belong to the above list!!</font>") if self.parts[1] == 'vs': if len(self.parts) > 3: self.warnning.setText("Enter two operands only!!") QtGui.QMessageBox.about(self, "Warning!!", "Recheck the expression syntax!") else: self.axes.cla() for i in range(len(self.obj_dataext.y[a[0]])): self.combo.append(self.obj_dataext.y[a[0]][i]) self.combo1.append(self.obj_dataext.y[a[1]][i]) self.axes.plot(self.combo,self.combo1,c=self.color[1],label=str(2))#_rev if max(a) < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') self.axes.set_xlabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.set_ylabel('Current(I)-->') elif max(a) >= self.volts_length and min(a) < self.volts_length: QtGui.QMessageBox.about(self, "Warning!!", "Do not combine Voltage and Current!!") else: for j in range(len(self.comboAll[0])): for i in range(len(self.values)): if i%2==0: self.values[i] = str(self.comboAll[i//2][j]) re = " ".join(self.values[:]) try: finalResult.append(eval(re)) except ArithmeticError: QtGui.QMessageBox.about(self, "Warning!!", "Dividing by zero!!") if self.plotType2[0]==0: #self.setWindowTitle('AC Analysis') if self.plotType2[1]==1: self.axes.semilogx(self.obj_dataext.x,finalResult,c=self.color[0],label=str(1)) else: self.axes.plot(self.obj_dataext.x,finalResult,c=self.color[0],label=str(1)) self.axes.set_xlabel('freq-->') if max(a) < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') elif self.plotType2[0]==1: #self.setWindowTitle('Transient Analysis') self.axes.plot(self.obj_dataext.x,finalResult,c=self.color[0],label=str(1)) self.axes.set_xlabel('time-->') if max(a) < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') else: #self.setWindowTitle('DC Analysis') self.axes.plot(self.obj_dataext.x,finalResult,c=self.color[0],label=str(1)) self.axes.set_xlabel('I/P Voltage-->') if max(a) < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) self.canvas.draw() self.combo = [] self.combo1 = [] self.combo1_rev = [] def onPush_decade(self): #print "Calling on push Decade" boxCheck = 0 self.axes.cla() for i,j in zip(self.chkbox,range(len(self.chkbox))): if i.isChecked(): boxCheck += 1 self.axes.semilogx(self.obj_dataext.x,self.obj_dataext.y[j],c=self.color[j],label=str(j+1)) self.axes.set_xlabel('freq-->') if j < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) if boxCheck == 0: QtGui.QMessageBox.about(self, "Warning!!","Please select at least one Node OR Branch") self.canvas.draw() def onPush_ac(self): #print "Calling on push ac" self.axes.cla() boxCheck = 0 for i,j in zip(self.chkbox,range(len(self.chkbox))): if i.isChecked(): boxCheck += 1 self.axes.plot(self.obj_dataext.x,self.obj_dataext.y[j],c=self.color[j],label=str(j+1)) self.axes.set_xlabel('freq-->') if j < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) if boxCheck == 0: QtGui.QMessageBox.about(self, "Warning!!","Please select at least one Node OR Branch") self.canvas.draw() def onPush_trans(self): #print "Calling on push trans" self.axes.cla() boxCheck = 0 for i,j in zip(self.chkbox,range(len(self.chkbox))): if i.isChecked(): boxCheck += 1 self.axes.plot(self.obj_dataext.x,self.obj_dataext.y[j],c=self.color[j],label=str(j+1)) self.axes.set_xlabel('time-->') if j < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) if boxCheck == 0: QtGui.QMessageBox.about(self, "Warning!!","Please select at least one Node OR Branch") self.canvas.draw() def onPush_dc(self): #print "Calling on push dc" boxCheck = 0 self.axes.cla() for i,j in zip(self.chkbox,range(len(self.chkbox))): if i.isChecked(): boxCheck += 1 self.axes.plot(self.obj_dataext.x,self.obj_dataext.y[j],c=self.color[j],label=str(j+1)) self.axes.set_xlabel('Voltage Sweep(V)-->') if j < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) if boxCheck == 0: QtGui.QMessageBox.about(self,"Warning!!", "Please select atleast one Node OR Branch") self.canvas.draw() def colorName(self,letter): return { 'r':'color:red', 'b':'color:blue', 'g':'color:green', 'y':'color:yellow', 'c':'color:cyan', 'm':'color:magenta', 'k':'color:black' }[letter]
class OpenProjectInfo(QtGui.QWidget): """ This class is called when User click on Open Project Button """ def __init__(self): super(OpenProjectInfo, self).__init__() self.obj_validation = Validation() def body(self): """ Open a project directory using Qt GUI and validate if .proj file present in it using `Validation` class @params @return :dirs => The directories inside the project folder :filelist => The files inside the project folder """ self.obj_Appconfig = Appconfig() self.openDir = self.obj_Appconfig.default_workspace["workspace"] self.projDir = QtGui.QFileDialog.getExistingDirectory( self, "open", self.openDir) if self.obj_validation.validateOpenproj(self.projDir): self.obj_Appconfig.current_project['ProjectName'] = str( self.projDir) if os.path.isdir(self.projDir): print("True") for dirs, subdirs, filelist in os.walk( self.obj_Appconfig.current_project["ProjectName"]): # directory = dirs # files = filelist # above 'directory' and 'files' variable never used pass self.obj_Appconfig.project_explorer[dirs] = filelist json.dump(self.obj_Appconfig.project_explorer, open(self.obj_Appconfig.dictPath["path"], 'w')) self.obj_Appconfig.print_info('Open Project called') self.obj_Appconfig.print_info('Current Project is ' + self.projDir) return dirs, filelist else: self.obj_Appconfig.print_error( "The project doesn't contain .proj file. Please select the " + "proper directory else you won't be able to perform any " + "operation") reply = QtGui.QMessageBox.critical( None, "Error Message", "<b>Error: The project doesn't contain .proj file.</b><br/>" "<b>Please select the proper project directory else you won't" " be able to perform any operation</b>", QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel) if reply == QtGui.QMessageBox.Ok: self.body() self.obj_Appconfig.print_info('Open Project called') self.obj_Appconfig.print_info('Current Project is ' + self.projDir) elif reply == QtGui.QMessageBox.Cancel: self.obj_Appconfig.print_info('No Project opened')
class Application(QtGui.QMainWindow): global project_name """ Its our main window of application """ def __init__(self, *args): """ Initialize main Application window """ #Calling __init__ of super class QtGui.QMainWindow.__init__(self, *args) #Creating require Object self.obj_workspace = Workspace.Workspace() self.obj_Mainview = MainView() self.obj_kicad = Kicad(self.obj_Mainview.obj_dockarea) self.obj_appconfig = Appconfig() #Initialize all widget self.setCentralWidget(self.obj_Mainview) self.initToolBar() self.setGeometry(self.obj_appconfig._app_xpos, self.obj_appconfig._app_ypos, self.obj_appconfig._app_width, self.obj_appconfig._app_heigth) self.setWindowTitle(self.obj_appconfig._APPLICATION) self.showMaximized() self.setWindowIcon(QtGui.QIcon('../../images/logo.png')) #self.show() def initToolBar(self): """ This function initialize Tool Bar """ #Top Tool bar self.newproj = QtGui.QAction( QtGui.QIcon('../../images/newProject.png'), '<b>New Project</b>', self) self.newproj.setShortcut('Ctrl+N') self.newproj.triggered.connect(self.new_project) #self.newproj.connect(self.newproj,QtCore.SIGNAL('triggered()'),self,QtCore.SLOT(self.new_project())) self.openproj = QtGui.QAction( QtGui.QIcon('../../images/openProject.png'), '<b>Open Project</b>', self) self.openproj.setShortcut('Ctrl+O') self.openproj.triggered.connect(self.open_project) self.exitproj = QtGui.QAction( QtGui.QIcon('../../images/closeProject.png'), '<b>Exit</b>', self) self.exitproj.setShortcut('Ctrl+X') self.exitproj.triggered.connect(self.exit_project) self.helpfile = QtGui.QAction( QtGui.QIcon('../../images/helpProject.png'), '<b>Help</b>', self) self.helpfile.setShortcut('Ctrl+H') self.helpfile.triggered.connect(self.help_project) self.topToolbar = self.addToolBar('Top Tool Bar') self.topToolbar.addAction(self.newproj) self.topToolbar.addAction(self.openproj) self.topToolbar.addAction(self.exitproj) self.topToolbar.addAction(self.helpfile) self.spacer = QtGui.QWidget() self.spacer.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) self.topToolbar.addWidget(self.spacer) self.logo = QtGui.QLabel() self.logopic = QtGui.QPixmap( os.path.join(os.path.abspath('../..'), 'images', 'fosseeLogo.png')) self.logopic = self.logopic.scaled(QSize(150, 150), QtCore.Qt.KeepAspectRatio) self.logo.setPixmap(self.logopic) self.logo.setStyleSheet("padding:0 15px 0 0;") self.topToolbar.addWidget(self.logo) #Left Tool bar Action Widget self.kicad = QtGui.QAction(QtGui.QIcon('../../images/kicad.png'), '<b>Open Schematic</b>', self) self.kicad.triggered.connect(self.obj_kicad.openSchematic) self.conversion = QtGui.QAction(QtGui.QIcon('../../images/ki-ng.png'), '<b>Convert Kicad to Ngspice</b>', self) self.conversion.triggered.connect(self.obj_kicad.openKicadToNgspice) self.ngspice = QtGui.QAction(QtGui.QIcon('../../images/ngspice.png'), '<b>Simulation</b>', self) self.ngspice.triggered.connect(self.open_ngspice) self.footprint = QtGui.QAction( QtGui.QIcon('../../images/footprint.png'), '<b>Footprint Editor</b>', self) self.footprint.triggered.connect(self.obj_kicad.openFootprint) self.pcb = QtGui.QAction(QtGui.QIcon('../../images/pcb.png'), '<b>PCB Layout</b>', self) self.pcb.triggered.connect(self.obj_kicad.openLayout) self.model = QtGui.QAction(QtGui.QIcon('../../images/model.png'), '<b>Model Editor</b>', self) self.model.triggered.connect(self.open_modelEditor) self.subcircuit = QtGui.QAction(QtGui.QIcon('../../images/subckt.png'), '<b>Subcircuit</b>', self) self.subcircuit.triggered.connect(self.open_subcircuit) #Adding Action Widget to tool bar self.lefttoolbar = QtGui.QToolBar('Left ToolBar') self.addToolBar(QtCore.Qt.LeftToolBarArea, self.lefttoolbar) self.lefttoolbar.addAction(self.kicad) self.lefttoolbar.addAction(self.conversion) self.lefttoolbar.addAction(self.ngspice) self.lefttoolbar.addAction(self.footprint) self.lefttoolbar.addAction(self.pcb) self.lefttoolbar.addAction(self.model) self.lefttoolbar.addAction(self.subcircuit) self.lefttoolbar.setOrientation(QtCore.Qt.Vertical) self.lefttoolbar.setIconSize(QSize(40, 40)) def new_project(self): """ This function call New Project Info class. """ text, ok = QtGui.QInputDialog.getText(self, 'New Project Info', 'Enter Project Name:') if ok: self.projname = (str(text)) self.project = NewProjectInfo() directory, filelist = self.project.createProject(self.projname) self.obj_Mainview.obj_projectExplorer.addTreeNode( directory, filelist) else: print "No project created" self.obj_appconfig.print_info('No new project created') try: self.obj_appconfig.print_info( 'Current project is : ' + self.obj_appconfig.current_project["ProjectName"]) except: pass def open_project(self): """ This project call Open Project Info class """ print "Open Project called" self.project = OpenProjectInfo() try: directory, filelist = self.project.body() self.obj_Mainview.obj_projectExplorer.addTreeNode( directory, filelist) except: pass def open_ngspice(self): """ This Function execute ngspice on current project """ self.projDir = self.obj_appconfig.current_project["ProjectName"] if self.projDir != None: self.obj_Mainview.obj_dockarea.ngspiceEditor(self.projDir) time.sleep(2) #Need permanent solution #Calling Python Plotting try: self.obj_Mainview.obj_dockarea.plottingEditor() except Exception as e: self.msg = QtGui.QErrorMessage(None) self.msg.showMessage( 'Error while opening python plotting Editor.') print "Exception:", str(e) self.obj_appconfig.print_error('Exception generated : ' + str(e)) self.msg.setWindowTitle("Error Message") else: self.msg = QtGui.QErrorMessage() self.msg.showMessage( 'Please select the project first. You can either create new project or open existing project' ) self.msg.setWindowTitle("Error Message") def open_subcircuit(self): print "Subcircuit editor is called" self.obj_appconfig.print_info('Subcircuit editor is called') self.obj_Mainview.obj_dockarea.subcircuiteditor() def exit_project(self): print "Exit Project called" for proc in self.obj_appconfig.procThread_list: try: proc.terminate() except: pass ##Just checking if open and New window is open. If yes just close it when application is closed try: self.project.close() except: pass self.close() def help_project(self): print "Help is called" self.obj_appconfig.print_info('Help is called') print "Current Project : ", self.obj_appconfig.current_project self.obj_Mainview.obj_dockarea.usermanual() def open_modelEditor(self): print "model editor is called" self.obj_appconfig.print_info('model editor is called') self.obj_Mainview.obj_dockarea.modelEditor() """ def open_kicadToNgspice(self): print "kicadToNgspice is called" self.obj_appconfig.print_info('kicadToNgspice is called') self.obj_Mainview.obj_dockarea.kicadToNgspiceEditor()""" def testing(self): print "Success hit kicad button"
class ModelEditorclass(QtGui.QWidget): def __init__(self): QtGui.QWidget.__init__(self) self.savepathtest = '../deviceModelLibrary' self.obj_appconfig = Appconfig() self.newflag=0 self.layout = QtGui.QVBoxLayout() self.splitter= QtGui.QSplitter() self.grid= QtGui.QGridLayout() self.splitter.setOrientation(QtCore.Qt.Vertical) self.modeltable = QtGui.QTableWidget() self.newbtn = QtGui.QPushButton('New') self.newbtn.setToolTip('<b>Creating new Model Library</b>') self.newbtn.clicked.connect(self.opennew) self.editbtn = QtGui.QPushButton('Edit') self.editbtn.setToolTip('<b>Editing current Model Library</b>') self.editbtn.clicked.connect(self.openedit) self.savebtn = QtGui.QPushButton('Save') self.savebtn.setToolTip('<b>Saves the Model Library</b>') self.savebtn.setDisabled(True) self.savebtn.clicked.connect(self.savemodelfile) self.removebtn = QtGui.QPushButton('Remove') self.removebtn.setHidden(True) self.removebtn.clicked.connect(self.removeparameter) self.addbtn = QtGui.QPushButton('Add') self.addbtn.setHidden(True) self.addbtn.clicked.connect(self.addparameters) self.uploadbtn = QtGui.QPushButton('Upload') self.uploadbtn.setToolTip('<b>Uploading external .lib file to eSim</b>') self.uploadbtn.clicked.connect(self.converttoxml) self.grid.addWidget(self.newbtn, 1,2) self.grid.addWidget(self.editbtn, 1,3) self.grid.addWidget(self.savebtn, 1,4) self.grid.addWidget(self.uploadbtn, 1,5) self.grid.addWidget(self.removebtn, 8,4) self.grid.addWidget(self.addbtn, 5,4) self.radiobtnbox = QtGui.QButtonGroup() self.diode = QtGui.QRadioButton('Diode') self.diode.setDisabled(True) self.bjt = QtGui.QRadioButton('BJT') self.bjt.setDisabled(True) self.mos = QtGui.QRadioButton('MOS') self.mos.setDisabled(True) self.jfet = QtGui.QRadioButton('JFET') self.jfet.setDisabled(True) self.igbt = QtGui.QRadioButton('IGBT') self.igbt.setDisabled(True) self.magnetic = QtGui.QRadioButton('Magnetic Core') self.magnetic.setDisabled(True) self.radiobtnbox.addButton(self.diode) self.diode.clicked.connect(self.diode_click) self.radiobtnbox.addButton(self.bjt) self.bjt.clicked.connect(self.bjt_click) self.radiobtnbox.addButton(self.mos) self.mos.clicked.connect(self.mos_click) self.radiobtnbox.addButton(self.jfet) self.jfet.clicked.connect(self.jfet_click) self.radiobtnbox.addButton(self.igbt) self.igbt.clicked.connect(self.igbt_click) self.radiobtnbox.addButton(self.magnetic) self.magnetic.clicked.connect(self.magnetic_click) self.types= QtGui.QComboBox() self.types.setHidden(True) self.grid.addWidget(self.types,2,2,2,3) self.grid.addWidget(self.diode, 3,1) self.grid.addWidget(self.bjt,4,1) self.grid.addWidget(self.mos,5,1) self.grid.addWidget(self.jfet,6,1) self.grid.addWidget(self.igbt,7,1) self.grid.addWidget(self.magnetic,8,1) self.setLayout(self.grid) self.show() '''To create New Model file ''' def opennew(self): self.addbtn.setHidden(True) try: self.removebtn.setHidden(True) self.modeltable.setHidden(True) except: pass os.chdir(self.savepathtest) text, ok = QtGui.QInputDialog.getText(self, 'New Model','Enter Model Name:') if ok: self.newflag=1 self.diode.setDisabled(False) self.bjt.setDisabled(False) self.mos.setDisabled(False) self.jfet.setDisabled(False) self.igbt.setDisabled(False) self.magnetic.setDisabled(False) self.modelname = (str(text)) else: pass self.validation(text) def diode_click(self): self.openfiletype('Diode') self.types.setHidden(True) def bjt_click(self): self.types.setHidden(False) self.types.clear() self.types.addItem('NPN') self.types.addItem('PNP') filetype = str(self.types.currentText()) self.openfiletype(filetype) self.types.activated[str].connect(self.setfiletype) def mos_click(self): self.types.setHidden(False) self.types.clear() self.types.addItem('NMOS(Level-1 5um)') self.types.addItem('NMOS(Level-3 0.5um)') self.types.addItem('NMOS(Level-8 180um)') self.types.addItem('PMOS(Level-1 5um)') self.types.addItem('PMOS(Level-3 0.5um)') self.types.addItem('PMOS(Level-8 180um)') filetype = str(self.types.currentText()) self.openfiletype(filetype) self.types.activated[str].connect(self.setfiletype) def jfet_click(self): self.types.setHidden(False) self.types.clear() self.types.addItem('N-JFET') self.types.addItem('P-JFET') filetype = str(self.types.currentText()) self.openfiletype(filetype) self.types.activated[str].connect(self.setfiletype) def igbt_click(self): self.types.setHidden(False) self.types.clear() self.types.addItem('N-IGBT') self.types.addItem('P-IGBT') filetype = str(self.types.currentText()) self.openfiletype(filetype) self.types.activated[str].connect(self.setfiletype) def magnetic_click(self): self.openfiletype('Magnetic Core') self.types.setHidden(True) def setfiletype(self,text): self.filetype = str(text) self.openfiletype(self.filetype) def openfiletype(self,filetype): ''' Select the path of the file to be opened depending upon selected file type ''' self.path = '../deviceModelLibrary/Templates' if self.diode.isChecked(): if filetype == 'Diode': path = os.path.join(self.path,'D.xml') self.createtable(path) if self.bjt.isChecked(): if filetype == 'NPN': path = os.path.join(self.path,'NPN.xml') self.createtable(path) elif filetype == 'PNP': path = os.path.join(self.path, 'PNP.xml') self.createtable(path) if self.mos.isChecked(): if filetype == 'NMOS(Level-1 5um)': path = os.path.join(self.path, 'NMOS-5um.xml') self.createtable(path) elif filetype == 'NMOS(Level-3 0.5um)': path = os.path.join(self.path, 'NMOS-0.5um.xml') self.createtable(path) elif filetype == 'NMOS(Level-8 180um)': path = os.path.join(self.path, 'NMOS-180nm.xml') self.createtable(path) elif filetype == 'PMOS(Level-1 5um)': path = os.path.join(self.path, 'PMOS-5um.xml') self.createtable(path) elif filetype == 'PMOS(Level-3 0.5um)': path = os.path.join(self.path, 'PMOS-0.5um.xml') self.createtable(path) elif filetype == 'PMOS(Level-8 180um)': path = os.path.join(self.path, 'PMOS-180nm.xml') self.createtable(path) if self.jfet.isChecked(): if filetype == 'N-JFET': path = os.path.join(self.path, 'NJF.xml') self.createtable(path) elif filetype == 'P-JFET': path = os.path.join(self.path, 'PJF.xml') self.createtable(path) if self.igbt.isChecked(): if filetype == 'N-IGBT': path = os.path.join(self.path, 'NIGBT.xml') self.createtable(path) elif filetype == 'P-IGBT': path = os.path.join(self.path, 'PIGBT.xml') self.createtable(path) if self.magnetic.isChecked(): if filetype == 'Magnetic Core': path = os.path.join(self.path, 'CORE.xml') self.createtable(path) else : pass def openedit(self): os.chdir(self.savepathtest) self.newflag=0 self.addbtn.setHidden(True) self.types.setHidden(True) self.diode.setDisabled(True) self.mos.setDisabled(True) self.jfet.setDisabled(True) self.igbt.setDisabled(True) self.bjt.setDisabled(True) self.magnetic.setDisabled(True) try: self.editfile=str(QtGui.QFileDialog.getOpenFileName(self,"Open Library Directory","../deviceModelLibrary","*.lib")) self.createtable(self.editfile) except: print"No File selected for edit" pass def createtable(self, modelfile): ''' This function Creates the model table by parsing the .xml file ''' self.savebtn.setDisabled(False) self.addbtn.setHidden(False) self.removebtn.setHidden(False) self.modelfile = modelfile self.modeldict = {} self.modeltable = QtGui.QTableWidget() self.modeltable.resizeColumnsToContents() self.modeltable.setColumnCount(2) self.modeltable.resizeRowsToContents() self.modeltable.resize(200,200) self.grid.addWidget(self.modeltable, 3,2,8,2) filepath, filename = os.path.split(self.modelfile) base, ext= os.path.splitext(filename) self.modelfile = os.path.join(filepath, base+'.xml') print"Model File used for creating table : ",self.modelfile self.tree = ET.parse(self.modelfile) self.root= self.tree.getroot() for elem in self.tree.iter(tag='ref_model'): self.ref_model = elem.text for elem in self.tree.iter(tag='model_name'): self.model_name = elem.text row=0 for params in self.tree.findall('param'): for paramlist in params: self.modeldict[paramlist.tag]= paramlist.text row= row+1 self.modeltable.setRowCount(row) count =0 for tags, values in self.modeldict.items(): self.modeltable.setItem(count,0, QTableWidgetItem(tags)) try: valueitem = QTableWidgetItem(values) except: pass self.modeltable.setItem(count,1, valueitem) count= count +1 self.modeltable.setHorizontalHeaderLabels(QtCore.QString("Parameters;Values").split(";")) self.modeltable.show() self.modeltable.itemChanged.connect(self.edit_modeltable) def edit_modeltable(self): self.savebtn.setDisabled(False) try: indexitem = self.modeltable.currentItem() name = str(indexitem.data(0).toString()) rowno = indexitem.row() para = self.modeltable.item(rowno,0) val = str(para.data(0).toString()) self.modeldict[val]= name except: pass def addparameters(self): ''' This function is used to add new parameter in the table ''' text1, ok = QtGui.QInputDialog.getText(self, 'Parameter','Enter Parameter') if ok: if text1 in self.modeldict.keys(): self.msg = QtGui.QErrorMessage(self) self.msg.showMessage("The paramaeter " + text1 + " is already in the list") self.msg.setWindowTitle("Error Message") return text2, ok = QtGui.QInputDialog.getText(self, 'Value','Enter Value') if ok : currentRowCount = self.modeltable.rowCount() self.modeltable.insertRow(currentRowCount) self.modeltable.setItem(currentRowCount, 0, QTableWidgetItem(text1)) self.modeltable.setItem(currentRowCount, 1, QTableWidgetItem(text2)) self.modeldict[str(text1)]= str(text2) else: pass else: pass def savemodelfile(self): if self.newflag== 1: self.createXML(self.model_name) else: self.savethefile(self.editfile) def createXML(self,model_name): ''' This function creates .xml and .lib files from the model table ''' root = ET.Element("library") ET.SubElement(root, "model_name").text = model_name ET.SubElement(root, "ref_model").text = self.modelname param = ET.SubElement(root, "param") for tags, text in self.modeldict.items(): ET.SubElement(param, tags).text = text tree = ET.ElementTree(root) defaultcwd = os.getcwd() self.savepath = '../deviceModelLibrary' if self.diode.isChecked(): savepath = os.path.join(self.savepath, 'Diode') os.chdir(savepath) txtfile = open(self.modelname+'.lib', 'w') txtfile.write('.MODEL ' + self.modelname +' ' + self.model_name + '(\n' ) for tags, text in self.modeldict.items(): txtfile.write('+ ' + tags + '=' + text +'\n') txtfile.write(')') tree.write(self.modelname +".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) if self.mos.isChecked(): savepath = os.path.join(self.savepath, 'MOS') os.chdir(savepath) txtfile = open(self.modelname+'.lib', 'w') txtfile.write('.MODEL ' + self.modelname +' ' + self.model_name + '(\n' ) for tags, text in self.modeldict.items(): txtfile.write('+ ' + tags + '=' + text +'\n') txtfile.write(')') tree.write(self.modelname +".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) if self.jfet.isChecked(): savepath = os.path.join(self.savepath, 'JFET') os.chdir(savepath) txtfile = open(self.modelname+'.lib', 'w') txtfile.write('.MODEL ' + self.modelname +' ' + self.model_name + '(\n' ) for tags, text in self.modeldict.items(): txtfile.write('+ ' + tags + '=' + text +'\n') txtfile.write(')') tree.write(self.modelname +".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) if self.igbt.isChecked(): savepath = os.path.join(self.savepath, 'IGBT') os.chdir(savepath) txtfile = open(self.modelname+'.lib', 'w') txtfile.write('.MODEL ' + self.modelname +' ' + self.model_name + '(\n' ) for tags, text in self.modeldict.items(): txtfile.write('+ ' + tags + '=' + text +'\n') txtfile.write(')') tree.write(self.modelname +".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) if self.magnetic.isChecked(): savepath = os.path.join(self.savepath, 'Misc') os.chdir(savepath) txtfile = open(self.modelname+'.lib', 'w') txtfile.write('.MODEL ' + self.modelname +' ' + self.model_name + '(\n' ) for tags, text in self.modeldict.items(): txtfile.write('+ ' + tags + '=' + text +'\n') txtfile.write(')') tree.write(self.modelname +".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) if self.bjt.isChecked(): savepath = os.path.join(self.savepath, 'Transistor') os.chdir(savepath) txtfile = open(self.modelname+'.lib', 'w') txtfile.write('.MODEL ' + self.modelname +' ' + self.model_name + '(\n' ) for tags, text in self.modeldict.items(): txtfile.write('+ ' + tags + '=' + text +'\n') txtfile.write(')') tree.write(self.modelname +".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) txtfile.close() os.chdir(defaultcwd) def validation(self,text): ''' This function checks if the file with the name already exists ''' newfilename = text+'.xml' all_dir = [x[0] for x in os.walk(self.savepathtest)] for each_dir in all_dir: all_files = os.listdir(each_dir) if newfilename in all_files: self.msg = QtGui.QErrorMessage(self) self.msg.showMessage('The file with name ' + text+ ' already exists.') self.msg.setWindowTitle("Error Message") def savethefile(self,editfile): ''' This function save the editing in the model table ''' xmlpath, file = os.path.split(editfile) filename = os.path.splitext(file)[0] libpath = os.path.join(xmlpath,filename+'.lib') libfile = open(libpath, 'w') libfile.write('.MODEL ' + self.ref_model +' ' + self.model_name + '(\n' ) for tags, text in self.modeldict.items(): libfile.write('+ ' + tags + '=' + text +'\n') libfile.write(')') libfile.close() root = ET.Element("library") ET.SubElement(root, "model_name").text = self.model_name ET.SubElement(root, "ref_model").text = self.ref_model param = ET.SubElement(root, "param") for tags, text in self.modeldict.items(): ET.SubElement(param, tags).text = text tree = ET.ElementTree(root) tree.write(os.path.join(xmlpath,filename +".xml")) self.obj_appconfig.print_info('Updated library ' + libpath) def removeparameter(self): self.savebtn.setDisabled(False) index = self.modeltable.currentIndex() param = index.data().toString() remove_item = self.modeltable.item(index.row(),0).text() self.modeltable.removeRow(index.row()) del self.modeldict[str(remove_item)] def converttoxml(self): os.chdir(self.savepathtest) self.addbtn.setHidden(True) self.removebtn.setHidden(True) self.modeltable.setHidden(True) model_dict = {} stringof = [] self.libfile = str(QtGui.QFileDialog.getOpenFileName(self,"Open Library Directory","../deviceModelLibrary","*.lib")) libopen = open(self.libfile) filedata = libopen.read().split() modelcount=0 for words in filedata: modelcount= modelcount +1 if words.lower() == '.model': break ref_model = filedata[modelcount] model_name = filedata[modelcount+1] model_name = list(model_name) modelnamecnt= 0 flag= 0 for chars in model_name: modelnamecnt = modelnamecnt +1 if chars == '(': flag = 1 break if flag == 1 : model_name = ''.join(model_name[0:modelnamecnt-1]) else: model_name = ''.join(model_name) libopen1 = open(self.libfile) while True: char = libopen1.read(1) if not char: break stringof.append(char) count = 0 for chars in stringof: count = count +1 if chars == '(': break count1=0 for chars in stringof: count1 = count1 +1 if chars == ')': break stringof = stringof[count:count1-1] stopcount=[] listofname = [] stopcount.append(0) count = 0 for chars in stringof: count = count +1 if chars == '=': stopcount.append(count) stopcount.append(count) i = 0 for no in stopcount: try: listofname.append(''.join(stringof[int(stopcount[i]):int(stopcount[i+1])])) i = i +1 except: pass listoflist =[] listofname2 = [el.replace('\t', '').replace('\n', ' ').replace('+', '').replace(')', '').replace('=', '') for el in listofname] listofname=[] for item in listofname2: listofname.append(item.rstrip().lstrip()) for values in listofname: valuelist = values.split(' ') listoflist.append(valuelist) for i in range(1, len(listoflist)): model_dict[listoflist[0][0]]=listoflist[1][0] try: model_dict[listoflist[i][-1]]= listoflist[i+1][0] except: pass root = ET.Element("library") ET.SubElement(root, "model_name").text = model_name ET.SubElement(root, "ref_model").text = ref_model param = ET.SubElement(root, "param") for tags, text in model_dict.items(): ET.SubElement(param, tags).text = text tree = ET.ElementTree(root) defaultcwd = os.getcwd() savepath = os.path.join(self.savepathtest, 'User Libraries') savefilepath= os.path.join(savepath, model_name +".xml") os.chdir(savepath) text, ok1 = QtGui.QInputDialog.getText(self, 'Model Name','Enter Model Library Name') if ok1: tree.write(text+".xml") fileopen = open(text+".lib",'w') f = open(self.libfile) fileopen.write(f.read()) f.close() fileopen.close() os.chdir(defaultcwd) libopen.close() libopen1.close()
class ModelEditorclass(QtWidgets.QWidget): ''' - Initialise the layout for dockarea - Use QVBoxLayout, QSplitter, QGridLayout to define the layout - Initalise directory to save new models, savepathtest = 'library/deviceModelLibrary' - Initialise buttons and options ====> - Name Function Called ======================================== - New opennew - Edit openedit - Save savemodelfile - Upload converttoxml - Add addparameters - Remove removeparameter - Diode diode_click - BJT bjt_click - MOS mos_click - JFET jfet_click - IGBT igbt_click - Magnetic Core magnetic_click ''' def __init__(self): QtWidgets.QWidget.__init__(self) self.init_path = '../../' if os.name == 'nt': self.init_path = '' self.savepathtest = self.init_path + 'library/deviceModelLibrary' self.obj_appconfig = Appconfig() self.newflag = 0 self.layout = QtWidgets.QVBoxLayout() self.splitter = QtWidgets.QSplitter() self.grid = QtWidgets.QGridLayout() self.splitter.setOrientation(QtCore.Qt.Vertical) # Initialise the table view self.modeltable = QtWidgets.QTableWidget() self.newbtn = QtWidgets.QPushButton('New') self.newbtn.setToolTip('<b>Creating new Model Library</b>') self.newbtn.clicked.connect(self.opennew) self.editbtn = QtWidgets.QPushButton('Edit') self.editbtn.setToolTip('<b>Editing current Model Library</b>') self.editbtn.clicked.connect(self.openedit) self.savebtn = QtWidgets.QPushButton('Save') self.savebtn.setToolTip('<b>Saves the Model Library</b>') self.savebtn.setDisabled(True) self.savebtn.clicked.connect(self.savemodelfile) self.removebtn = QtWidgets.QPushButton('Remove') self.removebtn.setHidden(True) self.removebtn.clicked.connect(self.removeparameter) self.addbtn = QtWidgets.QPushButton('Add') self.addbtn.setHidden(True) self.addbtn.clicked.connect(self.addparameters) self.uploadbtn = QtWidgets.QPushButton('Upload') self.uploadbtn.setToolTip( '<b>Uploading external .lib file to eSim</b>') self.uploadbtn.clicked.connect(self.converttoxml) self.grid.addWidget(self.newbtn, 1, 2) self.grid.addWidget(self.editbtn, 1, 3) self.grid.addWidget(self.savebtn, 1, 4) self.grid.addWidget(self.uploadbtn, 1, 5) self.grid.addWidget(self.removebtn, 8, 4) self.grid.addWidget(self.addbtn, 5, 4) self.radiobtnbox = QtWidgets.QButtonGroup() self.diode = QtWidgets.QRadioButton('Diode') self.diode.setDisabled(True) self.bjt = QtWidgets.QRadioButton('BJT') self.bjt.setDisabled(True) self.mos = QtWidgets.QRadioButton('MOS') self.mos.setDisabled(True) self.jfet = QtWidgets.QRadioButton('JFET') self.jfet.setDisabled(True) self.igbt = QtWidgets.QRadioButton('IGBT') self.igbt.setDisabled(True) self.magnetic = QtWidgets.QRadioButton('Magnetic Core') self.magnetic.setDisabled(True) self.radiobtnbox.addButton(self.diode) self.diode.clicked.connect(self.diode_click) self.radiobtnbox.addButton(self.bjt) self.bjt.clicked.connect(self.bjt_click) self.radiobtnbox.addButton(self.mos) self.mos.clicked.connect(self.mos_click) self.radiobtnbox.addButton(self.jfet) self.jfet.clicked.connect(self.jfet_click) self.radiobtnbox.addButton(self.igbt) self.igbt.clicked.connect(self.igbt_click) self.radiobtnbox.addButton(self.magnetic) self.magnetic.clicked.connect(self.magnetic_click) # Dropdown for various types supported by that element, ex bjt -> npn self.types = QtWidgets.QComboBox() self.types.setHidden(True) self.grid.addWidget(self.types, 2, 2, 2, 3) self.grid.addWidget(self.diode, 3, 1) self.grid.addWidget(self.bjt, 4, 1) self.grid.addWidget(self.mos, 5, 1) self.grid.addWidget(self.jfet, 6, 1) self.grid.addWidget(self.igbt, 7, 1) self.grid.addWidget(self.magnetic, 8, 1) self.setLayout(self.grid) self.show() def opennew(self): ''' - To create New Model file - Change state of other buttons accordingly, ex. enable diode, bjt, ... - Validate filename created, to check if one already exists ''' self.addbtn.setHidden(True) try: self.removebtn.setHidden(True) self.modeltable.setHidden(True) except BaseException: pass # Opens new dialog box text, ok = QtWidgets.QInputDialog.getText(self, 'New Model', 'Enter Model Name:') if ok: self.newflag = 1 self.diode.setDisabled(False) self.bjt.setDisabled(False) self.mos.setDisabled(False) self.jfet.setDisabled(False) self.igbt.setDisabled(False) self.magnetic.setDisabled(False) self.modelname = (str(text)) else: pass # Validate if the file created exists already or not # Show error accordingly self.validation(text) def diode_click(self): ''' - Call function, openfiletype, which opens the table view\ for Diode specs - Set states for other elements - Diode has no types, so hide that ''' self.openfiletype('Diode') self.types.setHidden(True) def bjt_click(self): ''' - Set states for other elements - Initialise types combo box elements - - NPN - - PNP - Open the default type in the table - Add an event listener for type-selection event ''' self.types.setHidden(False) self.types.clear() self.types.addItem('NPN') self.types.addItem('PNP') # Open in table default filetype = str(self.types.currentText()) self.openfiletype(filetype) # When element selected from combo box, call setfiletype self.types.activated[str].connect(self.setfiletype) def mos_click(self): ''' - Set states for other elements - Initialise types combo box elements - - NMOS(Level-1 5um) - - NMOS(Level-3 0.5um) - - ... - Open the default type in the table - Add an event listener for type-selection event ''' self.types.setHidden(False) self.types.clear() self.types.addItem('NMOS(Level-1 5um)') self.types.addItem('NMOS(Level-3 0.5um)') self.types.addItem('NMOS(Level-8 180um)') self.types.addItem('PMOS(Level-1 5um)') self.types.addItem('PMOS(Level-3 0.5um)') self.types.addItem('PMOS(Level-8 180um)') filetype = str(self.types.currentText()) self.openfiletype(filetype) self.types.activated[str].connect(self.setfiletype) def jfet_click(self): ''' - Set states for other elements - Initialise types combo box elements - - N-JFET - - P-JFET - Open the default type in the table - Add an event listener for type-selection event ''' self.types.setHidden(False) self.types.clear() self.types.addItem('N-JFET') self.types.addItem('P-JFET') filetype = str(self.types.currentText()) self.openfiletype(filetype) self.types.activated[str].connect(self.setfiletype) def igbt_click(self): ''' - Set states for other elements - Initialise types combo box elements - - N-IGBT - - P-IGBT - Open the default type in the table - Add an event listener for type-selection event ''' self.types.setHidden(False) self.types.clear() self.types.addItem('N-IGBT') self.types.addItem('P-IGBT') filetype = str(self.types.currentText()) self.openfiletype(filetype) self.types.activated[str].connect(self.setfiletype) def magnetic_click(self): ''' - Set states for other elements - Initialise types combo box elements - Open the default type in the table - Add an event listener for type-selection event - No types here, only one view ''' self.openfiletype('Magnetic Core') self.types.setHidden(True) def setfiletype(self, text): ''' - Triggered when each type selected - Get the type clicked, from text - Open appropriate table using openfiletype(filetype) ''' self.filetype = str(text) self.openfiletype(self.filetype) def openfiletype(self, filetype): ''' - Select path for the filetype passed - Accordingly call `createtable(path)` to draw tables usingg QTable - Check for the state of button before rendering ''' self.path = self.init_path + 'library/deviceModelLibrary/Templates' if self.diode.isChecked(): if filetype == 'Diode': path = os.path.join(self.path, 'D.xml') self.createtable(path) if self.bjt.isChecked(): if filetype == 'NPN': path = os.path.join(self.path, 'NPN.xml') self.createtable(path) elif filetype == 'PNP': path = os.path.join(self.path, 'PNP.xml') self.createtable(path) if self.mos.isChecked(): if filetype == 'NMOS(Level-1 5um)': path = os.path.join(self.path, 'NMOS-5um.xml') self.createtable(path) elif filetype == 'NMOS(Level-3 0.5um)': path = os.path.join(self.path, 'NMOS-0.5um.xml') self.createtable(path) elif filetype == 'NMOS(Level-8 180um)': path = os.path.join(self.path, 'NMOS-180nm.xml') self.createtable(path) elif filetype == 'PMOS(Level-1 5um)': path = os.path.join(self.path, 'PMOS-5um.xml') self.createtable(path) elif filetype == 'PMOS(Level-3 0.5um)': path = os.path.join(self.path, 'PMOS-0.5um.xml') self.createtable(path) elif filetype == 'PMOS(Level-8 180um)': path = os.path.join(self.path, 'PMOS-180nm.xml') self.createtable(path) if self.jfet.isChecked(): if filetype == 'N-JFET': path = os.path.join(self.path, 'NJF.xml') self.createtable(path) elif filetype == 'P-JFET': path = os.path.join(self.path, 'PJF.xml') self.createtable(path) if self.igbt.isChecked(): if filetype == 'N-IGBT': path = os.path.join(self.path, 'NIGBT.xml') self.createtable(path) elif filetype == 'P-IGBT': path = os.path.join(self.path, 'PIGBT.xml') self.createtable(path) if self.magnetic.isChecked(): if filetype == 'Magnetic Core': path = os.path.join(self.path, 'CORE.xml') self.createtable(path) def openedit(self): ''' - When `Edit` button clicked, this function called - Set states for other buttons accordingly - Open the file selector box with path as deviceModelLibrary and filetype set as .lib, save it in `self.editfile` - Create table for the selected .lib file using\ `self.createtable(path)` - Handle exception of no file selected ''' self.newflag = 0 self.addbtn.setHidden(True) self.types.setHidden(True) self.diode.setDisabled(True) self.mos.setDisabled(True) self.jfet.setDisabled(True) self.igbt.setDisabled(True) self.bjt.setDisabled(True) self.magnetic.setDisabled(True) try: self.editfile = QtWidgets.QFileDialog.getOpenFileName( self, "Open Library Directory", self.init_path + "library/deviceModelLibrary", "*.lib")[0] self.createtable(self.editfile) except BaseException: print("No File selected for edit") def createtable(self, modelfile): ''' - Set states for other components - Initialise QTable widget - Set options for QTable widget - Place QTable widget, using `self.grid.addWidget` - Select the `.xml` file from the modelfile passed as `.lib` - Use ET (xml.etree.ElementTree) to parse the xml file - Extract data from the XML and store it in `modeldict` - Show the extracted data in QTableWidget - Can edit QTable inplace, connect `edit_modeltable`\ function for editing ''' self.savebtn.setDisabled(False) self.addbtn.setHidden(False) self.removebtn.setHidden(False) self.modelfile = modelfile self.modeldict = {} self.modeltable = QtWidgets.QTableWidget() self.modeltable.resizeColumnsToContents() self.modeltable.setColumnCount(2) self.modeltable.resizeRowsToContents() self.modeltable.resize(200, 200) self.grid.addWidget(self.modeltable, 3, 2, 8, 2) filepath, filename = os.path.split(self.modelfile) base, ext = os.path.splitext(filename) self.modelfile = os.path.join(filepath, base + '.xml') print("Model File used for creating table : ", self.modelfile) self.tree = ET.parse(self.modelfile) self.root = self.tree.getroot() for elem in self.tree.iter(tag='ref_model'): self.ref_model = elem.text for elem in self.tree.iter(tag='model_name'): self.model_name = elem.text row = 0 # get data from XML and store to dictionary (self.modeldict) for params in self.tree.findall('param'): for paramlist in params: self.modeldict[paramlist.tag] = paramlist.text row = row + 1 self.modeltable.setRowCount(row) count = 0 # setItem in modeltable, for each item in modeldict for tags, values in list(self.modeldict.items()): self.modeltable.setItem(count, 0, QTableWidgetItem(tags)) try: valueitem = QTableWidgetItem(values) except BaseException: pass self.modeltable.setItem(count, 1, valueitem) count = count + 1 self.modeltable.setHorizontalHeaderLabels( ("Parameters;Values").split(";")) self.modeltable.show() self.modeltable.itemChanged.connect(self.edit_modeltable) def edit_modeltable(self): ''' - Called when editing model inplace in QTableWidget - Set states of other components - Get data from the modeltable of the selected row - Edit name and value as per needed - Add the val name pair in the modeldict ''' self.savebtn.setDisabled(False) try: indexitem = self.modeltable.currentItem() name = str(indexitem.data(0)) rowno = indexitem.row() para = self.modeltable.item(rowno, 0) val = str(para.data(0)) self.modeldict[val] = name except BaseException: pass def addparameters(self): ''' - Called when `Add` button clicked beside QTableWidget - Open up dialog box to enter parameter and value accordingly - Validate if parameter already in list of parameters - Accordingly add parameter and value in modeldict as well as table - text1 => parameter, text2 => value ''' text1, ok = QtWidgets.QInputDialog.getText(self, 'Parameter', 'Enter Parameter') if ok: if text1 in list(self.modeldict.keys()): self.msg = QtWidgets.QErrorMessage(self) self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage("The paramaeter " + text1 + " is already in the list") self.msg.exec_() return text2, ok = QtWidgets.QInputDialog.getText(self, 'Value', 'Enter Value') if ok: currentRowCount = self.modeltable.rowCount() self.modeltable.insertRow(currentRowCount) self.modeltable.setItem(currentRowCount, 0, QTableWidgetItem(text1)) self.modeltable.setItem(currentRowCount, 1, QTableWidgetItem(text2)) self.modeldict[str(text1)] = str(text2) else: pass else: pass def savemodelfile(self): ''' - Called when save functon clicked - If new file created, call `createXML` file - Else call `savethefile` ''' if self.newflag == 1: self.createXML(self.model_name) else: self.savethefile(self.editfile) def createXML(self, model_name): ''' - Create .xml and .lib file if new model is being created - Save it in the corresponding compoenent directory,\ example Diode, IGBT.. - For each component, separate folder is there - Check the contents of .lib and .xml file to\ understand their structure ''' root = ET.Element("library") ET.SubElement(root, "model_name").text = model_name ET.SubElement(root, "ref_model").text = self.modelname param = ET.SubElement(root, "param") for tags, text in list(self.modeldict.items()): ET.SubElement(param, tags).text = text tree = ET.ElementTree(root) defaultcwd = os.getcwd() self.savepath = self.init_path + 'library/deviceModelLibrary' if self.diode.isChecked(): savepath = os.path.join(self.savepath, 'Diode') os.chdir(savepath) txtfile = open(self.modelname + '.lib', 'w') txtfile.write('.MODEL ' + self.modelname + ' ' + self.model_name + '(') for tags, text in list(self.modeldict.items()): txtfile.write(' ' + tags + '=' + text) txtfile.write(' )\n') tree.write(self.modelname + ".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) if self.mos.isChecked(): savepath = os.path.join(self.savepath, 'MOS') os.chdir(savepath) txtfile = open(self.modelname + '.lib', 'w') txtfile.write('.MODEL ' + self.modelname + ' ' + self.model_name + '(') for tags, text in list(self.modeldict.items()): txtfile.write(' ' + tags + '=' + text) txtfile.write(' )\n') tree.write(self.modelname + ".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) if self.jfet.isChecked(): savepath = os.path.join(self.savepath, 'JFET') os.chdir(savepath) txtfile = open(self.modelname + '.lib', 'w') txtfile.write('.MODEL ' + self.modelname + ' ' + self.model_name + '(') for tags, text in list(self.modeldict.items()): txtfile.write(' ' + tags + '=' + text) txtfile.write(' )\n') tree.write(self.modelname + ".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) if self.igbt.isChecked(): savepath = os.path.join(self.savepath, 'IGBT') os.chdir(savepath) txtfile = open(self.modelname + '.lib', 'w') txtfile.write('.MODEL ' + self.modelname + ' ' + self.model_name + '(') for tags, text in list(self.modeldict.items()): txtfile.write(' ' + tags + '=' + text) txtfile.write(' )\n') tree.write(self.modelname + ".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) if self.magnetic.isChecked(): savepath = os.path.join(self.savepath, 'Misc') os.chdir(savepath) txtfile = open(self.modelname + '.lib', 'w') txtfile.write('.MODEL ' + self.modelname + ' ' + self.model_name + '(') for tags, text in list(self.modeldict.items()): txtfile.write(' ' + tags + '=' + text) txtfile.write(' )\n') tree.write(self.modelname + ".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) if self.bjt.isChecked(): savepath = os.path.join(self.savepath, 'Transistor') os.chdir(savepath) txtfile = open(self.modelname + '.lib', 'w') txtfile.write('.MODEL ' + self.modelname + ' ' + self.model_name + '(') for tags, text in list(self.modeldict.items()): txtfile.write(' ' + tags + '=' + text) txtfile.write(' )\n') tree.write(self.modelname + ".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) txtfile.close() msg = "Model saved successfully!" QtWidgets.QMessageBox.information(self, "Information", msg, QtWidgets.QMessageBox.Ok) os.chdir(defaultcwd) def validation(self, text): ''' - This function checks if the file (xml type) with the name\ already exists - Accordingly show error message ''' newfilename = text + '.xml' all_dir = [x[0] for x in os.walk(self.savepathtest)] for each_dir in all_dir: all_files = os.listdir(each_dir) if newfilename in all_files: self.msg = QtWidgets.QErrorMessage(self) self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage('The file with name ' + text + ' already exists.') self.msg.exec_() def savethefile(self, editfile): ''' - This function save the editing in the model table - Create .lib and .xml file for the editfile path and replace them - Also print Updated Library with libpath in the command window ''' xmlpath, file = os.path.split(editfile) filename = os.path.splitext(file)[0] libpath = os.path.join(xmlpath, filename + '.lib') libfile = open(libpath, 'w') libfile.write('.MODEL ' + self.ref_model + ' ' + self.model_name + '(') for tags, text in list(self.modeldict.items()): libfile.write(' ' + tags + '=' + text) libfile.write(' )\n') libfile.close() root = ET.Element("library") ET.SubElement(root, "model_name").text = self.model_name ET.SubElement(root, "ref_model").text = self.ref_model param = ET.SubElement(root, "param") for tags, text in list(self.modeldict.items()): ET.SubElement(param, tags).text = text tree = ET.ElementTree(root) tree.write(os.path.join(xmlpath, filename + ".xml")) self.obj_appconfig.print_info('Updated library ' + libpath) msg = "Model saved successfully!" QtWidgets.QMessageBox.information(self, "Information", msg, QtWidgets.QMessageBox.Ok) def removeparameter(self): ''' - Get the index of the current selected item - Remove the whole row from QTable Widget - Remove the param,value pair from modeldict ''' self.savebtn.setDisabled(False) index = self.modeltable.currentIndex() remove_item = self.modeltable.item(index.row(), 0).text() self.modeltable.removeRow(index.row()) del self.modeldict[str(remove_item)] def converttoxml(self): ''' - Called when upload button clicked - Used to read file form a certain location for .lib extension - Accordingly parse it and extract modelname and modelref - Also extract param value pairs - Take input the name of the library you want to save it as - Save it in `User Libraries` with the given name, and input from uploaded file ''' self.addbtn.setHidden(True) self.removebtn.setHidden(True) self.modeltable.setHidden(True) model_dict = {} stringof = [] self.libfile = QtWidgets.QFileDialog.getOpenFileName( self, "Open Library Directory", self.init_path + "library/deviceModelLibrary", "*.lib")[0] libopen = open(self.libfile) filedata = libopen.read().split() modelcount = 0 for words in filedata: modelcount = modelcount + 1 if words.lower() == '.model': break ref_model = filedata[modelcount] model_name = filedata[modelcount + 1] model_name = list(model_name) modelnamecnt = 0 flag = 0 for chars in model_name: modelnamecnt = modelnamecnt + 1 if chars == '(': flag = 1 break if flag == 1: model_name = ''.join(model_name[0:modelnamecnt - 1]) else: model_name = ''.join(model_name) libopen1 = open(self.libfile) while True: char = libopen1.read(1) if not char: break stringof.append(char) count = 0 for chars in stringof: count = count + 1 if chars == '(': break count1 = 0 for chars in stringof: count1 = count1 + 1 if chars == ')': break stringof = stringof[count:count1 - 1] stopcount = [] listofname = [] stopcount.append(0) count = 0 for chars in stringof: count = count + 1 if chars == '=': stopcount.append(count) stopcount.append(count) i = 0 for no in stopcount: try: listofname.append(''.join( stringof[int(stopcount[i]):int(stopcount[i + 1])])) i = i + 1 except BaseException: pass listoflist = [] listofname2 = [ el.replace('\t', '').replace('\n', ' ').replace('+', '').replace( ')', '').replace('=', '') for el in listofname ] listofname = [] for item in listofname2: listofname.append(item.rstrip().lstrip()) for values in listofname: valuelist = values.split(' ') listoflist.append(valuelist) for i in range(1, len(listoflist)): model_dict[listoflist[0][0]] = listoflist[1][0] try: model_dict[listoflist[i][-1]] = listoflist[i + 1][0] except BaseException: pass root = ET.Element("library") ET.SubElement(root, "model_name").text = model_name ET.SubElement(root, "ref_model").text = ref_model param = ET.SubElement(root, "param") for tags, text in list(model_dict.items()): ET.SubElement(param, tags).text = text tree = ET.ElementTree(root) defaultcwd = os.getcwd() savepath = os.path.join(self.savepathtest, 'User Libraries') os.chdir(savepath) text, ok1 = QtWidgets.QInputDialog.getText(self, 'Model Name', 'Enter Model Library Name') if ok1: tree.write(text + ".xml") fileopen = open(text + ".lib", 'w') f = open(self.libfile) fileopen.write(f.read()) f.close() fileopen.close() os.chdir(defaultcwd) libopen.close() libopen1.close()
class Workspace(QtGui.QWidget): """ This class creates Workspace GUI. """ def __init__(self,parent=None): super(Workspace, self).__init__() self.obj_appconfig = Appconfig() #Initializing Workspace directory for project self.initWorkspace() def initWorkspace(self): #print "Calling workspace" self.mainwindow = QtGui.QVBoxLayout() self.split = QtGui.QSplitter() self.split.setOrientation(QtCore.Qt.Vertical) self.grid = QtGui.QGridLayout() self.note = QtGui.QTextEdit(self) self.workspace_label = QtGui.QLabel(self) self.workspace_loc = QtGui.QLineEdit(self) self.note.append(self.obj_appconfig.workspace_text) self.workspace_label.setText("Workspace:") self.workspace_loc.setText(self.obj_appconfig.home) #Buttons self.browsebtn = QtGui.QPushButton('Browse') self.browsebtn.clicked.connect(self.browseLocation) self.okbtn = QtGui.QPushButton('OK') self.okbtn.clicked.connect(self.createWorkspace) self.cancelbtn = QtGui.QPushButton('Cancel') self.cancelbtn.clicked.connect(self.defaultWorkspace) #Layout self.grid.addWidget(self.note, 0,0,1,15) self.grid.addWidget(self.workspace_label, 2,1) self.grid.addWidget(self.workspace_loc,2,2,2,12) self.grid.addWidget(self.browsebtn, 2,14) self.grid.addWidget(self.okbtn, 4,13) self.grid.addWidget(self.cancelbtn, 4,14) self.setGeometry(QtCore.QRect(500,250,400,400)) self.setMaximumSize(4000, 200) self.setWindowTitle("eSim") self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) self.note.setReadOnly(True) self.setWindowIcon(QtGui.QIcon('../../images/logo.png')) self.setLayout(self.grid) self.show() def defaultWorkspace(self): print "Default location selected" self.imp_var=1 self.obj_appconfig.print_info('Default workspace selected : ' + self.obj_appconfig.default_workspace["workspace"]) self.close() var_appView.show() time.sleep(1) var_appView.splash.close() def close(self, *args, **kwargs): self.window_open_close=1 self.close_var=1 #with var_cond: # var_cond.notify() return QtGui.QWidget.close(self, *args, **kwargs) def returnWhetherClickedOrNot(self,appView): global var_appView var_appView=appView def createWorkspace(self): print "Create workspace is called" self.create_workspace = str(self.workspace_loc.text()) self.obj_appconfig.print_info('Workspace : ' + self.create_workspace) #Checking if Workspace already exist or not if os.path.isdir(self.create_workspace): print "Already present" self.obj_appconfig.default_workspace["workspace"] = self.create_workspace else: os.mkdir(self.create_workspace) self.obj_appconfig.default_workspace["workspace"] = self.create_workspace self.imp_var=1 self.close() var_appView.show() time.sleep(1) var_appView.splash.close() def browseLocation(self): print "Browse Location called" self.workspace_directory = QtGui.QFileDialog.getExistingDirectory(self, "Browse Location",os.path.expanduser("~")) print "Path file :", self.workspace_directory self.workspace_loc.setText(self.workspace_directory)
class OpenModelicaEditor(QtGui.QWidget): def __init__(self, dir=None): QtGui.QWidget.__init__(self) self.obj_validation = Validation() self.obj_appconfig = Appconfig() self.projDir = dir self.projName = os.path.basename(self.projDir) self.ngspiceNetlist = os.path.join(self.projDir,self.projName+".cir.out") self.modelicaNetlist = os.path.join(self.projDir,self.projName+".mo") self.map_json = Appconfig.modelica_map_json self.grid = QtGui.QGridLayout() self.FileEdit = QtGui.QLineEdit() self.FileEdit.setText(self.ngspiceNetlist) self.grid.addWidget(self.FileEdit, 0, 0) self.browsebtn = QtGui.QPushButton("Browse") self.browsebtn.clicked.connect(self.browseFile) self.grid.addWidget(self.browsebtn, 0, 1) self.convertbtn = QtGui.QPushButton("Convert") self.convertbtn.clicked.connect(self.callConverter) self.grid.addWidget(self.convertbtn, 2, 1) self.loadOMbtn = QtGui.QPushButton("Load OMEdit") self.loadOMbtn.clicked.connect(self.callOMEdit) self.grid.addWidget(self.loadOMbtn, 3, 1) #self.setGeometry(300, 300, 350, 300) self.setLayout(self.grid) self.show() def browseFile(self): self.ngspiceNetlist = QtGui.QFileDialog.getOpenFileName(self, 'Open Ngspice file', BROWSE_LOCATION) self.FileEdit.setText(self.ngspiceNetlist) def callConverter(self): try: ### TODO self.cmd1 = "python ../ngspicetoModelica/NgspicetoModelica.py " + self.ngspiceNetlist + ' ' + self.map_json #self.obj_workThread1 = Worker.WorkerThread(self.cmd1) #self.obj_workThread1.start() convert_process = Popen(self.cmd1, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) error_code = convert_process.stdout.read() if not error_code: self.msg = QtGui.QMessageBox() self.msg.setText("Ngspice netlist successfully converted to OpenModelica netlist") self.obj_appconfig.print_info("Ngspice netlist successfully converted to OpenModelica netlist") self.msg.exec_() else: self.err_msg = QtGui.QErrorMessage() self.err_msg.showMessage('Unable to convert NgSpice netlist to Modelica netlist. Check the netlist :'+ error_code) self.err_msg.setWindowTitle("Ngspice to Modelica conversion error") self.obj_appconfig.print_error(error_code) except Exception as e: self.msg = QtGui.QErrorMessage() self.msg.showMessage('Unable to convert NgSpice netlist to Modelica netlist. Check the netlist :'+str(e)) self.msg.setWindowTitle("Ngspice to Modelica conversion error") def callOMEdit(self): if self.obj_validation.validateTool("OMEdit"): self.cmd2 = "OMEdit " + self.modelicaNetlist self.obj_workThread2 = Worker.WorkerThread(self.cmd2) self.obj_workThread2.start() print "OMEdit called" self.obj_appconfig.print_info("OMEdit called") else: self.msg = QtGui.QMessageBox() self.msgContent = "There was an error while opening OMEdit.<br/>\ Please make sure OpenModelica is installed in your system. <br/>\ To install it on Linux : Go to <a href=https://www.openmodelica.org/download/download-linux>OpenModelica Linux</a> and install nigthly build release.<br/>\ To install it on Windows : Go to <a href=https://www.openmodelica.org/download/download-windows>OpenModelica Windows</a> and install latest version.<br/>" self.msg.setTextFormat(QtCore.Qt.RichText) self.msg.setText(self.msgContent) self.msg.setWindowTitle("Missing OpenModelica") self.obj_appconfig.print_info(self.msgContent) self.msg.exec_()
class NewProjectInfo(QtGui.QWidget): """ This class is called when User create new Project. """ def __init__(self): super(NewProjectInfo, self).__init__() self.obj_validation = Validation() self.obj_appconfig = Appconfig() def createProject(self,projName): """ This function create Project related directories and files """ #print "Create Project Called" self.projName= projName self.workspace = self.obj_appconfig.default_workspace['workspace'] #self.projName = self.projEdit.text() self.projName = str(self.projName).rstrip().lstrip() #Remove leading and trailing space self.projDir = os.path.join(self.workspace,str(self.projName)) #Validation for newProject if self.projName == "": self.reply = "NONE" else: self.reply = self.obj_validation.validateNewproj(str(self.projDir)) #Checking Validations Response if self.reply == "VALID": print "Validated : Creating project directory" #create project directory try: os.mkdir(self.projDir) self.close() self.projFile = os.path.join(self.projDir,self.projName+".proj") f = open(self.projFile,"w") except: #print "Some Thing Went Wrong" self.msg = QtGui.QErrorMessage(self) self.msg.showMessage('Unable to create project. Please make sure you have write permission on '+self.workspace) self.msg.setWindowTitle("Error Message") f.write("schematicFile " + self.projName+".sch\n") f.close() #Now Change the current working project newprojlist = [] #self.obj_appconfig = Appconfig() self.obj_appconfig.current_project['ProjectName'] = self.projDir newprojlist.append(self.projName+'.proj') self.obj_appconfig.project_explorer[self.projDir] = newprojlist self.obj_appconfig.print_info('New project created : ' + self.projName) self.obj_appconfig.print_info('Current project is : ' + self.projDir) json.dump(self.obj_appconfig.project_explorer, open(self.obj_appconfig.dictPath,'w')) return self.projDir, newprojlist elif self.reply == "CHECKEXIST": #print "Project already exist" self.msg = QtGui.QErrorMessage(self) self.msg.showMessage('The project "'+self.projName+'" already exist.Please select the different name or delete existing project') self.msg.setWindowTitle("Error Message") elif self.reply == "CHECKNAME": #print "Name is not proper" self.msg = QtGui.QErrorMessage(self) self.msg.showMessage('The project name should not contain space between them') self.msg.setWindowTitle("Error Message") elif self.reply == "NONE": #print "Empty Project Name" self.msg = QtGui.QErrorMessage(self) self.msg.showMessage('The project name cannot be empty') self.msg.setWindowTitle("Error Message") def cancelProject(self): self.close()
class Maker(QtWidgets.QWidget): # initailising the varaibles def __init__(self, filecount): print(self) QtWidgets.QWidget.__init__(self) self.count = 0 self.text = "" self.filecount = filecount self.entry_var = {} self.createMakerWidget() self.obj_Appconfig = Appconfig() verilogFile.append("") # Creating the various components of the Widget(Maker Tab) def createMakerWidget(self): self.grid = QtWidgets.QGridLayout() self.setLayout(self.grid) self.grid.addWidget(self.createoptionsBox(), 0, 0, QtCore.Qt.AlignTop) self.grid.addWidget(self.creategroup(), 1, 0, 5, 0) # self.grid.addWidget(self.creategroup(), 1, 0, 5, 0) self.show() # This function is to Add new verilog file def addverilog(self): init_path = '../../' if os.name == 'nt': init_path = '' self.verilogfile = QtCore.QDir.toNativeSeparators( QtWidgets.QFileDialog.getOpenFileName(self, "Open Verilog Directory", init_path + "home", "*v")[0]) if self.verilogfile == "": self.verilogfile = self.entry_var[0].text() if self.verilogfile == "": reply = QtWidgets.QMessageBox.critical( None, "Error Message", "<b>No Verilog File Chosen. \ Please choose a verilog file.</b>", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel) if reply == QtWidgets.QMessageBox.Ok: self.addverilog() if self.verilogfile == "": return self.obj_Appconfig.print_info('Add Verilog File Called') elif reply == QtWidgets.QMessageBox.Cancel: self.obj_Appconfig.print_info('No Verilog File Chosen') return self.text = open(self.verilogfile).read() self.entry_var[0].setText(self.verilogfile) self.entry_var[1].setText(self.text) global verilogFile verilogFile[self.filecount] = self.verilogfile if self.refreshoption in toggle_flag: toggle_flag.remove(self.refreshoption) self.observer = watchdog.observers.Observer() self.event_handler = Handler(self.verilogfile, self.refreshoption, self.observer) self.observer.schedule(self.event_handler, path=self.verilogfile, recursive=True) self.observer.start() # self.notify=notify(self.verilogfile,self.refreshoption) # self.notify.start() # open("filepath.txt","w").write(self.verilogfile) # This function is used to call refresh while # running Ngspice to Verilog Converter # (as the original one gets destroyed) def refresh_change(self): if self.refreshoption in toggle_flag: self.toggle = toggle(self.refreshoption) self.toggle.start() # It is used to refresh the file in eSim if its edited anywhere else def refresh(self): if not hasattr(self, 'verilogfile'): return self.text = open(self.verilogfile).read() self.entry_var[1].setText(self.text) print("NgVeri File: " + self.verilogfile + " Refreshed") self.obj_Appconfig.print_info("NgVeri File: " + self.verilogfile + " Refreshed") self.observer = watchdog.observers.Observer() self.event_handler = Handler(self.verilogfile, self.refreshoption, self.observer) self.observer.schedule(self.event_handler, path=self.verilogfile, recursive=True) self.observer.start() # self.notify.start() global toggle_flag if self.refreshoption in toggle_flag: toggle_flag.remove(self.refreshoption) # This function is used to save the edited file in eSim def save(self): try: wr = self.entry_var[1].toPlainText() open(self.verilogfile, "w+").write(wr) except BaseException as err: self.msg = QtWidgets.QErrorMessage(self) self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage( "Error in saving verilog file. Please check if it is chosen.") self.msg.exec_() print("Error in saving verilog file: " + str(err)) # This is used to run the makerchip-app def runmakerchip(self): init_path = '../../' if os.name == 'nt': init_path = '' try: if not makerchipTOSAccepted(True): return print("Running Makerchip IDE...........................") # self.file = open(self.verilogfile,"w") # self.file.write(self.entry_var[1].toPlainText()) # self.file.close() filename = self.verilogfile if self.verilogfile.split('.')[-1] != "tlv": reply = QtWidgets.QMessageBox.warning( None, "Do you want to automate the top module? ", "<b>Click on YES button if you want the top module \ to be added automatically. A .tlv file will be created \ in the directory of current verilog file \ and the Makerchip IDE will be running on \ this file. Otherwise click on NO button. \ To not open Makerchip IDE, click on CANCEL button. </b>\ <br><br> NOTE: Makerchip IDE requires an active \ internet connection and a browser.", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Cancel) if reply == QtWidgets.QMessageBox.Cancel: return if reply == QtWidgets.QMessageBox.Yes: code = open(self.verilogfile).read() text = code filename = '.'.join( self.verilogfile.split('.')[:-1]) + ".tlv" file = os.path.basename('.'.join( self.verilogfile.split('.')[:-1])) f = open(filename, 'w') code = code.replace(" wire ", " ") code = code.replace(" reg ", " ") vlog_ex = vlog.VerilogExtractor() vlog_mods = vlog_ex.extract_objects_from_source(code) lint_off = open(init_path + "library/tlv/lint_off.txt").readlines() string = '''\\TLV_version 1d: tl-x.org\n\\SV\n''' for item in lint_off: string += "/* verilator lint_off " + \ item.strip("\n") + "*/ " string += '''\n\n//Your Verilog/System \ Verilog Code Starts Here:\n''' + \ text + '''\n\n//Top Module Code \ Starts here:\n\tmodule top(input \ logic clk, input logic reset, input logic [31:0] cyc_cnt, \ output logic passed, output logic failed);\n''' print(file) for m in vlog_mods: if m.name.lower() == file.lower(): for p in m.ports: if str(p.name) != "clk" and str( p.name) != "reset" and str( p.name) != "cyc_cnt" and str( p.name) != "passed" and str( p.name) != "failed": string += '\t\tlogic ' + p.data_type\ + " " + p.name + ";//" + p.mode + "\n" if m.name.lower() != file.lower(): QtWidgets.QMessageBox.critical( None, "Error Message", "<b>Error: File name and module \ name are not same. Please \ ensure that they are same.</b>", QtWidgets.QMessageBox.Ok) self.obj_Appconfig.print_info( 'NgVeri stopped due to file \ name and module name not matching error') return string += "//The $random() can be replaced \ if user wants to assign values\n" for m in vlog_mods: if m.name.lower() == file.lower(): for p in m.ports: if str(p.mode) == "input" or str( p.mode) == "inout": if str(p.name) != "clk" and str( p.name) != "reset" and str( p.name) != "cyc_cnt" and str( p.name ) != "passed" and str( p.name) != "failed": string += '\t\tassign ' + p.name\ + " = " + "$random();\n" for m in vlog_mods: if m.name.lower() == file.lower(): string += '\t\t' + m.name + " " + m.name + '(' i = 0 for p in m.ports: i = i + 1 string += "." + p.name + "(" + p.name + ")" if i == len(m.ports): string += ");\n\t\n\\TLV\n//\ Add \\TLV here if desired\ \n\\SV\nendmodule\n\n" else: string += ", " f.write(string) self.process = QtCore.QProcess(self) cmd = 'makerchip ' + filename print("File: " + filename) self.process.start(cmd) print("Makerchip IDE command process pid ---------->", self.process.pid()) except BaseException as e: print(e) self.msg = QtWidgets.QErrorMessage(self) self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage("Error in running Makerchip IDE. \ Please check if verilog file is chosen.") self.msg.exec_() print("Error in running Makerchip IDE. \ Please check if verilog file is chosen.") # initial = self.read_file() # while True: # current = self.read_file() # if initial != current: # for line in current: # if line not in initial: # print(line) # initial = current # self.processfile = QtCore.QProcess(self) # self.processfile.start("python3 notify.py") # print(self.processfile.readChannel()) # This creates the buttons/options def createoptionsBox(self): self.optionsbox = QtWidgets.QGroupBox() self.optionsbox.setTitle("Select Options") self.optionsgrid = QtWidgets.QGridLayout() # self.optionsbox2 = QtWidgets.QGroupBox() # self.optionsbox2.setTitle("Note: Please save the file once edited") # self.optionsgrid2 = QtWidgets.QGridLayout() self.optionsgroupbtn = QtWidgets.QButtonGroup() self.addoptions = QtWidgets.QPushButton("Add Top Level Verilog Model") self.optionsgroupbtn.addButton(self.addoptions) self.addoptions.clicked.connect(self.addverilog) self.optionsgrid.addWidget(self.addoptions, 0, 1) # self.optionsbox.setLayout(self.optionsgrid) # self.grid.addWidget(self.creategroup(), 1, 0, 5, 0 self.refreshoption = QtWidgets.QPushButton("Refresh") self.optionsgroupbtn.addButton(self.refreshoption) self.refreshoption.clicked.connect(self.refresh) self.optionsgrid.addWidget(self.refreshoption, 0, 2) # self.optionsbox.setLayout(self.optionsgrid) # self.grid.addWidget(self.creategroup(), 1, 0, 5, 0) self.saveoption = QtWidgets.QPushButton("Save") self.optionsgroupbtn.addButton(self.saveoption) self.saveoption.clicked.connect(self.save) self.optionsgrid.addWidget(self.saveoption, 0, 3) # self.optionsbox.setLayout(self.optionsgrid) # self.grid.addWidget(self.creategroup(), 1, 0, 5, 0) self.runoptions = QtWidgets.QPushButton("Edit in Makerchip IDE") self.runoptions.setToolTip( "Requires internet connection and a browser") self.runoptions.setToolTipDuration(5000) self.optionsgroupbtn.addButton(self.runoptions) self.runoptions.clicked.connect(self.runmakerchip) self.optionsgrid.addWidget(self.runoptions, 0, 4) # self.optionsbox.setLayout(self.optionsgrid) # self.grid.addWidget(self.creategroup(), 1, 0, 5, 0) if not makerchipTOSAccepted(False): self.acceptTOS = QtWidgets.QPushButton("Accept Makerchip TOS") self.optionsgroupbtn.addButton(self.acceptTOS) self.acceptTOS.clicked.connect(lambda: makerchipTOSAccepted(True)) self.optionsgrid.addWidget(self.acceptTOS, 0, 5) # self.optionsbox.setLayout(self.optionsgrid) # self.grid.addWidget(self.creategroup(), 1, 0, 5, 0) self.optionsbox.setLayout(self.optionsgrid) return self.optionsbox # This function adds the other parts of widget like text box def creategroup(self): self.trbox = QtWidgets.QGroupBox() self.trbox.setTitle(".tlv file") # self.trbox.setDisabled(True) # self.trbox.setVisible(False) self.trgrid = QtWidgets.QGridLayout() self.trbox.setLayout(self.trgrid) self.start = QtWidgets.QLabel("Path to .tlv file") self.trgrid.addWidget(self.start, 1, 0) self.count = 0 self.entry_var[self.count] = QtWidgets.QLabel() self.trgrid.addWidget(self.entry_var[self.count], 1, 1) self.entry_var[self.count].setMaximumWidth(1000) self.count += 1 # CSS self.trbox.setStyleSheet(" \ QGroupBox { border: 1px solid gray; border-radius: \ 9px; margin-top: 0.5em; } \ QGroupBox::title { subcontrol-origin: margin; left: \ 10px; padding: 0 3px 0 3px; } \ ") self.start = QtWidgets.QLabel(".tlv code") # self.start2 = QtWidgets.QLabel("Note: \ # Please save the file once edited") # self.start2.setStyleSheet("background-color: red") self.trgrid.addWidget(self.start, 2, 0) # self.trgrid.addWidget(self.start2, 3,0) self.entry_var[self.count] = QtWidgets.QTextEdit() self.trgrid.addWidget(self.entry_var[self.count], 2, 1) self.entry_var[self.count].setMaximumWidth(1000) self.entry_var[self.count].setMaximumHeight(1000) # self.entry_var[self.count].textChanged.connect(self.save) self.count += 1 # CSS self.trbox.setStyleSheet(" \ QGroupBox { border: 1px solid gray; border-radius: \ 9px; margin-top: 0.5em; } \ QGroupBox::title { subcontrol-origin: margin; left: \ 10px; padding: 0 3px 0 3px; } \ ") return self.trbox
class Application(QtGui.QMainWindow): """This class initializes all objects used in this file.""" global project_name def __init__(self, *args): """Initialize main Application window.""" # Calling __init__ of super class QtGui.QMainWindow.__init__(self, *args) # Flag for mode of operation. Default is set to offline mode. self.online_flag = False # Creating require Object self.obj_workspace = Workspace.Workspace() self.obj_Mainview = MainView() self.obj_kicad = Kicad(self.obj_Mainview.obj_dockarea) self.obj_appconfig = Appconfig() self.obj_validation = Validation() # Initialize all widget self.setCentralWidget(self.obj_Mainview) self.initToolBar() self.setGeometry(self.obj_appconfig._app_xpos, self.obj_appconfig._app_ypos, self.obj_appconfig._app_width, self.obj_appconfig._app_heigth) self.setWindowTitle(self.obj_appconfig._APPLICATION) self.showMaximized() self.setWindowIcon(QtGui.QIcon('images/logo.png')) self.systemTrayIcon = QtGui.QSystemTrayIcon(self) self.systemTrayIcon.setIcon(QtGui.QIcon('images/logo.png')) self.systemTrayIcon.setVisible(True) def initToolBar(self): """ This function initializes Tool Bars. It setups the icons, short-cuts and defining functonality for: - Top-tool-bar (New project, Open project, Close project, \ Mode switch, Help option) - Left-tool-bar (Open Schematic, Convert KiCad to NgSpice, \ Simuation, Model Editor, Subcircuit, NGHDL, Modelica \ Converter, OM Optimisation) """ # Top Tool bar self.newproj = QtGui.QAction(QtGui.QIcon('images/newProject.png'), '<b>New Project</b>', self) self.newproj.setShortcut('Ctrl+N') self.newproj.triggered.connect(self.new_project) self.openproj = QtGui.QAction(QtGui.QIcon('images/openProject.png'), '<b>Open Project</b>', self) self.openproj.setShortcut('Ctrl+O') self.openproj.triggered.connect(self.open_project) self.closeproj = QtGui.QAction(QtGui.QIcon('images/closeProject.png'), '<b>Close Project</b>', self) self.closeproj.setShortcut('Ctrl+X') self.closeproj.triggered.connect(self.close_project) self.wrkspce = QtGui.QAction(QtGui.QIcon('images/workspace.ico'), '<b>Change Workspace</b>', self) self.wrkspce.setShortcut('Ctrl+W') self.wrkspce.triggered.connect(self.change_workspace) self.switchmode = None self.validate_mode() if self.online_flag is True: self.switchmode = QtGui.QAction(QtGui.QIcon('images/online.png'), '<b>Go Offline</b>', self) elif self.online_flag is False: self.switchmode = QtGui.QAction(QtGui.QIcon('images/offline.png'), '<b>Go Online</b>', self) elif self.online_flag is None: self.switchmode = QtGui.QAction( QtGui.QIcon('images/disable.png'), '<b>Mode switching has been disabled. ' + 'Default mode set to offline</b>', self) self.switchmode.setEnabled(False) self.switchmode.setShortcut('Ctrl+G') self.switchmode.triggered.connect(self.change_mode) self.helpfile = QtGui.QAction(QtGui.QIcon('images/helpProject.png'), '<b>Help</b>', self) self.helpfile.setShortcut('Ctrl+H') self.helpfile.triggered.connect(self.help_project) self.topToolbar = self.addToolBar('Top Tool Bar') self.topToolbar.addAction(self.newproj) self.topToolbar.addAction(self.openproj) self.topToolbar.addAction(self.closeproj) self.topToolbar.addAction(self.wrkspce) self.topToolbar.addAction(self.switchmode) self.topToolbar.addAction(self.helpfile) # This part is setting fossee logo to the right # corner in the application window. self.spacer = QtGui.QWidget() self.spacer.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) self.topToolbar.addWidget(self.spacer) self.logo = QtGui.QLabel() self.logopic = QtGui.QPixmap( os.path.join(os.path.abspath(''), 'images', 'fosseeLogo.png')) self.logopic = self.logopic.scaled(QSize(150, 150), QtCore.Qt.KeepAspectRatio) self.logo.setPixmap(self.logopic) self.logo.setStyleSheet("padding:0 15px 0 0;") self.topToolbar.addWidget(self.logo) # Left Tool bar Action Widget self.kicad = QtGui.QAction(QtGui.QIcon('images/kicad.png'), '<b>Open Schematic</b>', self) self.kicad.triggered.connect(self.obj_kicad.openSchematic) self.conversion = QtGui.QAction(QtGui.QIcon('images/ki-ng.png'), '<b>Convert Kicad to Ngspice</b>', self) self.conversion.triggered.connect(self.obj_kicad.openKicadToNgspice) self.ngspice = QtGui.QAction(QtGui.QIcon('images/ngspice.png'), '<b>Simulation</b>', self) self.ngspice.triggered.connect(self.open_ngspice) self.model = QtGui.QAction(QtGui.QIcon('images/model.png'), '<b>Model Editor</b>', self) self.model.triggered.connect(self.open_modelEditor) self.subcircuit = QtGui.QAction(QtGui.QIcon('images/subckt.png'), '<b>Subcircuit</b>', self) self.subcircuit.triggered.connect(self.open_subcircuit) self.nghdl = QtGui.QAction(QtGui.QIcon('images/nghdl.png'), '<b>Nghdl</b>', self) self.nghdl.triggered.connect(self.open_nghdl) self.omedit = QtGui.QAction(QtGui.QIcon('images/omedit.png'), '<b>Modelica Converter</b>', self) self.omedit.triggered.connect(self.open_OMedit) self.omoptim = QtGui.QAction(QtGui.QIcon('images/omoptim.png'), '<b>OM Optimisation</b>', self) self.omoptim.triggered.connect(self.open_OMoptim) # Adding Action Widget to tool bar self.lefttoolbar = QtGui.QToolBar('Left ToolBar') self.addToolBar(QtCore.Qt.LeftToolBarArea, self.lefttoolbar) self.lefttoolbar.addAction(self.kicad) self.lefttoolbar.addAction(self.conversion) self.lefttoolbar.addAction(self.ngspice) self.lefttoolbar.addAction(self.model) self.lefttoolbar.addAction(self.subcircuit) self.lefttoolbar.addAction(self.nghdl) self.lefttoolbar.addAction(self.omedit) self.lefttoolbar.addAction(self.omoptim) self.lefttoolbar.setOrientation(QtCore.Qt.Vertical) self.lefttoolbar.setIconSize(QSize(40, 40)) def closeEvent(self, event): ''' This function closes the ongoing program (process). When exit button is pressed a Message box pops out with \ exit message and buttons 'Yes', 'No'. 1. If 'Yes' is pressed: - check that program (process) in procThread_list \ (a list made in Appconfig.py): - if available it terminates that program. - if the program (process) is not available, \ then check it in process_obj (a list made in \ Appconfig.py) and if found, it closes the program. 2. If 'No' is pressed: - the program just continues as it was doing earlier. ''' exit_msg = "Are you sure you want to exit the program?" exit_msg += " All unsaved data will be lost." reply = QtGui.QMessageBox.question(self, 'Message', exit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: for proc in self.obj_appconfig.procThread_list: try: proc.terminate() except BaseException: pass try: for process_object in self.obj_appconfig.process_obj: try: process_object.close() except BaseException: pass except BaseException: pass # Check if "Open project" and "New project" window is open. # If yes, just close it when application is closed. try: self.project.close() except BaseException: pass event.accept() self.systemTrayIcon.showMessage('Exit', 'eSim is Closed.') elif reply == QtGui.QMessageBox.No: event.ignore() def new_project(self): """This function call New Project Info class.""" text, ok = QtGui.QInputDialog.getText(self, 'New Project Info', 'Enter Project Name:') if ok: self.projname = (str(text)) self.project = NewProjectInfo() directory, filelist = self.project.createProject(self.projname) self.obj_Mainview.obj_projectExplorer.addTreeNode( directory, filelist) else: print("No new project created") self.obj_appconfig.print_info('No new project created') try: self.obj_appconfig.print_info( 'Current project is : ' + self.obj_appconfig.current_project["ProjectName"]) except BaseException: pass def open_project(self): """This project call Open Project Info class.""" print("Function : Open Project") self.project = OpenProjectInfo() try: directory, filelist = self.project.body() self.obj_Mainview.obj_projectExplorer.addTreeNode( directory, filelist) except BaseException: pass def close_project(self): """ This function closes the saved project. It first checks whether project (file) is present in list. - If present: - it first kills that process-id. - closes that file. - Shows message "Current project <path_to_file> is closed" - If not present: pass """ print("Function : Close Project") current_project = self.obj_appconfig.current_project['ProjectName'] if current_project is None: pass else: temp = self.obj_appconfig.current_project['ProjectName'] for pid in self.obj_appconfig.proc_dict[temp]: try: os.kill(pid, 9) except BaseException: pass self.obj_Mainview.obj_dockarea.closeDock() self.obj_appconfig.current_project['ProjectName'] = None self.systemTrayIcon.showMessage( 'Close', 'Current project ' + os.path.basename(current_project) + ' is Closed.') def change_workspace(self): """ This function call changes Workspace """ print("Function : Change Workspace") self.obj_workspace.returnWhetherClickedOrNot(self) self.hide() self.obj_workspace.show() def validate_mode(self): """ This functions checks whether proper fp-lib-table* files are \ available or not. If not, then move appropriate files from \ library/supportFiles folder and set `self.online_flag` accordingly. @params @return None """ remove = False if self.obj_appconfig.kicad_path is not None: if not os.path.exists(self.obj_appconfig.kicad_path + "/fp-lib-table"): remove = True elif os.path.exists(self.obj_appconfig.kicad_path + "/fp-lib-table-offline"): if os.path.exists(self.obj_appconfig.kicad_path + "/fp-lib-table-online"): remove = True os.remove(self.obj_appconfig.kicad_path + "/fp-lib-table") else: self.online_flag = True else: if not os.path.exists(self.obj_appconfig.kicad_path + "/fp-lib-table-online"): remove = True os.remove(self.obj_appconfig.kicad_path + "/fp-lib-table") else: self.online_flag = False if remove: # Remove invalid files if os.path.exists(self.obj_appconfig.kicad_path + "/fp-lib-table-offline"): os.remove(self.obj_appconfig.kicad_path + "/fp-lib-table-offline") if os.path.exists(self.obj_appconfig.kicad_path + "/fp-lib-table-online"): os.remove(self.obj_appconfig.kicad_path + "/fp-lib-table-online") # Restore original files shutil.copy('library/supportFiles/fp-lib-table-online', self.obj_appconfig.kicad_path + "/") shutil.copy('library/supportFiles/fp-lib-table', self.obj_appconfig.kicad_path + "/") self.online_flag = False else: self.online_flag = None def change_mode(self): """ - This function is used for changing mode of operation for KiCad. \ - There are three modes of operation : - online - offline - disable - If none of the KiCad tools (associated with eSim) are \ open, then validate this mode by calling the function \ `validate_mode` and depending on online_flag, swap \ appropriate fp-lib-table files. - If any of the KiCad tools (associated with eSim) is open, \ then ask user to close all these tools. - If `online_flag` is `None`, then disable this feature. @params @return None """ if not self.obj_kicad.check_open_schematic(): self.validate_mode() if self.online_flag is True: os.rename( self.obj_appconfig.kicad_path + "/fp-lib-table", self.obj_appconfig.kicad_path + "/fp-lib-table-online") os.rename( self.obj_appconfig.kicad_path + "/fp-lib-table-offline", self.obj_appconfig.kicad_path + "/fp-lib-table") self.switchmode.setIcon(QtGui.QIcon('images/offline.png')) self.switchmode.setText('<b>Go Online</b>') self.switchmode.setEnabled(True) self.online_flag = False elif self.online_flag is False: os.rename( self.obj_appconfig.kicad_path + "/fp-lib-table", self.obj_appconfig.kicad_path + "/fp-lib-table-offline") os.rename( self.obj_appconfig.kicad_path + "/fp-lib-table-online", self.obj_appconfig.kicad_path + "/fp-lib-table") self.switchmode.setIcon(QtGui.QIcon('images/online.png')) self.switchmode.setText('<b>Go Offline</b>') self.switchmode.setEnabled(True) self.online_flag = True elif self.online_flag is None: self.switchmode.setIcon(QtGui.QIcon('images/disable.png')) self.switchmode.setText( '<b>Mode switching has been ' + 'disabled. Default mode set to offline</b>.') self.switchmode.setEnabled(False) else: self.msg = QtGui.QErrorMessage() self.msg.setWindowTitle("Error Message") self.msg.setModal(True) self.msg.showMessage('Please save and close all the Kicad ' + 'windows first, then change the mode') self.msg.exec_() def help_project(self): """ This function opens usermanual in dockarea. - It prints the message ""Function : Help"" - Uses print_info() method of class Appconfig from Configuration/Appconfig.py file. - Call method usermanual() from ./DockArea.py. """ print("Function : Help") self.obj_appconfig.print_info('Help is called') print("Current Project is : ", self.obj_appconfig.current_project) self.obj_Mainview.obj_dockarea.usermanual() def open_ngspice(self): """This Function execute ngspice on current project.""" self.projDir = self.obj_appconfig.current_project["ProjectName"] if self.projDir is not None: self.obj_Mainview.obj_dockarea.ngspiceEditor(self.projDir) currTime = time.time() count = 0 while True: try: st = os.stat(os.path.join(self.projDir, "plot_data_i.txt")) if st.st_mtime >= currTime: break except Exception: pass time.sleep(0.5) # Fail Safe ===> count += 1 if count >= 10: raise Exception( "Ngspice taking too long for simulation. " "Check netlist file to change simulation parameters.") # Calling Python Plotting try: self.obj_Mainview.obj_dockarea.plottingEditor() except Exception as e: self.msg = QtGui.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage( 'Error while opening python plotting Editor.' ' Please look at console for more details.') self.msg.exec_() print("Exception Message:", str(e)) self.obj_appconfig.print_error('Exception Message : ' + str(e)) else: self.msg = QtGui.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage( 'Please select the project first.' ' You can either create new project or open existing project') self.msg.exec_() def open_subcircuit(self): """ This function opens 'subcircuit' option in left-tool-bar. When 'subcircuit' icon is clicked wich is present in left-tool-bar of main page: - Meassge shown on screen "Subcircuit editor is called". - 'subcircuiteditor()' function is called using object 'obj_dockarea' of class 'Mainview'. """ print("Function : Subcircuit editor") self.obj_appconfig.print_info('Subcircuit editor is called') self.obj_Mainview.obj_dockarea.subcircuiteditor() def open_nghdl(self): """ This function calls NGHDL option in left-tool-bar. It uses validateTool() method from Validation.py: - If 'nghdl' is present in executables list then it passes command 'nghdl -e' to WorkerThread class of Worker.py. - If 'nghdl' is not present, then it shows error message. """ print("Function : NGHDL") self.obj_appconfig.print_info('NGHDL is called') if self.obj_validation.validateTool('nghdl'): self.cmd = 'nghdl -e' self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() else: self.msg = QtGui.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle('NGHDL Error') self.msg.showMessage('Error while opening NGHDL. ' + 'Please make sure it is installed') self.obj_appconfig.print_error('Error while opening NGHDL. ' + 'Please make sure it is installed') self.msg.exec_() def open_modelEditor(self): """ This function opens model editor option in left-tool-bar. When model editor icon is clicked which is present in left-tool-bar of main page: - Meassge shown on screen "Model editor is called". - 'modeleditor()' function is called using object 'obj_dockarea' of class 'Mainview'. """ print("Function : Model editor") self.obj_appconfig.print_info('Model editor is called') self.obj_Mainview.obj_dockarea.modelEditor() def open_OMedit(self): """ This function calls ngspice to OMEdit converter and then launch OMEdit. """ self.obj_appconfig.print_info('OMEdit is called') self.projDir = self.obj_appconfig.current_project["ProjectName"] if self.projDir is not None: if self.obj_validation.validateCirOut(self.projDir): self.projName = os.path.basename(self.projDir) self.ngspiceNetlist = os.path.join(self.projDir, self.projName + ".cir.out") self.modelicaNetlist = os.path.join(self.projDir, self.projName + ".mo") """ try: # Creating a command for Ngspice to Modelica converter self.cmd1 = " python3 ../ngspicetoModelica/NgspicetoModelica.py "\ +self.ngspiceNetlist self.obj_workThread1 = Worker.WorkerThread(self.cmd1) self.obj_workThread1.start() if self.obj_validation.validateTool("OMEdit"): # Creating command to run OMEdit self.cmd2 = "OMEdit "+self.modelicaNetlist self.obj_workThread2 = Worker.WorkerThread(self.cmd2) self.obj_workThread2.start() else: self.msg = QtGui.QMessageBox() self.msgContent = "There was an error while opening OMEdit.<br/>\ Please make sure OpenModelica is installed in your\ system. <br/>\ To install it on Linux : Go to\ <a href=https://www.openmodelica.org/download/\ download-linux>OpenModelica Linux</a> and \ install nigthly build release.<br/>\ To install it on Windows : Go to\ <a href=https://www.openmodelica.org/download/\ download-windows>OpenModelica Windows</a>\ and install latest version.<br/>" self.msg.setTextFormat(QtCore.Qt.RichText) self.msg.setText(self.msgContent) self.msg.setWindowTitle("Missing OpenModelica") self.obj_appconfig.print_info(self.msgContent) self.msg.exec_() except Exception as e: self.msg = QtGui.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle( "Ngspice to Modelica conversion error") self.msg.showMessage( 'Unable to convert NgSpice netlist to\ Modelica netlist :'+str(e)) self.msg.exec_() self.obj_appconfig.print_error(str(e)) """ self.obj_Mainview.obj_dockarea.modelicaEditor(self.projDir) else: self.msg = QtGui.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle("Missing Ngspice netlist") self.msg.showMessage( 'Current project does not contain any Ngspice file. ' + 'Please create Ngspice file with extension .cir.out') self.msg.exec_() else: self.msg = QtGui.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage( 'Please select the project first. ' + 'You can either create a new project or open existing project') self.exec_() def open_OMoptim(self): """ This function uses validateTool() method from Validation.py: - If 'OMOptim' is present in executables list then it passes command 'OMOptim' to WorkerThread class of Worker.py - If 'OMOptim' is not present, then it shows error message with link to download it on Linux and Windows. """ print("Function : OMOptim") self.obj_appconfig.print_info('OMOptim is called') # Check if OMOptim is installed if self.obj_validation.validateTool("OMOptim"): # Creating a command to run self.cmd = "OMOptim" self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() else: self.msg = QtGui.QMessageBox() self.msgContent = ( "There was an error while opening OMOptim.<br/>" "Please make sure OpenModelica is installed in your" " system.<br/>" "To install it on Linux : Go to <a href=" "https://www.openmodelica.org/download/download-linux" ">OpenModelica Linux</a> and install nightly build" " release.<br/>" "To install it on Windows : Go to <a href=" "https://www.openmodelica.org/download/download-windows" ">OpenModelica Windows</a> and install latest version.<br/>") self.msg.setTextFormat(QtCore.Qt.RichText) self.msg.setText(self.msgContent) self.msg.setWindowTitle("Error Message") self.obj_appconfig.print_info(self.msgContent) self.msg.exec_()
class Kicad: """ This class called the Kicad Schematic,KicadtoNgspice Converter,Layout editor and Footprint Editor Initialise validation, appconfig and dockarea @params :dockarea => passed from DockArea in frontEnd folder, consists of all functions for dockarea @return """ def __init__(self, dockarea): self.obj_validation = Validation.Validation() self.obj_appconfig = Appconfig() self.obj_dockarea = dockarea self.obj_workThread = Worker.WorkerThread(None) def check_open_schematic(self): """ This function checks if any of the project's schematic is open or not @params @return True => If the project's schematic is not open False => If the project's schematic is open """ if self.obj_workThread: procList = self.obj_workThread.get_proc_threads()[:] if procList: for proc in procList: if proc.poll() is None: return True else: self.obj_workThread.get_proc_threads().remove(proc) return False def openSchematic(self): """ This function create command to open Kicad schematic after appropriate validation checks @params @return """ print("Function : Open Kicad Schematic") self.projDir = self.obj_appconfig.current_project["ProjectName"] try: self.obj_appconfig.print_info( 'Kicad Schematic is called for project ' + self.projDir) except BaseException: pass # Validating if current project is available or not if self.obj_validation.validateKicad(self.projDir): self.projName = os.path.basename(self.projDir) self.project = os.path.join(self.projDir, self.projName) # Creating a command to run self.cmd = "eeschema " + self.project + ".sch " self.obj_workThread.args = self.cmd self.obj_workThread.start() else: self.msg = QtWidgets.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage( 'Please select the project first. You can either ' + 'create new project or open an existing project') self.msg.exec_() self.obj_appconfig.print_warning( 'Please select the project first. You can either ' + 'create new project or open an existing project') ''' # Commenting as it is no longer needed as PCB and Layout will open from # eeschema def openFootprint(self): """ This function create command to open Footprint editor """ print "Kicad Foot print Editor called" self.projDir = self.obj_appconfig.current_project["ProjectName"] try: self.obj_appconfig.print_info('Kicad Footprint Editor is called' + 'for project : ' + self.projDir) except: pass #Validating if current project is available or not if self.obj_validation.validateKicad(self.projDir): #print "calling Kicad FootPrint Editor ",self.projDir self.projName = os.path.basename(self.projDir) self.project = os.path.join(self.projDir,self.projName) #Creating a command to run self.cmd = "cvpcb "+self.project+".net " self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() else: self.msg = QtWidgets.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage('Please select the project first. You can' + 'either create new project or open an existing project') self.msg.exec_() self.obj_appconfig.print_warning('Please select the project' + 'first. You can either create new project or open an existing' + 'project') def openLayout(self): """ This function create command to open Layout editor """ print "Kicad Layout is called" self.projDir = self.obj_appconfig.current_project["ProjectName"] try: self.obj_appconfig.print_info('PCB Layout is called for project : ' + self.projDir) except: pass #Validating if current project is available or not if self.obj_validation.validateKicad(self.projDir): print "calling Kicad schematic ",self.projDir self.projName = os.path.basename(self.projDir) self.project = os.path.join(self.projDir,self.projName) #Creating a command to run self.cmd = "pcbnew "+self.project+".net " self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() else: self.msg = QtWidgets.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage('Please select the project first. You can' + 'either create new project or open an existing project') self.msg.exec_() self.obj_appconfig.print_warning('Please select the project' + 'first. You can either create new project or open an existing' + 'project') ''' def openKicadToNgspice(self): """ This function create command to validate and then call KicadToNgSPice converter from DockArea file @params @return """ print("Function: Open Kicad to Ngspice Converter") self.projDir = self.obj_appconfig.current_project["ProjectName"] try: self.obj_appconfig.print_info( 'Kicad to Ngspice Conversion is called') self.obj_appconfig.print_info('Current Project is ' + self.projDir) except BaseException: pass # Validating if current project is available or not if self.obj_validation.validateKicad(self.projDir): # Checking if project has .cir file or not if self.obj_validation.validateCir(self.projDir): self.projName = os.path.basename(self.projDir) self.project = os.path.join(self.projDir, self.projName) # Creating a command to run """ self.cmd = ("python3 ../kicadtoNgspice/KicadtoNgspice.py " + "self.project+".cir ") self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() """ var = self.project + ".cir" self.obj_dockarea.kicadToNgspiceEditor(var) else: self.msg = QtWidgets.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage( 'The project does not contain any Kicad netlist file ' + 'for conversion.') self.obj_appconfig.print_error( 'The project does not contain any Kicad netlist file ' + 'for conversion.') self.msg.exec_() else: self.msg = QtWidgets.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage( 'Please select the project first. You can either ' + 'create new project or open an existing project') self.msg.exec_() self.obj_appconfig.print_warning( 'Please select the project first. You can either ' + 'create new project or open an existing project')
class Application(QtGui.QMainWindow): global project_name """ Its our main window of application """ def __init__(self,*args): """ Initialize main Application window """ #Calling __init__ of super class QtGui.QMainWindow.__init__(self,*args) #Creating require Object self.obj_workspace = Workspace.Workspace() self.obj_Mainview = MainView() self.obj_kicad = Kicad(self.obj_Mainview.obj_dockarea) self.obj_appconfig = Appconfig() #Initialize all widget self.setCentralWidget(self.obj_Mainview) self.initToolBar() self.setGeometry(self.obj_appconfig._app_xpos, self.obj_appconfig._app_ypos, self.obj_appconfig._app_width, self.obj_appconfig._app_heigth) self.setWindowTitle(self.obj_appconfig._APPLICATION) self.showMaximized() self.setWindowIcon(QtGui.QIcon('../../images/logo.png')) #self.show() def initToolBar(self): """ This function initialize Tool Bar """ #Top Tool bar self.newproj = QtGui.QAction(QtGui.QIcon('../../images/newProject.png'),'<b>New Project</b>',self) self.newproj.setShortcut('Ctrl+N') self.newproj.triggered.connect(self.new_project) #self.newproj.connect(self.newproj,QtCore.SIGNAL('triggered()'),self,QtCore.SLOT(self.new_project())) self.openproj = QtGui.QAction(QtGui.QIcon('../../images/openProject.png'),'<b>Open Project</b>',self) self.openproj.setShortcut('Ctrl+O') self.openproj.triggered.connect(self.open_project) self.exitproj = QtGui.QAction(QtGui.QIcon('../../images/closeProject.png'),'<b>Exit</b>',self) self.exitproj.setShortcut('Ctrl+X') self.exitproj.triggered.connect(self.exit_project) self.helpfile = QtGui.QAction(QtGui.QIcon('../../images/helpProject.png'),'<b>Help</b>',self) self.helpfile.setShortcut('Ctrl+H') self.helpfile.triggered.connect(self.help_project) self.topToolbar = self.addToolBar('Top Tool Bar') self.topToolbar.addAction(self.newproj) self.topToolbar.addAction(self.openproj) self.topToolbar.addAction(self.exitproj) self.topToolbar.addAction(self.helpfile) self.spacer = QtGui.QWidget() self.spacer.setSizePolicy(QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Expanding) self.topToolbar.addWidget(self.spacer) self.logo = QtGui.QLabel() self.logopic = QtGui.QPixmap(os.path.join(os.path.abspath('../..'),'images','fosseeLogo.png')) self.logopic = self.logopic.scaled(QSize(150,150),QtCore.Qt.KeepAspectRatio) self.logo.setPixmap(self.logopic) self.logo.setStyleSheet("padding:0 15px 0 0;") self.topToolbar.addWidget(self.logo) #Left Tool bar Action Widget self.kicad = QtGui.QAction(QtGui.QIcon('../../images/kicad.png'),'<b>Open Schematic</b>',self) self.kicad.triggered.connect(self.obj_kicad.openSchematic) self.conversion = QtGui.QAction(QtGui.QIcon('../../images/ki-ng.png'),'<b>Convert Kicad to Ngspice</b>',self) self.conversion.triggered.connect(self.obj_kicad.openKicadToNgspice) self.ngspice = QtGui.QAction(QtGui.QIcon('../../images/ngspice.png'), '<b>Simulation</b>', self) self.ngspice.triggered.connect(self.open_ngspice) self.footprint = QtGui.QAction(QtGui.QIcon('../../images/footprint.png'),'<b>Footprint Editor</b>',self) self.footprint.triggered.connect(self.obj_kicad.openFootprint) self.pcb = QtGui.QAction(QtGui.QIcon('../../images/pcb.png'),'<b>PCB Layout</b>',self) self.pcb.triggered.connect(self.obj_kicad.openLayout) self.model = QtGui.QAction(QtGui.QIcon('../../images/model.png'),'<b>Model Editor</b>',self) self.model.triggered.connect(self.open_modelEditor) self.subcircuit=QtGui.QAction(QtGui.QIcon('../../images/subckt.png'),'<b>Subcircuit</b>',self) self.subcircuit.triggered.connect(self.open_subcircuit) #Adding Action Widget to tool bar self.lefttoolbar = QtGui.QToolBar('Left ToolBar') self.addToolBar(QtCore.Qt.LeftToolBarArea, self.lefttoolbar) self.lefttoolbar.addAction(self.kicad) self.lefttoolbar.addAction(self.conversion) self.lefttoolbar.addAction(self.ngspice) self.lefttoolbar.addAction(self.footprint) self.lefttoolbar.addAction(self.pcb) self.lefttoolbar.addAction(self.model) self.lefttoolbar.addAction(self.subcircuit) self.lefttoolbar.setOrientation(QtCore.Qt.Vertical) self.lefttoolbar.setIconSize(QSize(40,40)) def new_project(self): """ This function call New Project Info class. """ text, ok = QtGui.QInputDialog.getText(self, 'New Project Info','Enter Project Name:') if ok: self.projname = (str(text)) self.project = NewProjectInfo() directory, filelist =self.project.createProject(self.projname) self.obj_Mainview.obj_projectExplorer.addTreeNode(directory, filelist) else: print "No project created" self.obj_appconfig.print_info('No new project created') try: self.obj_appconfig.print_info('Current project is : ' + self.obj_appconfig.current_project["ProjectName"]) except: pass def open_project(self): """ This project call Open Project Info class """ print "Open Project called" self.project = OpenProjectInfo() try: directory, filelist = self.project.body() self.obj_Mainview.obj_projectExplorer.addTreeNode(directory, filelist) except: pass def open_ngspice(self): """ This Function execute ngspice on current project """ self.projDir = self.obj_appconfig.current_project["ProjectName"] if self.projDir != None: self.obj_Mainview.obj_dockarea.ngspiceEditor(self.projDir) time.sleep(2) #Need permanent solution #Calling Python Plotting try: self.obj_Mainview.obj_dockarea.plottingEditor() except Exception as e: self.msg = QtGui.QErrorMessage(None) self.msg.showMessage('Error while opening python plotting Editor.') print "Exception:",str(e) self.obj_appconfig.print_error('Exception generated : ' + str(e)) self.msg.setWindowTitle("Error Message") else: self.msg = QtGui.QErrorMessage() self.msg.showMessage('Please select the project first. You can either create new project or open existing project') self.msg.setWindowTitle("Error Message") def open_subcircuit(self): print "Subcircuit editor is called" self.obj_appconfig.print_info('Subcircuit editor is called') self.obj_Mainview.obj_dockarea.subcircuiteditor() def exit_project(self): print "Exit Project called" for proc in self.obj_appconfig.procThread_list: try: proc.terminate() except: pass ##Just checking if open and New window is open. If yes just close it when application is closed try: self.project.close() except: pass self.close() def help_project(self): print "Help is called" self.obj_appconfig.print_info('Help is called') print "Current Project : ",self.obj_appconfig.current_project #self.obj_appconfig.print_info('Current Project : ' + self.obj_appconfig.current_project['ProjectName']) #self.obj_Mainview.obj_dockarea.plottingEditor() def open_modelEditor(self): print "model editor is called" self.obj_appconfig.print_info('model editor is called') self.obj_Mainview.obj_dockarea.modelEditor() """ def open_kicadToNgspice(self): print "kicadToNgspice is called" self.obj_appconfig.print_info('kicadToNgspice is called') self.obj_Mainview.obj_dockarea.kicadToNgspiceEditor()""" def testing(self): print "Success hit kicad button"
class Workspace(QtWidgets.QWidget): """ This class creates UI for WorkSpace selection window. - This window contains text area to select location of your choice \ or browse location for workspace area. - By default workspace is set in ~/eSim-Workspace. - This workspace area contains all the projects made by user. """ def __init__(self, parent=None): super(Workspace, self).__init__() self.obj_appconfig = Appconfig() # Initializing Workspace directory for project self.initWorkspace() def initWorkspace(self): self.mainwindow = QtWidgets.QVBoxLayout() self.split = QtWidgets.QSplitter() self.split.setOrientation(QtCore.Qt.Vertical) self.grid = QtWidgets.QGridLayout() self.note = QtWidgets.QTextEdit(self) self.note.append(self.obj_appconfig.workspace_text) self.note.setReadOnly(True) self.workspace_label = QtWidgets.QLabel(self) self.workspace_label.setText("Workspace:") self.workspace_loc = QtWidgets.QLineEdit(self) self.workspace_loc.setText(self.obj_appconfig.home) # Buttons self.browsebtn = QtWidgets.QPushButton('Browse') self.browsebtn.clicked.connect(self.browseLocation) self.okbtn = QtWidgets.QPushButton('OK') self.okbtn.clicked.connect(self.createWorkspace) self.cancelbtn = QtWidgets.QPushButton('Cancel') self.cancelbtn.clicked.connect(self.defaultWorkspace) # Checkbox self.chkbox = QtWidgets.QCheckBox('Set Default', self) self.chkbox.setCheckState(int(self.obj_appconfig.workspace_check)) # Layout self.grid.addWidget(self.note, 0, 0, 1, 15) self.grid.addWidget(self.workspace_label, 2, 1) self.grid.addWidget(self.workspace_loc, 2, 2, 2, 12) self.grid.addWidget(self.browsebtn, 2, 14) self.grid.addWidget(self.chkbox, 4, 2) self.grid.addWidget(self.okbtn, 5, 13) self.grid.addWidget(self.cancelbtn, 5, 14) self.setGeometry(QtCore.QRect(500, 250, 400, 400)) self.setMaximumSize(4000, 200) self.setWindowTitle("eSim") self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) self.setWindowModality(2) init_path = '../../' if os.name == 'nt': init_path = '' self.setWindowIcon(QtGui.QIcon(init_path + 'images/logo.png')) self.setLayout(self.grid) def defaultWorkspace(self): print("Default workspace selected : " + self.obj_appconfig.default_workspace["workspace"]) self.imp_var = 1 self.obj_appconfig.print_info( 'Default workspace selected : ' + self.obj_appconfig.default_workspace["workspace"]) self.close() var_appView.obj_Mainview.obj_projectExplorer.treewidget.clear() for parent, children in self.obj_appconfig.project_explorer.items(): var_appView.obj_Mainview.obj_projectExplorer.addTreeNode( parent, children) time.sleep(1.5) var_appView.splash.close() var_appView.show() def close(self, *args, **kwargs): self.window_open_close = 1 self.close_var = 1 return QtWidgets.QWidget.close(self, *args, **kwargs) def returnWhetherClickedOrNot(self, appView): global var_appView var_appView = appView def createWorkspace(self): print("Function : Create workspace") self.obj_appconfig.workspace_check = self.chkbox.checkState() print(self.workspace_loc.text()) file = open( os.path.join(os.path.expanduser("~"), ".esim/workspace.txt"), 'w') file.writelines( str(self.obj_appconfig.workspace_check) + " " + self.workspace_loc.text()) file.close() self.create_workspace = str(self.workspace_loc.text()) self.obj_appconfig.print_info('Workspace : ' + self.create_workspace) # Checking if Workspace already exist or not if os.path.isdir(self.create_workspace): self.obj_appconfig.default_workspace["workspace"] \ = self.create_workspace else: os.mkdir(self.create_workspace) self.obj_appconfig.default_workspace["workspace"] \ = self.create_workspace self.imp_var = 1 self.close() self.obj_appconfig.dictPath["path"] = os.path.join( self.obj_appconfig.default_workspace["workspace"], ".projectExplorer.txt") try: self.obj_appconfig.project_explorer = json.load( open(self.obj_appconfig.dictPath["path"])) except BaseException: self.obj_appconfig.project_explorer = {} Appconfig.project_explorer = self.obj_appconfig.project_explorer var_appView.obj_Mainview.obj_projectExplorer.treewidget.clear() for parent, children in self.obj_appconfig.project_explorer.items(): var_appView.obj_Mainview.obj_projectExplorer.addTreeNode( parent, children) time.sleep(1.5) var_appView.splash.close() var_appView.show() def browseLocation(self): print("Function : Browse Location") self.workspace_directory = QtWidgets.QFileDialog.getExistingDirectory( self, "Browse Location", os.path.expanduser("~")) self.workspace_loc.setText(self.workspace_directory)
class Kicad: """ This class called the Kicad Schematic,KicadtoNgspice Converter,Layout editor and Footprint Editor """ def __init__(self,dockarea): self.obj_validation = Validation.Validation() self.obj_appconfig = Appconfig() self.obj_dockarea= dockarea def openSchematic(self): """ This function create command to open Kicad schematic """ print "Function : Open Kicad Schematic" self.projDir = self.obj_appconfig.current_project["ProjectName"] try: self.obj_appconfig.print_info('Kicad Schematic is called for project ' + self.projDir) except: pass #Validating if current project is available or not if self.obj_validation.validateKicad(self.projDir): #print "calling Kicad schematic ",self.projDir self.projName = os.path.basename(self.projDir) self.project = os.path.join(self.projDir,self.projName) #Creating a command to run self.cmd = "eeschema "+self.project+".sch " self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() else: self.msg = QtGui.QErrorMessage(None) self.msg.showMessage('Please select the project first. You can either create new project or open existing project') self.obj_appconfig.print_warning('Please select the project first. You can either create new project or open existing project') self.msg.setWindowTitle("Error Message") ''' #Commenting as it is no longer needed as PBC and Layout will open from eeschema def openFootprint(self): """ This function create command to open Footprint editor """ print "Kicad Foot print Editor called" self.projDir = self.obj_appconfig.current_project["ProjectName"] try: self.obj_appconfig.print_info('Kicad Footprint Editor is called for project : ' + self.projDir) except: pass #Validating if current project is available or not if self.obj_validation.validateKicad(self.projDir): #print "calling Kicad FootPrint Editor ",self.projDir self.projName = os.path.basename(self.projDir) self.project = os.path.join(self.projDir,self.projName) #Creating a command to run self.cmd = "cvpcb "+self.project+".net " self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() else: self.msg = QtGui.QErrorMessage(None) self.msg.showMessage('Please select the project first. You can either create new project or open existing project') self.obj_appconfig.print_warning('Please select the project first. You can either create new project or open existing project') self.msg.setWindowTitle("Error Message") def openLayout(self): """ This function create command to open Layout editor """ print "Kicad Layout is called" self.projDir = self.obj_appconfig.current_project["ProjectName"] try: self.obj_appconfig.print_info('PCB Layout is called for project : ' + self.projDir) except: pass #Validating if current project is available or not if self.obj_validation.validateKicad(self.projDir): print "calling Kicad schematic ",self.projDir self.projName = os.path.basename(self.projDir) self.project = os.path.join(self.projDir,self.projName) #Creating a command to run self.cmd = "pcbnew "+self.project+".net " self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() else: self.msg = QtGui.QErrorMessage(None) self.msg.showMessage('Please select the project first. You can either create new project or open existing project') self.obj_appconfig.print_warning('Please select the project first. You can either create new project or open existing project') self.msg.setWindowTitle("Error Message") ''' def openKicadToNgspice(self): """ This function create command to call kicad to Ngspice converter. """ print "Function: Open Kicad to Ngspice Converter" self.projDir = self.obj_appconfig.current_project["ProjectName"] try: self.obj_appconfig.print_info('Kicad to Ngspice Conversion is called') self.obj_appconfig.print_info('Current Project is ' + self.projDir) except: pass #Validating if current project is available or not if self.obj_validation.validateKicad(self.projDir): #Cheking if project has .cir file or not if self.obj_validation.validateCir(self.projDir): self.projName = os.path.basename(self.projDir) self.project = os.path.join(self.projDir,self.projName) ## TODO #Creating a command to run """ self.cmd = "python ../kicadtoNgspice/KicadtoNgspice.py " +self.project+".cir " self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() """ var=self.project+".cir" self.obj_dockarea.kicadToNgspiceEditor(var) else: self.msg = QtGui.QErrorMessage(None) self.msg.showMessage('The project does not contain any Kicad netlist file for conversion.') self.obj_appconfig.print_error('The project does not contain any Kicad netlist file for conversion.') self.msg.setWindowTitle("Error Message") else: self.msg = QtGui.QErrorMessage(None) self.msg.showMessage('Please select the project first. You can either create new project or open existing project') self.obj_appconfig.print_warning('Please select the project first. You can either create new project or open existing project') self.msg.setWindowTitle("Error Message")
class NewProjectInfo(QtWidgets.QWidget): """ This class is called when User create new Project. """ def __init__(self): super(NewProjectInfo, self).__init__() self.obj_validation = Validation() self.obj_appconfig = Appconfig() def createProject(self, projName): """ This function create Project related directories and files. Before creating also validates using the `Validation` class Validation codes - VALID - CHECKEXIST - CHECKNAME - NONE @params :projName => name of the project created passed from frontEnd/Application new_project() @return :dirs => The directories inside the project folder :filelist => The files inside the project folder @params :projName => name of the project created passed from frontEnd/Application new_project() @return :dirs => The directories inside the project folder :filelist => The files inside the project folder """ self.projName = projName self.workspace = self.obj_appconfig.default_workspace['workspace'] # self.projName = self.projEdit.text() # Remove leading and trailing space self.projName = str(self.projName).rstrip().lstrip() self.projDir = os.path.join(self.workspace, str(self.projName)) # Validation for newProject if self.projName == "": self.reply = "NONE" else: self.reply = self.obj_validation.validateNewproj(str(self.projDir)) # Checking Validations Response if self.reply == "VALID": # create project directory try: os.mkdir(self.projDir) self.close() self.projFile = os.path.join(self.projDir, self.projName + ".proj") f = open(self.projFile, "w") except BaseException: self.msg = QtWidgets.QErrorMessage(self) self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage( 'Unable to create project. Please make sure you have ' + 'write permission on ' + self.workspace) self.msg.exec_() f.write("schematicFile " + self.projName + ".sch\n") f.close() # Now Change the current working project newprojlist = [] # self.obj_appconfig = Appconfig() self.obj_appconfig.current_project['ProjectName'] = self.projDir newprojlist.append(self.projName + '.proj') self.obj_appconfig.project_explorer[self.projDir] = newprojlist self.obj_appconfig.print_info('New project created : ' + self.projName) self.obj_appconfig.print_info('Current project is : ' + self.projDir) json.dump(self.obj_appconfig.project_explorer, open(self.obj_appconfig.dictPath["path"], 'w')) return self.projDir, newprojlist elif self.reply == "CHECKEXIST": self.msg = QtWidgets.QErrorMessage(self) self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage( 'The project "' + self.projName + '" already exist.Please select the different name or delete' + ' existing project') self.msg.exec_() return None, None elif self.reply == "CHECKNAME": self.msg = QtWidgets.QErrorMessage(self) self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage( 'The project name should not contain space between them') self.msg.exec_() return None, None elif self.reply == "NONE": self.msg = QtWidgets.QErrorMessage(self) self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage('The project name cannot be empty') self.msg.exec_() return None, None def cancelProject(self): self.close()
class ProjectExplorer(QtGui.QWidget): def __init__(self): QtGui.QWidget.__init__(self) self.obj_appconfig = Appconfig() self.treewidget = QtGui.QTreeWidget() self.window = QtGui.QVBoxLayout() header = QtGui.QTreeWidgetItem(["Projects", "path"]) self.treewidget.setHeaderItem(header) self.treewidget.setColumnHidden(1, True) #CSS self.treewidget.setStyleSheet(" \ QTreeView { border-radius: 15px; border: 1px solid gray; padding: 5px; width: 200px; height: 150px; } \ QTreeView::branch:has-siblings:!adjoins-item { border-image: url(../../images/vline.png) 0; } \ QTreeView::branch:has-siblings:adjoins-item { border-image: url(../../images/branch-more.png) 0; } \ QTreeView::branch:!has-children:!has-siblings:adjoins-item { border-image: url(../../images/branch-end.png) 0; } \ QTreeView::branch:has-children:!has-siblings:closed, \ QTreeView::branch:closed:has-children:has-siblings { border-image: none; image: url(../../images/branch-closed.png); } \ QTreeView::branch:open:has-children:!has-siblings, \ QTreeView::branch:open:has-children:has-siblings { border-image: none; image: url(../../images/branch-open.png); } \ ") for parents, children in self.obj_appconfig.project_explorer.items(): os.path.join(parents) if os.path.exists(parents): pathlist = parents.split(os.sep) parentnode = QtGui.QTreeWidgetItem(self.treewidget, [pathlist[-1], parents]) for files in children: childnode = QtGui.QTreeWidgetItem( parentnode, [files, os.path.join(parents, files)]) self.window.addWidget(self.treewidget) self.treewidget.doubleClicked.connect(self.openProject) self.treewidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.treewidget.customContextMenuRequested.connect(self.openMenu) self.setLayout(self.window) self.show() def addTreeNode(self, parents, children): os.path.join(parents) pathlist = parents.split(os.sep) parentnode = QtGui.QTreeWidgetItem(self.treewidget, [pathlist[-1], parents]) for files in children: childnode = QtGui.QTreeWidgetItem( parentnode, [files, os.path.join(parents, files)]) def openMenu(self, position): indexes = self.treewidget.selectedIndexes() if len(indexes) > 0: level = 0 index = indexes[0] while index.parent().isValid(): index = index.parent() level += 1 menu = QtGui.QMenu() if level == 0: deleteproject = menu.addAction(self.tr("Remove Project")) deleteproject.triggered.connect(self.removeProject) refreshproject = menu.addAction(self.tr("Refresh")) refreshproject.triggered.connect(self.refreshProject) elif level == 1: openfile = menu.addAction(self.tr("Open")) openfile.triggered.connect(self.openProject) menu.exec_(self.treewidget.viewport().mapToGlobal(position)) def openProject(self): self.indexItem = self.treewidget.currentIndex() filename = self.indexItem.data().toString() self.filePath = self.indexItem.sibling(self.indexItem.row(), 1).data().toString() self.obj_appconfig.print_info('The current project is ' + self.filePath) self.textwindow = QtGui.QWidget() self.textwindow.setMinimumSize(600, 500) self.textwindow.setGeometry(QtCore.QRect(400, 150, 400, 400)) self.textwindow.setWindowTitle(filename) self.text = QtGui.QTextEdit() self.save = QtGui.QPushButton('Save and Exit') self.save.setDisabled(True) self.windowgrid = QtGui.QGridLayout() if (os.path.isfile(str(self.filePath))) == True: self.fopen = open(str(self.filePath), 'r') lines = self.fopen.read() self.text.setText(lines) QtCore.QObject.connect(self.text, QtCore.SIGNAL("textChanged()"), self.enable_save) vbox_main = QtGui.QVBoxLayout(self.textwindow) vbox_main.addWidget(self.text) vbox_main.addWidget(self.save) self.save.clicked.connect(self.save_data) #self.connect(exit,QtCore.SIGNAL('close()'), self.onQuit) self.textwindow.show() else: self.obj_appconfig.current_project["ProjectName"] = str( self.filePath) def enable_save(self): self.save.setEnabled(True) def save_data(self): self.fopen = open(self.filePath, 'w') self.fopen.write(self.text.toPlainText()) self.fopen.close() self.textwindow.close() def removeProject(self): self.indexItem = self.treewidget.currentIndex() filename = self.indexItem.data().toString() self.filePath = self.indexItem.sibling(self.indexItem.row(), 1).data().toString() self.int = self.indexItem.row() self.treewidget.takeTopLevelItem(self.int) if self.obj_appconfig.current_project["ProjectName"] == self.filePath: self.obj_appconfig.current_project["ProjectName"] = None del self.obj_appconfig.project_explorer[str(self.filePath)] json.dump(self.obj_appconfig.project_explorer, open(self.obj_appconfig.dictPath, 'w')) def refreshProject(self): self.indexItem = self.treewidget.currentIndex() filename = self.indexItem.data().toString() self.filePath = str( self.indexItem.sibling(self.indexItem.row(), 1).data().toString()) filelistnew = os.listdir(os.path.join(self.filePath)) print filelistnew parentnode = self.treewidget.currentItem() count = parentnode.childCount() for i in range(count): for items in self.treewidget.selectedItems(): items.removeChild(items.child(0)) for files in filelistnew: childnode = QtGui.QTreeWidgetItem( parentnode, [files, os.path.join(self.filePath, files)]) self.obj_appconfig.project_explorer[self.filePath] = filelistnew json.dump(self.obj_appconfig.project_explorer, open(self.obj_appconfig.dictPath, 'w'))
class ProjectExplorer(QtGui.QWidget): def __init__(self): QtGui.QWidget.__init__(self) self.obj_appconfig = Appconfig() self.treewidget = QtGui.QTreeWidget() self.window= QtGui.QVBoxLayout() header = QtGui.QTreeWidgetItem(["Projects","path"]) self.treewidget.setHeaderItem(header) self.treewidget.setColumnHidden(1,True) #CSS self.treewidget.setStyleSheet(" \ QTreeView { border-radius: 15px; border: 1px solid gray; padding: 5px; width: 200px; height: 150px; } \ QTreeView::branch:has-siblings:!adjoins-item { border-image: url(../../images/vline.png) 0; } \ QTreeView::branch:has-siblings:adjoins-item { border-image: url(../../images/branch-more.png) 0; } \ QTreeView::branch:!has-children:!has-siblings:adjoins-item { border-image: url(../../images/branch-end.png) 0; } \ QTreeView::branch:has-children:!has-siblings:closed, \ QTreeView::branch:closed:has-children:has-siblings { border-image: none; image: url(../../images/branch-closed.png); } \ QTreeView::branch:open:has-children:!has-siblings, \ QTreeView::branch:open:has-children:has-siblings { border-image: none; image: url(../../images/branch-open.png); } \ ") for parents, children in self.obj_appconfig.project_explorer.items(): os.path.join(parents) if os.path.exists(parents): pathlist= parents.split(os.sep) parentnode = QtGui.QTreeWidgetItem(self.treewidget, [pathlist[-1],parents]) for files in children: childnode = QtGui.QTreeWidgetItem(parentnode, [files, os.path.join(parents,files)]) self.window.addWidget(self.treewidget) self.treewidget.doubleClicked.connect(self.openProject) self.treewidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.treewidget.customContextMenuRequested.connect(self.openMenu) self.setLayout(self.window) self.show() def addTreeNode(self, parents, children): os.path.join(parents) pathlist= parents.split(os.sep) parentnode = QtGui.QTreeWidgetItem(self.treewidget, [pathlist[-1], parents]) for files in children: childnode = QtGui.QTreeWidgetItem(parentnode, [files, os.path.join(parents,files)]) def openMenu(self, position): indexes = self.treewidget.selectedIndexes() if len(indexes) > 0: level = 0 index = indexes[0] while index.parent().isValid(): index = index.parent() level += 1 menu = QtGui.QMenu() if level == 0: deleteproject = menu.addAction(self.tr("Remove Project")) deleteproject.triggered.connect(self.removeProject) refreshproject= menu.addAction(self.tr("Refresh")) refreshproject.triggered.connect(self.refreshProject) elif level == 1: openfile = menu.addAction(self.tr("Open")) openfile.triggered.connect(self.openProject) menu.exec_(self.treewidget.viewport().mapToGlobal(position)) def openProject(self): self.indexItem =self.treewidget.currentIndex() filename= self.indexItem.data().toString() self.filePath= self.indexItem.sibling(self.indexItem.row(), 1).data().toString() self.obj_appconfig.print_info('The current project is ' + self.filePath) self.textwindow = QtGui.QWidget() self.textwindow.setMinimumSize(600, 500) self.textwindow.setGeometry(QtCore.QRect(400,150,400,400)) self.textwindow.setWindowTitle(filename) self.text = QtGui.QTextEdit() self.save = QtGui.QPushButton('Save and Exit') self.save.setDisabled(True) self.windowgrid = QtGui.QGridLayout() if (os.path.isfile(str(self.filePath)))== True: self.fopen = open(str(self.filePath), 'r') lines = self.fopen.read() self.text.setText(lines) QtCore.QObject.connect(self.text,QtCore.SIGNAL("textChanged()"), self.enable_save) vbox_main = QtGui.QVBoxLayout(self.textwindow) vbox_main.addWidget(self.text) vbox_main.addWidget(self.save) self.save.clicked.connect(self.save_data) #self.connect(exit,QtCore.SIGNAL('close()'), self.onQuit) self.textwindow.show() else: self.obj_appconfig.current_project["ProjectName"]= str(self.filePath) def enable_save(self): self.save.setEnabled(True) def save_data(self): self.fopen=open(self.filePath, 'w') self.fopen.write(self.text.toPlainText()) self.fopen.close() self.textwindow.close() def removeProject(self): self.indexItem =self.treewidget.currentIndex() filename= self.indexItem.data().toString() self.filePath= self.indexItem.sibling(self.indexItem.row(), 1).data().toString() self.int = self.indexItem.row() self.treewidget.takeTopLevelItem(self.int) if self.obj_appconfig.current_project["ProjectName"] == self.filePath: self.obj_appconfig.current_project["ProjectName"] = None del self.obj_appconfig.project_explorer[str(self.filePath)] json.dump(self.obj_appconfig.project_explorer, open(self.obj_appconfig.dictPath,'w')) def refreshProject(self): self.indexItem =self.treewidget.currentIndex() filename= self.indexItem.data().toString() self.filePath= str(self.indexItem.sibling(self.indexItem.row(), 1).data().toString()) filelistnew= os.listdir(os.path.join(self.filePath)) parentnode = self.treewidget.currentItem() count = parentnode.childCount() for i in range(count): for items in self.treewidget.selectedItems(): items.removeChild(items.child(0)) for files in filelistnew: childnode= QtGui.QTreeWidgetItem(parentnode, [files, os.path.join(self.filePath,files)]) self.obj_appconfig.project_explorer[self.filePath]= filelistnew json.dump(self.obj_appconfig.project_explorer, open(self.obj_appconfig.dictPath,'w'))
class Application(QtGui.QMainWindow): global project_name """ Its our main window of application """ def __init__(self,*args): """ Initialize main Application window """ #Calling __init__ of super class QtGui.QMainWindow.__init__(self,*args) #Creating require Object self.obj_workspace = Workspace.Workspace() self.obj_Mainview = MainView() self.obj_kicad = Kicad(self.obj_Mainview.obj_dockarea) self.obj_appconfig = Appconfig() self.obj_validation = Validation() #Initialize all widget self.setCentralWidget(self.obj_Mainview) self.initToolBar() self.setGeometry(self.obj_appconfig._app_xpos, self.obj_appconfig._app_ypos, self.obj_appconfig._app_width, self.obj_appconfig._app_heigth) self.setWindowTitle(self.obj_appconfig._APPLICATION) self.showMaximized() self.setWindowIcon(QtGui.QIcon('res/images/logo.png')) #self.show() self.systemTrayIcon = QtGui.QSystemTrayIcon(self) self.systemTrayIcon.setIcon(QtGui.QIcon('res/images/logo.png')) self.systemTrayIcon.setVisible(True) def initToolBar(self): """ This function initialize Tool Bar """ #Top Tool bar self.newproj = QtGui.QAction(QtGui.QIcon('res/images/newProject.png'),'<b>New Project</b>',self) self.newproj.setShortcut('Ctrl+N') self.newproj.triggered.connect(self.new_project) #self.newproj.connect(self.newproj,QtCore.SIGNAL('triggered()'),self,QtCore.SLOT(self.new_project())) self.openproj = QtGui.QAction(QtGui.QIcon('res/images/openProject.png'),'<b>Open Project</b>',self) self.openproj.setShortcut('Ctrl+O') self.openproj.triggered.connect(self.open_project) self.closeproj = QtGui.QAction(QtGui.QIcon('res/images/closeProject.png'),'<b>Close Project</b>',self) self.closeproj.setShortcut('Ctrl+X') self.closeproj.triggered.connect(self.close_project) self.wrkspc = QtGui.QAction(QtGui.QIcon('res/images/workspace.ico'),'<b>Change Workspace</b>',self) self.wrkspc.setShortcut('Ctrl+W') self.wrkspc.triggered.connect(self.wrkspc_change) self.helpfile = QtGui.QAction(QtGui.QIcon('res/images/helpProject.png'),'<b>Help</b>',self) self.helpfile.setShortcut('Ctrl+H') self.helpfile.triggered.connect(self.help_project) self.topToolbar = self.addToolBar('Top Tool Bar') self.topToolbar.addAction(self.newproj) self.topToolbar.addAction(self.openproj) self.topToolbar.addAction(self.closeproj) self.topToolbar.addAction(self.wrkspc) self.topToolbar.addAction(self.helpfile) self.spacer = QtGui.QWidget() self.spacer.setSizePolicy(QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Expanding) self.topToolbar.addWidget(self.spacer) self.logo = QtGui.QLabel() self.logopic = QtGui.QPixmap(os.path.join('res/images','fosseeLogo.png')) self.logopic = self.logopic.scaled(QSize(150,150),QtCore.Qt.KeepAspectRatio) self.logo.setPixmap(self.logopic) self.logo.setStyleSheet("padding:0 15px 0 0;") self.topToolbar.addWidget(self.logo) #Left Tool bar Action Widget self.kicad = QtGui.QAction(QtGui.QIcon('res/images/kicad.png'),'<b>Open Schematic</b>',self) self.kicad.triggered.connect(self.obj_kicad.openSchematic) self.conversion = QtGui.QAction(QtGui.QIcon('res/images/ki-ng.png'),'<b>Convert Kicad to Ngspice</b>',self) self.conversion.triggered.connect(self.obj_kicad.openKicadToNgspice) self.ngspice = QtGui.QAction(QtGui.QIcon('res/images/ngspice.png'), '<b>Simulation</b>', self) self.ngspice.triggered.connect(self.open_ngspice) self.model = QtGui.QAction(QtGui.QIcon('res/images/model.png'),'<b>Model Editor</b>',self) self.model.triggered.connect(self.open_modelEditor) self.subcircuit=QtGui.QAction(QtGui.QIcon('res/images/subckt.png'),'<b>Subcircuit</b>',self) self.subcircuit.triggered.connect(self.open_subcircuit) self.nghdl = QtGui.QAction(QtGui.QIcon('res/images/nghdl.png'), '<b>Nghdl</b>', self) self.nghdl.triggered.connect(self.open_nghdl) self.omedit = QtGui.QAction(QtGui.QIcon('res/images/omedit.png'),'<b>Modelica Converter</b>',self) self.omedit.triggered.connect(self.open_OMedit) self.omoptim=QtGui.QAction(QtGui.QIcon('res/images/omoptim.png'),'<b>OM Optimisation</b>',self) self.omoptim.triggered.connect(self.open_OMoptim) #Adding Action Widget to tool bar self.lefttoolbar = QtGui.QToolBar('Left ToolBar') self.addToolBar(QtCore.Qt.LeftToolBarArea, self.lefttoolbar) self.lefttoolbar.addAction(self.kicad) self.lefttoolbar.addAction(self.conversion) self.lefttoolbar.addAction(self.ngspice) self.lefttoolbar.addAction(self.model) self.lefttoolbar.addAction(self.subcircuit) self.lefttoolbar.addAction(self.nghdl) self.lefttoolbar.addAction(self.omedit) self.lefttoolbar.addAction(self.omoptim) self.lefttoolbar.setOrientation(QtCore.Qt.Vertical) self.lefttoolbar.setIconSize(QSize(40,40)) def closeEvent(self, event): exit_msg = "Are you sure you want to exit the program ? All unsaved data will be lost." reply = QtGui.QMessageBox.question(self, 'Message', exit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: for proc in self.obj_appconfig.procThread_list: try: proc.terminate() except: pass try: for process_object in self.obj_appconfig.process_obj: try: process_object.close() except: pass except: pass ##Just checking if open project and New project window is open. If yes just close it when application is closed try: self.project.close() except: pass event.accept() self.systemTrayIcon.showMessage('Exit', 'eSim is Closed.') elif reply == QtGui.QMessageBox.No: event.ignore() def close_project(self): print "Function : Close Project" current_project = self.obj_appconfig.current_project['ProjectName'] if current_project==None: pass else: for pid in self.obj_appconfig.proc_dict[self.obj_appconfig.current_project['ProjectName']]: try: os.kill(pid, 9) except: pass self.obj_Mainview.obj_dockarea.closeDock() self.obj_appconfig.current_project['ProjectName'] = None self.systemTrayIcon.showMessage('Close', 'Current project '+os.path.basename(current_project)+' is Closed.') def new_project(self): """ This function call New Project Info class. """ text, ok = QtGui.QInputDialog.getText(self, 'New Project Info','Enter Project Name:') if ok: self.projname = (str(text)) self.project = NewProjectInfo() directory, filelist =self.project.createProject(self.projname) self.obj_Mainview.obj_projectExplorer.addTreeNode(directory, filelist) else: print "No new project created" self.obj_appconfig.print_info('No new project created') try: self.obj_appconfig.print_info('Current project is : ' + self.obj_appconfig.current_project["ProjectName"]) except: pass def open_project(self): """ This function call Open Project Info class """ print "Function : Open Project" self.project = OpenProjectInfo() try: directory, filelist = self.project.body() self.obj_Mainview.obj_projectExplorer.addTreeNode(directory, filelist) except: pass def wrkspc_change(self): """ This function calls Change workspace dialog """ print "Function : Change Workspace" self.obj_workspace.returnWhetherClickedOrNot(self) self.hide() self.obj_workspace.show() def help_project(self): print "Function : Help" self.obj_appconfig.print_info('Help is called') print "Current Project is : ",self.obj_appconfig.current_project self.obj_Mainview.obj_dockarea.usermanual() def open_ngspice(self): """ This Function execute ngspice on current project """ self.projDir = self.obj_appconfig.current_project["ProjectName"] if self.projDir != None: self.obj_Mainview.obj_dockarea.ngspiceEditor(self.projDir) #Calling Python Plotting try: self.obj_Mainview.obj_dockarea.plottingEditor() except Exception as e: self.msg = QtGui.QErrorMessage(None) self.msg.showMessage('Error while opening python plotting Editor.\ Please look at console for more details ') print "Exception Message:",str(e) self.obj_appconfig.print_error('Exception Message : ' + str(e)) self.msg.setWindowTitle("Error Message") else: self.msg = QtGui.QErrorMessage() self.msg.showMessage('Please select the project first. You can either create new project or open existing project') self.msg.setWindowTitle("Error Message") def open_subcircuit(self): print "Function : Subcircuit editor" self.obj_appconfig.print_info('Subcircuit editor is called') self.obj_Mainview.obj_dockarea.subcircuiteditor() def open_nghdl(self): print "Function : Nghdl" self.obj_appconfig.print_info('Nghdl is called') if self.obj_validation.validateTool('nghdl'): self.cmd = 'nghdl -e' self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() else: self.msg = QtGui.QErrorMessage(None) self.msg.showMessage('Error while opening nghdl. Please make sure nghdl is installed') self.obj_appconfig.print_error('Error while opening nghdl. Please make sure nghdl is installed') self.msg.setWindowTitle('nghdl Error Message') def open_modelEditor(self): print "Function : Model editor" self.obj_appconfig.print_info('Model editor is called') self.obj_Mainview.obj_dockarea.modelEditor() def open_OMedit(self): """ This function call ngspice to OM edit converter and then launch OM edit. """ self.obj_appconfig.print_info('OM edit is called') self.projDir = self.obj_appconfig.current_project["ProjectName"] if self.projDir != None: if self.obj_validation.validateCirOut(self.projDir): self.projName = os.path.basename(self.projDir) self.ngspiceNetlist = os.path.join(self.projDir,self.projName+".cir.out") self.modelicaNetlist = os.path.join(self.projDir,self.projName+".mo") """ try: #Creating a command for Ngspice to Modelica converter self.cmd1 = "python ../ngspicetoModelica/NgspicetoModelica.py "+self.ngspiceNetlist self.obj_workThread1 = Worker.WorkerThread(self.cmd1) self.obj_workThread1.start() if self.obj_validation.validateTool("OMEdit"): #Creating command to run OMEdit self.cmd2 = "OMEdit "+self.modelicaNetlist self.obj_workThread2 = Worker.WorkerThread(self.cmd2) self.obj_workThread2.start() else: self.msg = QtGui.QMessageBox() self.msgContent = "There was an error while opening OMEdit.<br/>\ Please make sure OpenModelica is installed in your system. <br/>\ To install it on Linux : Go to <a href=https://www.openmodelica.org/download/download-linux>OpenModelica Linux</a> and install nigthly build release.<br/>\ To install it on Windows : Go to <a href=https://www.openmodelica.org/download/download-windows>OpenModelica Windows</a> and install latest version.<br/>" self.msg.setTextFormat(QtCore.Qt.RichText) self.msg.setText(self.msgContent) self.msg.setWindowTitle("Missing OpenModelica") self.obj_appconfig.print_info(self.msgContent) self.msg.exec_() except Exception as e: self.msg = QtGui.QErrorMessage() self.msg.showMessage('Unable to convert NgSpice netlist to Modelica netlist :'+str(e)) self.msg.setWindowTitle("Ngspice to Modelica conversion error") self.obj_appconfig.print_error(str(e)) """ self.obj_Mainview.obj_dockarea.modelicaEditor(self.projDir) else: self.msg = QtGui.QErrorMessage() self.msg.showMessage('Current project does not contain any ngspice file. Please create ngspice file with extension .cir.out') self.msg.setWindowTitle("Missing Ngspice netlist") else: self.msg = QtGui.QErrorMessage() self.msg.showMessage('Please select the project first. You can either create new project or open existing project') self.msg.setWindowTitle("Error Message") def open_OMoptim(self): print "Function : OM Optim" self.obj_appconfig.print_info('OM Optim is called') #Check if OMOptim is installed if self.obj_validation.validateTool("OMOptim"): #Creating a command to run self.cmd = "OMOptim" self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() else: self.msg = QtGui.QMessageBox() self.msgContent = "There was an error while opening OMOptim.<br/>\ Please make sure OpenModelica is installed in your system. <br/>\ To install it on Linux : Go to <a href=https://www.openmodelica.org/download/download-linux>OpenModelica Linux</a> and install nigthly build release.<br/>\ To install it on Windows : Go to <a href=https://www.openmodelica.org/download/download-windows>OpenModelica Windows</a> and install latest version.<br/>" self.msg.setTextFormat(QtCore.Qt.RichText) self.msg.setText(self.msgContent) self.msg.setWindowTitle("Error Message") self.obj_appconfig.print_info(self.msgContent) self.msg.exec_()
class plotWindow(QtGui.QMainWindow): """ This class defines python plotting window, its features, buttons, colors, AC and DC analysis, plotting etc. """ def __init__(self, fpath, projectName): """This create constructor for plotWindow class.""" QtGui.QMainWindow.__init__(self) self.fpath = fpath self.projectName = projectName self.obj_appconfig = Appconfig() print("Complete Project Path : ", self.fpath) print("Project Name : ", self.projectName) self.obj_appconfig.print_info('Ngspice simulation is called : ' + self.fpath) self.obj_appconfig.print_info('PythonPlotting is called : ' + self.fpath) self.combo = [] self.combo1 = [] self.combo1_rev = [] # Creating Frame self.createMainFrame() def createMainFrame(self): self.mainFrame = QtGui.QWidget() self.dpi = 100 self.fig = Figure((7.0, 7.0), dpi=self.dpi) # Creating Canvas which will figure self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self.mainFrame) self.axes = self.fig.add_subplot(111) self.navToolBar = NavigationToolbar(self.canvas, self.mainFrame) # LeftVbox hold navigation tool bar and canvas self.left_vbox = QtGui.QVBoxLayout() self.left_vbox.addWidget(self.navToolBar) self.left_vbox.addWidget(self.canvas) # right VBOX is main Layout which hold right grid(bottom part) and top # grid(top part) self.right_vbox = QtGui.QVBoxLayout() self.right_grid = QtGui.QGridLayout() self.top_grid = QtGui.QGridLayout() # Get DataExtraction Details self.obj_dataext = DataExtraction() self.plotType = self.obj_dataext.openFile(self.fpath) self.obj_dataext.computeAxes() self.a = self.obj_dataext.numVals() self.chkbox = [] # Generating list of colors : # ,(0.4,0.5,0.2),(0.1,0.4,0.9),(0.4,0.9,0.2),(0.9,0.4,0.9)] self.full_colors = ['r', 'b', 'g', 'y', 'c', 'm', 'k'] self.color = [] for i in range(0, self.a[0] - 1): if i % 7 == 0: self.color.append(self.full_colors[0]) elif (i - 1) % 7 == 0: self.color.append(self.full_colors[1]) elif (i - 2) % 7 == 0: self.color.append(self.full_colors[2]) elif (i - 3) % 7 == 0: self.color.append(self.full_colors[3]) elif (i - 4) % 7 == 0: self.color.append(self.full_colors[4]) elif (i - 5) % 7 == 0: self.color.append(self.full_colors[5]) elif (i - 6) % 7 == 0: self.color.append(self.full_colors[6]) # Color generation ends here # Total number of voltage source self.volts_length = self.a[1] self.analysisType = QtGui.QLabel() self.top_grid.addWidget(self.analysisType, 0, 0) self.listNode = QtGui.QLabel() self.top_grid.addWidget(self.listNode, 1, 0) self.listBranch = QtGui.QLabel() self.top_grid.addWidget(self.listBranch, self.a[1] + 2, 0) for i in range(0, self.a[1]): # a[0]-1 self.chkbox.append(QtGui.QCheckBox(self.obj_dataext.NBList[i])) self.chkbox[i].setStyleSheet('color') self.chkbox[i].setToolTip('<b>Check To Plot</b>') self.top_grid.addWidget(self.chkbox[i], i + 2, 0) self.colorLab = QtGui.QLabel() self.colorLab.setText('____') self.colorLab.setStyleSheet( self.colorName(self.color[i]) + '; font-weight = bold;') self.top_grid.addWidget(self.colorLab, i + 2, 1) for i in range(self.a[1], self.a[0] - 1): # a[0]-1 self.chkbox.append(QtGui.QCheckBox(self.obj_dataext.NBList[i])) self.chkbox[i].setToolTip('<b>Check To Plot</b>') self.top_grid.addWidget(self.chkbox[i], i + 3, 0) self.colorLab = QtGui.QLabel() self.colorLab.setText('____') self.colorLab.setStyleSheet( self.colorName(self.color[i]) + '; font-weight = bold;') self.top_grid.addWidget(self.colorLab, i + 3, 1) # Buttons for Plot, multimeter, plotting function. self.clear = QtGui.QPushButton("Clear") self.warnning = QtGui.QLabel() self.funcName = QtGui.QLabel() self.funcExample = QtGui.QLabel() self.plotbtn = QtGui.QPushButton("Plot") self.plotbtn.setToolTip('<b>Press</b> to Plot') self.multimeterbtn = QtGui.QPushButton("Multimeter") self.multimeterbtn.setToolTip( '<b>RMS</b> value of the current and voltage is displayed') self.text = QtGui.QLineEdit() self.funcLabel = QtGui.QLabel() self.palette1 = QtGui.QPalette() self.palette2 = QtGui.QPalette() self.plotfuncbtn = QtGui.QPushButton("Plot Function") self.plotfuncbtn.setToolTip('<b>Press</b> to Plot the function') self.palette1.setColor(QtGui.QPalette.Foreground, QtCore.Qt.blue) self.palette2.setColor(QtGui.QPalette.Foreground, QtCore.Qt.red) self.funcName.setPalette(self.palette1) self.funcExample.setPalette(self.palette2) # Widgets for grid, plot button and multimeter button. self.right_vbox.addLayout(self.top_grid) self.right_vbox.addWidget(self.plotbtn) self.right_vbox.addWidget(self.multimeterbtn) self.right_grid.addWidget(self.funcLabel, 1, 0) self.right_grid.addWidget(self.text, 1, 1) self.right_grid.addWidget(self.plotfuncbtn, 2, 1) self.right_grid.addWidget(self.clear, 2, 0) self.right_grid.addWidget(self.warnning, 3, 0) self.right_grid.addWidget(self.funcName, 4, 0) self.right_grid.addWidget(self.funcExample, 4, 1) self.right_vbox.addLayout(self.right_grid) self.hbox = QtGui.QHBoxLayout() self.hbox.addLayout(self.left_vbox) self.hbox.addLayout(self.right_vbox) self.widget = QtGui.QWidget() self.widget.setLayout(self.hbox) # finalvbox self.scrollArea = QtGui.QScrollArea() self.scrollArea.setWidgetResizable(True) self.scrollArea.setWidget(self.widget) ''' Right side box containing checkbox for different inputs and options of plot, multimeter and plot function. ''' self.finalhbox = QtGui.QHBoxLayout() self.finalhbox.addWidget(self.scrollArea) # Right side window frame showing list of nodes and branches. self.mainFrame.setLayout(self.finalhbox) self.showMaximized() self.listNode.setText("<font color='indigo'>List of Nodes:</font>") self.listBranch.setText( "<font color='indigo'>List of Branches:</font>") self.funcLabel.setText("<font color='indigo'>Function:</font>") self.funcName.setText("<font color='indigo'>Standard functions</font>\ <br><br>Addition:<br>Subtraction:<br>\ Multiplication:<br>Division:<br>Comparison:") self.funcExample.setText( "\n\nNode1 + Node2\nNode1 - Node2\nNode1 * Node2\nNode1 / Node2\ \nNode1 vs Node2") # Connecting to plot and clear function self.connect(self.clear, QtCore.SIGNAL('clicked()'), self.pushedClear) self.connect(self.plotfuncbtn, QtCore.SIGNAL('clicked()'), self.pushedPlotFunc) self.connect(self.multimeterbtn, QtCore.SIGNAL('clicked()'), self.multiMeter) # for AC analysis if self.plotType[0] == 0: self.analysisType.setText("<b>AC Analysis</b>") if self.plotType[1] == 1: self.connect(self.plotbtn, QtCore.SIGNAL('clicked()'), self.onPush_decade) else: self.connect(self.plotbtn, QtCore.SIGNAL('clicked()'), self.onPush_ac) # for transient analysis elif self.plotType[0] == 1: self.analysisType.setText("<b>Transient Analysis</b>") self.connect(self.plotbtn, QtCore.SIGNAL('clicked()'), self.onPush_trans) else: # For DC analysis self.analysisType.setText("<b>DC Analysis</b>") self.connect(self.plotbtn, QtCore.SIGNAL('clicked()'), self.onPush_dc) self.setCentralWidget(self.mainFrame) # definition of functions pushedClear, pushedPlotFunc. def pushedClear(self): self.text.clear() self.axes.cla() self.canvas.draw() QtCore.SLOT('quit()') def pushedPlotFunc(self): self.parts = str(self.text.text()) self.parts = self.parts.split(" ") if self.parts[len(self.parts) - 1] == '': self.parts = self.parts[0:-1] self.values = self.parts self.comboAll = [] self.axes.cla() self.plotType2 = self.obj_dataext.openFile(self.fpath) if len(self.parts) <= 2: self.warnning.setText("Too few arguments!\nRefer syntax below!") QtGui.QMessageBox.about( self, "Warning!!", "Too Few Arguments/SYNTAX Error!\ \n Refer Examples") else: self.warnning.setText("") a = [] finalResult = [] # p = 0 for i in range(len(self.parts)): if i % 2 == 0: for j in range(len(self.obj_dataext.NBList)): if self.parts[i] == self.obj_dataext.NBList[j]: a.append(j) if len(a) != len(self.parts) // 2 + 1: QtGui.QMessageBox.about( self, "Warning!!", "One of the operands doesn't belong to " "the above list of Nodes!!") for i in a: self.comboAll.append(self.obj_dataext.y[i]) for i in range(len(a)): if a[i] == len(self.obj_dataext.NBList): QtGui.QMessageBox.about( self, "Warning!!", "One of the operands doesn't belong " + "to the above list!!") self.warnning.setText( "<font color='red'>To Err Is Human!<br>One of the " + "operands doesn't belong to the above list!!</font>") if self.parts[1] == 'vs': if len(self.parts) > 3: self.warnning.setText("Enter two operands only!!") QtGui.QMessageBox.about(self, "Warning!!", "Recheck the expression syntax!") else: self.axes.cla() for i in range(len(self.obj_dataext.y[a[0]])): self.combo.append(self.obj_dataext.y[a[0]][i]) self.combo1.append(self.obj_dataext.y[a[1]][i]) self.axes.plot(self.combo, self.combo1, c=self.color[1], label=str(2)) # _rev if max(a) < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') self.axes.set_xlabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.set_ylabel('Current(I)-->') elif max(a) >= self.volts_length and min(a) < self.volts_length: QtGui.QMessageBox.about(self, "Warning!!", "Do not combine Voltage and Current!!") else: for j in range(len(self.comboAll[0])): for i in range(len(self.values)): if i % 2 == 0: self.values[i] = str(self.comboAll[i // 2][j]) re = " ".join(self.values[:]) try: finalResult.append(eval(re)) except ArithmeticError: QtGui.QMessageBox.about(self, "Warning!!", "Dividing by zero!!") if self.plotType2[0] == 0: # self.setWindowTitle('AC Analysis') if self.plotType2[1] == 1: self.axes.semilogx(self.obj_dataext.x, finalResult, c=self.color[0], label=str(1)) else: self.axes.plot(self.obj_dataext.x, finalResult, c=self.color[0], label=str(1)) self.axes.set_xlabel('freq-->') if max(a) < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') elif self.plotType2[0] == 1: # self.setWindowTitle('Transient Analysis') self.axes.plot(self.obj_dataext.x, finalResult, c=self.color[0], label=str(1)) self.axes.set_xlabel('time-->') if max(a) < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') else: # self.setWindowTitle('DC Analysis') self.axes.plot(self.obj_dataext.x, finalResult, c=self.color[0], label=str(1)) self.axes.set_xlabel('I/P Voltage-->') if max(a) < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) self.canvas.draw() self.combo = [] self.combo1 = [] self.combo1_rev = [] # definition of functions onPush_decade, onPush_ac, onPush_trans,\ # onPush_dc, color and multimeter and getRMSValue. def onPush_decade(self): boxCheck = 0 self.axes.cla() for i, j in zip(self.chkbox, list(range(len(self.chkbox)))): if i.isChecked(): boxCheck += 1 self.axes.semilogx(self.obj_dataext.x, self.obj_dataext.y[j], c=self.color[j], label=str(j + 1)) self.axes.set_xlabel('freq-->') if j < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) if boxCheck == 0: QtGui.QMessageBox.about( self, "Warning!!", "Please select at least one Node OR Branch") self.canvas.draw() def onPush_ac(self): self.axes.cla() boxCheck = 0 for i, j in zip(self.chkbox, list(range(len(self.chkbox)))): if i.isChecked(): boxCheck += 1 self.axes.plot(self.obj_dataext.x, self.obj_dataext.y[j], c=self.color[j], label=str(j + 1)) self.axes.set_xlabel('freq-->') if j < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) if boxCheck == 0: QtGui.QMessageBox.about( self, "Warning!!", "Please select at least one Node OR Branch") self.canvas.draw() def onPush_trans(self): self.axes.cla() boxCheck = 0 for i, j in zip(self.chkbox, list(range(len(self.chkbox)))): if i.isChecked(): boxCheck += 1 self.axes.plot(self.obj_dataext.x, self.obj_dataext.y[j], c=self.color[j], label=str(j + 1)) self.axes.set_xlabel('time-->') if j < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) if boxCheck == 0: QtGui.QMessageBox.about( self, "Warning!!", "Please select at least one Node OR Branch") self.canvas.draw() def onPush_dc(self): boxCheck = 0 self.axes.cla() for i, j in zip(self.chkbox, list(range(len(self.chkbox)))): if i.isChecked(): boxCheck += 1 self.axes.plot(self.obj_dataext.x, self.obj_dataext.y[j], c=self.color[j], label=str(j + 1)) self.axes.set_xlabel('Voltage Sweep(V)-->') if j < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) if boxCheck == 0: QtGui.QMessageBox.about( self, "Warning!!", "Please select atleast one Node OR Branch") self.canvas.draw() def colorName(self, letter): return { 'r': 'color:red', 'b': 'color:blue', 'g': 'color:green', 'y': 'color:yellow', 'c': 'color:cyan', 'm': 'color:magenta', 'k': 'color:black' }[letter] def multiMeter(self): print("Function : MultiMeter") self.obj = {} boxCheck = 0 loc_x = 300 loc_y = 300 for i, j in zip(self.chkbox, list(range(len(self.chkbox)))): if i.isChecked(): print("Check box", self.obj_dataext.NBList[j]) boxCheck += 1 if self.obj_dataext.NBList[j] in self.obj_dataext.NBIList: voltFlag = False else: voltFlag = True # Initializing Multimeter self.obj[j] = MultimeterWidgetClass( self.obj_dataext.NBList[j], self.getRMSValue(self.obj_dataext.y[j]), loc_x, loc_y, voltFlag) loc_x += 50 loc_y += 50 # Adding object of multimeter to dictionary (self.obj_appconfig.dock_dict[ self.obj_appconfig.current_project['ProjectName']].append( self.obj[j])) if boxCheck == 0: QtGui.QMessageBox.about( self, "Warning!!", "Please select at least one Node OR Branch") def getRMSValue(self, dataPoints): getcontext().prec = 5 return np.sqrt(np.mean(np.square(dataPoints)))
class OpenModelicaEditor(QtGui.QWidget): def __init__(self, dir=None): QtGui.QWidget.__init__(self) self.obj_validation = Validation() self.obj_appconfig = Appconfig() self.projDir = dir self.projName = os.path.basename(self.projDir) self.ngspiceNetlist = os.path.join(self.projDir, self.projName + ".cir.out") self.modelicaNetlist = os.path.join(self.projDir, self.projName + ".mo") self.map_json = Appconfig.modelica_map_json self.grid = QtGui.QGridLayout() self.FileEdit = QtGui.QLineEdit() self.FileEdit.setText(self.ngspiceNetlist) self.grid.addWidget(self.FileEdit, 0, 0) self.browsebtn = QtGui.QPushButton("Browse") self.browsebtn.clicked.connect(self.browseFile) self.grid.addWidget(self.browsebtn, 0, 1) self.convertbtn = QtGui.QPushButton("Convert") self.convertbtn.clicked.connect(self.callConverter) self.grid.addWidget(self.convertbtn, 2, 1) self.loadOMbtn = QtGui.QPushButton("Load OMEdit") self.loadOMbtn.clicked.connect(self.callOMEdit) self.grid.addWidget(self.loadOMbtn, 3, 1) #self.setGeometry(300, 300, 350, 300) self.setLayout(self.grid) self.show() def browseFile(self): self.ngspiceNetlist = QtGui.QFileDialog.getOpenFileName( self, 'Open Ngspice file', BROWSE_LOCATION) self.FileEdit.setText(self.ngspiceNetlist) def callConverter(self): try: ### TODO self.cmd1 = "python ../ngspicetoModelica/NgspicetoModelica.py " + self.ngspiceNetlist + ' ' + self.map_json #self.obj_workThread1 = Worker.WorkerThread(self.cmd1) #self.obj_workThread1.start() convert_process = Popen(self.cmd1, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) error_code = convert_process.stdout.read() if not error_code: self.msg = QtGui.QMessageBox() self.msg.setText( "Ngspice netlist successfully converted to OpenModelica netlist" ) self.obj_appconfig.print_info( "Ngspice netlist successfully converted to OpenModelica netlist" ) self.msg.exec_() else: self.err_msg = QtGui.QErrorMessage() self.err_msg.showMessage( 'Unable to convert NgSpice netlist to Modelica netlist. Check the netlist :' + error_code) self.err_msg.setWindowTitle( "Ngspice to Modelica conversion error") self.obj_appconfig.print_error(error_code) except Exception as e: self.msg = QtGui.QErrorMessage() self.msg.showMessage( 'Unable to convert NgSpice netlist to Modelica netlist. Check the netlist :' + str(e)) self.msg.setWindowTitle("Ngspice to Modelica conversion error") def callOMEdit(self): if self.obj_validation.validateTool("OMEdit"): self.cmd2 = "OMEdit " + self.modelicaNetlist self.obj_workThread2 = Worker.WorkerThread(self.cmd2) self.obj_workThread2.start() print "OMEdit called" self.obj_appconfig.print_info("OMEdit called") else: self.msg = QtGui.QMessageBox() self.msgContent = "There was an error while opening OMEdit.<br/>\ Please make sure OpenModelica is installed in your system. <br/>\ To install it on Linux : Go to <a href=https://www.openmodelica.org/download/download-linux>OpenModelica Linux</a> and install nigthly build release.<br/>\ To install it on Windows : Go to <a href=https://www.openmodelica.org/download/download-windows>OpenModelica Windows</a> and install latest version.<br/>" self.msg.setTextFormat(QtCore.Qt.RichText) self.msg.setText(self.msgContent) self.msg.setWindowTitle("Missing OpenModelica") self.obj_appconfig.print_info(self.msgContent) self.msg.exec_()
class Application(QtGui.QMainWindow): global project_name """ Its our main window of application """ def __init__(self,*args): """ Initialize main Application window """ #Calling __init__ of super class QtGui.QMainWindow.__init__(self,*args) #Flag for online-offline mode. Default is set offline mode. #Mode gets updated dynamically from the previous eSim session. self.online_flag = False #Creating require Object self.obj_workspace = Workspace.Workspace() self.obj_Mainview = MainView() self.obj_kicad = Kicad(self.obj_Mainview.obj_dockarea) self.obj_appconfig = Appconfig() self.obj_validation = Validation() #Initialize all widget self.setCentralWidget(self.obj_Mainview) self.initToolBar() self.setGeometry(self.obj_appconfig._app_xpos, self.obj_appconfig._app_ypos, self.obj_appconfig._app_width, self.obj_appconfig._app_heigth) self.setWindowTitle(self.obj_appconfig._APPLICATION) self.showMaximized() self.setWindowIcon(QtGui.QIcon('../../images/logo.png')) #self.show() self.systemTrayIcon = QtGui.QSystemTrayIcon(self) self.systemTrayIcon.setIcon(QtGui.QIcon('../../images/logo.png')) self.systemTrayIcon.setVisible(True) def initToolBar(self): """ This function initialize Tool Bar """ #Top Tool bar self.newproj = QtGui.QAction(QtGui.QIcon('../../images/newProject.png'),'<b>New Project</b>',self) self.newproj.setShortcut('Ctrl+N') self.newproj.triggered.connect(self.new_project) #self.newproj.connect(self.newproj,QtCore.SIGNAL('triggered()'),self,QtCore.SLOT(self.new_project())) self.openproj = QtGui.QAction(QtGui.QIcon('../../images/openProject.png'),'<b>Open Project</b>',self) self.openproj.setShortcut('Ctrl+O') self.openproj.triggered.connect(self.open_project) self.closeproj = QtGui.QAction(QtGui.QIcon('../../images/closeProject.png'),'<b>Close Project</b>',self) self.closeproj.setShortcut('Ctrl+X') self.closeproj.triggered.connect(self.close_project) for file in os.listdir(os.getenv('HOME') + "/.config/kicad"): if file.startswith("fp-lib-table"): if file.endswith("offline"): self.webConnect = QtGui.QAction(QtGui.QIcon('../../images/online.png'),'<b>Go Offline</b>',self) self.online_flag = True break elif file.endswith("online"): self.webConnect = QtGui.QAction(QtGui.QIcon('../../images/offline.png'),'<b>Go Online</b>',self) self.online_flag = False break self.webConnect.setShortcut('Ctrl+G') self.webConnect.triggered.connect(self.go_online_offline) self.helpfile = QtGui.QAction(QtGui.QIcon('../../images/helpProject.png'),'<b>Help</b>',self) self.helpfile.setShortcut('Ctrl+H') self.helpfile.triggered.connect(self.help_project) self.topToolbar = self.addToolBar('Top Tool Bar') self.topToolbar.addAction(self.newproj) self.topToolbar.addAction(self.openproj) self.topToolbar.addAction(self.closeproj) self.topToolbar.addAction(self.webConnect) self.topToolbar.addAction(self.helpfile) self.spacer = QtGui.QWidget() self.spacer.setSizePolicy(QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Expanding) self.topToolbar.addWidget(self.spacer) self.logo = QtGui.QLabel() self.logopic = QtGui.QPixmap(os.path.join(os.path.abspath('../..'),'images','fosseeLogo.png')) self.logopic = self.logopic.scaled(QSize(150,150),QtCore.Qt.KeepAspectRatio) self.logo.setPixmap(self.logopic) self.logo.setStyleSheet("padding:0 15px 0 0;") self.topToolbar.addWidget(self.logo) #Left Tool bar Action Widget self.kicad = QtGui.QAction(QtGui.QIcon('../../images/kicad.png'),'<b>Open Schematic</b>',self) self.kicad.triggered.connect(self.obj_kicad.openSchematic) self.conversion = QtGui.QAction(QtGui.QIcon('../../images/ki-ng.png'),'<b>Convert Kicad to Ngspice</b>',self) self.conversion.triggered.connect(self.obj_kicad.openKicadToNgspice) self.ngspice = QtGui.QAction(QtGui.QIcon('../../images/ngspice.png'), '<b>Simulation</b>', self) self.ngspice.triggered.connect(self.open_ngspice) self.model = QtGui.QAction(QtGui.QIcon('../../images/model.png'),'<b>Model Editor</b>',self) self.model.triggered.connect(self.open_modelEditor) self.subcircuit=QtGui.QAction(QtGui.QIcon('../../images/subckt.png'),'<b>Subcircuit</b>',self) self.subcircuit.triggered.connect(self.open_subcircuit) self.nghdl = QtGui.QAction(QtGui.QIcon('../../images/nghdl.png'), '<b>Nghdl</b>', self) self.nghdl.triggered.connect(self.open_nghdl) self.omedit = QtGui.QAction(QtGui.QIcon('../../images/omedit.png'),'<b>Modelica Converter</b>',self) self.omedit.triggered.connect(self.open_OMedit) self.omoptim=QtGui.QAction(QtGui.QIcon('../../images/omoptim.png'),'<b>OM Optimisation</b>',self) self.omoptim.triggered.connect(self.open_OMoptim) #Adding Action Widget to tool bar self.lefttoolbar = QtGui.QToolBar('Left ToolBar') self.addToolBar(QtCore.Qt.LeftToolBarArea, self.lefttoolbar) self.lefttoolbar.addAction(self.kicad) self.lefttoolbar.addAction(self.conversion) self.lefttoolbar.addAction(self.ngspice) self.lefttoolbar.addAction(self.model) self.lefttoolbar.addAction(self.subcircuit) self.lefttoolbar.addAction(self.nghdl) self.lefttoolbar.addAction(self.omedit) self.lefttoolbar.addAction(self.omoptim) self.lefttoolbar.setOrientation(QtCore.Qt.Vertical) self.lefttoolbar.setIconSize(QSize(40,40)) def closeEvent(self, event): exit_msg = "Are you sure you want to exit the program ? All unsaved data will be lost." reply = QtGui.QMessageBox.question(self, 'Message', exit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: for proc in self.obj_appconfig.procThread_list: try: proc.terminate() except: pass try: for process_object in self.obj_appconfig.process_obj: try: process_object.close() except: pass except: pass ##Just checking if open project and New project window is open. If yes just close it when application is closed try: self.project.close() except: pass event.accept() self.systemTrayIcon.showMessage('Exit', 'eSim is Closed.') elif reply == QtGui.QMessageBox.No: event.ignore() def close_project(self): print "Function : Close Project" current_project = self.obj_appconfig.current_project['ProjectName'] if current_project==None: pass else: for pid in self.obj_appconfig.proc_dict[self.obj_appconfig.current_project['ProjectName']]: try: os.kill(pid, 9) except: pass self.obj_Mainview.obj_dockarea.closeDock() self.obj_appconfig.current_project['ProjectName'] = None self.systemTrayIcon.showMessage('Close', 'Current project '+os.path.basename(current_project)+' is Closed.') def new_project(self): """ This function call New Project Info class. """ text, ok = QtGui.QInputDialog.getText(self, 'New Project Info','Enter Project Name:') if ok: self.projname = (str(text)) self.project = NewProjectInfo() directory, filelist =self.project.createProject(self.projname) self.obj_Mainview.obj_projectExplorer.addTreeNode(directory, filelist) else: print "No new project created" self.obj_appconfig.print_info('No new project created') try: self.obj_appconfig.print_info('Current project is : ' + self.obj_appconfig.current_project["ProjectName"]) except: pass def open_project(self): """ This project call Open Project Info class """ print "Function : Open Project" self.project = OpenProjectInfo() try: directory, filelist = self.project.body() self.obj_Mainview.obj_projectExplorer.addTreeNode(directory, filelist) except: pass def help_project(self): print "Function : Help" self.obj_appconfig.print_info('Help is called') print "Current Project is : ",self.obj_appconfig.current_project self.obj_Mainview.obj_dockarea.usermanual() def go_online_offline(self): if not self.obj_kicad.check_open_schematic(): if self.online_flag: os.rename(os.getenv('HOME') + "/.config/kicad/fp-lib-table", os.getenv('HOME') + "/.config/kicad/fp-lib-table-online") os.rename(os.getenv('HOME') + "/.config/kicad/fp-lib-table-offline", os.getenv('HOME') + "/.config/kicad/fp-lib-table") self.webConnect.setIcon(QtGui.QIcon('../../images/offline.png')) self.webConnect.setText('<b>Go Online</b>') self.online_flag = False else: os.rename(os.getenv('HOME') + "/.config/kicad/fp-lib-table", os.getenv('HOME') + "/.config/kicad/fp-lib-table-offline") os.rename(os.getenv('HOME') + "/.config/kicad/fp-lib-table-online", os.getenv('HOME') + "/.config/kicad/fp-lib-table") self.webConnect.setIcon(QtGui.QIcon('../../images/online.png')) self.webConnect.setText('<b>Go Offline</b>') self.online_flag = True else: self.msg = QtGui.QErrorMessage() self.msg.showMessage('Please save and close all the Kicad Windows first, and then change the online-offline mode') self.msg.setWindowTitle("Error Message") def open_ngspice(self): """ This Function execute ngspice on current project """ self.projDir = self.obj_appconfig.current_project["ProjectName"] if self.projDir != None: self.obj_Mainview.obj_dockarea.ngspiceEditor(self.projDir) time.sleep(2) #Need permanent solution #Calling Python Plotting try: self.obj_Mainview.obj_dockarea.plottingEditor() except Exception as e: self.msg = QtGui.QErrorMessage(None) self.msg.showMessage('Error while opening python plotting Editor. Please look at console for more details ') print "Exception Message:",str(e) self.obj_appconfig.print_error('Exception Message : ' + str(e)) self.msg.setWindowTitle("Error Message") else: self.msg = QtGui.QErrorMessage() self.msg.showMessage('Please select the project first. You can either create new project or open existing project') self.msg.setWindowTitle("Error Message") def open_subcircuit(self): print "Function : Subcircuit editor" self.obj_appconfig.print_info('Subcircuit editor is called') self.obj_Mainview.obj_dockarea.subcircuiteditor() def open_nghdl(self): print "Function : Nghdl" self.obj_appconfig.print_info('Nghdl is called') if self.obj_validation.validateTool('nghdl'): self.cmd = 'nghdl -e' self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() else: self.msg = QtGui.QErrorMessage(None) self.msg.showMessage('Error while opening nghdl. Please make sure nghdl is installed') self.obj_appconfig.print_error('Error while opening nghdl. Please make sure nghdl is installed') self.msg.setWindowTitle('nghdl Error Message') def open_modelEditor(self): print "Function : Model editor" self.obj_appconfig.print_info('Model editor is called') self.obj_Mainview.obj_dockarea.modelEditor() def open_OMedit(self): """ This function call ngspice to OM edit converter and then launch OM edit. """ self.obj_appconfig.print_info('OM edit is called') self.projDir = self.obj_appconfig.current_project["ProjectName"] if self.projDir != None: if self.obj_validation.validateCirOut(self.projDir): self.projName = os.path.basename(self.projDir) self.ngspiceNetlist = os.path.join(self.projDir,self.projName+".cir.out") self.modelicaNetlist = os.path.join(self.projDir,self.projName+".mo") """ try: #Creating a command for Ngspice to Modelica converter self.cmd1 = "python ../ngspicetoModelica/NgspicetoModelica.py "+self.ngspiceNetlist self.obj_workThread1 = Worker.WorkerThread(self.cmd1) self.obj_workThread1.start() if self.obj_validation.validateTool("OMEdit"): #Creating command to run OMEdit self.cmd2 = "OMEdit "+self.modelicaNetlist self.obj_workThread2 = Worker.WorkerThread(self.cmd2) self.obj_workThread2.start() else: self.msg = QtGui.QMessageBox() self.msgContent = "There was an error while opening OMEdit.<br/>\ Please make sure OpenModelica is installed in your system. <br/>\ To install it on Linux : Go to <a href=https://www.openmodelica.org/download/download-linux>OpenModelica Linux</a> and install nigthly build release.<br/>\ To install it on Windows : Go to <a href=https://www.openmodelica.org/download/download-windows>OpenModelica Windows</a> and install latest version.<br/>" self.msg.setTextFormat(QtCore.Qt.RichText) self.msg.setText(self.msgContent) self.msg.setWindowTitle("Missing OpenModelica") self.obj_appconfig.print_info(self.msgContent) self.msg.exec_() except Exception as e: self.msg = QtGui.QErrorMessage() self.msg.showMessage('Unable to convert NgSpice netlist to Modelica netlist :'+str(e)) self.msg.setWindowTitle("Ngspice to Modelica conversion error") self.obj_appconfig.print_error(str(e)) """ self.obj_Mainview.obj_dockarea.modelicaEditor(self.projDir) else: self.msg = QtGui.QErrorMessage() self.msg.showMessage('Current project does not contain any ngspice file. Please create ngspice file with extension .cir.out') self.msg.setWindowTitle("Missing Ngspice netlist") else: self.msg = QtGui.QErrorMessage() self.msg.showMessage('Please select the project first. You can either create new project or open existing project') self.msg.setWindowTitle("Error Message") def open_OMoptim(self): print "Function : OM Optim" self.obj_appconfig.print_info('OM Optim is called') #Check if OMOptim is installed if self.obj_validation.validateTool("OMOptim"): #Creating a command to run self.cmd = "OMOptim" self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() else: self.msg = QtGui.QMessageBox() self.msgContent = "There was an error while opening OMOptim.<br/>\ Please make sure OpenModelica is installed in your system. <br/>\ To install it on Linux : Go to <a href=https://www.openmodelica.org/download/download-linux>OpenModelica Linux</a> and install nigthly build release.<br/>\ To install it on Windows : Go to <a href=https://www.openmodelica.org/download/download-windows>OpenModelica Windows</a> and install latest version.<br/>" self.msg.setTextFormat(QtCore.Qt.RichText) self.msg.setText(self.msgContent) self.msg.setWindowTitle("Error Message") self.obj_appconfig.print_info(self.msgContent) self.msg.exec_()
class NewProjectInfo(QtGui.QWidget): """ This class is called when User create new Project. """ def __init__(self): super(NewProjectInfo, self).__init__() self.obj_validation = Validation() self.obj_appconfig = Appconfig() def createProject(self, projName): """ This function create Project related directories and files """ #print "Create Project Called" self.projName = projName self.workspace = self.obj_appconfig.default_workspace['workspace'] #self.projName = self.projEdit.text() self.projName = str(self.projName).rstrip().lstrip( ) #Remove leading and trailing space self.projDir = os.path.join(self.workspace, str(self.projName)) #Validation for newProject if self.projName == "": self.reply = "NONE" else: self.reply = self.obj_validation.validateNewproj(str(self.projDir)) #Checking Validations Response if self.reply == "VALID": #create project directory try: os.mkdir(self.projDir) self.close() self.projFile = os.path.join(self.projDir, self.projName + ".proj") f = open(self.projFile, "w") except: #print "Some Thing Went Wrong" self.msg = QtGui.QErrorMessage(self) self.msg.showMessage( 'Unable to create project. Please make sure you have write permission on ' + self.workspace) self.msg.setWindowTitle("Error Message") f.write("schematicFile " + self.projName + ".sch\n") f.close() #Now Change the current working project newprojlist = [] #self.obj_appconfig = Appconfig() self.obj_appconfig.current_project['ProjectName'] = self.projDir newprojlist.append(self.projName + '.proj') self.obj_appconfig.project_explorer[self.projDir] = newprojlist self.obj_appconfig.print_info('New project created : ' + self.projName) self.obj_appconfig.print_info('Current project is : ' + self.projDir) json.dump(self.obj_appconfig.project_explorer, open(self.obj_appconfig.dictPath, 'w')) return self.projDir, newprojlist elif self.reply == "CHECKEXIST": #print "Project already exist" self.msg = QtGui.QErrorMessage(self) self.msg.showMessage( 'The project "' + self.projName + '" already exist.Please select the different name or delete existing project' ) self.msg.setWindowTitle("Error Message") elif self.reply == "CHECKNAME": #print "Name is not proper" self.msg = QtGui.QErrorMessage(self) self.msg.showMessage( 'The project name should not contain space between them') self.msg.setWindowTitle("Error Message") elif self.reply == "NONE": #print "Empty Project Name" self.msg = QtGui.QErrorMessage(self) self.msg.showMessage('The project name cannot be empty') self.msg.setWindowTitle("Error Message") def cancelProject(self): self.close()
class Kicad: """ This class called the Kicad Schematic,KicadtoNgspice Converter,Layout editor and Footprint Editor """ def __init__(self, dockarea): self.obj_validation = Validation.Validation() self.obj_appconfig = Appconfig() self.obj_dockarea = dockarea def openSchematic(self): """ This function create command to open Kicad schematic """ print "Function : Open Kicad Schematic" self.projDir = self.obj_appconfig.current_project["ProjectName"] try: self.obj_appconfig.print_info( 'Kicad Schematic is called for project ' + self.projDir) except: pass #Validating if current project is available or not if self.obj_validation.validateKicad(self.projDir): #print "calling Kicad schematic ",self.projDir self.projName = os.path.basename(self.projDir) self.project = os.path.join(self.projDir, self.projName) #Creating a command to run self.cmd = "eeschema " + self.project + ".sch " self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() else: self.msg = QtGui.QErrorMessage(None) self.msg.showMessage( 'Please select the project first. You can either create new project or open existing project' ) self.obj_appconfig.print_warning( 'Please select the project first. You can either create new project or open existing project' ) self.msg.setWindowTitle("Error Message") ''' #Commenting as it is no longer needed as PBC and Layout will open from eeschema def openFootprint(self): """ This function create command to open Footprint editor """ print "Kicad Foot print Editor called" self.projDir = self.obj_appconfig.current_project["ProjectName"] try: self.obj_appconfig.print_info('Kicad Footprint Editor is called for project : ' + self.projDir) except: pass #Validating if current project is available or not if self.obj_validation.validateKicad(self.projDir): #print "calling Kicad FootPrint Editor ",self.projDir self.projName = os.path.basename(self.projDir) self.project = os.path.join(self.projDir,self.projName) #Creating a command to run self.cmd = "cvpcb "+self.project+".net " self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() else: self.msg = QtGui.QErrorMessage(None) self.msg.showMessage('Please select the project first. You can either create new project or open existing project') self.obj_appconfig.print_warning('Please select the project first. You can either create new project or open existing project') self.msg.setWindowTitle("Error Message") def openLayout(self): """ This function create command to open Layout editor """ print "Kicad Layout is called" self.projDir = self.obj_appconfig.current_project["ProjectName"] try: self.obj_appconfig.print_info('PCB Layout is called for project : ' + self.projDir) except: pass #Validating if current project is available or not if self.obj_validation.validateKicad(self.projDir): print "calling Kicad schematic ",self.projDir self.projName = os.path.basename(self.projDir) self.project = os.path.join(self.projDir,self.projName) #Creating a command to run self.cmd = "pcbnew "+self.project+".net " self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() else: self.msg = QtGui.QErrorMessage(None) self.msg.showMessage('Please select the project first. You can either create new project or open existing project') self.obj_appconfig.print_warning('Please select the project first. You can either create new project or open existing project') self.msg.setWindowTitle("Error Message") ''' def openKicadToNgspice(self): """ This function create command to call kicad to Ngspice converter. """ print "Function: Open Kicad to Ngspice Converter" self.projDir = self.obj_appconfig.current_project["ProjectName"] try: self.obj_appconfig.print_info( 'Kicad to Ngspice Conversion is called') self.obj_appconfig.print_info('Current Project is ' + self.projDir) except: pass #Validating if current project is available or not if self.obj_validation.validateKicad(self.projDir): #Cheking if project has .cir file or not if self.obj_validation.validateCir(self.projDir): self.projName = os.path.basename(self.projDir) self.project = os.path.join(self.projDir, self.projName) ## TODO #Creating a command to run """ self.cmd = "python ../kicadtoNgspice/KicadtoNgspice.py " +self.project+".cir " self.obj_workThread = Worker.WorkerThread(self.cmd) self.obj_workThread.start() """ var = self.project + ".cir" self.obj_dockarea.kicadToNgspiceEditor(var) else: self.msg = QtGui.QErrorMessage(None) self.msg.showMessage( 'The project does not contain any Kicad netlist file for conversion.' ) self.obj_appconfig.print_error( 'The project does not contain any Kicad netlist file for conversion.' ) self.msg.setWindowTitle("Error Message") else: self.msg = QtGui.QErrorMessage(None) self.msg.showMessage( 'Please select the project first. You can either create new project or open existing project' ) self.obj_appconfig.print_warning( 'Please select the project first. You can either create new project or open existing project' ) self.msg.setWindowTitle("Error Message")
class plotWindow(QtGui.QMainWindow): def __init__(self, fpath, projectName): QtGui.QMainWindow.__init__(self) self.fpath = fpath #+".cir.out" self.projectName = projectName self.obj_appconfig = Appconfig() print "Path : ", self.fpath print "Project Name : ", self.projectName self.obj_appconfig.print_info('Ngspice simulation is called : ' + self.fpath) self.obj_appconfig.print_info('PythonPlotting is called : ' + self.fpath) self.combo = [] self.combo1 = [] self.combo1_rev = [] #Creating Frame self.createMainFrame() def createMainFrame(self): self.mainFrame = QtGui.QWidget() self.dpi = 100 self.fig = Figure((7.0, 7.0), dpi=self.dpi) #Creating Canvas which will figure self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self.mainFrame) self.axes = self.fig.add_subplot(111) self.navToolBar = NavigationToolbar(self.canvas, self.mainFrame) #LeftVbox hold navigation tool bar and canvas self.left_vbox = QtGui.QVBoxLayout() self.left_vbox.addWidget(self.navToolBar) self.left_vbox.addWidget(self.canvas) #right VBOX is main Layout which hold right grid(bottom part) and top grid(top part) self.right_vbox = QtGui.QVBoxLayout() self.right_grid = QtGui.QGridLayout() self.top_grid = QtGui.QGridLayout() #Get DataExtraction Details self.obj_dataext = DataExtraction() self.plotType = self.obj_dataext.openFile(self.fpath) self.obj_dataext.computeAxes() self.a = self.obj_dataext.numVals() self.chkbox = [] ########### Generating list of colors : self.full_colors = [ 'r', 'b', 'g', 'y', 'c', 'm', 'k' ] #,(0.4,0.5,0.2),(0.1,0.4,0.9),(0.4,0.9,0.2),(0.9,0.4,0.9)] self.color = [] for i in range(0, self.a[0] - 1): if i % 7 == 0: self.color.append(self.full_colors[0]) elif (i - 1) % 7 == 0: self.color.append(self.full_colors[1]) elif (i - 2) % 7 == 0: self.color.append(self.full_colors[2]) elif (i - 3) % 7 == 0: self.color.append(self.full_colors[3]) elif (i - 4) % 7 == 0: self.color.append(self.full_colors[4]) elif (i - 5) % 7 == 0: self.color.append(self.full_colors[5]) elif (i - 6) % 7 == 0: self.color.append(self.full_colors[6]) ###########Color generation ends here #Total number of voltage source self.volts_length = self.a[1] self.analysisType = QtGui.QLabel() self.top_grid.addWidget(self.analysisType, 0, 0) self.listNode = QtGui.QLabel() self.top_grid.addWidget(self.listNode, 1, 0) self.listBranch = QtGui.QLabel() self.top_grid.addWidget(self.listBranch, self.a[1] + 2, 0) for i in range(0, self.a[1]): #a[0]-1 self.chkbox.append(QtGui.QCheckBox(self.obj_dataext.NBList[i])) self.chkbox[i].setStyleSheet('color') self.chkbox[i].setToolTip('<b>Check To Plot</b>') self.top_grid.addWidget(self.chkbox[i], i + 2, 0) self.colorLab = QtGui.QLabel() self.colorLab.setText('____') self.colorLab.setStyleSheet( self.colorName(self.color[i]) + '; font-weight = bold;') self.top_grid.addWidget(self.colorLab, i + 2, 1) for i in range(self.a[1], self.a[0] - 1): #a[0]-1 self.chkbox.append(QtGui.QCheckBox(self.obj_dataext.NBList[i])) self.chkbox[i].setToolTip('<b>Check To Plot</b>') self.top_grid.addWidget(self.chkbox[i], i + 3, 0) self.colorLab = QtGui.QLabel() self.colorLab.setText('____') self.colorLab.setStyleSheet( self.colorName(self.color[i]) + '; font-weight = bold;') self.top_grid.addWidget(self.colorLab, i + 3, 1) self.clear = QtGui.QPushButton("Clear") self.warnning = QtGui.QLabel() self.funcName = QtGui.QLabel() self.funcExample = QtGui.QLabel() self.plotbtn = QtGui.QPushButton("Plot") self.plotbtn.setToolTip('<b>Press</b> to Plot') self.text = QtGui.QLineEdit() self.funcLabel = QtGui.QLabel() self.palette1 = QtGui.QPalette() self.palette2 = QtGui.QPalette() self.plotfuncbtn = QtGui.QPushButton("Plot Function") self.plotfuncbtn.setToolTip('<b>Press</b> to Plot the function') self.palette1.setColor(QtGui.QPalette.Foreground, QtCore.Qt.blue) self.palette2.setColor(QtGui.QPalette.Foreground, QtCore.Qt.red) self.funcName.setPalette(self.palette1) self.funcExample.setPalette(self.palette2) self.right_vbox.addLayout(self.top_grid) self.right_vbox.addWidget(self.plotbtn) self.right_grid.addWidget(self.funcLabel, 1, 0) self.right_grid.addWidget(self.text, 1, 1) self.right_grid.addWidget(self.plotfuncbtn, 2, 1) self.right_grid.addWidget(self.clear, 2, 0) self.right_grid.addWidget(self.warnning, 3, 0) self.right_grid.addWidget(self.funcName, 4, 0) self.right_grid.addWidget(self.funcExample, 4, 1) self.right_vbox.addLayout(self.right_grid) self.hbox = QtGui.QHBoxLayout() self.hbox.addLayout(self.left_vbox) self.hbox.addLayout(self.right_vbox) self.widget = QtGui.QWidget() self.widget.setLayout(self.hbox) #finalvbox self.scrollArea = QtGui.QScrollArea() self.scrollArea.setWidgetResizable(True) self.scrollArea.setWidget(self.widget) self.finalhbox = QtGui.QHBoxLayout() self.finalhbox.addWidget(self.scrollArea) self.mainFrame.setLayout(self.finalhbox) self.showMaximized() self.listNode.setText("<font color='indigo'>List of Nodes:</font>") self.listBranch.setText( "<font color='indigo'>List of Branches:</font>") self.funcLabel.setText("<font color='indigo'>Function:</font>") self.funcName.setText("<font color='indigo'>Examples:</font>\ <br><br>Addition:<br>Subtraction:<br>Multiplication:<br>Division:<br>Comparison:" ) self.funcExample.setText( "\n\nV(1) + V(2)\nV(1) - V(2)\nV(1) * V(2)\nV(1) / V(2)\nV(1) vs V(2)" ) #Connecting to plot and clear function self.connect(self.clear, QtCore.SIGNAL('clicked()'), self.pushedClear) self.connect(self.plotfuncbtn, QtCore.SIGNAL('clicked()'), self.pushedPlotFunc) if self.plotType[0] == 0: self.analysisType.setText("<b>AC Analysis</b>") if self.plotType[1] == 1: self.connect(self.plotbtn, QtCore.SIGNAL('clicked()'), self.onPush_decade) else: self.connect(self.plotbtn, QtCore.SIGNAL('clicked()'), self.onPush_ac) elif self.plotType[0] == 1: self.analysisType.setText("<b>Transient Analysis</b>") self.connect(self.plotbtn, QtCore.SIGNAL('clicked()'), self.onPush_trans) else: self.analysisType.setText("<b>DC Analysis</b>") self.connect(self.plotbtn, QtCore.SIGNAL('clicked()'), self.onPush_dc) self.setCentralWidget(self.mainFrame) def pushedClear(self): #print "Calling Clear Canvas function" self.text.clear() self.axes.cla() self.canvas.draw() QtCore.SLOT('quit()') def pushedPlotFunc(self): #print "Calling Plot function" self.parts = str(self.text.text()) self.parts = self.parts.split(" ") #print "Parts :",self.parts if self.parts[len(self.parts) - 1] == '': self.parts = self.parts[0:-1] self.values = self.parts self.comboAll = [] self.axes.cla() self.plotType2 = self.obj_dataext.openFile(self.fpath) if len(self.parts) <= 2: self.warnning.setText("Too few arguments!\nRefer syntax below!") QtGui.QMessageBox.about( self, "Warning!!", "Too Few Arguments/SYNTAX Error!\n Refer Examples") else: self.warnning.setText("") a = [] finalResult = [] p = 0 for i in range(len(self.parts)): #print "I",i if i % 2 == 0: #print "I'm in:" for j in range(len(self.obj_dataext.NBList)): if self.parts[i] == self.obj_dataext.NBList[j]: #print "I got you:",self.parts[i] a.append(j) if len(a) != len(self.parts) // 2 + 1: QtGui.QMessageBox.about( self, "Warning!!", "One of the operands doesn't belong to the above list of Nodes!!" ) for i in a: self.comboAll.append(self.obj_dataext.y[i]) for i in range(len(a)): if a[i] == len(self.obj_dataext.NBList): QtGui.QMessageBox.about( self, "Warning!!", "One of the operands doesn't belong to the above list!!") self.warnning.setText( "<font color='red'>To Err Is Human!<br>One of the operands doesn't belong to the above list!!</font>" ) if self.parts[1] == 'vs': if len(self.parts) > 3: self.warnning.setText("Enter two operands only!!") QtGui.QMessageBox.about(self, "Warning!!", "Recheck the expression syntax!") else: self.axes.cla() for i in range(len(self.obj_dataext.y[a[0]])): self.combo.append(self.obj_dataext.y[a[0]][i]) self.combo1.append(self.obj_dataext.y[a[1]][i]) self.axes.plot(self.combo, self.combo1, c=self.color[1], label=str(2)) #_rev if max(a) < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') self.axes.set_xlabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.set_ylabel('Current(I)-->') elif max(a) >= self.volts_length and min(a) < self.volts_length: QtGui.QMessageBox.about(self, "Warning!!", "Do not combine Voltage and Current!!") else: for j in range(len(self.comboAll[0])): for i in range(len(self.values)): if i % 2 == 0: self.values[i] = str(self.comboAll[i // 2][j]) re = " ".join(self.values[:]) try: finalResult.append(eval(re)) except ArithmeticError: QtGui.QMessageBox.about(self, "Warning!!", "Dividing by zero!!") if self.plotType2[0] == 0: #self.setWindowTitle('AC Analysis') if self.plotType2[1] == 1: self.axes.semilogx(self.obj_dataext.x, finalResult, c=self.color[0], label=str(1)) else: self.axes.plot(self.obj_dataext.x, finalResult, c=self.color[0], label=str(1)) self.axes.set_xlabel('freq-->') if max(a) < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') elif self.plotType2[0] == 1: #self.setWindowTitle('Transient Analysis') self.axes.plot(self.obj_dataext.x, finalResult, c=self.color[0], label=str(1)) self.axes.set_xlabel('time-->') if max(a) < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') else: #self.setWindowTitle('DC Analysis') self.axes.plot(self.obj_dataext.x, finalResult, c=self.color[0], label=str(1)) self.axes.set_xlabel('I/P Voltage-->') if max(a) < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) self.canvas.draw() self.combo = [] self.combo1 = [] self.combo1_rev = [] def onPush_decade(self): #print "Calling on push Decade" boxCheck = 0 self.axes.cla() for i, j in zip(self.chkbox, range(len(self.chkbox))): if i.isChecked(): boxCheck += 1 self.axes.semilogx(self.obj_dataext.x, self.obj_dataext.y[j], c=self.color[j], label=str(j + 1)) self.axes.set_xlabel('freq-->') if j < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) if boxCheck == 0: QtGui.QMessageBox.about( self, "Warning!!", "Please select at least one Node OR Branch") self.canvas.draw() def onPush_ac(self): #print "Calling on push ac" self.axes.cla() boxCheck = 0 for i, j in zip(self.chkbox, range(len(self.chkbox))): if i.isChecked(): boxCheck += 1 self.axes.plot(self.obj_dataext.x, self.obj_dataext.y[j], c=self.color[j], label=str(j + 1)) self.axes.set_xlabel('freq-->') if j < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) if boxCheck == 0: QtGui.QMessageBox.about( self, "Warning!!", "Please select at least one Node OR Branch") self.canvas.draw() def onPush_trans(self): #print "Calling on push trans" self.axes.cla() boxCheck = 0 for i, j in zip(self.chkbox, range(len(self.chkbox))): if i.isChecked(): boxCheck += 1 self.axes.plot(self.obj_dataext.x, self.obj_dataext.y[j], c=self.color[j], label=str(j + 1)) self.axes.set_xlabel('time-->') if j < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) if boxCheck == 0: QtGui.QMessageBox.about( self, "Warning!!", "Please select at least one Node OR Branch") self.canvas.draw() def onPush_dc(self): #print "Calling on push dc" boxCheck = 0 self.axes.cla() for i, j in zip(self.chkbox, range(len(self.chkbox))): if i.isChecked(): boxCheck += 1 self.axes.plot(self.obj_dataext.x, self.obj_dataext.y[j], c=self.color[j], label=str(j + 1)) self.axes.set_xlabel('Voltage Sweep(V)-->') if j < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) if boxCheck == 0: QtGui.QMessageBox.about( self, "Warning!!", "Please select atleast one Node OR Branch") self.canvas.draw() def colorName(self, letter): return { 'r': 'color:red', 'b': 'color:blue', 'g': 'color:green', 'y': 'color:yellow', 'c': 'color:cyan', 'm': 'color:magenta', 'k': 'color:black' }[letter]
class ModelEditorclass(QtGui.QWidget): def __init__(self): QtGui.QWidget.__init__(self) self.savepathtest = 'res/deviceModelLibrary' self.obj_appconfig = Appconfig() self.newflag=0 self.layout = QtGui.QVBoxLayout() self.splitter= QtGui.QSplitter() self.grid= QtGui.QGridLayout() self.splitter.setOrientation(QtCore.Qt.Vertical) self.modeltable = QtGui.QTableWidget() self.newbtn = QtGui.QPushButton('New') self.newbtn.setToolTip('<b>Creating new Model Library</b>') self.newbtn.clicked.connect(self.opennew) self.editbtn = QtGui.QPushButton('Edit') self.editbtn.setToolTip('<b>Editing current Model Library</b>') self.editbtn.clicked.connect(self.openedit) self.savebtn = QtGui.QPushButton('Save') self.savebtn.setToolTip('<b>Saves the Model Library</b>') self.savebtn.setDisabled(True) self.savebtn.clicked.connect(self.savemodelfile) self.removebtn = QtGui.QPushButton('Remove') self.removebtn.setHidden(True) self.removebtn.clicked.connect(self.removeparameter) self.addbtn = QtGui.QPushButton('Add') self.addbtn.setHidden(True) self.addbtn.clicked.connect(self.addparameters) self.uploadbtn = QtGui.QPushButton('Upload') self.uploadbtn.setToolTip('<b>Uploading external .lib file to eSim</b>') self.uploadbtn.clicked.connect(self.converttoxml) self.grid.addWidget(self.newbtn, 1,2) self.grid.addWidget(self.editbtn, 1,3) self.grid.addWidget(self.savebtn, 1,4) self.grid.addWidget(self.uploadbtn, 1,5) self.grid.addWidget(self.removebtn, 8,4) self.grid.addWidget(self.addbtn, 5,4) self.radiobtnbox = QtGui.QButtonGroup() self.diode = QtGui.QRadioButton('Diode') self.diode.setDisabled(True) self.bjt = QtGui.QRadioButton('BJT') self.bjt.setDisabled(True) self.mos = QtGui.QRadioButton('MOS') self.mos.setDisabled(True) self.jfet = QtGui.QRadioButton('JFET') self.jfet.setDisabled(True) self.igbt = QtGui.QRadioButton('IGBT') self.igbt.setDisabled(True) self.magnetic = QtGui.QRadioButton('Magnetic Core') self.magnetic.setDisabled(True) self.radiobtnbox.addButton(self.diode) self.diode.clicked.connect(self.diode_click) self.radiobtnbox.addButton(self.bjt) self.bjt.clicked.connect(self.bjt_click) self.radiobtnbox.addButton(self.mos) self.mos.clicked.connect(self.mos_click) self.radiobtnbox.addButton(self.jfet) self.jfet.clicked.connect(self.jfet_click) self.radiobtnbox.addButton(self.igbt) self.igbt.clicked.connect(self.igbt_click) self.radiobtnbox.addButton(self.magnetic) self.magnetic.clicked.connect(self.magnetic_click) self.types= QtGui.QComboBox() self.types.setHidden(True) self.grid.addWidget(self.types,2,2,2,3) self.grid.addWidget(self.diode, 3,1) self.grid.addWidget(self.bjt,4,1) self.grid.addWidget(self.mos,5,1) self.grid.addWidget(self.jfet,6,1) self.grid.addWidget(self.igbt,7,1) self.grid.addWidget(self.magnetic,8,1) self.setLayout(self.grid) self.show() '''To create New Model file ''' def opennew(self): self.addbtn.setHidden(True) try: self.removebtn.setHidden(True) self.modeltable.setHidden(True) except: pass os.chdir(self.savepathtest) text, ok = QtGui.QInputDialog.getText(self, 'New Model','Enter Model Name:') if ok: self.newflag=1 self.diode.setDisabled(False) self.bjt.setDisabled(False) self.mos.setDisabled(False) self.jfet.setDisabled(False) self.igbt.setDisabled(False) self.magnetic.setDisabled(False) self.modelname = (str(text)) else: pass self.validation(text) def diode_click(self): self.openfiletype('Diode') self.types.setHidden(True) def bjt_click(self): self.types.setHidden(False) self.types.clear() self.types.addItem('NPN') self.types.addItem('PNP') filetype = str(self.types.currentText()) self.openfiletype(filetype) self.types.activated[str].connect(self.setfiletype) def mos_click(self): self.types.setHidden(False) self.types.clear() self.types.addItem('NMOS(Level-1 5um)') self.types.addItem('NMOS(Level-3 0.5um)') self.types.addItem('NMOS(Level-8 180um)') self.types.addItem('PMOS(Level-1 5um)') self.types.addItem('PMOS(Level-3 0.5um)') self.types.addItem('PMOS(Level-8 180um)') filetype = str(self.types.currentText()) self.openfiletype(filetype) self.types.activated[str].connect(self.setfiletype) def jfet_click(self): self.types.setHidden(False) self.types.clear() self.types.addItem('N-JFET') self.types.addItem('P-JFET') filetype = str(self.types.currentText()) self.openfiletype(filetype) self.types.activated[str].connect(self.setfiletype) def igbt_click(self): self.types.setHidden(False) self.types.clear() self.types.addItem('N-IGBT') self.types.addItem('P-IGBT') filetype = str(self.types.currentText()) self.openfiletype(filetype) self.types.activated[str].connect(self.setfiletype) def magnetic_click(self): self.openfiletype('Magnetic Core') self.types.setHidden(True) def setfiletype(self,text): self.filetype = str(text) self.openfiletype(self.filetype) def openfiletype(self,filetype): ''' Select the path of the file to be opened depending upon selected file type ''' self.path = 'res/deviceModelLibrary/Templates' if self.diode.isChecked(): if filetype == 'Diode': path = os.path.join(self.path,'D.xml') self.createtable(path) if self.bjt.isChecked(): if filetype == 'NPN': path = os.path.join(self.path,'NPN.xml') self.createtable(path) elif filetype == 'PNP': path = os.path.join(self.path, 'PNP.xml') self.createtable(path) if self.mos.isChecked(): if filetype == 'NMOS(Level-1 5um)': path = os.path.join(self.path, 'NMOS-5um.xml') self.createtable(path) elif filetype == 'NMOS(Level-3 0.5um)': path = os.path.join(self.path, 'NMOS-0.5um.xml') self.createtable(path) elif filetype == 'NMOS(Level-8 180um)': path = os.path.join(self.path, 'NMOS-180nm.xml') self.createtable(path) elif filetype == 'PMOS(Level-1 5um)': path = os.path.join(self.path, 'PMOS-5um.xml') self.createtable(path) elif filetype == 'PMOS(Level-3 0.5um)': path = os.path.join(self.path, 'PMOS-0.5um.xml') self.createtable(path) elif filetype == 'PMOS(Level-8 180um)': path = os.path.join(self.path, 'PMOS-180nm.xml') self.createtable(path) if self.jfet.isChecked(): if filetype == 'N-JFET': path = os.path.join(self.path, 'NJF.xml') self.createtable(path) elif filetype == 'P-JFET': path = os.path.join(self.path, 'PJF.xml') self.createtable(path) if self.igbt.isChecked(): if filetype == 'N-IGBT': path = os.path.join(self.path, 'NIGBT.xml') self.createtable(path) elif filetype == 'P-IGBT': path = os.path.join(self.path, 'PIGBT.xml') self.createtable(path) if self.magnetic.isChecked(): if filetype == 'Magnetic Core': path = os.path.join(self.path, 'CORE.xml') self.createtable(path) else : pass def openedit(self): os.chdir(self.savepathtest) self.newflag=0 self.addbtn.setHidden(True) self.types.setHidden(True) self.diode.setDisabled(True) self.mos.setDisabled(True) self.jfet.setDisabled(True) self.igbt.setDisabled(True) self.bjt.setDisabled(True) self.magnetic.setDisabled(True) try: self.editfile=str(QtGui.QFileDialog.getOpenFileName(self,"Open Library Directory","res/deviceModelLibrary","*.lib")) self.createtable(self.editfile) except: print"No File selected for edit" pass def createtable(self, modelfile): ''' This function Creates the model table by parsing the .xml file ''' self.savebtn.setDisabled(False) self.addbtn.setHidden(False) self.removebtn.setHidden(False) self.modelfile = modelfile self.modeldict = {} self.modeltable = QtGui.QTableWidget() self.modeltable.resizeColumnsToContents() self.modeltable.setColumnCount(2) self.modeltable.resizeRowsToContents() self.modeltable.resize(200,200) self.grid.addWidget(self.modeltable, 3,2,8,2) filepath, filename = os.path.split(self.modelfile) base, ext= os.path.splitext(filename) self.modelfile = os.path.join(filepath, base+'.xml') print"Model File used for creating table : ",self.modelfile self.tree = ET.parse(self.modelfile) self.root= self.tree.getroot() for elem in self.tree.iter(tag='ref_model'): self.ref_model = elem.text for elem in self.tree.iter(tag='model_name'): self.model_name = elem.text row=0 for params in self.tree.findall('param'): for paramlist in params: self.modeldict[paramlist.tag]= paramlist.text row= row+1 self.modeltable.setRowCount(row) count =0 for tags, values in self.modeldict.items(): self.modeltable.setItem(count,0, QTableWidgetItem(tags)) try: valueitem = QTableWidgetItem(values) except: pass self.modeltable.setItem(count,1, valueitem) count= count +1 self.modeltable.setHorizontalHeaderLabels(QtCore.QString("Parameters;Values").split(";")) self.modeltable.show() self.modeltable.itemChanged.connect(self.edit_modeltable) def edit_modeltable(self): self.savebtn.setDisabled(False) try: indexitem = self.modeltable.currentItem() name = str(indexitem.data(0).toString()) rowno = indexitem.row() para = self.modeltable.item(rowno,0) val = str(para.data(0).toString()) self.modeldict[val]= name except: pass def addparameters(self): ''' This function is used to add new parameter in the table ''' text1, ok = QtGui.QInputDialog.getText(self, 'Parameter','Enter Parameter') if ok: if text1 in self.modeldict.keys(): self.msg = QtGui.QErrorMessage(self) self.msg.showMessage("The paramaeter " + text1 + " is already in the list") self.msg.setWindowTitle("Error Message") return text2, ok = QtGui.QInputDialog.getText(self, 'Value','Enter Value') if ok : currentRowCount = self.modeltable.rowCount() self.modeltable.insertRow(currentRowCount) self.modeltable.setItem(currentRowCount, 0, QTableWidgetItem(text1)) self.modeltable.setItem(currentRowCount, 1, QTableWidgetItem(text2)) self.modeldict[str(text1)]= str(text2) else: pass else: pass def savemodelfile(self): if self.newflag== 1: self.createXML(self.model_name) else: self.savethefile(self.editfile) def createXML(self,model_name): ''' This function creates .xml and .lib files from the model table ''' root = ET.Element("library") ET.SubElement(root, "model_name").text = model_name ET.SubElement(root, "ref_model").text = self.modelname param = ET.SubElement(root, "param") for tags, text in self.modeldict.items(): ET.SubElement(param, tags).text = text tree = ET.ElementTree(root) defaultcwd = os.getcwd() self.savepath = 'res/deviceModelLibrary' if self.diode.isChecked(): savepath = os.path.join(self.savepath, 'Diode') os.chdir(savepath) txtfile = open(self.modelname+'.lib', 'w') txtfile.write('.MODEL ' + self.modelname + ' ' + self.model_name + '(') for tags, text in self.modeldict.items(): txtfile.write(' ' + tags + '=' + text) txtfile.write(' )\n') tree.write(self.modelname +".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) if self.mos.isChecked(): savepath = os.path.join(self.savepath, 'MOS') os.chdir(savepath) txtfile = open(self.modelname+'.lib', 'w') txtfile.write('.MODEL ' + self.modelname + ' ' + self.model_name + '(') for tags, text in self.modeldict.items(): txtfile.write(' ' + tags + '=' + text) txtfile.write(' )\n') tree.write(self.modelname +".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) if self.jfet.isChecked(): savepath = os.path.join(self.savepath, 'JFET') os.chdir(savepath) txtfile = open(self.modelname+'.lib', 'w') txtfile.write('.MODEL ' + self.modelname + ' ' + self.model_name + '(') for tags, text in self.modeldict.items(): txtfile.write(' ' + tags + '=' + text) txtfile.write(' )\n') tree.write(self.modelname +".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) if self.igbt.isChecked(): savepath = os.path.join(self.savepath, 'IGBT') os.chdir(savepath) txtfile = open(self.modelname+'.lib', 'w') txtfile.write('.MODEL ' + self.modelname + ' ' + self.model_name + '(') for tags, text in self.modeldict.items(): txtfile.write(' ' + tags + '=' + text) txtfile.write(' )\n') tree.write(self.modelname +".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) if self.magnetic.isChecked(): savepath = os.path.join(self.savepath, 'Misc') os.chdir(savepath) txtfile = open(self.modelname+'.lib', 'w') txtfile.write('.MODEL ' + self.modelname + ' ' + self.model_name + '(') for tags, text in self.modeldict.items(): txtfile.write(' ' + tags + '=' + text) txtfile.write(' )\n') tree.write(self.modelname +".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) if self.bjt.isChecked(): savepath = os.path.join(self.savepath, 'Transistor') os.chdir(savepath) txtfile = open(self.modelname+'.lib', 'w') txtfile.write('.MODEL ' + self.modelname + ' ' + self.model_name + '(') for tags, text in self.modeldict.items(): txtfile.write(' ' + tags + '=' + text) txtfile.write(' )\n') tree.write(self.modelname +".xml") self.obj_appconfig.print_info('New ' + self.modelname + ' ' + self.model_name + ' library created at ' + os.getcwd()) txtfile.close() os.chdir(defaultcwd) def validation(self,text): ''' This function checks if the file with the name already exists ''' newfilename = text+'.xml' all_dir = [x[0] for x in os.walk(self.savepathtest)] for each_dir in all_dir: all_files = os.listdir(each_dir) if newfilename in all_files: self.msg = QtGui.QErrorMessage(self) self.msg.showMessage('The file with name ' + text+ ' already exists.') self.msg.setWindowTitle("Error Message") def savethefile(self,editfile): ''' This function save the editing in the model table ''' xmlpath, file = os.path.split(editfile) filename = os.path.splitext(file)[0] libpath = os.path.join(xmlpath,filename+'.lib') libfile = open(libpath, 'w') libfile.write('.MODEL ' + self.ref_model + ' ' + self.model_name + '(') for tags, text in self.modeldict.items(): libfile.write(' ' + tags + '=' + text) libfile.write(' )\n') libfile.close() root = ET.Element("library") ET.SubElement(root, "model_name").text = self.model_name ET.SubElement(root, "ref_model").text = self.ref_model param = ET.SubElement(root, "param") for tags, text in self.modeldict.items(): ET.SubElement(param, tags).text = text tree = ET.ElementTree(root) tree.write(os.path.join(xmlpath,filename +".xml")) self.obj_appconfig.print_info('Updated library ' + libpath) def removeparameter(self): self.savebtn.setDisabled(False) index = self.modeltable.currentIndex() param = index.data().toString() remove_item = self.modeltable.item(index.row(),0).text() self.modeltable.removeRow(index.row()) del self.modeldict[str(remove_item)] def converttoxml(self): os.chdir(self.savepathtest) self.addbtn.setHidden(True) self.removebtn.setHidden(True) self.modeltable.setHidden(True) model_dict = {} stringof = [] self.libfile = str(QtGui.QFileDialog.getOpenFileName(self,"Open Library Directory","res/deviceModelLibrary","*.lib")) libopen = open(self.libfile) filedata = libopen.read().split() modelcount=0 for words in filedata: modelcount= modelcount +1 if words.lower() == '.model': break ref_model = filedata[modelcount] model_name = filedata[modelcount+1] model_name = list(model_name) modelnamecnt= 0 flag= 0 for chars in model_name: modelnamecnt = modelnamecnt +1 if chars == '(': flag = 1 break if flag == 1 : model_name = ''.join(model_name[0:modelnamecnt-1]) else: model_name = ''.join(model_name) libopen1 = open(self.libfile) while True: char = libopen1.read(1) if not char: break stringof.append(char) count = 0 for chars in stringof: count = count +1 if chars == '(': break count1=0 for chars in stringof: count1 = count1 +1 if chars == ')': break stringof = stringof[count:count1-1] stopcount=[] listofname = [] stopcount.append(0) count = 0 for chars in stringof: count = count +1 if chars == '=': stopcount.append(count) stopcount.append(count) i = 0 for no in stopcount: try: listofname.append(''.join(stringof[int(stopcount[i]):int(stopcount[i+1])])) i = i +1 except: pass listoflist =[] listofname2 = [el.replace('\t', '').replace('\n', ' ').replace('+', '').replace(')', '').replace('=', '') for el in listofname] listofname=[] for item in listofname2: listofname.append(item.rstrip().lstrip()) for values in listofname: valuelist = values.split(' ') listoflist.append(valuelist) for i in range(1, len(listoflist)): model_dict[listoflist[0][0]]=listoflist[1][0] try: model_dict[listoflist[i][-1]]= listoflist[i+1][0] except: pass root = ET.Element("library") ET.SubElement(root, "model_name").text = model_name ET.SubElement(root, "ref_model").text = ref_model param = ET.SubElement(root, "param") for tags, text in model_dict.items(): ET.SubElement(param, tags).text = text tree = ET.ElementTree(root) defaultcwd = os.getcwd() savepath = os.path.join(self.savepathtest, 'User Libraries') savefilepath= os.path.join(savepath, model_name +".xml") os.chdir(savepath) text, ok1 = QtGui.QInputDialog.getText(self, 'Model Name','Enter Model Library Name') if ok1: tree.write(text+".xml") fileopen = open(text+".lib",'w') f = open(self.libfile) fileopen.write(f.read()) f.close() fileopen.close() os.chdir(defaultcwd) libopen.close() libopen1.close()
class Workspace(QtGui.QWidget): """ This class creates Workspace GUI. """ def __init__(self,parent=None): super(Workspace, self).__init__() self.obj_appconfig = Appconfig() #Initializing Workspace directory for project self.initWorkspace() def initWorkspace(self): #print "Calling workspace" self.mainwindow = QtGui.QVBoxLayout() self.split = QtGui.QSplitter() self.split.setOrientation(QtCore.Qt.Vertical) self.grid = QtGui.QGridLayout() self.note = QtGui.QTextEdit(self) self.workspace_label = QtGui.QLabel(self) self.workspace_loc = QtGui.QLineEdit(self) self.note.append(self.obj_appconfig.workspace_text) self.workspace_label.setText("Workspace:") self.workspace_loc.setText(self.obj_appconfig.home) #Buttons self.browsebtn = QtGui.QPushButton('Browse') self.browsebtn.clicked.connect(self.browseLocation) self.okbtn = QtGui.QPushButton('OK') self.okbtn.clicked.connect(self.createWorkspace) self.cancelbtn = QtGui.QPushButton('Cancel') self.cancelbtn.clicked.connect(self.defaultWorkspace) #checkbox self.chkbox = QtGui.QCheckBox('Set Default', self) self.chkbox.setCheckState( int(self.obj_appconfig.workspace_check) ) #Layout self.grid.addWidget(self.note, 0,0,1,15) self.grid.addWidget(self.workspace_label, 2,1) self.grid.addWidget(self.workspace_loc,2,2,2,12) self.grid.addWidget(self.browsebtn, 2,14) self.grid.addWidget(self.chkbox, 4, 2) self.grid.addWidget(self.okbtn, 5, 13) self.grid.addWidget(self.cancelbtn, 5, 14) self.setGeometry(QtCore.QRect(500,250,400,400)) self.setMaximumSize(4000, 200) self.setWindowTitle("eSim") self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) self.note.setReadOnly(True) self.setWindowIcon(QtGui.QIcon('res/images/logo.png')) self.setLayout(self.grid) def defaultWorkspace(self): print "Default workspace selected : "+self.obj_appconfig.default_workspace["workspace"] self.imp_var=1 self.obj_appconfig.print_info('Default workspace selected : ' + self.obj_appconfig.default_workspace["workspace"]) self.close() var_appView.show() time.sleep(1) var_appView.splash.close() def close(self, *args, **kwargs): self.window_open_close=1 self.close_var=1 return QtGui.QWidget.close(self, *args, **kwargs) def returnWhetherClickedOrNot(self,appView): global var_appView var_appView=appView def createWorkspace(self): print "Function : Create workspace" self.obj_appconfig.workspace_check = self.chkbox.checkState() print self.workspace_loc.text() file = open (os.path.join(os.path.expanduser("~"),".esim/workspace.txt"), 'w') file.writelines(str(self.obj_appconfig.workspace_check) + " " + self.workspace_loc.text()) file.close() self.create_workspace = str(self.workspace_loc.text()) self.obj_appconfig.print_info('Workspace : ' + self.create_workspace) #Checking if Workspace already exist or not if os.path.isdir(self.create_workspace): self.obj_appconfig.default_workspace["workspace"] = self.create_workspace else: os.mkdir(self.create_workspace) self.obj_appconfig.default_workspace["workspace"] = self.create_workspace self.imp_var=1 self.close() self.obj_appconfig.dictPath = os.path.join(self.obj_appconfig.default_workspace["workspace"], ".projectExplorer.txt") try: self.obj_appconfig.project_explorer = json.load(open(self.obj_appconfig.dictPath)) print ".projectExplorer content : " print self.obj_appconfig.project_explorer except: self.obj_appconfig.project_explorer= {} var_appView.obj_Mainview.obj_projectExplorer.treewidget.clear() for parent, children in self.obj_appconfig.project_explorer.items(): var_appView.obj_Mainview.obj_projectExplorer.addTreeNode(parent, children) var_appView.show() time.sleep(1) var_appView.splash.close() def browseLocation(self): print "Function : Browse Location" self.workspace_directory = QtGui.QFileDialog.getExistingDirectory(self, "Browse Location",os.path.expanduser("~")) self.workspace_loc.setText(self.workspace_directory)