""" python/ui/dataobj.py: CCP4MG Molecular Graphics Program Copyright (C) 2001-2008 University of York, CCLRC Copyright (C) 2009-2011 University of York Copyright (C) 2012 STFC This library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 3, modified in accordance with the provisions of the license to address the requirements of UK law. You should have received a copy of the modified GNU Lesser General Public License along with this library. If not, copies may be downloaded from http://www.ccp4.ac.uk/ccp4license.php This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. """ import sys,os import traceback from global_definitions import * import version DATAOBJ_TYPES = ['MolData','MapData','FieldData','VectorsData','GL2dScreen','CrystalData'] PLUGIN_DATAOBJ_TYPES = [] #-------------------------------------------------------------------- #-------------------------------------------------------------------- #-------------------------------------------------------------------- class Dependency: valid_attributes = ['selection','colour','visibility','create','delete', 'rename', 'transform','reconfigure','edit'] def __init__(self): #print "init Dependency",self # For the master object # dependents[attribute][object] = callback method self.dependents = {} # For dependent object # dependencies[master] = list of attributes self.dependencies = {} #------------------------------------------------------------------- def delete(self): #------------------------------------------------------------------- # A derived object is being deleted so clean up.. # inform any object which is dependent on this one self.update_dependents('delete') # relieve any object of responsibility for this one self.remove_all_dependency() #--------------------------------------------------------------------- def add_dependency(self,master='',attributes='',handlers='', callback=''): #--------------------------------------------------------------------- ''' Add a dependency master = the master object on which this object is dependent attributes = list of the masters attributes that this is dependent on handlers = list of methods of this to be called when master attribute changes callback = string which is can be executed in global context to identify the master object. This is not essential input for any DispObj or DataObj ''' import types # Is there already some dependency registered? if self.dependencies.has_key(master): dependencies = self.dependencies[master] else: dependencies = [] # Add each new dependency to the dependencies list and # also to the appropriate attribute dependents list in # the master object i = -1 for att in attributes: i = i + 1; if not self.valid_attributes.count(att): break if not dependencies.count(att): dependencies.append(att) #print "add_dependency master",master if isinstance(master,types.ClassType): if master == DispObj: if not DispObj.class_dependents.has_key(att): DispObj.class_dependents[att]={} DispObj.class_dependents[att][self] = handlers[i] #print "add_dependency DispObj",self.dependencies, DispObj.class_dependents else: if not master.class_dependents.has_key(att): master.class_dependents[att]={} #master.class_dependents[att][self] = callback+handlers[i] master.class_dependents[att][self] = handlers[i] #print "add_dependency class",self.dependencies, master.class_dependents else: if not master.dependents.has_key(att): master.dependents[att]={} if len(handlers)>i and handlers[i]: master.dependents[att][self] = handlers[i] else: master.dependents[att][self] = '' #print "add_dependency",self.dependencies, master.dependents self.dependencies[master] = dependencies #--------------------------------------------------------------------- def remove_dependency(self,master,attributes=[]): #--------------------------------------------------------------------- # Are there dependencies registered? if self.dependencies.has_key(master): dependencies = self.dependencies[master] else: return # If no input attributes then assume to remove all if len(attributes) == 0: attributes = dependencies # Remove specified dependency from the dependencies list and # from the appropriate attribute dependents list in # the master object import types for att in attributes: if dependencies.count(att): dependencies.remove(att) #exec "del master."+att+"_dependents[self]" if isinstance(master,types.ClassType) and \ hasattr(master,'class_dependents') and \ master.class_dependents.has_key(att) and \ master.class_dependents[att].has_key(self): del master.class_dependents[att][self] if hasattr(master,'dependents') and \ master.dependents.has_key(att) and \ master.dependents[att].has_key(self): del master.dependents[att][self] if len(dependencies): self.dependencies[master] = dependencies else: del self.dependencies[master] #--------------------------------------------------------------------- def remove_all_dependency(self): #--------------------------------------------------------------------- ''' Remove this object from all dependent lists - probably because we are deleting this object ''' import types for master in self.dependencies.keys(): if hasattr(master,'class_dependents'): for att in self.dependencies[master]: if master.class_dependents.has_key(att) and \ master.class_dependents[att].has_key(self): del master.class_dependents[att][self] if hasattr(master,'dependents'): for att in self.dependencies[master]: if master.dependents.has_key(att) and \ master.dependents[att].has_key(self): del master.dependents[att][self] del self.dependencies[master] #-------------------------------------------------------------------- def update_dependents(self,attribute): #-------------------------------------------------------------------- ''' This method will be called by the master object to update its dependents ''' import map import model #print "into update_dependents ",self,attribute,self.dependents if not self.valid_attributes.count(attribute): return if hasattr(self,'class_dependents'): #print "class_dependents",self.class_dependents if self.class_dependents.has_key(attribute): for obj,cmd in self.class_dependents[attribute].items(): if cmd: try: exec cmd+"(master='"+self.name+"',attribute='"+attribute+"')" except: pass if isinstance(self,DispObj): #print "DispObj class_dependents",DispObj.class_dependents if DispObj.class_dependents.has_key(attribute): for obj,cmd in DispObj.class_dependents[attribute].items(): #print "trying",DispObj.class_dependents[attribute][obj] try: apply(DispObj.class_dependents[attribute][obj],[], \ {'master' : self.name, 'attribute':attribute } ) except: pass if hasattr(self,'dependents') and self.dependents.has_key(attribute): for obj in self.dependents[attribute].keys(): #print "updating obj",attribute,obj,self.dependents[attribute][obj] if DEVELOPER(): #print "apply",obj,self.dependents[attribute][obj] #apply(self.dependents[attribute][obj],[], \ # {'master' : self.name, 'attribute':attribute } ) apply(self.dependents[attribute][obj],[], \ {'master' : self, 'attribute':attribute } ) else: try: #apply(self.dependents[attribute][obj],[], \ # {'master' : self.name, 'attribute':attribute } ) apply(self.dependents[attribute][obj],[], \ {'master' : self, 'attribute':attribute } ) except: pass #------------------------------------------------------------------ #------------------------------------------------------------------ #------------------------------------------------------------------ # The dataobj class #------------------------------------------------------------------ #------------------------------------------------------------------ #------------------------------------------------------------------ class DataObj(Dependency): dataobj_names = [] dataobj_insts = [] moldata_order = ['MolDisp','SurfaceDispobj','HBonds','Contacts','AnisoU','Annotation'] #------------------------------------------------------------------ def __init__(self,type='',name='',filename='',module={},dataparams={}): #------------------------------------------------------------------ #print "DataObj dataparams",name,dataparams,filename import os import utils self.ccp4mg_creator_version = version.ccp4mg_version self.name = name self.filename = ['','',''] self.visible = 1 self.expanded = 1 self.update_gui = [] self.moving = 0 if dataparams: for item in dataparams.keys(): setattr(self,item,dataparams[item]) if filename: self.filename = utils.check_filename(filename) #if filename: self.filename = os.path.abspath(filename) if type: self.object_type = type if module: self.module = module # Derive a unique name #print "DataObj.init self.filename",self,self.filename if not name: name = os.path.basename( os.path.splitext(self.filename[2])[0]) if not name: name = name + self.object_type self.uniquename(name) # Initiallise the visiblity and objects data self.objnames = [] self.objinsts = [] Dependency.__init__(self) import generate_uuid self.uuid = generate_uuid.generate_uuid() #------------------------------------------------------------------ def renameuniquename(self,name,oldname): #------------------------------------------------------------------ if not oldname or name==oldname: return oldidx = DataObj.dataobj_names.index(oldname) # find a name unique across all data objects import re,string # Make sure no dots that will break Tcl name = re.sub('\.','_',name) # -- or arithmetic symbols that will break python when they # appear in the keyword name = re.sub('-|\+|\/|%|\*','_',name) self.name_label = name # Beware picture definition may use name as python variable # --- not currently done # if string.find(string.digits,name[0:1])>0: name = '_'+name if DataObj.dataobj_names.count ( name ) <= 0: nname = name else: cont = 1 n = 0 while cont: n = n + 1 nname = name + "_" + str(n) if DataObj.dataobj_names.count ( nname ) <= 0: cont = 0 #print "Renaming",self.name,"to",nname self.name = nname # append to list of all data objects DataObj.dataobj_names[oldidx] = nname return nname #------------------------------------------------------------------ def uniquename(self,name,oldname=""): #------------------------------------------------------------------ # find a name unique across all data objects import re,string # Make sure no dots that will break Tcl name = re.sub('\.','_',name) # -- or arithmetic symbols that will break python when they # appear in the keyword name = re.sub('-|\+|\/|%|\*','_',name) self.name_label = name # Beware picture definition may use name as python variable # --- not currently done # if string.find(string.digits,name[0:1])>0: name = '_'+name if DataObj.dataobj_names.count ( name ) <= 0: nname = name else: cont = 1 n = 0 while cont: n = n + 1 nname = name + "_" + str(n) if DataObj.dataobj_names.count ( nname ) <= 0: cont = 0 self.name = nname # append to list of all data objects DataObj.dataobj_names.append (nname ) DataObj.dataobj_insts.append (self) return nname def get_label(self): return self.name_label #------------------------------------------------------------------ def delete(self,**keywords): #------------------------------------------------------------------ # delete child (disp) objects if len (self.objinsts) > 0: #Make an independent list or Python get confused by #items disappearing from objinst llen = len( self.objinsts) for ii in range(llen-1,-1,-1): #print "DataObj.delete deleting",ii,self.objinsts[ii] self.objinsts[ii].delete() #print "remaining objinsts",self.objinsts Dependency.delete(self) # remove from the global dataobj list if DataObj.dataobj_insts.count(self): i = DataObj.dataobj_insts.index(self) DataObj.dataobj_names.pop(i) DataObj.dataobj_insts.pop(i) #------------------------------------------------------------------ def getDependentsForDeletion(self): #------------------------------------------------------------------ return [] #------------------------------------------------------------------ def dataparams(self,all=1): #------------------------------------------------------------------ # save the key data which is necessary when restoring the # object on restart or 'restore status' datapar = {} for item in ['module','object_type','filename','visible','ccp4mg_creator_version','expanded','customResCIFFiles','uuid']: if hasattr(self,item): datapar[item]=getattr(self,item) #print "dataparams",datapar return datapar #------------------------------------------------------------------- def loaddata(self,**keywords): #------------------------------------------------------------------- # loaddata should load the data from self.filename. It should # not create any display objects. # The return tuple should be # status 0=success, 1=failure # message (note a message can be set even if status is 0 # - this may happen if data file has been restored from backup) # info - optional parameters whose interpretation is class dependent return [0,''] #----------------------------------------------------------------------- def add_dispobj(self,dispobj): #----------------------------------------------------------------------- # Support the dataobj icon menu by providing functionality # to add a new display object self.objnames.append(dispobj.name) self.objinsts.append(dispobj) #print "objnames",self.objnames #-------------------------------------------------------------------- def get_dispobj(self,object_type='',mode='all',name=''): #-------------------------------------------------------------------- import types if not object_type: obj_type = [] if not isinstance(object_type,types.ListType) and object_type: obj_type = [object_type] else: obj_type = object_type if name: if self.objnames.count(name): return self.objinsts[self.objnames.index(name)] else: return '' else: ret = [] for obj in self.objinsts: if not obj_type or obj_type.count(obj.object_type): ret.append(obj) if mode == 'first': return ret return ret #------------------------------------------------------------------- def getFilename(self): #------------------------------------------------------------------- return self.filename[2] #------------------------------------------------------------------- def setFilename(self,filename): #------------------------------------------------------------------- import utils,os self.filename = utils.check_filename(filename) self.name_label = os.path.basename( os.path.splitext(self.filename[2])[0]) #------------------------------------------------------------------- def transform(self,dx='',dy='',dz='',rotx='',roty='',rotz=''): #------------------------------------------------------------------- ''' Handle translation commands from mouse movement ''' pass #------------------------------------------------------------------------- def set_visibility ( self,toggle_visibility='',visibility='',**keywords): #------------------------------------------------------------------------- if toggle_visibility: vis = 1 - self.visible elif visibility != '': vis = int(visibility) else: return self.visible = vis def get_visibility(self): return self.visible #------------------------------------------------------------------------- def set_expanded ( self,toggle_expanded='',expanded='',**keywords): #------------------------------------------------------------------------- if toggle_expanded: expd = 1 - self.expanded elif expanded != '': expd = int(expanded) else: return self.expanded = expd def get_expanded(self): return self.expanded #------------------------------------------------------------------ def handle_program_exit(self): #------------------------------------------------------------------ pass #------------------------------------------------------------------ def movie_interpolation(self,initial_status=None,final_status=None, \ fraction=0.0,step='',**keywords): #------------------------------------------------------------------ if initial_status and final_status: for item in final_status.objnames: if initial_status.objnames.count(item) and self.objnames.count(item): self.objinsts[self.objnames.index(item)].movie_interpolation( \ initial_status=initial_status.objinsts[initial_status.objnames.index(item)], \ final_status=final_status.objinsts[final_status.objnames.index(item)], \ fraction=fraction,step=step ) #-------------------------------------------------------------------- def isSameData(self,shadow_data): #-------------------------------------------------------------------- # print "dataobj isSameData",self.filename,shadow_data.dataparams['filename'] if not hasattr(self,'filename') or not shadow_data.dataparams.has_key('filename'): return False elif self.filename == shadow_data.dataparams['filename']: return False else: return True #--------------------------------------------------------------------- def update_data_status (self,shadow_data,clear=1): #--------------------------------------------------------------------- #print "update_data_status",self,shadow_data,shadow_data.dataparams rv = 0 if isinstance(shadow_data,DataObj): other_dataparams = shadow_data.dataparams() else: other_dataparams = shadow_data.dataparams if other_dataparams.get('visible',1) != getattr(self,'visible',1): rv = 1 self.update_gui.append(['visible']) self.set_visibility(visibility=other_dataparams.get('visible',1)) # Do we currently have some display obj which is not # in the updated shadow_data? delinsts_list = [] for ii in range(0,len(self.objnames)): if not shadow_data.objnames.count(self.objnames[ii]): delinsts_list.append(self.objinsts[ii]) else: shadow_disp = shadow_data.objinsts[ \ shadow_data.objnames.index(self.objnames[ii])] if self.objinsts[ii].object_type != shadow_disp.object_type: \ delinsts_list.append(self.objinsts[ii]) else: rv0 = self.objinsts[ii].update_data_status(shadow_disp) if rv0: self.update_gui.append(['update_DispObj',self.objnames[ii]]) rv = 1 #print "after DispObj.update_data_status",self.objnames[ii],rv0 #print "DataObj:update_data_status delete_list",self,delinsts_list if clear: for obj in delinsts_list: self.update_gui.append(['delete',obj.name]) rv = 1 obj.delete() del delinsts_list addinsts_list = [] for ii in range(0,len(shadow_data.objnames)): if not self.objnames.count(shadow_data.objnames[ii]): addinsts_list.append(shadow_data.objinsts[ii]) #print "DataObj:update_data_status add_list",addinsts_list for obj in addinsts_list: obj.restore(self.name) self.update_gui.append(['add',obj.name]) rv = 1 #print "DataObj.update_data_status",self.name,self.update_gui return rv #----------------------------------------------------------------- def animate(self,shadow_data): #----------------------------------------------------------------- if isinstance(shadow_data,DataObj): other_dataparams = shadow_data.dataparams() else: other_dataparams = shadow_data.dataparams if other_dataparams.get('visible',1) != getattr(self,'visible',1): rv = 1 #self.update_gui.append(['visible']) self.set_visibility(visibility=other_dataparams.get('visible',1)) for ii in range(0,len(self.objnames)): if shadow_data.objnames.count(self.objnames[ii]): shadow_disp = shadow_data.objinsts[shadow_data.objnames.index(self.objnames[ii])] if self.objinsts[ii].object_type == shadow_disp.object_type: \ rv0 = self.objinsts[ii].animate(shadow_disp) #----------------------------------------------------------------- def copy_data_files(self,project='',dir='',overwrite=1,extra_files=[]): #----------------------------------------------------------------- ''' Copy the data file(s) to another directory ''' import utils,os,shutil copied = [] errors = [] if self.filename: filn = utils.get_filename(self.filename[0],self.filename[1]) ret=utils.copy_data_file(filename=filn,dir=dir,overwrite=overwrite) errors.extend(ret[1]) copied.extend(ret[2]) if not ret[0] and project: self.dataparams['filename']=[project,filename[1],ret[1]] if self.object_type == 'MolData': mgfile = os.path.splitext(filn)[0]+'.ccp4mg' if os.path.exists(mgfile): extra_files.insert(1,mgfile) if hasattr(self,'animation') and self.animation: ret=anim.copy_data_files(project=project,dir=dir) copied.extend(ret[2]) for filn in extra_files: ret=utils.copy_data_file(filename=filn,dir=dir,overwrite=overwrite) errors.extend(ret[1]) copied.extend(ret[2]) print "copy_data_files",errors,copied return [len(errors),errors,copied] #------------------------------------------------------------------- class COneColour: #------------------------------------------------------------------- #------------------------------------------------------------------- def __init__(self,colour='',ifcomplement=1): #------------------------------------------------------------------- self.colour=colour self.colour_label = '' self.ifcomplement = ifcomplement #------------------------------------------------------------------- def __del__(self): #------------------------------------------------------------------- pass #----------------------------------------------------------------------- def set_colour ( self,colour='',colparams='',force=0,**keywords): #----------------------------------------------------------------------- #print "COneColour.set_colour",colour changed = 0 if colparams: for item in colparams.keys(): setattr(self,item,colparams[item]) if colour == 'complement': self.colour = 'complement' self.colour_label = 'complement' self.do_recolour = 1 if self.legend_visible: self.update_legend = 1 return 1 ii= MGCOLOUR().colour_index(colour) #print "COneColour.set_colour",colour,ii if ii>=0: self.colour = colour self.colour_label = colour self.do_recolour = 1 if self.legend_visible: self.update_legend = 1 changed = 1 return changed #------------------------------------------------------------------- def get_colour(self): #------------------------------------------------------------------- return self.colour #------------------------------------------------------------------- def handle_colour_change (self,name='',standard=0,rename='',delete=0): #------------------------------------------------------------------- # Handle a redefinition of the colour with name 'name' # If the changed colour is one of the 'standard' colours # then just need to refresh the display # If the colour is user defined then it will only be used in # a user defined colour scheme - addition/deletion of colours # would require apply_colour #print "handle_colour_change",self,name,'*',rename,delete if rename: if self.colour == name: self.colour=rename self.colour_label = self.colour elif delete: if self.colour == name: self.colour='grey' self.colour_label = self.colour else: self.do_recolour = 1 if self.legend_visible: self.update_legend = 1 #------------------------------------------------------------------ #------------------------------------------------------------------ #------------------------------------------------------------------ class DataObjShadow: #------------------------------------------------------------------ #------------------------------------------------------------------ #------------------------------------------------------------------ def __init__(self,name='',object_type='',filename='',objnames=[],objinsts=[],dataparams={}): self.name = name self.object_type = object_type self.filename=filename self.dataparams= {} self.dataparams.update(dataparams) self.objnames = objnames self.objinsts = objinsts self.visible = 1 #---------------------------------------------------------------------- def save(self,dataobj='',all=1,save_visible=0): #---------------------------------------------------------------------- # If the data has not been saved to file then don't attempt # to save the dataobj if not ['CrystalData','GL2dScreen'].count(dataobj.object_type): if not dataobj.filename[0]: return 1 self.filename = dataobj.filename # For legend/images check there are some objects which are not slaves #if dataobj.object_type == 'GL2dScreen': # nobj = 0 # for obj in dataobj.objinsts: # if (not hasattr(obj,'master_application') or \ # not obj.master_application) and not hasattr( obj,'master') : # nobj = nobj+1 # if nobj == 0 : return 1 #print "saving",dataobj.name self.name = dataobj.name self.object_type = dataobj.object_type if isinstance(dataobj,DataObjShadow): self.dataparams=dataobj.dataparams else: self.dataparams=dataobj.dataparams(all=all) self.objnames = [] self.objinsts = [] for i in range(0,len(dataobj.objnames)): #Save objects which do not have a master controlling application if (not save_visible or dataobj.objinsts[i].visible) and \ (not hasattr(dataobj.objinsts[i],'master_application') or not \ dataobj.objinsts[i].master_application ) and \ not hasattr( dataobj.objinsts[i],'master') : self.objnames.append(dataobj.objnames[i]) objinsts = DispObjShadow() self.objinsts.append( objinsts ) objinsts.save(dataobj.objinsts[i],all=all) return 0 #------------------------------------------------------------------------- def get_filename(self): #------------------------------------------------------------------------- if self.dataparams.has_key('filename'): return self.dataparams['filename'] else: return [] #------------------------------------------------------------------------- def set_filename(self,filn): #------------------------------------------------------------------------- self.dataparams['filename'] = filn #------------------------------------------------------------------------- def set_dataobj(self,dataobj): #------------------------------------------------------------------------- self.dataobj = dataobj #------------------------------------------------------------------------- def restore(self,version=0,default_dir='',**kw): #------------------------------------------------------------------------ from model import MolData from map import MapData from Legend import GL2dScreen from Crystal import CrystalData from VectorsDispobj import VectorsData import os import history import utils #print 'DataObjShadow.restore',self.name,self.dataparams.get('filename',''),default_dir self.dataparams["name"] = self.name restore_message = '' if hasattr(self,'dataobj') and False: #return [0,'Data object already restored',self.dataobj.name] return [0,'',self.dataobj.name] self.dataobj = None # Test if data file still exists if self.dataparams.has_key('filename'): # Reset the full file path on basis of current # project directory definition filedef = [self.dataparams['filename'][0],self.dataparams['filename'][1]] fullpath = utils.get_filename( self.dataparams['filename'][0], self.dataparams['filename'][1], default_dir ) if not os.path.exists(fullpath) and os.path.exists(self.dataparams['filename'][2]): #print "get_filename failed, try",self.dataparams['filename'][2] filedef.append(self.dataparams['filename'][2]) # Since get_filename failed so dotCCP4MG or project dir must be wrong, but it is a valid path. if sys.platform != 'win32': # I am not at all sure that drive letters etc. would help here. if False and os.path.dirname(self.dataparams['filename'][2]) == '' and os.path.exists(os.path.join(os.environ['PWD'],self.dataparams['filename'][2])): # Coerce int a full path. Not sure about this, so disabling for now (False above) filedef[0] = 'FULLPATH' filedef[2] = os.path.join(os.environ['PWD'],self.dataparams['filename'][2]) elif os.path.dirname(self.dataparams['filename'][2]) != '': # It seesm to be a valid fullpath here, but project, etc. is not valid, so call it a fullpath. filedef[0] = 'FULLPATH' #print "using filedef",filedef else: filedef.append( fullpath ) filedef[1] = os.path.basename(fullpath) if len(filedef)>1 and type(filedef[1]) == unicode: filedef[1] = str(filedef[1]) if len(filedef)>2 and type(filedef[2]) == unicode: filedef[2] = str(filedef[2]) self.dataparams['filename'] = filedef if self.dataparams['filename'][2] and not os.path.exists(self.dataparams['filename'][2]): try: if PM('save_sesion_options').get('backup_data_files'): rv = restore_data_file(self.dataparams['filename']) if rv[0]: return [rv[0],rv[1],None] else: restore_message = rv[1] else: return ['1','Error restoring data.\n File does not exist '+ \ self.dataparams['filename'][2]] except: return ['1','Error restoring data.\n File does not exist '+ \ self.dataparams['filename'][2]] #print "DataObjShadow.restore dataparams:",self.dataparams.get('filename','') if self.dataparams.has_key('modules'): for module in self.dataparams['modules']: try: exec 'from ' + module + ' import *' except: pass """ thisRestored = False if self.dataparams.has_key('modules'): for module in self.dataparams['modules']: try: exec 'from ' + module + ' import *' thisRestored = True except: pass """ """ if not thisRestored: import MGApplication mainwin = MGApplication.GetMainWindow() mainwin.loadPlugins() if self.dataparams.has_key('modules'): for module in self.dataparams['modules']: try: print "trying module", module exec 'from ' + module + ' import *' print "success" thisRestored = True except: pass """ #print 'DataObjShadow.restore object_type',self.object_type try: exec 'self.dataobj='+self.object_type + '(dataparams=self.dataparams,restore_from_version=version)' # '(name="' + self.name + '",dataparams=self.dataparams)' except: return [1,'Failed to create data object of type '+self.object_type,None] rv = self.dataobj.loaddata(recentre=0,warnings=0) # Only react if loading data file completely failed? if rv[0]==1: self.dataobj.delete() del self.dataobj return [1,restore_message+rv[1],None] return [0,restore_message,self.dataobj] #----------------------------------------------------------------------- def restore_display_objects(self,override_visible=1,version=0): #----------------------------------------------------------------------- # Load the display objects import model import map import Legend #print "restore_display_objects",self,self.dataobj,self.dataobj.name,self.objinsts,version,self.get_filename(),dir(self) if not hasattr(self,'dataobj') or not self.dataobj: traceback.print_stack() return [0,'No defined data object restoring display object '+self.name] if isinstance(self.dataobj,model.MolData) or isinstance(self.dataobj,map.MapData): fname = self.get_filename() if fname[2] != os.path.abspath(fname[2]): fname[2] = os.path.abspath(fname[2]) self.set_filename(fname) restore_message = '' if self.objinsts: for obj in self.objinsts: if isinstance(obj,DispObjShadow): if isinstance(self.dataobj,Legend.GL2dScreen): #print "restore_display_object",obj,self.dataobj fname = obj.get_filename() if type(fname) == list or type(fname) == tuple: if fname[2] != os.path.abspath(fname[2]): fname[2] = os.path.abspath(fname[2]) obj.set_filename(fname) obj.restore(self.dataobj.name,override_visible=override_visible,version=version) return [0,restore_message] #----------------------------------------------------------------- def copy_data_files(self,project='',dir='',overwrite=1,extra_files=[]): #----------------------------------------------------------------- ''' Copy the data file(s) to another directory ''' import utils,os,shutil copied = [] errors = [] if self.dataparams['filename']: print self.dataparams['filename'] if os.path.exists(self.dataparams['filename'][1]): filn = self.dataparams['filename'][1] elif os.path.exists(self.dataparams['filename'][2]): filn = self.dataparams['filename'][2] else: filn = utils.get_filename(self.dataparams['filename'][0],self.dataparams['filename'][1]) if not os.path.exists(filn): return [1,['No source data file '+filn],[]] if os.path.exists(filn) and not os.path.isdir(filn): ret=utils.copy_data_file(filename=filn,dir=dir,overwrite=overwrite) errors.extend(ret[1]) copied.extend(ret[2]) if project: self.dataparams['filename']= [project,self.dataparams['filename'][1],''] #print "dataparamsfilename",self.dataparams['filename'] if self.object_type == 'MolData': path = os.path.splitext(filn)[0]+'.ccp4mg' if os.path.exists(path): extra_files.insert(1,path) if self.dataparams.has_key('load_animation'): import Animation anim = Animation.Animation(parent=self, \ params=self.dataparams['load_animation'],load=0) ret=anim.copy_data_files(project=project,dir=dir) del anim errors.extend(ret[1]) copied.extend(ret[2]) for filn in extra_files: ret=utils.copy_data_file(filename=filn,dir=dir,overwrite=overwrite) errors.extend(ret[1]) copied.extend(ret[2]) return [len(errors),errors,copied] #---------------------------------------------------------------- def difference(self,first=None,second=None): #---------------------------------------------------------------- import utils errcodes = { 'object_type' : 4 , 'filename' : 3 } rv = 0 self.minus_dataparams = {} self.minus_objnames = [] self.minus_objinsts = [] rv,self.dataparams,self.minus_dataparams = utils.dict_diffs( \ first.dataparams,second.dataparams,errcodes) ii = -1 for objname in first.objnames: ii = ii+1 if second.objnames.count(objname) and first.objinsts[ii].object_type == second.objinsts[ second.objnames.index(objname)].object_type: jj = second.objnames.index(objname) tmp = DispObjShadow(name=objname,object_type=first.objinsts[ii].object_type) diff = tmp.difference(first=first.objinsts[ii],second=second.objinsts[jj]) if not diff: del tmp else: rv = max(rv,diff) self.objnames.append(first.objnames[ii]) self.objinsts.append(tmp) else: self.minus_objnames.append(first.objnames[ii]) rv = max(rv,2) jj = -1 for objname in second.objnames: jj = jj+1 if not first.objnames.count(objname) or second.objinsts[jj].object_type != first.objinsts[ first.objnames.index(objname)].object_type: tmp = DispObjShadow() tmp.save(second.objinsts[jj]) tmp.minus_params={} self.objinsts.append(tmp) self.objnames.append(tmp.name) rv = max(rv,2) #print "DataObjShadow difference minus_objnames",self.minus_objnames return rv #------------------------------------------------------------------ def add(self,source=None): #------------------------------------------------------------------ import utils self.dataparams = utils.dict_add(self.dataparams, \ source.dataparams,source.minus_dataparams) for objname in source.minus_objnames: if self.objnames.count(objname): ii = self.objnames.index(objname) #print "DataObjShadow::add delete self.objnames[ii]" del self.objinsts[ii] del self.objnames[ii] for objname in source.objnames: if self.objnames.count(objname): self.objinsts[self.objnames.index(objname)].add( \ source.objinsts[source.objnames.index(objname)]) else: #print "DAtaObjShadow::add add objname" tmp = DispObjShadow() tmp.save(source.objinsts[source.objnames.index(objname)]) self.objinsts.append(tmp) self.objnames.append(tmp.name) #-------------------------------------------------------------------- def save_picture_definition(self,pretty_print,style='method'): #-------------------------------------------------------------------- # CrystalData and GL2dScreen objects are not written out if ['CrystalData','GL2dScreen'].count(self.object_type): return '' import utils indent=5 if style == 'mgpic': return '' elif style == 'method': b_end = ')' stream = self.object_type+' (' else: b_end = '}' stream = self.name + ' = {' #for item in ['name','object_type','filename','objnames']: for item in ['filename','name']: if getattr(self,item,''): stream = stream+utils.picture_defn_item(item,getattr(self,item,''),pretty_print,style=style,indent=indent) #if getattr(self,'objnames',''): # stream = stream+utils.picture_defn_item('display_objects',self.objnames,pretty_print,style=style,indent=indent) # Only write out 'visible' if it is false if self.dataparams.has_key('visible') and not self.dataparams['visible']: stream =stream+utils.picture_defn_item('visible',0,pretty_print,style=style,indent=indent) for item in self.dataparams.keys(): if not ['filename','object_type','module','visible'].count(item): stream = stream+utils.picture_defn_item(item,self.dataparams[item],pretty_print,style=style,indent=indent) stream = stream[0:-1]+ '\n '+b_end+'\n\n' return stream #-------------------------------------------------------------------- def nofTransparentObjects(self): #-------------------------------------------------------------------- nn = 0 for obj in self.objinsts: nn = nn + obj.isTransparent() return nn #-------------------------------------------------------------------- #-------------------------------------------------------------------- #-------------------------------------------------------------------- class DispObjShadow: #-------------------------------------------------------------------- #-------------------------------------------------------------------- #-------------------------------------------------------------------- objnames = [] objinsts = [] #------------------------------------------------------------------- def __init__(self,name='',object_type='',visible=1,selparams={},colparams={},styleparams={},params={}, default_dir='',**keywords): #------------------------------------------------------------------- self.name = name self.object_type = object_type self.visible = visible if params.has_key("opacity"): if type(params["opacity"]) == str: params["opacity"] = float(params["opacity"]) if ['MolDisp','SurfaceDispobj','HBonds','Contacts'].count(self.object_type): if selparams: self.selparams = {} self.selparams.update(selparams) elif params.has_key('selection'): self.selparams = { 'cid': params['selection'], 'select': 'cid'} else: self.selparams = {} if colparams: self.colparams = {} self.colparams.update(colparams) elif params.has_key('colour'): if ['MolDisp','SurfaceDispobj'].count(self.object_type): if MGCOLOUR().index(params['colour'],safe=0)>=0: self.colparams = { 'colour_mode': 'one_colour', 'one_colour': params['colour'] } else: self.colparams = { 'colour_mode': params['colour'] , 'one_colour': '' } else: self.colparams = { 'colour' : params['colour'] } else: self.colparams = {} if styleparams: self.styleparams = {} self.styleparams.update(styleparams) elif params.has_key('style'): if ['MolDisp'].count(self.object_type): self.styleparams = { 'style_mode': params['style'] } else: if ['same_as'].count( params['style']): self.styleparams = { 'select': params['selection'] } else: self.styleparams = { 'cid': params['style'], 'select': 'cid'} else: self.styleparams = {} #print "init",self.name #print "selparams",self.selparams #print "colparams",self.colparams #print "styleparams",self.styleparams self.params = { } self.params.update(params) #print "Setting self.params['default_dir']",default_dir; sys.stdout.flush() self.params['default_dir'] = default_dir #------------------------------------------------------------------ def get_filename(self): #------------------------------------------------------------------ if "Image" in self.object_type: return self.params.get('filename','') else: return '' #------------------------------------------------------------------------- def set_filename(self,filn): #------------------------------------------------------------------------- self.params['filename']=filn #------------------------------------------------------------------ def convert_selection(self,select='',mode='string'): #------------------------------------------------------------------ if not ['MolDisp','SurfaceDispobj','HBonds','Contacts'].count(self.object_type): return [0,''] import types if mode == 'list': if isinstance(select,types.StringType): if not select: return [0,[None,'']] else: import model_selection parser= model_selection.SelectionParser() return parser.command_to_list(select) else: return [0,select] else: if isinstance(select,types.ListType): import model_selection parser= model_selection.SelectionParser() return parser.list_to_command(select) else: return [0,select] #-------------------------------------------------------------------- def save ( self,dispobj ,all=1): #-------------------------------------------------------------------- self.name = dispobj.name self.object_type = dispobj.object_type self.visible = dispobj.visible if ['MolDisp','SurfaceDispobj','HBonds','Contacts'].count(self.object_type) : if isinstance(dispobj,DispObjShadow): self.selparams = dispobj.selparams self.colparams = dispobj.colparams self.styleparams = dispobj.styleparams else: self.selparams = dispobj.selparams(all=all) self.colparams = dispobj.colparams(all=all) self.styleparams = dispobj.styleparams(all=all) #print 'DispObjShadow.save',self,self.styleparams if isinstance(dispobj,DispObjShadow): self.params = dispobj.params else: self.params = dispobj.params(all=all) # "visible",self.visible,'params',self.params #--------------------------------------------------------------------- def restore(self,parent_name,override_visible=1,version =0,deleteEmpty=False): #--------------------------------------------------------------------- from model import MolDisp from map import MapDisp import HBonds,SurfaceDispobj,Contacts,Annotation #print "DispObjShadow restore",self,self.params if not ['MolDisp','MapDisp'].count(self.object_type): try: exec 'from ' + self.object_type + ' import *' except: import re module = re.sub('Dispobj','',self.object_type) try: exec 'from ' + module + ' import *' except: pass # Restore surfaces invisible if override_visible and \ ( self.object_type == 'SurfaceDispobj' or \ (self.object_type == 'MolDisp' and self.styleparams.has_key('style_mode') and self.styleparams['style_mode'] == 'SURFACE') ): #print "setting invisible",dispobj.name self.visible = 0 if ['MolDisp','SurfaceDispobj','HBonds','Contacts'].count(self.object_type): if self.params.has_key('selection'): print '??? old selection',self.params['selection'] self.selparams['oldSelection'] = self.params['selection'] exec self.object_type + '(parent_name,name=self.name ' \ +',visible=self.visible,params = self.params' \ +',selparams=self.selparams,colparams=self.colparams' \ +',styleparams=self.styleparams,restore_from_version=version)' if deleteEmpty: dobjs = get_dataobj(object_type="MolData") theDobj = None for dobj in dobjs: if dobj.name == parent_name: theDobj = dobj if theDobj is not None: dispobjs = theDobj.get_dispobj() for dispobj in dispobjs: if dispobj.name == self.name: if hasattr(dispobj,"SelHandle1") and hasattr(dispobj,"SelHandle2"): nat1,nat2 = dispobj.SelHandle1.getNofAtoms(),dispobj.SelHandle2.getNofAtoms() if nat1 <= 0 or nat2 <= 0: dispobj.delete() elif hasattr(dispobj,"SelHandle"): nat = dispobj.SelHandle.getNofAtoms() if nat <= 0: dispobj.delete() elif hasattr(dispobj,"style") and dispobj.style == "SPLINE" and nat < 3: dispobj.delete() else: thisRestored = False try: exec self.object_type + '(parent_name,name=self.name ' \ +',visible=self.visible,params = self.params )' thisRestored = True except: pass if not thisRestored: import MGApplication mainwin = MGApplication.GetMainWindow() if hasattr(mainwin,"plugins"): for plug in mainwin.plugins: for obj in dir(plug): if obj == self.object_type: try: exec 'from '+plug.__name__+' import '+obj print self.object_type + '(parent_name,name=self.name ' \ +',visible=self.visible,params = self.params )' exec self.object_type + '(parent_name,name=self.name ' \ +',visible=self.visible,params = self.params )' thisRestored = True break except: pass if not thisRestored: mainwin.loadPlugins() for plug in mainwin.plugins: for obj in dir(plug): if obj == self.object_type: try: exec 'from '+plug.__name__+' import '+obj print self.object_type + '(parent_name,name=self.name ' \ +',visible=self.visible,params = self.params )' exec self.object_type + '(parent_name,name=self.name ' \ +',visible=self.visible,params = self.params )' thisRestored = True break except: pass if not thisRestored: try: from MGGLImage import Image print 'Attempting to restore',self.object_type,self.name,self.visible,self.params exec self.object_type + '(parent_name,name=self.name ' \ +',visible=self.visible,params = self.params )' except: exc_type, exc_value,exc_tb = sys.exc_info()[:3] print exc_type print exc_value traceback.print_tb(exc_tb) print 'DID NOT restore',self.name #----------------------------------------------------------------- def difference(self,first=None,second=None): #----------------------------------------------------------------- import utils rv = 0 if first.visible != second.visible: self.visible = second.visible rv = 1 rv0,self.params,self.minus_params=utils.dict_diffs(first.params,second.params) #print 'dispobjshadow.difference',self,rv0,first.params,second.params rv=max(rv,rv0) if ['MolDisp','SurfaceDispobj','HBonds','Contacts'].count(self.object_type): for item in 'selparams','colparams','styleparams': ff = getattr(first,item,{}) ss = getattr(second,item,{}) rv0,fdiff,mdiff = utils.dict_diffs(getattr(first,item,{}), getattr(second,item,{})) rv=max(rv,rv0) setattr(self,item,fdiff) setattr(self,'minus_'+item,mdiff) #print "DispObj difference",self.name #print "diffs",self.params #print "minus_params",self.minus_params return rv #---------------------------------------------------------------- def add(self,source=None): #---------------------------------------------------------------- import utils if hasattr(source,'visible'): self.visible = source.visible attrib_list = ['params'] if ['MolDisp','SurfaceDispobj','HBonds','Contacts'].count(self.object_type): attrib_list.extend(['selparams','colparams','styleparams']) for attrib in attrib_list: setattr(self,attrib, utils.dict_add(getattr(self,attrib,{}), \ getattr(source,attrib,{}),getattr(source,'minus_'+attrib,{}))) #-------------------------------------------------------------------- def save_picture_definition(self,pretty_print,style='method',attributes={},parent=''): #-------------------------------------------------------------------- import utils,model,model_selection,model_colour if style == 'method': b_end = ')' stream = self.object_type+' (' else: b_end='}' stream = self.name + ' = {' #print "save_picture_definition",self.name,self.colparams #for item in ['name','object_type']: # stream=stream+utils.picture_defn_item(item,getattr(self,item,''),pretty_print,style=style) if parent: stream=stream+"\n parent = "+parent+"," for key,value in attributes.items(): stream=stream+utils.picture_defn_item(key,value,pretty_print,style=style) if not getattr(self,'visible',1): stream=stream+utils.picture_defn_item('visible',0,pretty_print,style=style) for item in self.params.keys(): if not ['name','object_type','visible'].count(item): stream=stream+utils.picture_defn_item(item,self.params[item],pretty_print,style=style) if ['MolDisp','SurfaceDispobj','HBonds','Contacts'].count(self.object_type): if self.selparams: stream=stream+utils.picture_defn_item('selection_parameters',self.selparams,pretty_print,style=style,dict_order=model_selection.SelHandle.selection_initialisation) if self.colparams: if ['MolDisp','SurfaceDispobj'].count(self.object_type): #if ['SurfaceDispobj'].count(self.object_type): #print 'save_picture_definition',self.colparams #print 'picture_defn_item',utils.picture_defn_item('colour_parameters',self.colparams,pretty_print,style=style,dict_order=model_colour.model_colour.colour_initialisation_order) stream=stream+utils.picture_defn_item('colour_parameters',self.colparams,pretty_print,style=style,dict_order=model_colour.model_colour.colour_initialisation_order) else: stream=stream+utils.picture_defn_item('colour_parameters',self.colparams,pretty_print,style=style,dict_order=['colour']) if self.styleparams: if ['SurfaceDispobj','HBonds','Contacts'].count(self.object_type): stream=stream+utils.picture_defn_item('style_parameters',self.styleparams,pretty_print,style=style,dict_order=model_selection.SelHandle.selection_initialisation) else: stream=stream+utils.picture_defn_item('style_parameters',self.styleparams,pretty_print,style=style,dict_order=model.MolDisp.style_initialisation) elif ['MapDisp'].count(self.object_type): pass """ import map,MapPlane for item in map.MapDisp.map_initialisation_order: if self.params.has_key(item): stream=stream+utils.picture_defn_item(item,self.params[item],pretty_print,style=style) if self.params.has_key('plane_definition'): stream=stream+utils.picture_defn_item('plane_definition',self.params['plane_definition'],pretty_print,style=style,dict_order=MapPlane.MapPlane.initialisation_order) """ stream = stream[0:-1]+ ' '+b_end+'\n\n' return stream #------------------------------------------------------------------ def uniquename(self,name='',parent=None): #------------------------------------------------------------------ if name: return name else: #print "uniquename",name,parent,parent.objnames n = len(parent.objnames) contu = 1 while contu: n = n + 1 nname = parent.name+self.object_type+str(n) contu = parent.objnames.count(nname) return nname #------------------------------------------------------------------ def isTransparent(self): #------------------------------------------------------------------ if self.params.get('opacity',1.0)< 0.99: return 1 else: return 0 #------------------------------------------------------------------ #------------------------------------------------------------------ #------------------------------------------------------------------ # DispObj class #------------------------------------------------------------------ #------------------------------------------------------------------ #------------------------------------------------------------------ class DispObj(COneColour,Dependency): class_dependents = {} #------------------------------------------------------------------ def __init__(self,theType,name='',parent='',visible=1, master_application=None, display_table_visible = 1, \ selparams={},colparams={},styleparams={},params={}): #------------------------------------------------------------------ #print "DispObj init parent",parent,'params',params,'master_application',master_application import types if params.has_key("opacity"): if type(params["opacity"]) == str: params["opacity"] = float(params["opacity"]) if isinstance(parent,types.StringType): self.parent = data(parent) else: self.parent = parent self.object_type = theType self.visible = int(visible) self.opacity = float(params.get('opacity',1.0)) self.display_class = params.get('display_class',"") self.do_update_opacity = 0 self.flashing = 0 self.do_redraw = 1 self.redraw_labels= 0 self.do_recolour = 1 self.built = 0 self.moving = 0 self.graphmod = None self.label_graphmod = None self.do_rebuildGL = [] # List of graphmods that need rebuilding in GL windows self.update_gui = [] self.name_label = "" self.style_label = "" self.style_icon = None self.colour_label = "" self.legend_visible = params.get('legend_visible',0) self.customSelectionName = params.get('customSelectionName','') # Name of object which controls this MolDisp - default is 'None' # which means the object is controlled by user/gui self.master_application = master_application self.display_table_visible = display_table_visible import copy self.transparent = 0 COneColour.__init__(self) self.name = self.uniquename (name) #print "DispObj name",name self.parent.add_dispobj(self) #Unpack parameters from dictionaries if selparams: for item in selparams.keys(): setattr(self,item,selparams[item]) if colparams: for item in colparams.keys(): setattr(self,item,colparams[item]) if styleparams: for item in styleparams.keys(): setattr(self,item,styleparams[item]) if params: #print 'dispobj params',params for item in params.keys(): if item == "font": if hasattr(self,"font"): font = self.font else: font = FONTMANAGER().GetValidFont() for item2 in params[item].keys(): font[item2] = params[item][item2] self.font = font else: setattr(self,item,params[item]) Dependency.__init__(self) self.update_dependents('create') import generate_uuid self.uuid = generate_uuid.generate_uuid() #------------------------------------------------------------------ def uniquename(self,name=''): #------------------------------------------------------------------ # Beware picture definition may use name as python variable #if name: # import string # if string.find(string.digits,name[0:1])>0: name = '_'+name if name and not get_dispobj( name = name ): nname = name else: n = len(self.parent.objnames) contu = 1 while contu: n = n + 1 nname = self.parent.name+self.object_type+str(n) contu = get_dispobj ( name = nname ) return nname def get_label(self): if self.object_type == 'MolDisp': return self.get_selection_label() else: return self.object_type+' '+self.get_selection_label() def get_selection_icon(self): import model_selection icon = None label = self.get_selection_label() if label in model_selection.SELECTION_ICONS: icon = model_selection.SELECTION_ICONS[label] if icon: if os.path.exists(os.path.join(os.environ['CCP4MG'],'qticons','disptab','selections',icon)): icon = os.path.join(os.environ['CCP4MG'],'qticons','disptab','selections',icon) return icon def setCustomSelectionName(self,t): self.customSelectionName = t def get_selection_label(self): if hasattr(self,'customSelectionName') and self.customSelectionName: return self.customSelectionName elif hasattr(self,'SelHandle'): return self.SelHandle.getLabel() elif hasattr(self,'SelHandle1'): return self.SelHandle1.getLabel() elif hasattr(self,'selection_label'): return self.selection_label else: return self.name_label def get_colour_label(self): #print "DispObj.get_colour_label",self.colour_label return self.colour_label def get_style_label(self): return self.style_label def get_style_icon(self): return self.style_icon def set_reapply_selection(self,mode=1): self.reapply_selection = 1 def set_redraw_text(self): if hasattr(self,"get_position_label") or hasattr(self,"create_annotation") or hasattr(self,"get_text") or hasattr(self,"Connectivity2"): self.do_redraw = 2 #------------------------------------------------------------------------- def set_visibility ( self, toggle_visibility='', visibility='',*args,**keywords): #------------------------------------------------------------------------- if toggle_visibility: vis = 1 - self.visible elif visibility != '': vis = int(visibility) else: return self.visible = vis self.update_dependents('visibility') for gobj in [self.graphmod, self.label_graphmod ]: if gobj: setattr(gobj.obj,'visible',self.visible) return vis def get_visibility(self): return self.visible #------------------------------------------------------------------- def set_flashing(self,mode=-1): #------------------------------------------------------------------- if mode<0: mode = 1- self.flashing if mode: self.flashing = 1 self.flash_count = 0 setattr(self,'saved_visible',self.visible) MAINWINDOW().addAnimationHandler('flash'+self.name,self.flash) else: self.flashing = 0 MAINWINDOW().removeAnimationHandler('flash'+self.name) if hasattr(self,'saved_visible'): setattr(self,'visible',self.saved_visible) import rebuild rebuild.UpdateDisplay(auto_save=0) del self.saved_visible #------------------------------------------------------------------- def isFlashing(self): #------------------------------------------------------------------- return self.flashing #------------------------------------------------------------------- def flash(self): #------------------------------------------------------------------- self.flash_count = self.flash_count+1 # beware animationInterval is in milliSec if self.flash_count< PM('Animation_param').get('flash_delay') * ( 1000/MAINWINDOW().animationInterval()): return self.flash_count = 0 self.visible = 1 - self.visible import rebuild rebuild.UpdateDisplay(auto_save=0) #------------------------------------------------------------------- def set_do_redraw(self): #------------------------------------------------------------------- self.do_redraw = 1 #------------------------------------------------------------------- def unthreadedDraw(self): #------------------------------------------------------------------- return 0 #------------------------------------------------------------------- def draw(self): #------------------------------------------------------------------- return 0 #------------------------------------------------------------------- def rebuildGLDisplayObject(self,main): #------------------------------------------------------------------- #print 'rebuildGLDisplayObject',self.do_rebuildGL if self.do_rebuildGL: for gobj_name in self.do_rebuildGL: gobj = getattr(self,gobj_name,None) if gobj: main.rebuildGLDisplayObject(gobj) self.do_rebuildGL = [] return 0 #------------------------------------------------------------------- def clone (self,**keywords): #------------------------------------------------------------------- pars = self.params() exec 'import '+self.object_type cmd = self.object_type+'.'+ self.object_type+ \ '(self.parent.name,visible=self.visible,params = pars)' exec cmd #------------------------------------------------------------------ def delete(self,**keywords): #------------------------------------------------------------------ # Beware that updating dependencies may have already # zapped an object Dependency.delete(self) if self.isFlashing(): MAINWINDOW().removeAnimationHandler('flash'+self.name) for gobj_name in ['graphmod','label_graphmod']: gobj = getattr(self,gobj_name,None) if gobj: MAINWINDOW().removeGLDisplayObject(gobj) BUILD().deletemod(gobj) self.legend_object = None if self.parent.objinsts.count(self): i = self.parent.objinsts.index(self) self.parent.objnames.pop(i) self.parent.objinsts.pop(i) del self #------------------------------------------------------------------ def params(self,all=1,rename={}): #------------------------------------------------------------------ sel = {} #print "params",self,self.opacity for item in ['visible','opacity','legend_visible','customSelectionName','display_class','uuid']: if hasattr(self,item): sel[item]=getattr(self,item) if rename: for key,newkey in rename.items(): if sel.has_key(key): sel[newkey] = sel[key] del sel[key] return sel #----------------------------------------------------------------- def isSameData(self,shadowdisp): #----------------------------------------------------------------- return False #----------------------------------------------------------------- def update_data_status(self,shadowdisp): #----------------------------------------------------------------- import utils rv = 0 if shadowdisp.params.has_key('selection') and self.selection != shadowdisp.params['selection']: #print "DisPObj update_data_status",shadowdisp.params['selection'] rv = 1 self.set_selection(selection=shadowdisp.params['selection']) if shadowdisp.params.has_key('colour') and self.colour != shadowdisp.params['colour']: rv = 1 self.set_colour(colour=shadowdisp.params['colour']) if shadowdisp.params.has_key('style') and self.style != shadowdisp.params['style']: rv = 1 self.set_style(style=shadowdisp.params['style']) rv = max(rv,self.update_data_status0(shadowdisp)) if rv: self.update_gui.append(['update']) return rv #----------------------------------------------------------------- def update_data_status0(self,shadowdisp): #----------------------------------------------------------------- import utils if shadowdisp.visible != self.visible: self.set_visibility(visibility = shadowdisp.visible) self.update_gui.append(['visible']) return 1 else: return 0 #----------------------------------------------------------------- def animate(self,shadowdisp): #----------------------------------------------------------------- #print "Dispobj.animate",self.name if shadowdisp.visible != self.visible: self.set_visibility(visibility = shadowdisp.visible) #self.update_gui.append(['visible']) return 1 else: return 0 #------------------------------------------------------------------ def selparams(self): #------------------------------------------------------------------ return {} #------------------------------------------------------------------ def colparams(self,all=1): #------------------------------------------------------------------ col = {} for item in ['colour']: col[item]=getattr(self,item) return col #------------------------------------------------------------------ def styleparams(self,all=1): #------------------------------------------------------------------ col = {} #for item in ['style']: # col[item]=getattr(self,item) return col #------------------------------------------------------------------ def centre_on ( self,**keywords ): #------------------------------------------------------------------ pass #------------------------------------------------------------------ def list_data(self): #------------------------------------------------------------------ return '' #-------------------------------------------------------------------- def name_string(self): #------------------------------------------------------------------- return "disp('" + self.parent.name + "','" + self.name + "')" #-------------------------------------------------------------------- def handle_moving_data(self,**keywords): #-------------------------------------------------------------------- pass #---------------------------------------------------------------------- def set_graphmod_visibility(self): #---------------------------------------------------------------------- """ Set the visibility of the graphmod appropriately for the visibility of the dataobj and dispobj """ vis = 1 if not int(self.visible): vis = 0 elif not int(self.parent.visible): vis = 0 # does this object has visibility dependency on any # master object which is currently invisible elif len(self.dependencies.keys())>0: for master,attlist in self.dependencies.items(): if attlist.count('visibility') and not master.visible: vis = 0 break if self.graphmod: self.graphmod.obj.visible = vis if self.label_graphmod: self.label_graphmod.obj.visible = vis #print "set_graphmod_visibility",self.visible,self.parent.visible,vis return vis #--------------------------------------------------------------------- def draw (self): #--------------------------------------------------------------------- return 0 #--------------------------------------------------------------------- def drawPickedLabels(self): #--------------------------------------------------------------------- return 0 # # Movement of object should usually apply to the dataobj but for # legend/image the following is needed # #------------------------------------------------------------------- def transform(self,dx='',dy='',dz='',rotx='',roty='',rotz=''): #------------------------------------------------------------------- ''' Handle translation commands from mouse movement ''' pass #------------------------------------------------------------------ def canBeTransparent(self): #------------------------------------------------------------------ return 0 #----------------------------------------------------------------------- def set_opacity(self,opacity=-1.0,**keywords): #----------------------------------------------------------------------- #print 'Dispobj.set_opacity',self.name,opacity,self.canBeTransparent() if self.canBeTransparent() and opacity>=0.0: self.opacity = float(opacity) self.do_update_opacity = 1 #------------------------------------------------------------------ def movie_interpolation(self,initial_status=None,final_status=None, \ fraction=0.0,step='',**keywords): #------------------------------------------------------------------ #print "DispObj.movie_interpolation" if final_status.params.has_key('opacity') and initial_status.params.has_key('opacity'): do = float(final_status.params['opacity'])-float(initial_status.params['opacity']) if (do<-0.001 or do>0.001) and hasattr(self,'graphmod') and self.graphmod: self.opacity = float(initial_status.params['opacity'])+fraction*do # Belt and braces self.graphmod.obj.SetAlpha(float(initial_status.params['opacity'])+fraction*do) #---------------------------------------------------------------- def setMasterCrystal(self,crystal): #---------------------------------------------------------------- self.masterCrystal = crystal self.updateCrystal() #---------------------------------------------------------------- def updateCrystal(self): #---------------------------------------------------------------- if not self.graphmod: return if not hasattr(self,'masterCrystal'): return if not self.label_graphmod: import graphicsmodel self.label_graphmod = graphicsmodel.graphicsmodel() BUILD().append(self.label_graphmod) if self.label_graphmod: self.label_graphmod.symmetry_dependent = self.graphmod #print "dataobj.updateCrystal",self.masterCrystal if not self.masterCrystal: self.graphmod.DrawUnitCell(0) self.graphmod.obj.SetDrawUnitCell(0) self.graphmod.setparams(draw_symmetry = 0) self.graphmod.setparams(symmetry_labels=0) else: xtl = get_dispobj(name=self.masterCrystal) self.graphmod.obj.SetDrawSymmetryColoured(xtl.symm_diff_colour) self.graphmod.obj.SetDrawUnitCell(xtl.cell_edges) self.graphmod.DrawUnitCell(draw_unit_cell=xtl.draw_unit_cell, \ xshift=xtl.unit_cell_shift[0], \ yshift=xtl.unit_cell_shift[1], zshift=xtl.unit_cell_shift[2]) self.graphmod.setparams(symmetry_labels= xtl.symmetry_labels) self.graphmod.setparams(draw_symmetry = xtl.mode) self.graphmod.setparams(symmetry_radius = xtl.atom_symm_radius) self.graphmod.draw_contacts=xtl.draw_contacts self.do_redraw = 1 #------------------------------------------------------------------------ def isLegendPossible(self): #------------------------------------------------------------------------ return 0 ''' #------------------------------------------------------------------------ def drawLegend(self): #------------------------------------------------------------------------ # Draw the legend - append text to DispObj.graphmod.obj if (not self.update_legend) or (not self.graphmod) or (not self.isLegendPossible()): return 0 if self.legend_object: import cprim cprim.DeleteTextLabel(self.graphmod.obj,self.legend_object.GetID()) self.legend_object = None if self.legend_visible: import TextLabel,pygl_coord x,y= 0.0,0.0 text = self.getLegend() self.legend_object = TextLabel.CreateBillBoardTextLabel(text,pygl_coord.Cartesian(x,y,0.0),pygl_coord.Cartesian(x,y,0.0)) self.legend_object.thisown = 0 self.graphmod.obj.add_text_primitive(self.legend_object) self.update_legend = 0 print 'DispObj.drawLegend' return 1 ''' #------------------------------------------------------------------- #------------------------------------------------------------------- #------------------------------------------------------------------- class CFont: #------------------------------------------------------------------ def set_font(self,font={},**keywords): #------------------------------------------------------------------ redraw = 0 # Input could be be a dictionary 'font' or individual # font attributes which will be put in keywords dictionary #print "set_font",self.name,font,'self',self.font font.update(keywords) font['underline']=0 for item in ['family','size','weight','slant','underline']: if font.has_key(item) and font[item] and font[item] != self.font[item]: self.font[item] = font[item] redraw = 1 #print "resetting",item if redraw: self.update_font() #----------------------------------------------------------------------- def update_font(self,label_ob = None): #----------------------------------------------------------------------- import utils #self.font = utils.GetValidFont(self.font) #print "CFont update_font",self.font if label_ob: label_ob.SetFontFamily(self.font['family']) label_ob.SetFontSize(int(self.font['size'])) label_ob.SetFontWeight(self.font['weight']) label_ob.SetFontSlant(self.font['slant']) label_ob.SetFontUnderline(bool(self.font['underline'])) elif self.graphmod and self.graphmod.obj: self.graphmod.obj.SetTextFont(str(self.font['family']),str(self.font['weight']), \ str(self.font['slant']),self.font['size'],self.font['underline']) self.graphmod.obj.rebuild() #---------------------------------------------------------------------- def scale_font(self,scale=-1.0,**keywords): #---------------------------------------------------------------------- #print "scale_font",self,scale font_sizes = [8,10,11,12,14,18,20,24,34,45,60] if scale < 0.0: self.graphmod.obj.SetTextFont(str(self.font['family']),str(self.font['weight']), \ str(self.font['slant']),self.font['size'],self.font['underline']) self.graphmod.obj.rebuild() else: scaled_size = float(self.font['size']) * scale if scaled_size < font_sizes[0]: new_size = font_sizes[0] elif scaled_size > font_sizes[-1]: new_size = font_sizes[-1] else: n = 0 while n < len(font_sizes)-1 and scaled_size > font_sizes[n]: n = n+1 if scaled_size-font_sizes[n-1] > font_sizes[n]-scaled_size: new_size = font_sizes[n] else: new_size = font_sizes[n-1] #print "scale_font" , scaled_size, n, new_size self.graphmod.obj.SetTextFont(str(self.font['family']),str(self.font['weight']), \ str(self.font['slant']),str(new_size),self.font['underline']) self.graphmod.obj.rebuild() #---------------------------------------------------------------------- #---------------------------------------------------------------------- #---------------------------------------------------------------------- #---------------------------------------------------------------------- def restore_data_file(filename=[],dir='',query=1): #---------------------------------------------------------------------- import utils import shutil filn = utils.get_filename(filename[0],filename[1]) if not dir: # Make an empty directory .CCP4MG/saved_data_files dir = os.path.join( utils.get_CCP4MG(),'saved_data_files' ) backup = os.path.join(dir,os.path.split(filn)[1]) if not os.path.exists(backup): return [1,"Backup for file "+filn+" does not exist"] # if query and not exit: # GUI.insts.CreateGUIWindow ('restore_data_file',self, [ # ['TITLE','Restore backed up file'], # ['RETURN_METHOD','restore_data_file'], # ['PARAM','filename', # ['INITIAL',filename]], # ['PARAM','dir', # ['INITIAL',dir]], # ['DISPLAY','WINDOW', # ['LINE', # ['LABEL','Attempting to restore datafrom file']], # ['LINE', # ['LABEL',filename]], # ['LINE', # ['LABEL','File does not exist. Do you want']], # ['LINE', # ['LABEL','to copy backup file to that filename?']], # ['BUTTONS', # ['ok', ['LABEL','Yes']], # ['dismiss',['LABEL','No'],['CLOSE']]] # ]]) # return try: shutil.copy( backup, os.path.split(filn)[0]) except: return [1,'Error attempting to restore file '+filn] return [0,'*****PLEASE NOTE*****\nRestoring data - data file '+filn+' not found.\n It has being recreated from backup made on '+utils.fileDate(backup)]