예제 #1
0
 def updateTable(self, table, args):
     model = QStandardItemModel(len(args), 2)
     model.setHorizontalHeaderLabels(["Name", "Value", "Type"])
     indexitem = 0
     for name, val in args.items():
         si = QStandardItem(name)
         si.setEditable(False)
         model.setItem(indexitem, 0, si)
         si = QStandardItem(repr(val))
         si.setEditable(False)
         model.setItem(indexitem, 1, si)
         try:
             si = QStandardItem(str(val.__class__.__name__))
         except:
             si = QStandardItem(str(type(val).__name__))
         si.setEditable(False)
         model.setItem(indexitem, 2, si)
         indexitem += 1
     table.setModel(model)
     table.model = model
예제 #2
0
class AbstractSimulation:
    def __init__(self, lpywidget, index = 0, fname = None):
        self.lpywidget = lpywidget
        self.index = index
        self._fname = fname
        self._tmpfname = None

        self.textedition = False
        self._edited = False
        self._oldedited = False

        self.code = defaultcode
        self.textdocument = None
        self.cursor = None
        self.optionModel = None
        self.optionDelegate = None

        self.readonly = False
        self._oldreadonly = False

        self.modulemonitor = pm.ModuleMonitor()

    def tabbar(self):
        return self.lpywidget.documentNames

    def getFname(self) : return self._fname
    def setFname(self,value) :
        self._fname = value
        self.tabbar().setTabText(self.index,self.getShortName())
    fname = property(getFname,setFname)

    def isEdited(self):
        return self._edited 
    def setEdited(self,value):
        self._edited = value
        self.lpywidget.printTitle()
        self.updateTabName()
    edited = property(isEdited,setEdited)

    def textEdited(self):
        self.textedition = True
        self._edited = True
        self.lpywidget.printTitle()
        self.updateTabName()
    def isTextEdited(self):
        r = self.textedition
        self.textedition = False
        self.lpywidget.printTitle()
        self.updateTabName()
        return r

    def isCurrent(self):
        return self.index == self.lpywidget.currentSimulationId
    def makeCurrent(self):
        self.lpywidget.changeDocument(self.index)

    def isDefault(self):
        if self.isCurrent():
            self.saveState()
        if not self.fname is None : return False
        if self.code != defaultcode : return False
        if self.textedition == True : return False
        if self._edited == True: return False
        for i in self.desc_items.values():
            if len(i) > 0:
                return False
        ini = self.getInitialisationCode()
        if len(ini) > 0: return False
        return True  
                  
    def getShortName(self):
        if self._fname is None : return 'New'
        else : return os.path.splitext(os.path.basename(self.fname))[0]
    def getBaseName(self):
        if self._fname is None : return 'New'
        else : return os.path.basename(self.fname)
    def getFileName(self):
        return self._fname
    def getTabName(self):
        t = ''
        #if self.textedition:
        #    t += '*'
        if self.fname is None:
            t += 'New'
        else:
            t += os.path.splitext(os.path.basename(self.fname))[0]
        #if self._edited:
        #    t += '*'
        return t
    def generateIcon(self):
        from . import svnmanip
        if self.readonly is True:
            pixmap = QPixmap(":/images/icons/lock.png")
        elif self._edited:
            pixmap = QPixmap(":/images/icons/codefile-red.png")
        else:
            pixmap = QPixmap(":/images/icons/codefile.png")
        if not self.readonly and not self.fname is None and svnmanip.hasSvnSupport() :
            if svnmanip.isSvnFile(self.fname):
                status = svnmanip.svnFileTextStatus(self.fname)
                self.svnstatus = status
                if  status == svnmanip.modified:
                    pixmap2 = QPixmap(":/images/icons/svn-modified.png")
                elif status == svnmanip.normal:
                    pixmap2 = QPixmap(":/images/icons/svn-normal.png")
                elif status == svnmanip.conflicted:
                    pixmap2 = QPixmap(":/images/icons/svn-conflict.png")
                elif status == svnmanip.added:
                    pixmap2 = QPixmap(":/images/icons/svn-add.png")
                else:
                    pixmap2 = None
                if not pixmap2 is None:
                    painter = QPainter(pixmap);
                    painter.drawPixmap(pixmap.width()-pixmap2.width(),pixmap.height()-pixmap2.height(),pixmap2)
                    painter.end()
        icon = QIcon()
        icon.addPixmap(pixmap.scaledToHeight(32),QIcon.Normal,QIcon.Off)
        return icon
    def registerTab(self):
        #self.tabbar().insertTab(self.index, self.getTabName())
        self.tabbar().insertTab(self.index,self.generateIcon(),self.getTabName())
        pass
    def updateTabName(self, force = False):
        if self._oldedited != self._edited or self._oldreadonly != self.readonly:
            self._oldedited = self._edited
            self._oldreadonly = self.readonly
        self.tabbar().setTabIcon(self.index,self.generateIcon())
        self.tabbar().setTabText(self.index,self.getTabName())

    def getBackupName(self):
        if self.fname:
            return os.path.join(os.path.dirname(self.fname),'#'+os.path.basename(self.fname)+'#')
        else:
            if not self._tmpfname:
                self._tmpfname = getNewTmpLpyFile()
            return self._tmpfname

    def restoreState(self):        
        self.lpywidget.textEditionWatch = False
        te, tf = self.textedition, self._edited
        self.lpywidget.codeeditor.restoreSimuState(self)
        if self.optionModel is None:
            self.initializeParametersTable()
        self.lpywidget.parametersTable.setModel(self.optionModel)
        self.lpywidget.parametersTable.setItemDelegateForColumn(1,self.optionDelegate)
        self.textedition, self._edited = te, tf
        for key,editor in self.lpywidget.desc_items.items():
            editor.setText(self.desc_items[key])
        self.lpywidget.setTimeStep(self.lsystem.context().animation_timestep)
        self.lpywidget.materialed.setTurtle(self.lsystem.context().turtle)
        #self.lpywidget.functionDock.setFunctions(self.functions)
        #self.lpywidget.curveDock.setCurves(self.curves)
        self.lpywidget.setObjectPanelNb(len(self.visualparameters))
        for panel,data in zip(self.lpywidget.getObjectPanels(),self.visualparameters):
            panelinfo,objects = data
            panel.setInfo(panelinfo)
            panel.setObjects(objects)
        self.lpywidget.scalarEditor.setScalars(self.scalars)
        if not self.lpywidget.interpreter is None:
            self.lpywidget.interpreter.locals['lstring'] = self.tree
            self.lpywidget.interpreter.locals['lsystem'] = self.lsystem
        self.lpywidget.printTitle()
        self.lpywidget.setTimeStep(self.lsystem.context().animation_timestep)
        if self.tabbar().currentIndex() != self.index:
            self.tabbar().setCurrentIndex(self.index)
        self.lpywidget.textEditionWatch = True
        if not self.fname is None:
            os.chdir(os.path.dirname(self.fname))         
        self.lpywidget.actionAutoRun.setChecked(self.autorun)
        self.updateReadOnly()
        #if not self.lsystem.isCurrent() : self.lsystem.makeCurrent()

    def saveState(self):
        #if self.lsystem.isCurrent() :self.lsystem.done()
        self.lpywidget.codeeditor.saveSimuState(self)
        for key,editor in self.lpywidget.desc_items.items():
            if type(editor) == QLineEdit:
                self.desc_items[key] = editor.text()
            else:
                self.desc_items[key] = editor.toPlainText().encode('iso-8859-1','replace').decode('iso-8859-1')
        #self.functions = self.lpywidget.functionpanel.getFunctions()
        #self.curves = self.lpywidget.curvepanel.getCurves()
        self.visualparameters = [(panel.getInfo(),panel.getObjects()) for panel in self.lpywidget.getObjectPanels()]
        self.scalars = self.lpywidget.scalarEditor.getScalars()

    def initializeParametersTable(self):
        self.optionModel = QStandardItemModel(0, 1)
        self.optionModel.setHorizontalHeaderLabels(["Parameter", "Value" ])
        options = self.lsystem.context().options
        self.optionDelegate = oed.OptionEditorDelegate()
        category = None
        categoryItem = None
        indexitem = 0
        for i in range(len(options)):
            option = options[i]
            if option.category != category:
                category = option.category
                sc = QStandardItem(category)                
                sc.setEditable(False)
                sc.setBackground(QBrush(QColor(172,168,153)))
                sc.setForeground(QBrush(QColor(255,255,255)))
                qf = QFont()
                qf.setBold(True)
                sc.setFont(qf)
                self.optionModel.setItem(indexitem, 0, sc)
                sc = QStandardItem()                
                sc.setEditable(False)
                sc.setBackground(QBrush(QColor(172,168,153)))
                sc.setForeground(QBrush(QColor(255,255,255)))
                self.optionModel.setItem(indexitem, 1, sc)
                indexitem += 1             
            si = QStandardItem(option.name)
            si.setToolTip(option.comment)
            si.setEditable(False)
            self.optionModel.setItem(indexitem, 0, si)
            si = QStandardItem(option.currentValue())
            si.option = option
            self.optionModel.setItem(indexitem, 1, si)
            indexitem += 1
        self.optionModel.itemChanged.connect(self.textEdited) # QObject.connect(self.optionModel,SIGNAL('itemChanged(QStandardItem*)'),self.textEdited)



    def close(self):
        if self._edited:
            if not self.isCurrent():
                self.makeCurrent()
            answer = QMessageBox.warning(self.lpywidget,self.getShortName(),"Do you want to save this document ?",
                                        QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel, QMessageBox.Save)
            if answer == QMessageBox.Save: self.save()
            elif answer == QMessageBox.Cancel: return False
            elif answer == QMessageBox.Discard:
                bckupname = self.getBackupName()
                if bckupname and os.path.exists(bckupname): os.remove(bckupname)
        return True

    def save(self):
        if self.fname and not self.readonly:
            if self.isCurrent():
                self.saveState()
            bckupname = self.getBackupName()
            if bckupname and os.path.exists(bckupname):
                os.remove(bckupname)
            if os.path.exists(self.fname) and  self.lpywidget.fileBackupEnabled :
                try:
                    shutil.copy(self.fname,self.fname+'~')
                except Exception as e:
                    print('Cannot create backup file',repr(self.fname+'~'))
                    print(e)
            self.saveToFile(self.fname)
            self.mtime = os.stat(self.fname).st_mtime
            self.lpywidget.statusBar().showMessage("Save file '"+self.fname+"'",2000)
            self.lpywidget.appendInHistory(self.fname)
            self.lsystem.filename = self.getStrFname()
            self.setEdited(False)
            self.updateReadOnly()
        else:
            self.saveas()

    def saveas(self):
        bckupname = self.getBackupName()
        qfname, mfilter = QFileDialog.getSaveFileName(self.lpywidget,"Save L-Py file",self.fname if self.fname else '.',"L-Py Files (*.lpy);;All Files (*.*)")
        if  qfname :
            fname = str(qfname)
            if not os.path.exists(fname):
                self.readonly = False  
            else : 
                self.readonly = (not os.access(fname, os.W_OK))
            self.fname = fname
            os.chdir(os.path.dirname(fname))
            if not self.readonly and bckupname and os.path.exists(bckupname):
                os.remove(bckupname)
            self.save()

    def removeReadOnly(self):
        if not os.access(self.fname, os.W_OK):
            import stat
            st = os.stat(self.fname)[0]
            os.chmod(self.fname,st | stat.S_IWRITE)
            self.readonly = not os.access(self.fname, os.W_OK)
            self.updateTabName()
            self.updateReadOnly()

    def setReadOnly(self):
        if os.access(self.fname, os.W_OK):
            import stat
            st = os.stat(self.fname)[0]
            os.chmod(self.fname,st ^ stat.S_IWRITE)
            self.readonly = not os.access(self.fname, os.W_OK)
            self.updateTabName()
            self.updateReadOnly()

    def updateReadOnly(self):
        self.lpywidget.codeeditor.setReadOnly(self.readonly)
        self.lpywidget.materialed.setEnabled(not self.readonly)
        self.lpywidget.parametersTable.setEnabled(not self.readonly)
        self.lpywidget.scalarEditor.setEnabled(not self.readonly)
        self.lpywidget.animtimeSpinBox.setEnabled(not self.readonly)
        self.lpywidget.profileView.setEnabled(not self.readonly)
        self.lpywidget.descriptionEdit.setEnabled(not self.readonly)
        self.lpywidget.referenceEdit.setEnabled(not self.readonly)
        self.lpywidget.authorsEdit.setEnabled(not self.readonly)
        self.lpywidget.intitutesEdit.setEnabled(not self.readonly)
        self.lpywidget.copyrightEdit.setEnabled(not self.readonly)
        self.lpywidget.copyrightEdit.setEnabled(not self.readonly)
        for panel in self.lpywidget.getObjectPanels():
            panel.setEnabled(not self.readonly)

    def saveToFile(self,fname):
        f = open(fname,'w')
        f.write(self.code)
        initcode = self.getInitialisationCode()
        if len(initcode) > 0 :
            if self.code[-1] != '\n':
                f.write('\n')
            f.write(initcode)
        f.close()

    def getStrFname(self):
        return self.fname.encode('iso-8859-1','replace').decode('iso-8859-1')
        
    def open(self,fname):
        self.setFname(fname)
        assert self._fname == fname
        recovery = False
        readname = self.fname
        bckupname = self.getBackupName()
        if bckupname and os.path.exists(bckupname):
            answer = QMessageBox.warning(self.lpywidget,"Recovery mode","A backup file '"+os.path.basename(bckupname)+"' exists. Do you want to recover ?",QMessageBox.Ok,QMessageBox.Discard)
            if answer == QMessageBox.Ok:
                recovery = True
                readname = bckupname
            elif answer == QMessageBox.Discard:
                os.remove(bckupname)     
        os.chdir(os.path.dirname(self.fname))        
        code = open(readname,'rU').read()
        self.readonly = (not os.access(fname, os.W_OK))
        self.textedition = recovery
        self.setEdited(recovery)
        self.opencode(code)
        self.mtime = os.stat(self.fname).st_mtime
        self.updateReadOnly()
    
    def importtmpfile(self,fname):
        self.textedition = True
        self.setEdited(True)
        try:
            lpycode = open(fname,'rU').read()
            self.opencode(lpycode)
            self._tmpfname = fname
        except:
            exc_info = sys.exc_info()
            traceback.print_exception(*exc_info)

    def reload(self):
        if self.fname:
            self.open(self.fname)

    def opencode(self,txt):
        pass

    def pre_run(self,task):
        pass
    def run(self, task):
        pass
    def post_run(self,task):
        pass
    def animate(self,task):
        pass
    def pre_animate(self,task):
        pass
    def post_animate(self,task):
        pass
    def pre_step(self,task):
        pass
    def step(self,task):
        pass
    def post_step(self,task):
        pass
    def iterate(self,task,n = None):    
        pass
    def debug(self):
        pass
    def rewind(self):
        pass
    def stepInterpretation(self,task):
        pass        
    def pre_stepInterpretation(self,task):
        pass
    def post_stepInterpretation(self,task):
        pass
    def profile(self,task):
        pass
    def pre_profile(self,task):
        pass
    def post_profile(self,task):
        pass
        
    def clear(self):
        pass

    def cancel(self):
        pass

    def cleanup(self):
        pass

    def monitorfile(self):
        if not hasattr(self,'monitoring'):
          self.monitoring = True
          if not self.fname is None:
            if not os.path.exists(self.fname):
                answer = QMessageBox.warning(self.lpywidget,"Removed file","File '"+os.path.basename(self.fname)+"' do not exists anymore. Do you want to keep it in editor ?",QMessageBox.Yes,QMessageBox.No)
                if answer == QMessageBox.No:
                    self.lpywidget.closeDocument(self.index)
            elif os.stat(self.fname).st_mtime > self.mtime :
                answer = QMessageBox.warning(self.lpywidget,"File has changed","File '"+os.path.basename(self.fname)+"' has changed on disk. Do you want to reload it ?",QMessageBox.Yes,QMessageBox.No)
                if answer == QMessageBox.Yes:
                    self.reload()
                else:
                    self.mtime = os.stat(self.fname).st_mtime +1
            self.updateSvnStatus()

          del self.monitoring

    def updateSvnStatus(self):
        from . import svnmanip
        if svnmanip.hasSvnSupport():
            if (not hasattr(self,'svnstatus') and svnmanip.isSvnFile(self.fname)) or (hasattr(self,'svnstatus') and svnmanip.svnFileTextStatus(self.fname) != self.svnstatus):
                self.updateTabName(force=True)

    def svnUpdate(self):
        from . import svnmanip
        hasupdated = svnmanip.svnUpdate(self.fname,self.lpywidget)
        if hasupdated: self.reload()
        self.updateSvnStatus()
        
    def svnIsUpToDate(self):
        from . import svnmanip
        svnmanip.svnIsUpToDate(self.fname,self.lpywidget)
        self.updateSvnStatus()
        
    def svnAdd(self):
        from . import svnmanip
        svnmanip.svnFileAdd(self.fname)
        self.updateSvnStatus()
        
    def svnRevert(self):
        from . import svnmanip
        svnmanip.svnFileRevert(self.fname)
        self.reload()
        self.updateSvnStatus()
        
    def svnCommit(self):
        from . import svnmanip
        svnmanip.svnFileCommit(self.fname, None, self.lpywidget)
        self.updateSvnStatus()