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 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 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 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 DataExtraction: def __init__(self): self.obj_appconfig = Appconfig() self.data = [] # consists of all the columns of data belonging to nodes and branches self.y = [] # stores y-axis data self.x = [] # stores x-axis data def numberFinder(self, fpath): # Opening Analysis file with open(os.path.join(fpath, "analysis")) as f3: self.analysisInfo = f3.read() self.analysisInfo = self.analysisInfo.split(" ") # Reading data file for voltage with open(os.path.join(fpath, "plot_data_v.txt")) as f2: self.voltData = f2.read() self.voltData = self.voltData.split("\n") # Initializing variable # 'p' gives no. of lines of data for each node/branch # 'npv' gives the no of partitions for a single voltage node # 'vnumber' gives total number of voltage # 'inumber' gives total number of current p = npv = vnumber = inumber = 0 # Finding totla number of voltage node for i in self.voltData[3:]: # it has possible names of voltage nodes in NgSpice if "Index" in i: # "V(" in i or "x1" in i or "u3" in i: vnumber += 1 # Reading Current Source Data with open(os.path.join(fpath, "plot_data_i.txt")) as f1: self.currentData = f1.read() self.currentData = self.currentData.split("\n") # Finding Number of Branch for i in self.currentData[3:]: if "#branch" in i: inumber += 1 self.dec = 0 # For AC if self.analysisInfo[0][-3:] == ".ac": self.analysisType = 0 if "dec" in self.analysisInfo: self.dec = 1 for i in self.voltData[3:]: p += 1 # 'p' gives no. of lines of data for each node/branch if "Index" in i: npv += 1 # 'npv' gives the no of partitions for a single voltage node # print("npv:", npv) if "AC" in i: # DC for dc files and AC for ac ones break elif ".tran" in self.analysisInfo: self.analysisType = 1 for i in self.voltData[3:]: p += 1 if "Index" in i: npv += 1 # 'npv' gives the no of partitions for a single voltage node # print("npv:", npv) if "Transient" in i: # DC for dc files and AC for ac ones break # For DC: else: self.analysisType = 2 for i in self.voltData[3:]: p += 1 if "Index" in i: npv += 1 # 'npv' gives the no of partitions for a single voltage node # print("npv:", npv) if "DC" in i: # DC for dc files and AC for ac ones break vnumber = vnumber // npv # vnumber gives the no of voltage nodes inumber = inumber // npv # inumber gives the no of branches p = [p, vnumber, self.analysisType, self.dec, inumber] return p def openFile(self, fpath): try: with open(os.path.join(fpath, "plot_data_i.txt")) as f2: alli = f2.read() alli = alli.split("\n") self.NBIList = [] with open(os.path.join(fpath, "plot_data_v.txt")) as f1: allv = f1.read() except Exception as e: print("Exception Message : ", str(e)) self.obj_appconfig.print_error('Exception Message :' + str(e)) self.msg = QtGui.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage('Unable to open plot data files.') self.msg.exec_() try: for l in alli[3].split(" "): if len(l) > 0: self.NBIList.append(l) self.NBIList = self.NBIList[2:] len_NBIList = len(self.NBIList) except Exception as e: print("Exception Message : ", str(e)) self.obj_appconfig.print_error('Exception Message :' + str(e)) self.msg = QtGui.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage('Unable to read Analysis File.') self.msg.exec_() d = self.numberFinder(fpath) d1 = int(d[0] + 1) d2 = int(d[1]) d3 = d[2] d4 = d[4] dec = [d3, d[3]] self.NBList = [] allv = allv.split("\n") for l in allv[3].split(" "): if len(l) > 0: self.NBList.append(l) self.NBList = self.NBList[2:] len_NBList = len(self.NBList) print("NBLIST", self.NBList) ivals = [] inum = len(allv[5].split("\t")) inum_i = len(alli[5].split("\t")) full_data = [] # Creating list of data: if d3 < 3: for i in range(1, d2): for l in allv[3 + i * d1].split(" "): if len(l) > 0: self.NBList.append(l) self.NBList.pop(len_NBList) self.NBList.pop(len_NBList) len_NBList = len(self.NBList) for n in range(1, d4): for l in alli[3 + n * d1].split(" "): if len(l) > 0: self.NBIList.append(l) self.NBIList.pop(len_NBIList) self.NBIList.pop(len_NBIList) len_NBIList = len(self.NBIList) p = 0 k = 0 m = 0 for i in alli[5:d1 - 1]: if len(i.split("\t")) == inum_i: j2 = i.split("\t") j2.pop(0) j2.pop(0) j2.pop() if d3 == 0: # not in trans j2.pop() for l in range(1, d4): j3 = alli[5 + l * d1 + k].split("\t") j3.pop(0) j3.pop(0) if d3 == 0: j3.pop() # not required for dc j3.pop() j2 = j2 + j3 full_data.append(j2) k += 1 for i in allv[5:d1 - 1]: if len(i.split("\t")) == inum: j = i.split("\t") j.pop() if d3 == 0: j.pop() for l in range(1, d2): j1 = allv[5 + l * d1 + p].split("\t") j1.pop(0) j1.pop(0) if d3 == 0: j1.pop() # not required for dc if self.NBList[len(self.NBList) - 1] == 'v-sweep': self.NBList.pop() j1.pop() j1.pop() j = j + j1 j = j + full_data[m] m += 1 j = "\t".join(j[1:]) j = j.replace(",", "") ivals.append(j) p += 1 self.data = ivals self.volts_length = len(self.NBList) self.NBList = self.NBList + self.NBIList print(dec) return dec def numVals(self): a = self.volts_length # No of voltage nodes b = len(self.data[0].split("\t")) return [b, a] def computeAxes(self): nums = len(self.data[0].split("\t")) self.y = [] var = self.data[0].split("\t") for i in range(1, nums): self.y.append([Decimal(var[i])]) for i in self.data[1:]: temp = i.split("\t") for j in range(1, nums): self.y[j - 1].append(Decimal(temp[j])) for i in self.data: temp = i.split("\t") self.x.append(Decimal(temp[0]))
class DataExtraction: def __init__(self): self.obj_appconfig = Appconfig() print "Initialization" self.data=[] #consists of all the columns of data belonging to nodes and branches self.y=[] #stores y-axis data self.x=[] #stores x-axis data def numberFinder(self,fpath): #Opening ANalysis file with open(os.path.join(fpath,"analysis")) as f3: self.analysisInfo = f3.read() self.analysisInfo = self.analysisInfo.split(" ") #Reading data file for voltage with open(os.path.join(fpath,"plot_data_v.txt")) as f2: self.voltData = f2.read() self.voltData = self.voltData.split("\n") #Initializing variable #'p' gives no. of lines of data for each node/branch # 'l' gives the no of partitions for a single voltage node #'vnumber' gives total number of voltage #'inumber' gives total number of current p = l = vnumber = inumber = 0 #print "VoltsData : ",self.voltData #Finding totla number of voltage node for i in self.voltData[3:]: #it has possible names of voltage nodes in NgSpice if "Index" in i:#"V(" in i or "x1" in i or "u3" in i: vnumber+=1 #print "Voltage Number :",vnumber #Reading Current Source Data with open (os.path.join(fpath,"plot_data_i.txt")) as f1: self.currentData = f1.read() self.currentData = self.currentData.split("\n") #print "CurrentData : ",self.currentData #Finding Number of Branch for i in self.currentData[3:]: if "#branch" in i: inumber+=1 #print "Current Number :",inumber self.dec = 0 #For AC if self.analysisInfo[0][-3:]==".ac": self.analysisType = 0 if "dec" in self.analysisInfo: self.dec = 1 for i in self.voltData[3:]: p+=1 #'p' gives no. of lines of data for each node/branch if "Index" in i: l+=1 # 'l' gives the no of partitions for a single voltage node #print "l:",l if "AC" in i: #DC for dc files and AC for ac ones break elif ".tran" in self.analysisInfo: self.analysisType = 1 for i in self.voltData[3:]: p+=1 if "Index" in i: l+=1 # 'l' gives the no of partitions for a single voltage node #print "l:",l if "Transient" in i: #DC for dc files and AC for ac ones break # For DC: else: self.analysisType = 2 for i in self.voltData[3:]: p+=1 if "Index" in i: l+=1 # 'l' gives the no of partitions for a single voltage node #print "l:",l if "DC" in i: #DC for dc files and AC for ac ones break #print "VoltNumber",vnumber #print "CurrentNumber",inumber vnumber = vnumber//l #vnumber gives the no of voltage nodes inumber = inumber//l #inumber gives the no of branches #print "VoltNumber",vnumber #print "CurrentNumber",inumber p=[p,vnumber,self.analysisType,self.dec,inumber] return p def openFile(self,fpath): #print "Calling Open File" try: with open (os.path.join(fpath,"plot_data_i.txt")) as f2: alli = f2.read() alli = alli.split("\n") self.NBIList = [] with open (os.path.join(fpath,"plot_data_v.txt")) as f1: allv = f1.read() except Exception as e: print "Exception Message : ",str(e) self.obj_appconfig.print_error('Exception Message :' + str(e)) self.msg = QtGui.QErrorMessage(None) self.msg.showMessage('Unable to open plot data files.') self.msg.setWindowTitle("Error Message:openFile") try: for l in alli[3].split(" "): if len(l)>0: self.NBIList.append(l) self.NBIList = self.NBIList[2:] len_NBIList = len(self.NBIList) #print "NBILIST : ",self.NBIList except Exception as e: print "Exception Message : ",str(e) self.obj_appconfig.print_error('Exception Message :' + str(e)) self.msg = QtGui.QErrorMessage(None) self.msg.showMessage('Error in Analysis File.') self.msg.setWindowTitle("Error Message:openFile") d = self.numberFinder(fpath) d1 = int(d[0] + 1) d2 = int(d[1]) d3 = d[2] d4 = d[4] dec = [d3,d[3]] #print "No. of Nodes:", d2 self.NBList = [] allv=allv.split("\n") for l in allv[3].split(" "): if len(l)>0: self.NBList.append(l) self.NBList=self.NBList[2:] len_NBList = len(self.NBList) print "NBLIST",self.NBList ivals=[] inum = len(allv[5].split("\t")) inum_i = len(alli[5].split("\t")) full_data = [] # Creating list of data: if d3 < 3 : for i in range(1,d2): for l in allv[3+i*d1].split(" "): if len(l)>0: self.NBList.append(l) self.NBList.pop(len_NBList) self.NBList.pop(len_NBList) len_NBList = len(self.NBList) for n in range(1,d4): for l in alli[3+n*d1].split(" "): if len(l)>0: self.NBIList.append(l) self.NBIList.pop(len_NBIList) self.NBIList.pop(len_NBIList) len_NBIList = len(self.NBIList) p=0 k = 0 m=0 for i in alli[5:d1-1]: if len(i.split("\t"))==inum_i: j2=i.split("\t") #print j2 j2.pop(0) j2.pop(0) j2.pop() if d3 == 0: #not in trans j2.pop() #print j2 for l in range(1,d4): j3 = alli[5+l*d1+k].split("\t") j3.pop(0) j3.pop(0) if d3==0: j3.pop() #not required for dc j3.pop() j2 = j2 + j3 #print j2 full_data.append(j2) k+=1 #print "FULL DATA :",full_data for i in allv[5:d1-1]: if len(i.split("\t"))==inum: j=i.split("\t") j.pop() if d3==0: j.pop() for l in range(1,d2): j1 = allv[5+l*d1+p].split("\t") j1.pop(0) j1.pop(0) if d3==0: j1.pop() #not required for dc if self.NBList[len(self.NBList)-1] == 'v-sweep': self.NBList.pop() j1.pop() j1.pop() j = j + j1 j = j + full_data[m] #print j m+=1 #print j[:20] j = "\t".join(j[1:]) j = j.replace(",","") ivals.append(j) p+=1 self.data = ivals #print "volts:",self.butnames self.volts_length = len(self.NBList) self.NBList = self.NBList + self.NBIList print dec return dec def numVals(self): a = self.volts_length # No of voltage nodes b = len(self.data[0].split("\t")) #print "numvals:",b return [b,a] def computeAxes(self): nums = len(self.data[0].split("\t")) #print "i'm nums:",nums self.y=[] var=self.data[0].split("\t") for i in range(1,nums): self.y.append([Decimal(var[i])]) for i in self.data[1:]: temp=i.split("\t") for j in range(1,nums): self.y[j-1].append(Decimal(temp[j])) for i in self.data: temp=i.split("\t") self.x.append(Decimal(temp[0]))
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) #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 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): """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 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 NgVeri(QtWidgets.QWidget): # initialising the variables def __init__(self, filecount): QtWidgets.QWidget.__init__(self) # Maker.addverilog(self) self.obj_Appconfig = Appconfig() if os.name == 'nt': self.home = os.path.join('library', 'config') else: self.home = os.path.expanduser('~') self.parser = ConfigParser() self.parser.read(os.path.join( self.home, os.path.join('.nghdl', 'config.ini'))) self.nghdl_home = self.parser.get('NGHDL', 'NGHDL_HOME') self.release_dir = self.parser.get('NGHDL', 'RELEASE') self.src_home = self.parser.get('SRC', 'SRC_HOME') self.licensefile = self.parser.get('SRC', 'LICENSE') self.digital_home = self.parser.get('NGHDL', 'DIGITAL_MODEL') self.digital_home = self.digital_home + "/Ngveri" self.count = 0 self.text = "" self.entry_var = {} self.createNgveriWidget() self.fname = "" self.filecount = filecount # Creating the various components of the Widget(Ngveri Tab) def createNgveriWidget(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.show() # Adding the verilog file in Maker tab to Ngveri Tab automatically def addverilog(self): # b=Maker.Maker(self) print(Maker.verilogFile) if Maker.verilogFile[self.filecount] == "": reply = QtWidgets.QMessageBox.critical( None, "Error Message", "<b>Error: No Verilog File Chosen. \ Please choose a verilog file in Makerchip Tab</b>", QtWidgets.QMessageBox.Ok) if reply == QtWidgets.QMessageBox.Ok: self.obj_Appconfig.print_error( 'No Verilog File Chosen. ' 'Please choose a verilog file in Makerchip Tab' ) return self.fname = Maker.verilogFile[self.filecount] currentTermLogs = QtWidgets.QTextEdit() model = ModelGeneration.ModelGeneration(self.fname, currentTermLogs) file = (os.path.basename(self.fname)).split('.')[0] if self.entry_var[1].findText(file) == -1: self.entry_var[1].addItem(file) if not Maker.makerchipTOSAccepted(True): QtWidgets.QMessageBox.warning( None, "Warning Message", "Please accept the Makerchip Terms of Service " "to proceed further.", QtWidgets.QMessageBox.Ok ) return try: model.verilogfile() error = model.verilogParse() if error != "Error": model.getPortInfo() model.cfuncmod() model.ifspecwrite() model.sim_main_header() model.sim_main() model.modpathlst() model.run_verilator() model.make_verilator() model.copy_verilator() model.runMake() if os.name != 'nt': model.runMakeInstall() else: try: shutil.copy( self.release_dir + "/src/xspice/icm/Ngveri/Ngveri.cm", self.nghdl_home + "/lib/ngspice/" ) except FileNotFoundError as err: currentTermLogs.append( "Error in copying Ngveri code model: " + str(err) ) if "error" not in currentTermLogs.toPlainText().lower(): currentTermLogs.append(''' <p style=\" font-size:16pt; font-weight:1000; color:#00FF00;\"> Model Created Successfully! </p> ''') except BaseException as err: currentTermLogs.append( "Error in Ngspice code model generation " + "from Verilog: " + str(err) ) if "error" in currentTermLogs.toPlainText().lower(): currentTermLogs.append(''' <p style=\" font-size:16pt; font-weight:1000; color:#FF0000;\">There was an error during model creation, <br/>Please rectify the error and try again! </p> ''') self.entry_var[0].append(currentTermLogs.toHtml()) # Force scroll the terminal widget at bottom self.entry_var[0].verticalScrollBar().setValue( self.entry_var[0].verticalScrollBar().maximum() ) def addfile(self): ''' This function is used to add additional files required by the verilog top module ''' if len(Maker.verilogFile) < (self.filecount + 1): reply = QtWidgets.QMessageBox.critical( None, "Error Message", "<b>Error: No Verilog File Chosen. \ Please choose a verilog file in Makerchip Tab</b>", QtWidgets.QMessageBox.Ok) if reply == QtWidgets.QMessageBox.Ok: self.obj_Appconfig.print_error( 'No Verilog File Chosen. Please choose \ a verilog file in Makerchip Tab') return self.fname = Maker.verilogFile[self.filecount] model = ModelGeneration.ModelGeneration(self.fname, self.entry_var[0]) # model.verilogfile() model.addfile() # This function is used to add additional folder required by the verilog # top module def addfolder(self): if len(Maker.verilogFile) < (self.filecount + 1): reply = QtWidgets.QMessageBox.critical( None, "Error Message", "<b>Error: No Verilog File Chosen. \ Please choose a verilog file in Makerchip Tab</b>", QtWidgets.QMessageBox.Ok) if reply == QtWidgets.QMessageBox.Ok: self.obj_Appconfig.print_error( 'No Verilog File Chosen. Please choose \ a verilog file in Makerchip Tab') return self.fname = Maker.verilogFile[self.filecount] model = ModelGeneration.ModelGeneration(self.fname, self.entry_var[0]) # model.verilogfile() model.addfolder() # This function is used to clear the terminal def clearTerminal(self): self.entry_var[0].setText("") # This function is used to create buttons/options def createoptionsBox(self): self.optionsbox = QtWidgets.QGroupBox() self.optionsbox.setTitle("Select Options") self.optionsgrid = QtWidgets.QGridLayout() self.optionsgroupbtn = QtWidgets.QButtonGroup() self.addverilogbutton = QtWidgets.QPushButton( "Convert Verilog to Ngspice") self.addverilogbutton.setToolTip( "Requires internet connection for converting TL-Verilog models" ) self.addverilogbutton.setToolTipDuration(5000) self.optionsgroupbtn.addButton(self.addverilogbutton) self.addverilogbutton.clicked.connect(self.addverilog) self.optionsgrid.addWidget(self.addverilogbutton, 0, 1) # self.optionsbox.setLayout(self.optionsgrid) # self.grid.addWidget(self.creategroup(), 1, 0, 5, 0) self.addfilebutton = QtWidgets.QPushButton("Add dependency files") self.optionsgroupbtn.addButton(self.addfilebutton) self.addfilebutton.clicked.connect(self.addfile) self.optionsgrid.addWidget(self.addfilebutton, 0, 2) # self.optionsbox.setLayout(self.optionsgrid) # self.grid.addWidget(self.creategroup(), 1, 0, 5, 0) self.addfolderbutton = QtWidgets.QPushButton("Add dependency folder") self.optionsgroupbtn.addButton(self.addfolderbutton) self.addfolderbutton.clicked.connect(self.addfolder) self.optionsgrid.addWidget(self.addfolderbutton, 0, 3) # self.optionsbox.setLayout(self.optionsgrid) # self.grid.addWidget(self.creategroup(), 1, 0, 5, 0) self.clearTerminalBtn = QtWidgets.QPushButton("Clear Terminal") self.optionsgroupbtn.addButton(self.clearTerminalBtn) self.clearTerminalBtn.clicked.connect(self.clearTerminal) self.optionsgrid.addWidget(self.clearTerminalBtn, 0, 4) self.optionsbox.setLayout(self.optionsgrid) # self.grid.addWidget(self.creategroup(), 1, 0, 5, 0) return self.optionsbox # This function is used to remove models in modlst of Ngspice folder if # the user wants to remove a model. Note: files do not get removed def edit_modlst(self, text): if text == "Remove Verilog Models": return index = self.entry_var[1].findText(text) self.entry_var[1].removeItem(index) self.entry_var[1].setCurrentIndex(0) ret = QtWidgets.QMessageBox.warning( None, "Warning", '''<b>Do you want to remove the model: ''' + text, QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Cancel ) if ret == QtWidgets.QMessageBox.Ok: mod = open(self.digital_home + '/modpath.lst', 'r') data = mod.readlines() mod.close() data.remove(text + "\n") mod = open(self.digital_home + '/modpath.lst', 'w') for item in data: mod.write(item) self.fname = Maker.verilogFile[self.filecount] model = ModelGeneration.ModelGeneration( self.fname, self.entry_var[0]) try: model.runMake() if os.name != 'nt': model.runMakeInstall() else: shutil.copy( self.release_dir + "/src/xspice/icm/Ngveri/Ngveri.cm", self.nghdl_home + "/lib/ngspice/" ) except BaseException as err: QtWidgets.QMessageBox.critical( None, "Error Message", "The verilog model '" + str(text) + "' could not be removed: " + str(err), QtWidgets.QMessageBox.Ok ) def lint_off_edit(self, text): ''' This is to remove lint_off comments needed by the verilator warnings. This function writes to the lint_off.txt in the library/tlv folder. ''' init_path = '../../' if os.name == 'nt': init_path = '' if text == "Remove lint_off": return index = self.entry_var[2].findText(text) self.entry_var[2].removeItem(index) self.entry_var[2].setCurrentIndex(0) ret = QtWidgets.QMessageBox.warning( None, "Warning", '''<b>Do you want to remove the lint off error: ''' + text, QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Cancel) if ret == QtWidgets.QMessageBox.Ok: file = open(init_path + "library/tlv/lint_off.txt", 'r') data = file.readlines() file.close() data.remove(text + "\n") file = open(init_path + "library/tlv/lint_off.txt", 'w') for item in data: file.write(item) def add_lint_off(self): ''' This is to add lint_off comments needed by the verilator warnings. This function writes to the lint_off.txt in the library/tlv folder. ''' init_path = '../../' if os.name == 'nt': init_path = '' text = self.entry_var[3].text() if self.entry_var[2].findText(text) == -1: self.entry_var[2].addItem(text) file = open(init_path + "library/tlv/lint_off.txt", 'a+') file.write(text + "\n") file.close() self.entry_var[3].setText("") # creating various other groups like terminal, remove modlst, remove lint_off # and add lint_off def creategroup(self): self.trbox = QtWidgets.QGroupBox() self.trbox.setTitle("Terminal") # self.trbox.setDisabled(True) # self.trbox.setVisible(False) self.trgrid = QtWidgets.QGridLayout() self.trbox.setLayout(self.trgrid) self.count = 0 self.start = QtWidgets.QLabel("Terminal") # self.trgrid.addWidget(self.start, 2,0) self.entry_var[self.count] = QtWidgets.QTextEdit() self.entry_var[self.count].setReadOnly(1) self.trgrid.addWidget(self.entry_var[self.count], 1, 1, 5, 3) self.entry_var[self.count].setMaximumWidth(1000) self.entry_var[self.count].setMaximumHeight(1000) self.count += 1 self.entry_var[self.count] = QtWidgets.QComboBox() self.entry_var[self.count].addItem("Remove Verilog Models") self.modlst = open(self.digital_home + '/modpath.lst', 'r') self.data = self.modlst.readlines() self.modlst.close() for item in self.data: if item != "\n": self.entry_var[self.count].addItem(item.strip()) self.entry_var[self.count].activated[str].connect(self.edit_modlst) self.trgrid.addWidget(self.entry_var[self.count], 1, 4, 1, 2) self.count += 1 self.entry_var[self.count] = QtWidgets.QComboBox() self.entry_var[self.count].addItem("Remove lint_off") init_path = '../../' if os.name == 'nt': init_path = '' self.lint_off = open(init_path + "library/tlv/lint_off.txt", 'r') self.data = self.lint_off.readlines() self.lint_off.close() for item in self.data: if item != "\n": self.entry_var[self.count].addItem(item.strip()) self.entry_var[self.count].activated[str].connect(self.lint_off_edit) self.trgrid.addWidget(self.entry_var[self.count], 2, 4, 1, 2) self.count += 1 self.entry_var[self.count] = QtWidgets.QLineEdit(self) self.trgrid.addWidget(self.entry_var[self.count], 3, 4) self.entry_var[self.count].setMaximumWidth(100) self.count += 1 self.entry_var[self.count] = QtWidgets.QPushButton("Add lint_off") self.entry_var[self.count].setMaximumWidth(100) self.trgrid.addWidget(self.entry_var[self.count], 3, 5) self.entry_var[self.count].clicked.connect(self.add_lint_off) 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 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 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) #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"