""" qtgui/MGMainWindow.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. """ from PyQt4 import QtGui,QtCore,QtOpenGL import tempfile from global_definitions import * import functools import sys,os import shutil import math import time import guiUtils,mgWidgets,MGSimpleDialog import utils import pygl_coord import mmdb2 as mmdb def getSuffixes(chomp): suffixes = [] if chomp.find('.')<0: return suffixes while chomp: newchomp = chomp[chomp.find('.')+1:] suffixes.append(newchomp) if newchomp.find('.')<0: break chomp = newchomp return suffixes def applyAdvancedPrefs(): DISPLAYTABLE().update(all=1) def createAdvancedParamsManager(): import services import MGMainWindow pm = services.ParamsManager ( name="advanced_options", apply_action = applyAdvancedPrefs, title='Advanced', help = '_has_no_help_', gui=['display_table_header','dockable_display_table','iconized_display_table','super_compact_display_table','other_header','developer_mode','spacer','restart_label'], default = { 'developer_mode' : 0, 'dockable_display_table' : 1, 'iconized_display_table' : 0, 'super_compact_display_table' : 0}, definition = { 'display_table_header' : dict(type=str, label='Display Table options', style='label'), 'other_header' : dict(type=str, label='Other options', style='label'), 'spacer' : dict(type=str, size=170, style='spacer'), 'dockable_display_table' : dict(type=str, label='Dock display table (*)',style='checkbox'), 'iconized_display_table' : dict(type=str, label='Use icons in display table',style='checkbox'), 'super_compact_display_table' : dict(type=str, label='Super-compact when docked (*)',style='checkbox'), 'restart_label' : dict(type=str, label='* Requires program restart', style='label'), 'developer_mode' : dict(type=str, label='Enable development features (*)',style='checkbox') } ) return pm def createRecentreParamsManager(): import services import MGMainWindow pm = services.ParamsManager ( name="centre_mode", title='Recentre method', help = '_has_no_help_', gui=['centre_method'], default = { 'centre_method' : MGMainWindow.MGMainWindow.CENTRE_MODE_EXTENTS }, definition = { 'centre_method' : dict(type=str, label='Recenter method',style='combobox',alias = [MGMainWindow.MGMainWindow.CENTRE_MODE_EXTENTS,MGMainWindow.MGMainWindow.CENTRE_MODE_COORDS,MGMainWindow.MGMainWindow.CENTRE_MODE_MASS],menu= ['Extents Box','Centre of Coordinates','Centre of Mass']) } ) return pm """ import opengl class GLWidget(QtOpenGL.QGLWidget): def __init__(self,parent=None,share=None,fmt=None): if fmt: QtOpenGL.QGLWidget.__init__(self,fmt,parent,share) else: QtOpenGL.QGLWidget.__init__(self,parent) self.viewsize = 100.0; self.NEAR = 0.01 self.FAR = 1000 self.obj = None self.lastPos = QtCore.QPoint() self.mouseDownPos = QtCore.QPoint() self.quat = pygl_coord.Quat(0.0,0.0,0.0,0) self.RADIUS = 60. self.rpos = (0,0,0) self.slab_enabled = False self.slab_width = 10. self.slab_offset = 0. self.clip_cap = False self.customClipPlanes = [] self.fog_enabled = False self.fog_strength = 1. self.fog_near = self.NEAR self.fog_far = self.FAR self.fog_auto = False self.slab_auto = False self.ambientOcclusionZNear = 100.0 self.ambientOcclusionZFar = 150.0 self.ambientOcclusionRadius = 15.0 self.ambientOcclusionBias = 0.3 self.ambientOcclusionScale = 1.0 self.show_axes = 0 self.show_scale = 0 self.shaders_on = 0 self.vertexShader = '' self.fragmentShader = '' self.show_fps = False import mmdb2 as mmdb import SimpleObject mmdb.InitMatType() molHnd = mmdb.Manager() molHnd.SetFlag(mmdb.MMDBF_AllowDuplChainID) molHnd.ReadCoorFile("/richelieu/stuart/ccp4-jhbuild-distutils/1sva_1.mmol") self.obj = SimpleObject.SimpleObject(molHnd) self.nframes = 0 self.previous_frames = 0 self.previous_time = time.time() self.current_fps_text = "0" def setPosition(self,axes): pass def setZoom(self,axes): pass def setQuat(self,axes): pass def setMouseBindings(self,axes): pass def getAxes(self): return self.show_axes def setShowScale(self,show): pass def getShowScale(self): return 0 def rebuildAllDisplayObjects(self): pass def setAmbientOcclusionState(self,state): pass def setOutlineState(self,state): pass def setShadowState(self,state=None,foo=False): pass def transparency(self): return False def setAxes(self,axes): pass def getAxes(self): return self.show_axes def setShowScale(self,show): pass def getShowScale(self): return 0 def rebuildAllDisplayObjects(self): pass def setAmbientOcclusionState(self,state): pass def setOutlineState(self,state): pass def setShadowState(self,state=None,foo=False): pass def setShaderState(self,state=None): pass def setBackground(self,r,g,b): pass def getBackground(self): return [1.0,1.0,1.0] def setAmbientOcclusionPrefs(self,lights=None): pass def setLights(self,lights=None): pass def calculateShadowExtents(self): return 200. def getStereo(self): return False def handleZoom(self,dx,dy): factor = 1. - dy/50. self.RADIUS = self.RADIUS * factor if self.RADIUS < 1: self.RADIUS = 1 def mousePressEvent(self, event): self.lastPos = QtCore.QPoint(event.pos()) self.mouseDownPos = QtCore.QPoint(event.pos()) def mouseMoveEvent(self,event): diff = QtCore.QPoint(event.pos()) - self.lastPos dx = event.x() - self.lastPos.x() dy = event.y() - self.lastPos.y() if (dx==0 and abs(dy)<2) or (abs(dy)<2 and dx==0): return button = int(event.buttons()) if button == QtCore.Qt.MidButton: self.handleZoom(dx,dy) if button == QtCore.Qt.LeftButton: rotQ = pygl_coord.Quat(dy,dx,0,0) self.quat.postMult(rotQ) self.updateGL() self.lastPos = QtCore.QPoint(event.pos()) def resizeGL(self,w,h): if h == 0: h = 1 if w == 0: w = 1 ratio = 1.0*w / h opengl.glMatrixMode(opengl.GL_PROJECTION); opengl.glLoadIdentity(); opengl.glViewport(0, 0, w, h); opengl.glOrtho(-self.viewsize*ratio,self.viewsize*ratio,-self.viewsize,self.viewsize,self.NEAR,self.FAR); opengl.glMatrixMode(opengl.GL_MODELVIEW) def paintGL(self): opengl.glLoadIdentity(); opengl.glTranslatef(0,0,-600); opengl.glScalef(60.0/float(self.RADIUS),60.0/float(self.RADIUS),60.0/float(self.RADIUS)) glrotmat = self.quat.getInvMatrix().to_dp() opengl.glMultMatrixd(glrotmat) opengl.delcdp(glrotmat) self.qglClearColor(QtGui.QColor(QtCore.Qt.white)) opengl.glClear(opengl.GL_COLOR_BUFFER_BIT | opengl.GL_DEPTH_BUFFER_BIT) opengl.glDisable(opengl.GL_LIGHTING); opengl.glEnableClientState(opengl.GL_VERTEX_ARRAY) opengl.glEnableClientState(opengl.GL_COLOR_ARRAY) if hasattr(self,"obj") and hasattr(self.obj,"draw") and callable(self.obj.draw): self.obj.draw() if True: message = "" if True: self.nframes = self.nframes + 1 t = time.time() if t - self.previous_time > 1: fps = (self.nframes-self.previous_frames)/( time.time()-self.previous_time) fps_text = ( "%4.0f" ) % fps self.previous_frames = self.nframes self.previous_time = t message = message + "framerate:"+fps_text+" " self.current_fps_text = fps_text else: message = message + "framerate:"+self.current_fps_text+" " print message """ class MoviePresQuestion(QtGui.QDialog): def __init__(self,parent=None): QtGui.QDialog. __init__(self,parent) layout = QtGui.QGridLayout(self) label = QtGui.QLabel(self) label.setText(self.tr("Open this file as")) layout.addWidget(label) self.combo = QtGui.QComboBox(self) self.combo.addItems(["Movie","Presentation","Animation"]) layout.addWidget(self.combo,0,1) buttonbox = QtGui.QDialogButtonBox(self) button = buttonbox.addButton(QtGui.QDialogButtonBox.Ok) cancel = buttonbox.addButton(QtGui.QDialogButtonBox.Cancel) layout.addWidget(buttonbox) self.connect(button,QtCore.SIGNAL("clicked(bool)"),self.Done) self.connect(cancel,QtCore.SIGNAL("clicked(bool)"),functools.partial(self.done,-1)) self.setLayout(layout) def Done(self): self.done(self.combo.currentIndex()) class GLView: def __init__(self,quat=None,pos=[],scale=0.0,glWidget=None): if glWidget: self.getFromGLWidget(glWidget) else: self.pos = pos self.quat = quat self.scale = scale def Quat(self): return self.quat def Position(self): return self.pos def Scale(self): return self.scale def getFromGLWidget(self,glWidget): self.quat = pygl_coord.Quat() self.quat.Setdval(glWidget.quat.Getdval()) self.pos = [] self.pos.extend([glWidget.rpos[0],glWidget.rpos[1],glWidget.rpos[2]]) import copy self.scale = copy.deepcopy(glWidget.RADIUS) for item in ['fog_enabled','fog_strength','fog_near','fog_far','slab_enabled','slab_width','slab_offset','clip_cap','customClipPlanes','fog_auto','slab_auto']: setattr(self,item,getattr(glWidget,item)) def setGLWidget(self,glWidget): quat = pygl_coord.Quat() quat.Setdval(self.quat.Getdval()) glWidget.setQuat(quat) glWidget.setPosition(self.pos) glWidget.setZoom(self.scale) for item in ['fog_enabled','fog_strength','fog_near','fog_far','slab_enabled','slab_width','slab_offset','clip_cap','customClipPlanes','fog_auto','slab_auto']: setattr(glWidget,item,getattr(self,item)) class MGMainWindowCore: plugins = [] CENTRE_MODE_EXTENTS = 0 CENTRE_MODE_COORDS = 1 CENTRE_MODE_MASS = 2 centre_mode = CENTRE_MODE_EXTENTS def show(self): pass def hide(self): pass def __init__(self, parent=None,application=None,gui_params={},stereoFormatAvailable=False): self.downloadThreads = [] self.customDownloadFilterTypes = [] self.defaultObjBodyVisibility = 'open_all' self.okToSave = True self.newRestore = False def setUpAskPrevStatus(self): pass def showMainDisplay(self): pass def addCustomDownloadFilterType(self,filter): if not filter in self.customDownloadFilterTypes: self.customDownloadFilterTypes.append(filter) def applyStereoPrefs(self): try: params = PM("stereo_prefs").getparams() if params.has_key('stereo_mode'): if params['stereo_mode'] == 0: self.stereo_mode = 'SHEAR' else: self.stereo_mode = 'ROTATION' else: self.stereo_mode = 'SHEAR' if params.has_key('shear_sep'): self.stereo_shear_separation = float(params['shear_sep']) else: self.stereo_shear_separation = 0.1 if params.has_key('rot_sep'): self.stereo_rotation_angle = float(params['rot_sep']) else: self.stereo_rotation_angle = 6.0 except: print "Exception!" exc_type, exc_value,exc_tb = sys.exc_info()[:3] print exc_type print exc_value self.stereo_mode = 'SHEAR' self.stereo_shear_separation = 0.1 self.stereo_rotation_angle = 6.0 self.setStereoMatrices() """ def findWidgetPosition(self,findWidget): for i in range(self.box_layout.count()): item = self.box_layout.itemAt(i) if item.widget() is findWidget: return self.box_layout.getItemPosition(i) return None """ def removeGLDisplayObject(self,mod): #print "MGMainWindow.removeGLDisplayObject", mod self.glWidget.removeDisplayObject(mod,1) for widget in self.glWidgets: if widget is not self.glWidget: widget.SetGO(self.glWidget.go,1) def rebuildGLDisplayObject(self,mod): # This probably ought loop over all the GLWidgets we want to draw the same thing. for widget in self.glWidgets: widget.rebuildDisplayObject(mod,1) def setGLSize(self,size=None,width=0,height=0,restore=0,save=0): # This probably ought loop over all the GLWidgets we want to draw the same thing. if restore and self.savedGLSize: #self.glWidget.setViewsize(self.savedGLSize) self.glWidget.resize(self.savedGLSize[0],self.savedGLSize[1]) if save: #self.savedGLSize = self.glWidget.size() self.savedGLSize = (self.glWidget.width(),self.glWidget.height()) if size: #self.glWidget.setViewsize(size) self.glWidget.resize(size.width(),size.height()) elif width and height: #self.glWidget.setViewsize(QtCore.QSize(width,height)) self.glWidget.resize(width,height) def addGLDisplayObject(self,mod): # This probably ought loop over all the GLWidgets we want to draw the same thing. self.glWidget.addDisplayObject(mod,1) for widget in self.glWidgets: if widget is not self.glWidget: widget.SetGO(self.glWidget.go,1) def updateGLWindows(self): for widget in self.glWidgets: widget.makeCurrent() widget.updateGL() def clearLabels(self): PICKLABEL().clear_labels(0) self.updateGLWindows() #--------------------------------------------------------------------------- def getParams(self): #--------------------------------------------------------------------------- params = {} params['background_colour'] = self.glWidget.getBackground() params['show_axes'] = self.glWidget.getAxes() params['show_scale'] = self.glWidget.getShowScale() params['main_toolbar']=self.toolbar.getParams() params['centre_mode']=self.centre_mode params['defaultObjBodyVisibility']=self.defaultObjBodyVisibility pars = {} for item in ['rollspeed','rockspeed','rockangle','rollorientation']: pars[item] = getattr(self,item) params['rockParams']= pars # last directory accessed by file browser is saved but not # currently used on restart params['last_directory'] = mgWidgets.MGFileDialog.last_directory #print "MGMainWindow.getParams",params return params #--------------------------------------------------------------------------- def setParams(self,params): #--------------------------------------------------------------------------- #print "MGMainWindow.setParams",params if params.has_key('background_colour'): for widget in self.glWidgets: r,g,b=params['background_colour'] widget.setBackground(r,g,b) if params.has_key('show_axes'): for widget in self.glWidgets: widget.setAxes(params['show_axes']) if params.has_key('show_scale'): for widget in self.glWidgets: widget.setShowScale(params['show_scale']) if params.has_key('centre_mode'): self.centre_mode = params['centre_mode'] if params.has_key('defaultObjBodyVisibility'): self.defaultObjBodyVisibility = params['defaultObjBodyVisibility'] def checkIfStereoAvailable(self): return 0 # This function is broken fmt = QtOpenGL.QGLFormat() fmt.setStereo (1); ctx = QtOpenGL.QGLContext(fmt,pd) if ctx.create(): return 1 else: return 0 def openCloseAllObjects(self,mode): import displayTable self.defaultObjBodyVisibility = mode if mode == 'open_all': for obj in DISPLAYTABLE().findChildren(displayTable.GDataObj): if not obj.isOpen(): obj.toggleBodyVisibility(updateWidth=0) elif mode == 'close_all': for obj in DISPLAYTABLE().findChildren(displayTable.GDataObj): if obj.isOpen(): obj.toggleBodyVisibility(updateWidth=0) self.wMGDisplayTable.updateWidth() def getActionDef(self,name,**info): # This will work for picking any object that # is properly handled by PickEvent if name =='pickInfo': pickevent = info.get('pickevent',None) if not pickevent or not pickevent.getDataObj(): return dict() dobj = DISPLAYTABLE().getDataObj(pickevent.getDataObj().name) #print 'getActionDef pickInfo dobj',dobj if not dobj: return dict() return dict( text = 'Info about '+pickevent.getLabel(), tip = 'More information '+pickevent.getLabel(), signal = 'triggered()', slot = [dobj.pickInfo,pickevent], deleteLater = 1 ) if name =='centreOnAtom': pickevent = info.get('pickevent',None) if pickevent: return dict( text = 'Centre on '+pickevent.getLabel(), tip = 'Centre on atom '+pickevent.getLabel(), signal = 'triggered()', slot = [self.centreOn,pickevent.getPickPosition()], deleteLater = 1, ) elif self.actionDefinitions.has_key(name): return self.actionDefinitions[name] else: return dict() def initializeActionDefinitions(self): import opengl import ccp4iGui self.actionDefinitions = {} # Loading data self.actionDefinitions['download'] = dict ( text = 'Download coordinates..', icon = 'download', tip = 'Download coordinate,map data from server', signal = 'triggered()', slot = self.handleDownload ) self.actionDefinitions['open'] = dict ( text = 'Open..', shortcut = QtGui.QKeySequence.Open, icon = 'fileopen', tip = 'Open coordinate,map,vector or image file', signal = 'triggered()', slot = self.handleOpen ) self.actionDefinitions['open_presentation'] = dict ( text = 'Open presentation', tip = 'Open directory to edit or show presentation', signal = 'triggered()', slot = guiUtils.partial(self.handlePresentation,'open_presentation'), ) self.actionDefinitions['zip_presentation'] = dict ( text = 'Open zipped presentation', icon = 'open_presentation', tip = 'UNcompress zip and open directory to edit or show presentation', signal = 'triggered()', slot = guiUtils.partial(self.handlePresentation,'zip_presentation'), ) self.actionDefinitions['new_presentation'] = dict ( text = 'New presentation', tip = 'Create directory to save presentation', signal = 'triggered()', slot = guiUtils.partial(self.handlePresentation,'new_presentation'), ) self.actionDefinitions['file_viewer'] = dict ( text = 'File viewer', tip = 'View text, image or movie files', signal = 'triggered()', slot = self.handleFileViewer ) self.actionDefinitions['superpose'] = dict ( text = 'Superpose models', tip = 'Automatic and manual model superposition', signal = 'triggered()', slot = self.handleSuperpose ) self.actionDefinitions['transparency'] = dict ( text = 'Transparency..', tip = 'Set display object(s) transparent', signal = 'triggered()', slot = guiUtils.partial(self.openTransparency), ) self.actionDefinitions['setup_animation'] = dict ( text = 'Setup animation', tip = 'Define the alternating scenes for an animation', signal = 'triggered()', slot = guiUtils.partial(self.openAnimation,'setup'), ) def a(): return self.handleAnimationGui('animate_on') def e(): return self.handleAnimationGui('animate_enabled') self.actionDefinitions['animate'] = dict ( text = 'Run animation', tip = 'Switch animation on/off', signal = 'triggered()', slot = guiUtils.partial(self.handleAnimationGui,'animate'), enabled = e, checkable = 1, checked = a ) self.actionDefinitions['open_movie'] = dict ( text = 'Open movie', tip = 'Open directory to edit or show movie', signal = 'triggered()', slot = guiUtils.partial(self.handlePresentation,'open_movie'), ) self.actionDefinitions['new_movie'] = dict ( text = 'New movie', tip = 'Create directory to save movie', signal = 'triggered()', slot = guiUtils.partial(self.handlePresentation,'new_movie'), ) self.actionDefinitions['restore_status_from_file'] = dict ( text = 'Restore..', shortcut = '', icon = 'restore', tip = 'Restore status', signal = 'triggered()', slot = self.handleRestore ) self.actionDefinitions['save_status_to_file'] = dict ( text = 'Save status to file..', shortcut = 'Shift+Ctrl+S', icon = 'save_status', tip = 'Save the current program status', signal = 'triggered()', slot = self.handleSaveStatus ) self.actionDefinitions['save_html'] = dict ( text = 'Save zipped HTML', tip = 'Save zipped HTML page and javascript', signal = 'triggered()', slot = self.handleHTML ) self.actionDefinitions['save_json'] = dict ( text = 'Save JSON', tip = 'Save json data for WebMG', signal = 'triggered()', slot = self.handleJSON ) self.actionDefinitions['save_visible_to_file'] = dict ( text = 'Save all visible to file..', icon = 'save_status', tip = 'Save all visible atoms as a single file (ensemble)', signal = 'triggered()', slot = self.handleSaveEnsemble ) self.actionDefinitions['save_default_status'] = dict ( text = 'Save as default status..', shortcut = QtGui.QKeySequence.Save, icon = 'save_status', tip = 'Save the current program status to the default status file', signal = 'triggered()', slot = HISTORY().save_program_status ) # Saving to files self.actionDefinitions['print'] = dict ( text = 'Print screen', shortcut = QtGui.QKeySequence.Print, tip = 'Print screen', signal = 'triggered()', slot = self.handlePrint ) self.actionDefinitions['screenshot'] = dict ( text = 'Screenshot', icon = 'camera', tip = 'Make image from current display', signal = 'triggered()', slot = self.screenshotGUI, checkable = 0, initialise = '' ) self.actionDefinitions['tutorial_data'] = dict ( text = 'Get tutorial data', icon = 'tutorial', tip = 'Copy data for tutorial to your own directory', slot = self.copyTutorialData ) self.actionDefinitions['exit'] = dict ( text = 'Exit', shortcut = 'Ctrl+Q', icon = 'exit', tip = 'Exit program', signal = 'triggered()', slot = self.handleExit, checkable = 0, initialise = '' ) # Edit tools self.actionDefinitions['paste'] = dict ( text = 'Paste', shortcut = QtGui.QKeySequence.Paste, icon = '', tip = 'Paste', signal = 'triggered()', slot = self.handlePaste, checkable = 0, initialise = '' ) self.actionDefinitions['collapse_all'] = dict ( text = 'Minimize all', slot = guiUtils.partial(self.openCloseAllObjects,'close_all') ) self.actionDefinitions['show_all'] = dict ( text = 'Maximize all', slot = guiUtils.partial(self.openCloseAllObjects,'open_all') ) self.actionDefinitions['all_data_hide'] = dict ( text = 'Hide', slot = guiUtils.partial(self.handleAllDataAction,'all_data_hide') ) self.actionDefinitions['all_data_show'] = dict ( text = 'Show', slot = guiUtils.partial(self.handleAllDataAction,'all_data_show') ) self.actionDefinitions['all_disp_labels'] = dict ( text = 'Hide labels', slot = guiUtils.partial(self.handleAllDataAction,'all_disp_labels') ) self.actionDefinitions['all_disp_flashing'] = dict ( text = 'Stop flashing', slot = guiUtils.partial(self.handleAllDataAction,'all_disp_flashing') ) self.actionDefinitions['all_disp_transparency'] = dict ( text = 'Undo transparency', slot = guiUtils.partial(self.handleAllDataAction,'all_disp_transparency') ) self.actionDefinitions['all_data_close'] = dict ( text = 'Close all data', slot = guiUtils.partial(self.handleAllDataAction,'all_data_close') ) self.actionDefinitions['picture_wizard'] = dict ( text = 'Picture Wizard', slot = guiUtils.partial(self.handleAllDataAction,'all_data_picture_wizard') ) self.actionDefinitions['ccp4i_aliases'] = dict ( text = 'CCP4i projects and aliases', tip = 'Add or change project and directory aliases as used in CCP4i', slot = ccp4iGui.openGui ) self.actionDefinitions['preferences'] = dict ( text = 'Preferences..', icon = 'preferences', tip = 'Program preferences', signal = 'triggered()', slot = self.handlePreferences, checkable = 0, initialise = '' ) # View tools self.actionDefinitions['view_forward'] = dict ( text = 'View redo', tip = 'Undo revert view', shortcut = QtGui.QKeySequence.Forward, slot = self.viewForward ) self.actionDefinitions['view_back'] = dict ( text = 'View undo', shortcut = QtGui.QKeySequence.Back, tip = 'Revert view', slot = self.viewBack ) self.actionDefinitions['view_from_left'] = dict ( text = 'Left', tip = 'Rotate to view from left', slot = guiUtils.partial(self.viewFrom,'left') ) self.actionDefinitions['view_from_right'] = dict ( text = 'right', tip = 'Rotate to view from right', slot = guiUtils.partial(self.viewFrom,'right') ) self.actionDefinitions['view_from_top'] = dict ( text = 'top', tip = 'Rotate to view from top', slot = guiUtils.partial(self.viewFrom,'top') ) self.actionDefinitions['view_from_bottom'] = dict ( text = 'bottom', tip = 'Rotate to view from bottom', slot = guiUtils.partial(self.viewFrom,'bottom') ) self.actionDefinitions['view_from_back-x'] = dict ( text = 'back (about x)', tip = 'Rotate to view from back', slot = guiUtils.partial(self.viewFrom,'back-x') ) self.actionDefinitions['view_from_back-y'] = dict ( text = 'back (about y)', tip = 'Rotate to view from back', slot = guiUtils.partial(self.viewFrom,'back-y') ) self.actionDefinitions['copyclipboard'] = dict ( text = 'Copy to clipboard', shortcut = 'Ctrl+C', tip = 'Copy graphics window image to clipboard', signal = 'triggered()', slot = self.handleCopyClipboard ) self.actionDefinitions['recentre'] = dict ( text = 'Recentre', shortcut = 'Ctrl+E', tip = 'Recentre view to show all visible objects', signal = 'triggered()', slot = self.handleRecentre ) self.actionDefinitions['centreOn'] = dict ( text = 'Find, centre on..', shortcut = QtGui.QKeySequence.Find, tip = 'Centre on selected atom(s) or residue(s)', signal = 'triggered()', slot = self.handleCentreOn, checkable = 0, ) self.actionDefinitions['clearLabels'] = dict ( text = 'Clear picked labels', shortcut = '', icon = '', tip = 'Delete all labels on picked atoms', slot = self.clearLabels ) def a(): return len(self.glWidgets)==2 self.actionDefinitions['sideBySide'] = dict ( text = 'Side by side stereo', shortcut = '', icon = '', tip = 'Side by side stereo', signal = 'triggered()', group = 'screenSplit', slot = self.handleScreenSplit, checkable = 1, checked = a ) def a(): return len(self.glWidgets)==1 self.actionDefinitions['singleView'] = dict ( text = 'Single view', shortcut = '', icon = '', tip = 'Normal view', signal = 'triggered()', group = 'screenSplit', slot = self.handleScreenSplit, checkable = 1, checked = a ) def a(): return len(self.glWidgets)==3 self.actionDefinitions['threeView'] = dict ( text = 'Three way view', shortcut = '', icon = '', tip = 'Three way orthogonal view', signal = 'triggered()', group = 'screenSplit', slot = self.handleScreenSplit, checkable = 1, checked = a ) def a(): return len(self.glWidgets)==2 self.actionDefinitions['toolbar_sideBySide'] = dict ( text = 'Side by side stereo', shortcut = '', icon = '', tip = 'Side by side stereo', signal = 'triggered()', slot = guiUtils.partial(self.toggleScreenSplit,'sideBySide'), checkable = 1, checked = a ) def a(): return len(self.glWidgets)==3 self.actionDefinitions['toolbar_threeView'] = dict ( text = 'Three way view', shortcut = '', icon = '', tip = 'Three way orthogonal view', signal = 'triggered()', slot = guiUtils.partial(self.toggleScreenSplit,'threeView'), checkable = 1, checked = a ) self.actionDefinitions['window_size'] = dict ( text = 'Set window size..', tip = 'Set the main window size', signal = 'triggered()', slot = self.handleWindowSize, ) def a(): return self.rockroll == 1 self.actionDefinitions['roll_view'] = dict ( text = 'Roll view', shortcut = '', tip = 'Rotate view continuously', icon = '', checkable = 1, checked = a, slot = guiUtils.partial(self.toggleRockRoll,1) ) def a(): return self.rockroll == 2 self.actionDefinitions['rock_view'] = dict ( text = 'Rock view', shortcut = '', tip = 'Rock view continuously', icon = '', checkable = 1, checked = a, slot = guiUtils.partial(self.toggleRockRoll,2) ) self.actionDefinitions['rock_details'] = dict ( text = 'Details..', shortcut = '', tip = 'Rock and roll details', icon = '', slot = self.rockAndRoll ) # Help tools if sys.platform == "darwin": helpShortCut = "" else: helpShortCut = "F1" self.actionDefinitions['help'] = dict ( text = 'Help..', icon = 'help', tip = 'Program documentation', shortcut = helpShortCut, signal = 'triggered()', slot = self.handleHelp, checkable = 0, ) self.actionDefinitions['about'] = dict ( text = 'About..', shortcut = '', tip = 'About CCP4mg', signal = 'triggered()', slot = self.handleAbout, checkable = 0, initialise = '' ) self.actionDefinitions['unclose'] = dict ( text = 'Graphics Window', shortcut = '', icon = '', tip = 'Graphics Window', signal = 'triggered()', slot = self.UnClose, checkable = 0, initialise = '' ) self.actionDefinitions['create_legend'] = dict ( text = 'Legend', shortcut = '', tip = 'Create a 2D text legend object', slot = guiUtils.partial(self.createObject,'legend') ) self.actionDefinitions['create_crystal'] = dict ( text = 'Crystal', shortcut = '', tip = 'Create a crystal object', slot = guiUtils.partial(self.createObject,'crystal') ) self.actionDefinitions['create_vectors'] = dict ( text = 'Vectors', shortcut = '', tip = 'Create a vector object', slot = guiUtils.partial(self.createObject,'vectors'), ) # Display menu self.actionDefinitions['display_back'] = dict ( text = 'Undo', shortcut = QtGui.QKeySequence.Undo, tip = 'Revert status of displayed objects', slot = guiUtils.partial(self.restoreDisplay,-1) ) self.actionDefinitions['display_forward'] = dict ( text = 'Redo', shortcut = QtGui.QKeySequence.Redo, tip = 'Undo revert status of displayed objects', slot = guiUtils.partial(self.restoreDisplay,1) ) def a(): return self.glWidgets[0].show_axes self.actionDefinitions['show_axes'] = dict ( text = 'Axes', tip = 'Show coordinate system axes in the main window', shortcut = '', checkable = 1, checked = a, slot = self.toggleAxes ) def a(): return self.glWidgets[0].show_scale self.actionDefinitions['show_scale'] = dict ( text = 'Scale', tip = 'Show coordinate system scale in the main window', shortcut = '', checkable = 1, checked = a, slot = self.toggleShowScale ) def a(): return self.glWidgets[0].getStereo() and not self.glWidgets[0].getDoZalmanStereo() def stereoAvailable(): return True # TEST SJM 15/02/2011 return self.stereoFormatAvailable self.actionDefinitions['stereo_on'] = dict ( text = 'Hardware Stereo', tip = 'Turn hardware stereo on/off', checkable = 1, enabled = stereoAvailable, checked = a, slot = self.toggleStereo ) def a(): return self.glWidgets[0].getStereo() and self.glWidgets[0].getDoZalmanStereo() self.actionDefinitions['zalman_stereo_on'] = dict ( text = 'Zalman Stereo', tip = 'Turn line-by line polarized stereo on/off', checkable = 1, enabled = 1, checked = a, slot = self.toggleZalmanStereo ) if sys.platform == "darwin": fullScreenShortCut = "Ctrl+Meta+F" else: fullScreenShortCut = "F11" self.actionDefinitions['fullscreen'] = dict ( text = 'Fullscreen', tip = 'Turn fullscreen on/off', shortcut = fullScreenShortCut, checkable = 1, enabled = 1, checked = 0, slot = self.toggleFullscreen ) def a(): return self.glWidgets[0].show_fps self.actionDefinitions['framerate'] = dict ( text = 'Show framerate', tip = 'Show framerate in status bar', checkable = 1, enabled = 1, checked = a, slot = self.toggleFramerate ) self.actionDefinitions['zoom_display'] = dict ( text = 'Show/change zoom', tip = 'Show/change zoom factor in status bar', checkable = 1, enabled = 1, checked = 0, slot = self.toggleZoomDisplay ) def a(): return self.glWidgets[0].format().sampleBuffers() self.actionDefinitions['fsaa_on'] = dict ( text = 'Solid smoothing', tip = 'Use antialiasing to reduce jagged edges of solid objects', checkable = 1, checked = a, slot = self.toggleFSAA ) def a(): return self.glWidgets[0].fog_enabled self.actionDefinitions['fog_on'] = dict ( text = 'Depth cue fog', tip = 'Fog out distant objects', shortcut = 'Ctrl+W', checkable = 1, checked = a, slot = self.toggleFog ) def a(): return self.glWidgets[0].slab_enabled self.actionDefinitions['slab_on'] = dict ( text = 'Clip front/back', tip = 'Clip front and rear of view', shortcut = 'Ctrl+L', checkable = 1, checked = a, slot = self.toggleSlab ) """ self.actionDefinitions['toggle_toolbar'] = dict ( text = 'Toolbar', shortcut = '', tip = 'Show/hide toolbar', action = self.toolbar.toggleViewAction() ) """ import slabAndFog self.actionDefinitions['slab_n_fog'] = dict ( shortcut = '', text = 'Clip and fog details..', tip = 'Control depth clipping and fog out distant objects', slot = slabAndFog.slabAndFog ) self.actionDefinitions['background_black'] = dict ( shortcut = '', text = 'Black', slot = guiUtils.partial(self.setBackgroundColour,'black') ) self.actionDefinitions['background_white'] = dict ( shortcut = '', text = 'White', slot = guiUtils.partial(self.setBackgroundColour,'white') ) self.actionDefinitions['background_other'] = dict ( shortcut = '', text = 'Select other..', slot = guiUtils.partial(self.setBackgroundColour,'other') ) light_menu = { 'light_shiny' : 'Shiny', 'light_soft' : 'Soft', 'light_shaded' : 'Shaded', 'light_shadows_top_right' : 'Ray-trace shadows' } for item in ['light_shiny','light_soft','light_shaded','light_shadows_top_right']: self.actionDefinitions[item] = dict ( text = light_menu[item], tip = 'Reset the lighting', slot = guiUtils.partial(self.setLighting,item) ) def removeMenuDefinition(self,name,defn,menu,force=0): self.actionDefinitions[name] = defn if self.menuDefinitions.has_key(menu): if self.menuDefinitions[menu].count(name)>0: idx = self.menuDefinitions[menu].index(name) if idx >=0 : self.menuDefinitions[menu].pop(idx) #self.drawMenu(menu) else: if self.menuDefinitions.has_key("Tools"): if self.menuDefinitions["Tools"].count(name)>0: idx = self.menuDefinitions["Tools"].index(name) if idx >=0 : self.menuDefinitions["Tools"].pop(idx) #self.drawMenu('Tools') def addMenuDefinition(self,name,defn,menu,force=0,submenu=None,draw_menu=True): if force or not self.actionDefinitions.has_key(name): self.actionDefinitions[name] = defn if defn.has_key("icon_path"): action = guiUtils.createAction(name,self,icon_path=defn["icon_path"]) else: action = guiUtils.createAction(name,self) if self.menuDefinitions.has_key(menu): if submenu: try: for it in self.menuDefinitions[menu]: if type(it) == list: if len(it)>0 and it[0]==submenu: idx = it.count(name) if idx==0: it.append(name) if draw_menu: self.drawMenu(menu) except: idx = self.menuDefinitions["Tools"].count(name) if idx == 0: self.menuDefinitions["Tools"].append(name) if draw_menu: self.drawMenu('Tools') else: idx = self.menuDefinitions[menu].count(name) if idx == 0: self.menuDefinitions[menu].append(name) if draw_menu: self.drawMenu(menu) else: if self.menuDefinitions.has_key("Tools"): idx = self.menuDefinitions["Tools"].count(name) if idx == 0: self.menuDefinitions["Tools"].append(name) if draw_menu: self.drawMenu('Tools') return action def initializeMenuDefinitions(self): import sys self.menuDefinitions = {} # Definition of popup screen context menu self.menuDefinitions['context'] = ['recentre','centreOnAtom','pickInfo'] # Definition of sub-sections of File menu and File menu self.menuDefinitions['_file_download'] = ['download'] self.menuDefinitions['_file_open'] = ['open',self.recentFilesList,'_file_download','restore_status_from_file',['Edit/show presentation','new_presentation','open_presentation','zip_presentation']] self.menuDefinitions['_file_close'] = ['all_data_close'] self.menuDefinitions['_file_create'] = [['Create object','create_legend','create_crystal','create_vectors']] self.menuDefinitions['_tutorial'] = ['tutorial_data'] self.menuDefinitions['_file_save'] = [ 'save_status_to_file','save_default_status','save_visible_to_file','screenshot','print',['Save for WebMG','save_html','save_json']] #self.menuDefinitions['File'] = ['_file_open','_file_create','sep','_tutorial','sep','_file_save'] self.menuDefinitions['File'] = ['_file_open','sep','_file_close','sep','_tutorial','sep','_file_save'] if sys.platform != 'darwin': #self.menuDefinitions['Edit'] = ['copyclipboard','paste',['For all data','all_data_hide','all_data_show'],['For all display objects','all_disp_labels','all_disp_flashing','all_disp_transparency'],'preferences'] self.menuDefinitions['Edit'] = ['copyclipboard','paste','sep','display_back','display_forward','sep','preferences'] else: #self.menuDefinitions['Edit'] = ['paste',['For all data','all_data_hide','all_data_show'],['For all display objects','all_disp_labels','all_disp_flashing','all_disp_transparency']] self.menuDefinitions['Edit'] = ['copyclipboard','paste','sep','display_back','display_forward'] self.menuDefinitions['_view_orientation'] = [['View history','view_back','view_forward'],'recentre','centreOn',['View from','view_from_left','view_from_right','view_from_bottom','view_from_top','view_from_back-x','view_from_back-y'],'window_size'] self.menuDefinitions['_view_applications'] = [['Rock and roll','roll_view','rock_view','rock_details']] self.menuDefinitions['View'] = ['_view_orientation','sep',['Split screen','singleView','sideBySide','threeView'],'sep','_view_applications'] self.menuDefinitions['_display_onoff'] = ['toggle_toolbar','fog_on','slab_on','slab_n_fog','show_axes','show_scale'] self.menuDefinitions['_display_applications'] = [['Animate display','animate','setup_animation']] self.menuDefinitions['Display'] = ['clearLabels','sep','_display_onoff','sep',['Background colour','background_black','background_white','background_other'],'stereo_on','zalman_stereo_on','fsaa_on','sep','_display_applications','fullscreen','sep','framerate','zoom_display'] self.menuDefinitions['Windows'] = [] self.menuDefinitions['Tools'] = [] self.menuDefinitions['Applications'] = ['file_viewer','superpose',['Movie editor','open_movie','new_movie'],'picture_wizard'] if sys.platform != 'darwin': self.menuDefinitions['Help'] = ['help','about'] else: self.menuDefinitions['Help'] = ['help'] # Definition of toolbar self.menuDefinitions['main_toolbar_supported'] = ['open','download','save_status_to_file','screenshot','all_data_close','preferences','view_back','view_forward','recentre','centreOn','rock_view','roll_view','display_back','display_forward','clearLabels','fog_on','slab_on','slab_n_fog','show_axes','show_scale','background_black','background_white','stereo_on','superpose','open_movie','new_movie','picture_wizard'] self.menuDefinitions['main_toolbar_default'] = ['open','download','save_status_to_file','screenshot','view_back','view_forward','display_back','display_forward','recentre','centreOn','clearLabels','fog_on','slab_on','superpose','open_movie','new_movie','preferences','picture_wizard'] if sys.platform != 'darwin': self.menuDefinitions['File'].extend(['sep','exit']) if sys.platform == 'darwin': self.menuDefinitions['_dummy'] = ['about','preferences','exit'] def getGuiDef(self,name='',pickevent=None): if name == 'menus': if sys.platform == 'darwin': return [['File','&File','aboutToShow'], ['Edit','&Edit'],['View','&View','aboutToShow'], ['Display','&Display','aboutToShow'],['Applications','&Applications','aboutToShow'],['Windows','&Windows','aboutToShow'],['Tools','&Tools','aboutToShow'],['Help','&Help'],['_dummy','_dummy']] else: return [['File','&File','aboutToShow'], ['Edit','&Edit'],['View','&View','aboutToShow'], ['Display','&Display','aboutToShow'],['Applications','&Applications','aboutToShow'],['Windows','&Windows','aboutToShow'],['Tools','&Tools','aboutToShow'],['Help','&Help']] else: defn = [] defn.extend(self.getGuiDef0(name)) return defn def getGuiDef0(self,name=''): if not self.menuDefinitions.has_key( name): return [] defn = [] for item in self.menuDefinitions[name]: if item[0] == '_' and self.menuDefinitions.has_key(item): defn.extend(self.getGuiDef0(item)) else: defn.append(item) return defn def PositionChanged(self,args=None): if args: widget = args self.statusBar().showMessage("Origin: %.3f %.3f %.3f | Size: %d x %d" % (widget.rpos[0],widget.rpos[1],widget.rpos[2],widget.width(),widget.height())) for glwidget in self.glWidgets: if glwidget is not widget: glwidget.SetOrigin(widget.rpos,1) def enterEvent(self,e): self.showDefaultMessage() QtGui.QMainWindow.enterEvent(self,e) def SizeChanged(self,args=None): if args: size = args if hasattr(self,"glWidgets") and len(self.glWidgets)>0 and hasattr(self.glWidgets[0],"rpos"): self.statusBar().showMessage("Origin: %.3f %.3f %.3f | Size: %d x %d" % (self.glWidgets[0].rpos[0],self.glWidgets[0].rpos[1],self.glWidgets[0].rpos[2],size.width(),size.height())) else: self.statusBar().showMessage("Size: %d x %d" % (size.width(),size.height())) def showDefaultMessage(self,args=None): size = self.size() if hasattr(self,"glWidgets") and len(self.glWidgets)>0 and hasattr(self.glWidgets[0],"rpos"): self.statusBar().showMessage("Origin: %.3f %.3f %.3f | Size: %d x %d" % (self.glWidgets[0].rpos[0],self.glWidgets[0].rpos[1],self.glWidgets[0].rpos[2],size.width(),size.height())) else: self.statusBar().showMessage("Size: %d x %d" % (size.width(),size.height())) def MousePress(self,args=None): event = args[0] widget = args[1] #print event.pos().x(), event.pos().y() #print widget def ZoomChanged(self,args=None): if args: widget = args for glwidget in self.glWidgets: if glwidget is not widget: glwidget.RADIUS = widget.RADIUS glwidget.updateGL() def QuatChanged(self,args=None): if args: widget = args for glwidget in self.glWidgets: if glwidget is not widget: glwidget.quat = widget.quat glwidget.updateGL() def toggleScreenSplit(self,mode): ''' Handle the toolbar buttons which are not in an QActionGroup Check the appropriate button in the group to force required action current = self.findChild(QtGui.QActionGroup,'screenSplit').checkedAction().objectName() if mode == current: # Trying to switch off stereo/three way - reset to single self.findChild(QtGui.QAction,'singleView').setChecked(1) else: self.findChild(QtGui.QAction,mode).setChecked(1) ''' self.handleScreenSplit() def handleScreenSplit(self): new = self.findChild(QtGui.QActionGroup,'screenSplit').checkedAction().objectName() # Do we need to close any exisiting views? if len(self.glWidgets) == 3: if new == 'threeView': return else: self.handleThreeWayView() elif len(self.glWidgets) == 2: if new == 'sideBySide': return else: self.handleSideBySide() #print "closed views",len(self.glWidgets) # Should be back at single view now - do we need to open # new views? if new == 'threeView': self.handleThreeWayView() elif new == 'sideBySide': self.handleSideBySide() self.toggleAxes() action = self.findChild(QtGui.QAction,'toolbar_sideBySide') ## ?? Why separate actions for toolbar? if action: action.setChecked(len(self.glWidgets)==2) action = self.findChild(QtGui.QAction,'toolbar_threeView') if action: action.setChecked(len(self.glWidgets)==3) def handleThreeWayView(self): if len(self.glWidgets)==3: while len(self.glWidgets)>1: glwidget = self.glWidgets.pop() self.disconnect(self.glWidgets[0],QtCore.SIGNAL("ShadowStateChanged"),glwidget.setShadowState) self.disconnect(self.glWidgets[0],QtCore.SIGNAL("AmbientOcclusionStateChanged"),glwidget.setAmbientOcclusionState) self.disconnect(self.glWidgets[0],QtCore.SIGNAL("ShaderStateChanged"),glwidget.setShaderState) glwidget.SetGO([],0) glwidget.close() self.box_layout.removeWidget(glwidget) glwidget.deleteLater() else: if len(self.glWidgets)>0: while len(self.glWidgets)>1: glwidget = self.glWidgets.pop() self.disconnect(self.glWidgets[0],QtCore.SIGNAL("ShadowStateChanged"),glwidget.setShadowState) self.disconnect(self.glWidgets[0],QtCore.SIGNAL("AmbientOcclusionStateChanged"),glwidget.setAmbientOcclusionState) self.disconnect(self.glWidgets[0],QtCore.SIGNAL("ShaderStateChanged"),glwidget.setShaderState) glwidget.SetGO([],0) glwidget.close() self.box_layout.removeWidget(glwidget) glwidget.deleteLater() import MGGLWidget y_glWidget = MGGLWidget.MGGLWidget(self,self.glWidget,format=self.glWidget.format()) y_glWidget.setStereo(self.glWidget.getStereo()) y_glWidget.setDoZalmanStereo(self.glWidget.getDoZalmanStereo()) self.glWidgets.append(y_glWidget) self.box_layout.addWidget(y_glWidget,0,1) for item in ['RADIUS','quat','fog_enabled','fog_strength','fog_near','fog_far','slab_enabled','slab_width','slab_offset','clip_cap','customClipPlanes','fog_auto','slab_auto']: setattr(y_glWidget,item,getattr(self.glWidgets[0],item)) r,g,b = self.glWidgets[0].getBackground() y_glWidget.setBackground(r,g,b) y_glWidget.setDoubleClickHandler(self.pickEventRecentre) y_glWidget.setLeftClickHandler(self.labelPickedObject) y_glWidget.setContextMenuHandler(self.contextMenuHandler) self.connect(y_glWidget,QtCore.SIGNAL("QuatChanged"),self.QuatChanged) self.connect(y_glWidget,QtCore.SIGNAL("ZoomChanged"),self.ZoomChanged) self.connect(y_glWidget,QtCore.SIGNAL("PositionChanged"),self.PositionChanged) self.connect(y_glWidget,QtCore.SIGNAL("SizeChanged"),self.SizeChanged) self.connect(y_glWidget,QtCore.SIGNAL("ViewChanged"),self.GLLeftMouseReleased) self.connect(y_glWidget,QtCore.SIGNAL("TransformObject"),self.MGDisplayTable.handleObjectMoving) self.connect(y_glWidget,QtCore.SIGNAL("MouseEntered"),self.showDefaultMessage) y_glWidget.extra_quat = pygl_coord.Quat(1.0,0.0,0.0,1,90) y_glWidget.setExtraMatrix(None) y_glWidget.updateGL() if self.glWidget.go: y_glWidget.SetGO(self.glWidget.go,1) y_glWidget.SetOrigin(self.glWidget.rpos,1) x_glWidget = MGGLWidget.MGGLWidget(self,self.glWidget,format=self.glWidget.format()) x_glWidget.setStereo(self.glWidget.getStereo()) x_glWidget.setDoZalmanStereo(self.glWidget.getDoZalmanStereo()) self.glWidgets.append(x_glWidget) self.box_layout.addWidget(x_glWidget,1,0) for item in ['RADIUS','quat','fog_enabled','fog_strength','fog_near','fog_far','slab_enabled','slab_width','slab_offset','clip_cap','customClipPlanes','fog_auto','slab_auto']: setattr(x_glWidget,item,getattr(self.glWidgets[0],item)) r,g,b = self.glWidgets[0].getBackground() x_glWidget.setBackground(r,g,b) x_glWidget.setDoubleClickHandler(self.pickEventRecentre) x_glWidget.setLeftClickHandler(self.labelPickedObject) x_glWidget.setContextMenuHandler(self.contextMenuHandler) self.connect(x_glWidget,QtCore.SIGNAL("QuatChanged"),self.QuatChanged) self.connect(x_glWidget,QtCore.SIGNAL("ZoomChanged"),self.ZoomChanged) self.connect(x_glWidget,QtCore.SIGNAL("PositionChanged"),self.PositionChanged) self.connect(x_glWidget,QtCore.SIGNAL("SizeChanged"),self.SizeChanged) self.connect(x_glWidget,QtCore.SIGNAL("ViewChanged"),self.GLLeftMouseReleased) self.connect(x_glWidget,QtCore.SIGNAL("TransformObject"),self.MGDisplayTable.handleObjectMoving) self.connect(x_glWidget,QtCore.SIGNAL("MouseEntered"),self.showDefaultMessage) for mapdisp in get_dispobj(object_type=['MapDisp']): if hasattr(mapdisp,'graphmod') and mapdisp.graphmod: y_glWidget.connect(y_glWidget,QtCore.SIGNAL("PositionChanged"),mapdisp.graphmod.handleGLWidgetChangePostion) x_glWidget.connect(x_glWidget,QtCore.SIGNAL("PositionChanged"),mapdisp.graphmod.handleGLWidgetChangePostion) x_glWidget.updateGL() if self.glWidget.go: x_glWidget.SetGO(self.glWidget.go,1) x_glWidget.SetOrigin(self.glWidget.rpos,1) x_glWidget.extra_quat = pygl_coord.Quat(0.0,1.0,0.0,1,-90) x_glWidget.setExtraMatrix(None) self.applyGLLighting() # We more or less must, load shaders here into main GL widget, any other way is going to be # too complicated. if not hasattr(self.glWidgets[0],"circleShader"): # We are protecting with try, but the module should be available. (I think Shaders should be core, not plugin.) try: oldState = self.glWidgets[0].getShaderState() import Shaders Shaders.handleShaders({"use_shaders":1}) self.glWidgets[0].setShaderState(oldState) except: pass x_glWidget.copyShaders(self.glWidgets[0]) y_glWidget.copyShaders(self.glWidgets[0]) self.connect(self.glWidgets[0],QtCore.SIGNAL("ShadowStateChanged"),x_glWidget.setShadowState) self.connect(self.glWidgets[0],QtCore.SIGNAL("ShadowStateChanged"),y_glWidget.setShadowState) self.connect(self.glWidgets[0],QtCore.SIGNAL("AmbientOcclusionStateChanged"),x_glWidget.setAmbientOcclusionState) self.connect(self.glWidgets[0],QtCore.SIGNAL("AmbientOcclusionStateChanged"),y_glWidget.setAmbientOcclusionState) self.connect(self.glWidgets[0],QtCore.SIGNAL("ShaderStateChanged"),x_glWidget.setShaderState) self.connect(self.glWidgets[0],QtCore.SIGNAL("ShaderStateChanged"),y_glWidget.setShaderState) def handleSideBySide(self): if len(self.glWidgets)==2: while len(self.glWidgets)>1: glwidget = self.glWidgets.pop() self.disconnect(self.glWidgets[0],QtCore.SIGNAL("ShadowStateChanged"),glwidget.setShadowState) self.disconnect(self.glWidgets[0],QtCore.SIGNAL("AmbientOcclusionStateChanged"),glwidget.setAmbientOcclusionState) self.disconnect(self.glWidgets[0],QtCore.SIGNAL("ShaderStateChanged"),glwidget.setShaderState) glwidget.SetGO([],0) glwidget.close() self.box_layout.removeWidget(glwidget) glwidget.deleteLater() self.glWidgets[0].extra_quat = pygl_coord.Quat(0.0,0.0,0.0,0) self.glWidgets[0].setExtraMatrix(None) else: if len(self.glWidgets)>0: while len(self.glWidgets)>1: glwidget = self.glWidgets.pop() self.disconnect(self.glWidgets[0],QtCore.SIGNAL("ShadowStateChanged"),glwidget.setShadowState) self.disconnect(self.glWidgets[0],QtCore.SIGNAL("AmbientOcclusionStateChanged"),glwidget.setAmbientOcclusionState) self.disconnect(self.glWidgets[0],QtCore.SIGNAL("ShaderStateChanged"),glwidget.setShaderState) glwidget.SetGO([],0) glwidget.close() self.box_layout.removeWidget(glwidget) glwidget.deleteLater() import MGGLWidget sideStereo_glWidget = MGGLWidget.MGGLWidget(self,self.glWidget,format=self.glWidget.format()) sideStereo_glWidget.setStereo(self.glWidget.getStereo()) sideStereo_glWidget.setDoZalmanStereo(self.glWidget.getDoZalmanStereo()) self.glWidgets.append(sideStereo_glWidget) self.box_layout.addWidget(sideStereo_glWidget,0,1) for item in ['RADIUS','quat','fog_enabled','fog_strength','fog_near','fog_far','slab_enabled','slab_width','slab_offset','clip_cap','customClipPlanes','fog_auto','slab_auto']: setattr(sideStereo_glWidget,item,getattr(self.glWidgets[0],item)) r,g,b = self.glWidgets[0].getBackground() sideStereo_glWidget.setBackground(r,g,b) sideStereo_glWidget.setDoubleClickHandler(self.pickEventRecentre) sideStereo_glWidget.setLeftClickHandler(self.labelPickedObject) sideStereo_glWidget.setContextMenuHandler(self.contextMenuHandler) self.connect(sideStereo_glWidget,QtCore.SIGNAL("QuatChanged"),self.QuatChanged) self.connect(sideStereo_glWidget,QtCore.SIGNAL("ZoomChanged"),self.ZoomChanged) self.connect(sideStereo_glWidget,QtCore.SIGNAL("PositionChanged"),self.PositionChanged) self.connect(sideStereo_glWidget,QtCore.SIGNAL("SizeChanged"),self.SizeChanged) self.connect(sideStereo_glWidget,QtCore.SIGNAL("ViewChanged"),self.GLLeftMouseReleased) self.connect(sideStereo_glWidget,QtCore.SIGNAL("TransformObject"),self.MGDisplayTable.handleObjectMoving) self.connect(sideStereo_glWidget,QtCore.SIGNAL("MouseEntered"),self.showDefaultMessage) for mapdisp in get_dispobj(object_type=['MapDisp']): if hasattr(mapdisp,'graphmod') and mapdisp.graphmod: sideStereo_glWidget.connect(sideStereo_glWidget,QtCore.SIGNAL("PositionChanged"),mapdisp.graphmod.handleGLWidgetChangePostion) sideStereo_glWidget.updateGL() if self.glWidget.go: sideStereo_glWidget.SetGO(self.glWidget.go,1) sideStereo_glWidget.SetOrigin(self.glWidget.rpos,1) self.setStereoMatrices() self.applyGLLighting() # We more or less must, load shaders here into main GL widget, any other way is going to be # too complicated. if not hasattr(self.glWidgets[0],"circleShader"): # We are protecting with try, but the module should be available. (I think Shaders should be core, not plugin.) try: oldState = self.glWidgets[0].getShaderState() import Shaders Shaders.handleShaders({"use_shaders":1}) self.glWidgets[0].setShaderState(oldState) except: pass sideStereo_glWidget.copyShaders(self.glWidgets[0]) self.connect(self.glWidgets[0],QtCore.SIGNAL("ShadowStateChanged"),sideStereo_glWidget.setShadowState) self.connect(self.glWidgets[0],QtCore.SIGNAL("AmbientOcclusionStateChanged"),sideStereo_glWidget.setAmbientOcclusionState) self.connect(self.glWidgets[0],QtCore.SIGNAL("ShaderStateChanged"),sideStereo_glWidget.setShaderState) def setStereoMatrices(self): if len(self.glWidgets)!=2: return if self.stereo_mode == 'SHEAR': shear_plus = pygl_coord.matrix(4,4,[1,0,0,0, 0,1,0,0, self.stereo_shear_separation,0,1,0, 0,0,0,1]) shear_minus = pygl_coord.matrix(4,4,[1,0,0,0, 0,1,0,0, -self.stereo_shear_separation,0,1,0, 0,0,0,1]) matp = shear_plus.to_dp() matm = shear_minus.to_dp() self.glWidgets[0].setExtraMatrix(matp) self.glWidgets[1].setExtraMatrix(matm) self.glWidgets[0].extra_quat = pygl_coord.Quat(0.0,1.0,0.0,1,0.0) self.glWidgets[1].extra_quat = pygl_coord.Quat(0.0,1.0,0.0,1,0.0) else: self.glWidgets[0].setExtraMatrix(None) self.glWidgets[1].setExtraMatrix(None) self.glWidgets[0].extra_quat = pygl_coord.Quat(0.0,1.0,0.0,1,0.5*self.stereo_rotation_angle) self.glWidgets[1].extra_quat = pygl_coord.Quat(0.0,1.0,0.0,1,-0.5*self.stereo_rotation_angle) self.glWidgets[0].updateGL() self.glWidgets[1].updateGL() def labelPickedObject(self,pickevent): #print "labelPickedObject",pickevent if pickevent.getPickedAtoms(): ret = PICKLABEL().addLabel(pickevent) #print 'MGMainWindow.labelPickedObject',ret if ret: import rebuild #rebuild.UpdateDisplay(target=pickevent.getDispObj(),controllingWidget=self) rebuild.UpdateDisplay() MGAPPLICATION().clipboard().setText(pickevent.getLabel(format='full')) #self.lastPickEvent = pickevent del pickevent def getLastPickEvent(self): return getattr(self,'lastPickEvent',None) def pickEventRecentre(self,pickevent): # Centre on picked atoms - check that atoms have been picked atoms = pickevent.getPickedAtoms() if atoms: pos = pickevent.getPickPosition() if pos: for glwidget in self.glWidgets: glwidget.centreOn(pos) def contextMenuHandler(self,pickevent): menu = pickevent.getContextMenu() if not menu: print "not menu!" del pickevent return menu.clear() # Add actions for the MGWindow class menudef = self.getGuiDef('context',pickevent=pickevent) if menudef: guiUtils.populateMenu(self,menu,menudef,self.getActionDef,info = { 'pickevent' : pickevent } ) # Add actions for the picked dataobj and dispobj dispobj_menudef = [] dataobj_menudef = [] gui_disp = pickevent.getGuiObject() #print "MGMainWindow.contextMenuHandler guiobj",gui_disp if gui_disp: dispobj_menudef = gui_disp.getGuiDef('context',pickevent=pickevent) pick_dataobj = pickevent.getDataObj() if pick_dataobj: gui_data = self.MGDisplayTable.getDataObj(pick_dataobj.name) if gui_data: dataobj_menudef = gui_data.getGuiDef('context',pickevent=pickevent) #print "menudef",dispobj_menudef,dataobj_menudef if dataobj_menudef: dataobj_menudef.insert(0,'sep') guiUtils.populateMenu(gui_data,menu,dataobj_menudef,gui_data.getActionDef,info = { 'pickevent' : pickevent } ) if dispobj_menudef: dispobj_menudef.insert(0,'sep') guiUtils.populateMenu(gui_disp,menu,dispobj_menudef,gui_disp.getActionDef,info = { 'pickevent' : pickevent } ) #Give open applications a chance to add to menu self.emit(QtCore.SIGNAL('atomContextMenu'),pickevent) """ # The stuff for QWhatsThis menu.addSeparator() whatsthis = menu.addAction(self.tr("What's this?")) self.connect(whatsthis,QtCore.SIGNAL("triggered(bool)"),functools.partial(QtGui.QWhatsThis.showText,self.mapToGlobal(pickevent.pos()),self.tr("The main graphics window."))) """ del pickevent def handleAllDataAction(self,action): # This method is necessary 'cos on program startup the # menubar is defined before the display table so DISPLAYTABLE() # is undefined. if action == 'all_data_show': DISPLAYTABLE().showAllDataObj(1) elif action == 'all_data_hide': DISPLAYTABLE().showAllDataObj(0) elif action == 'all_disp_labels': for obj in get_dispobj(): label = getattr(obj,'label',None) if label: label.setparams(label_select='label_no') import rebuild rebuild.UpdateDisplay() elif action == 'all_disp_flashing': for obj in get_dispobj(): obj.set_flashing(0) elif action == 'all_disp_transparency': for obj in get_dispobj(): obj.set_opacity(1.0) import rebuild rebuild.UpdateDisplay() elif action =='all_data_close': rv = QtGui.QMessageBox.question(self, "Close data", "Close all files?", QtGui.QMessageBox.Ok,QtGui.QMessageBox.Cancel) if rv == QtGui.QMessageBox.Ok: doSideBySide = False doThreeWayView = False if len(self.glWidgets) == 2: self.handleSideBySide() doSideBySide = True elif len(self.glWidgets) == 3: self.handleThreeWayView() doThreeWayView = True DISPLAYTABLE().deleteAllDataObj() if doSideBySide: self.handleSideBySide() elif doThreeWayView: self.handleThreeWayView() import rebuild rebuild.UpdateDisplay() elif action == 'all_data_picture_wizard': #import pictureWizardGui #pictureWizardGui.pictureWizardGui(parent=self,moldata_name='ALL') if not hasattr(self,"all_data_picture_wizard"): import pictureWizardGui self.all_data_picture_wizard = pictureWizardGui.pictureWizardGui(parent=self,moldata_name='ALL') self.all_data_picture_wizard.show() self.all_data_picture_wizard.raise_() def createPreferencesWindows(self): import mgPreferences self.wPreferences = mgPreferences.preferencesBrowser(self) def showPrefsPane(self,paneText): if not self.wPreferences: self.createPreferencesWindows() self.wPreferences.show() self.wPreferences.raise_() items = self.wPreferences.tree.findItems(self.tr("Plugins preferences"),QtCore.Qt.MatchContains) if len(items)>0: items[0].setExpanded(True) for i in range(items[0].childCount()): if items[0].child(i).text(0) == self.tr(paneText): self.wPreferences.tree.setCurrentItem(items[0].child(i)) break def handlePreferences(self): if not self.wPreferences: self.createPreferencesWindows() self.wPreferences.show() self.wPreferences.raise_() def screenshotGUI(self): import screenshot screenShotGui= screenshot.screenShotGUI(self) screenShotGui.exec_() def handleExit(self): #print "MGMainWindow.handleExit"; sys.stdout.flush() QtGui.QApplication.instance().quit() def removeFileTypeFilter(self,filter): while self.extra_filters.count(filter)>0: self.extra_filters.pop(self.extra_filters.index(filter)) def addFileTypeFilter(self,filter): if not filter in self.extra_filters: self.extra_filters.append(filter) def defaultFileTypeHandler(self,args): print "Don't know what to do with file",args return 1 def getSaveFileTypeHandlerByFullName(self,fn): for key,val in self.extra_save_handlers.items(): if fn.endswith(key): return val return self.defaultFileTypeHandler def directoryHandlers(self,fname): for dirHandler in self.directory_handlers: try: return dirHandler(fname) except: pass print "No directory handler for", fname QtGui.QMessageBox.warning(self,"Unknown directory/folder type","Directory/folder "+fname+" is not a recognised CCP4MG input.") return None def getFileTypeHandler(self,filter): if self.extra_handlers.has_key(filter.lower()): return self.extra_handlers[filter.lower()] else: return self.defaultFileTypeHandler def addFileTypeHandler(self,filter,handler): self.extra_handlers[filter] = handler def addSaveFileTypeHandler(self,filter,handler): self.extra_save_handlers[filter] = handler def handlePrint(self): printer = QtGui.QPrinter() pd = QtGui.QPrintDialog(printer) pdret = pd.exec_() if pdret == QtGui.QDialog.Accepted: import screenshot rv = screenshot.makePDF(printer) def handleDownload(self): import downloadPdb download = self.findChild(downloadPdb.downloadPdb) if download: download.resetSelection() download.show() else: download_open = downloadPdb.downloadPdb(parent=self) download_open.show() def handleOpen(self): gui_open = guiOpen(parent=self) if hasattr(self,'extra_filters'): gui_open.addFilters(self.extra_filters) self.connect(gui_open,QtCore.SIGNAL('filesSelected'),self.openFile) gui_open.exec_() def handleFileViewer(self): viewer = FILEVIEWER() viewer.show() viewer.raise_() """ if not hasattr(self,'viewer'): import mgFileViewer self.viewer = mgFileViewer.mgFileViewer(self) self.viewer.show() self.viewer.raise_() """ def handleSuperpose(self): if not hasattr(self,'superpose'): import superposeGui self.superpose = superposeGui.superposeWindow(self) else: self.superpose.UnClose() self.superpose.show() def openTransparency(self): if not hasattr(self,'transparencyGui') or not self.transparencyGui: import TransparencyDialog self.transparencyGui = TransparencyDialog.TransparencyDialog(self) self.transparencyGui.UnClose() def openAnimation(self,mode): if not hasattr(self,'animationGui') or not self.animationGui: import animationGui self.animationGui = animationGui.animationGui(self) self.animationGui.show() self.animationGui.raise_() def handleAnimationGui(self,mode): if mode == 'animate_enabled': if not hasattr(self,'animationGui') or not self.animationGui or \ self.animationGui.numberOfFrames(selected=1)<2: return 0 else: return 1 elif mode == 'animate_on': if not hasattr(self,'animationGui') or not self.animationGui: return 0 else: return self.animationGui.presentation.animation_on elif mode == 'animate': if not hasattr(self,'animationGui') or not self.animationGui: return widget = self.findChild(QtGui.QAction,'animate') if widget: self.animationGui.presentation.animate(widget.isChecked()) def handlePresentation(self,mode='open_presentation'): self.showMainDisplay() import string mode,application= string.split(mode,'_') gui_open = guiOpenPresentation(parent=self,mode=mode,application=application) self.connect(gui_open,QtCore.SIGNAL('filesSelected'),self.openPresentation) gui_open.exec_() def openPresentation(self,file='',application='presentation',**kw): self.showMainDisplay() #print "openPresentation",file,application if not file.endswith(".ccp4mg_presentation") and not file.endswith(".ccp4mg_presentation.zip") : file = file+".ccp4mg_presentation" # Open the application (from python/ui) import presentation,mgPresentation p = presentation.open_presentation(file) #print "openPresentation p,open guis",p,self.findChildren(mgPresentation.mgPresentation) # Is there a gui to this presentation already open? if not p: return for gui in self.findChildren(mgPresentation.mgPresentation): if gui.presentation == p: gui.show() return # Close the selection gui (do this before opening movie gui or mac puts movie # beneath main window for item in self.findChildren(guiOpenPresentation): item.close() # Create gui for this presentation if os.path.exists(os.path.join(file,"PRESENTATION_TYPE")): try: os.unlink(os.path.join(file,"PRESENTATION_TYPE")) except: exc_type, exc_value,exc_tb = sys.exc_info()[:3] print "Do not seem to have write permission on presentation directory",file sys.stderr.write(str(exc_type)+'\n') sys.stderr.write(str(exc_value)+'\n') if application == 'movie': import movieGui gui = movieGui.movieGui(self,presentation=p) if not os.path.exists(os.path.join(file,"PRESENTATION_TYPE")): # It *should* have been deleted above. ptf = open(os.path.join(file,"PRESENTATION_TYPE"),"wb") ptf.write("movie\n") ptf.close() elif application == 'animation': import animationGui gui = animationGui.animationGui(self,presentation=p) if not os.path.exists(os.path.join(file,"PRESENTATION_TYPE")): ptf = open(os.path.join(file,"PRESENTATION_TYPE"),"wb") ptf.write("animation\n") ptf.close() else: gui = mgPresentation.mgPresentation(self,presentation=p) if os.path.isdir(file): if not os.path.exists(os.path.join(file,"PRESENTATION_TYPE")): ptf = open(os.path.join(file,"PRESENTATION_TYPE"),"wb") ptf.write("presentation\n") ptf.close() elif file.endswith(".zip") and os.path.exists(file[:-4]): if not os.path.exists(os.path.join(file[:-4],"PRESENTATION_TYPE")): ptf = open(os.path.join(file[:-4],"PRESENTATION_TYPE"),"wb") ptf.write("presentation\n") ptf.close() gui.show() def createObject(self,object_type = ''): self.showMainDisplay() #print "createObject",object_type if object_type == 'legend': import Legend legend = Legend.Legend(parent=GL2DMANAGER(),name='Legend') self.MGDisplayTable.addDispObj(object_type='Legend',name=legend.name,parent_name = GL2DMANAGER().name) import rebuild rebuild.UpdateDisplay() elif object_type == 'crystal': import Crystal xtl = CRYSTALMANAGER().add_object() self.MGDisplayTable.addDispObj(object_type='Crystal',name=xtl.name) elif object_type == 'vectors': import VectorsDispobj dobj = VectorsDispobj.VectorsData() disp = VectorsDispobj.VectorsDispobj(parent=dobj.name,visible=1) gui_obj = self.MGDisplayTable.addDataObj(object_type='VectorsData',name=dobj.name) gui_obj.editVector() #------------------------------------------------------------------- def openFile(self,file='',drawing_style='',use_current_style=0,show_wizard_choices=0,filter='',pasteAtCursor=False,setDefaultDirectory=True,mgpic_file='',customResCIFFiles={},check_graphs=True,updateDT=True): #------------------------------------------------------------------- self.showMainDisplay() if setDefaultDirectory: #print "set directory to",os.path.dirname(file) mgWidgets.MGFileDialog.last_directory = os.path.dirname(file) # This should be calling functions from appropariate data modules!! import rebuild,MGGLImage if not os.path.exists(file): return 2 ext = os.path.splitext(file)[1][1:].lower() extgz = None if ext == 'gz': ext2 = os.path.splitext(os.path.splitext(file)[0])[1] if ext2 != '': extgz = (ext2 + '.' + ext)[1:].lower() ''' dir_alias = CCP4DATABASE().aliasForDir(os.path.split(file)[0]) if dir_alias: file_list_def = [dir_alias,os.path.split(file)[1],file] else: file_list_def = ['FULLPATH',file,file] print 'openFile ccp4 alias',file,dir_alias,file_list_def ''' if file.endswith('.ccp4mg_presentation.zip'): self.openPresentation(file,"presentation") return if file.endswith('.ccp4mg_presentation'): if os.path.exists(os.path.join(file,"PRESENTATION_TYPE")): ptf = open(os.path.join(file,"PRESENTATION_TYPE")) pres_type = ptf.read().strip() ptf.close() if pres_type in ["movie","presentation","animation"]: idx = ["movie","presentation","animation"].index(pres_type) self.openPresentation(file,["movie","presentation","animation"][idx]) return print "Maybe a presentation, animation or movie ...." dialog = MoviePresQuestion(self) dialog.setWindowTitle("Open presentation/movie/animation") rt = dialog.exec_() if rt>-1 and rt < 3: self.openPresentation(file,["movie","presentation","animation"][rt]) self.addToRecentList(file) return if file.endswith('.mgpic.py') or file.endswith('.pkl'): self.loadStatusFile(file,restore_status=1,restore_view=1) self.showMainDisplay() self.addToRecentList(file) return nvis = 0 if ext in ['map','mrc']: theDataobjs = get_dataobj(object_type='MolData') nvis = 0 for obj in theDataobjs: if hasattr(obj,"visible"): if obj.visible: for dispobj in obj.get_dispobj('MolDisp'): if hasattr(dispobj,"visible"): if dispobj.visible: nvis = nvis + 1 mapdispobjs = get_dispobj(object_type =['MapDisp']) for dispobj in mapdispobjs: if hasattr(dispobj.parent,"is_em_map") and dispobj.parent.is_em_map and dispobj.visible and dispobj.parent.visible: nvis = nvis + 1 if ext in ['ent','brk','pdb','cif'] or extgz in ['ent.gz','brk.gz','pdb.gz','cif.gz']: if extgz: file = utils.gunzipToNamedFile(file) if (not drawing_style and not mgpic_file) and use_current_style: drawing_style = PICTUREWIZARD().default_drawing_style if not show_wizard_choices and not mgpic_file: # Test if this drawing_style absolutely requires user input (if so will return show_wizard_choices = 1) show_wizard_choices,choices = PICTUREWIZARD().read_mgpic_file_choices(drawing_style=drawing_style) #print "openFile drawing_style",show_wizard_choices,drawing_style theDataobjs = get_dataobj(object_type='MolData') nvis = 0 for obj in theDataobjs: if hasattr(obj,"visible"): if obj.visible: for dispobj in obj.get_dispobj('MolDisp'): if hasattr(dispobj,"visible"): if dispobj.visible: nvis = nvis + 1 mapdispobjs = get_dispobj(object_type =['MapDisp']) for dispobj in mapdispobjs: if hasattr(dispobj.parent,"is_em_map") and dispobj.parent.is_em_map and dispobj.visible and dispobj.parent.visible: nvis = nvis + 1 import model rv,m = model.openpdbfile( file,customResCIFFiles=customResCIFFiles,check_graphs=check_graphs ) print "openpdbfile ret",rv,m if rv and rv != model.MolData.NO_ATOMS_IN_CIF_FILE: print "Error opening file",file return 1 if rv == model.MolData.NO_ATOMS_IN_CIF_FILE and (file.lower().endswith('.cif') or file.lower().endswith('.cif.gz')): print "This is not a coordinate cif file, maybe a reflection list?" # Is it supported by a plugin? suffix = file[file.rfind('.')+1:] handler = MAINWINDOW().getFileTypeHandler(suffix) #print "openFile handler",handler return handler(file) self.addToRecentList(file) if show_wizard_choices: import pictureWizardGui gui = pictureWizardGui.pictureWizardGui(MAINWINDOW(),drawing_style=drawing_style,moldata_name=m.name,recentreIfOnlyOne=True) else: m.applyDrawingStyle(drawing_style=drawing_style,mgpic_file=mgpic_file) if updateDT: DISPLAYTABLE().emit(QtCore.SIGNAL("applyWizard")) m_gui = DISPLAYTABLE().addDataObj(object_type='MolData',name=m.name,label=m.name_label) if hasattr(m_gui,"toggleBodyVisibility") and self.defaultObjBodyVisibility != "open_all": m_gui.toggleBodyVisibility(updateWidth=0) DISPLAYTABLE().emit(QtCore.SIGNAL("finishedApplyWizard")) rebuild.UpdateDisplay() #print "MGMainWindow.openFile nvis",nvis if nvis == 0: MAINWINDOW().handleRecentre(glide=0) selection = 'all' rv = m.parse_selection(command=selection) if rv[0] == 0 and rv[1] > 0: selHnd = rv[1] rtde = m.molHnd.Extent(selHnd) mine,maxe = (rtde[0],rtde[1],rtde[2]),(rtde[3],rtde[4],rtde[5]) rtde = () del rtde mide = ((mine[0]+maxe[0])/2.,(mine[1]+maxe[1])/2.,(mine[2]+maxe[2])/2.) theSize = max(abs(mine[0]-maxe[0]),abs(mine[1]-maxe[1]),abs(mine[2]-maxe[2])) if hasattr(self,"glWidget"): self.glWidget.setZoom(theSize*2.5*1.25) elif ['map','mrc'].count(ext) or ['map.gz','mrc.gz'].count(extgz): if extgz: file = utils.gunzipToNamedFile(file) import map m = map.MapData(filename=file,filetype='MAP') emMap = False if QtGui.QMessageBox.question(self,"EM or Xtal map","Is this an EM map?",buttons=QtGui.QMessageBox.Yes|QtGui.QMessageBox.No) == QtGui.QMessageBox.Yes: print "EM map!!" emMap = True m.loaddata(emMap=emMap) m.create_contours() m_gui = DISPLAYTABLE().addDataObj(object_type='MapData',name=m.name,label=m.name_label) xtl = CRYSTALMANAGER().add_object() xtl.set_source(m.name) DISPLAYTABLE().addDispObj(parent_name=CRYSTALMANAGER().name,object_type='Crystal',name=xtl.name) rebuild.UpdateDisplay() self.addToRecentList(file) if nvis == 0: MAINWINDOW().handleRecentre(glide=0) radius = m.clipper_map.GetMaxDim() self.glWidget.setZoom(radius*2.5*1.25) elif ['vector'].count(ext): # Assume it is a vector file for now import VectorsDispobj m = VectorsDispobj.openvectorfile(file) if m: m_gui = DISPLAYTABLE().addDataObj(object_type='VectorsData',name=m.name,label=m.name_label) rebuild.UpdateDisplay() elif MGGLImage.supportedReadFormats().count(ext) and ext != "svg": if pasteAtCursor: xfrac,yfrac = self.getGLWidgetFractionalCursorPosition() m = MGGLImage.Image(filename = str(file),parent=GL2DMANAGER(),params={"x":xfrac,"y":yfrac}) else: m = MGGLImage.Image(filename = str(file),parent=GL2DMANAGER()) if m.isValid: m_gui = DISPLAYTABLE().addDispObj(object_type='Image',name=m.name,parent_name ='Legends&Images') rebuild.UpdateDisplay() elif os.path.isdir(file): return self.directoryHandlers(file) elif file.find('.') > -1: # Is it supported by a plugin? suffixes = getSuffixes(file) for suffix in suffixes: handler = MAINWINDOW().getFileTypeHandler(suffix) if not handler == self.defaultFileTypeHandler: break #print "openFile handler",handler return handler(file) else: # Nothing matched.. return 1 return 0 def addToRecentList(self,f): settings = QtCore.QSettings("CCP4","CCP4MG") recentFiles = settings.value("recentFileList").toStringList() if not f in recentFiles: recentFiles.prepend(f) recentFiles = recentFiles[:10] settings.setValue("recentFileList",QtCore.QVariant(recentFiles)) settings.sync() self.setupRecentList() def setupRecentList(self): settings = QtCore.QSettings("CCP4","CCP4MG") recentFiles = settings.value("recentFileList").toStringList() recentFiles = list(set(list(recentFiles))) recentFiles = sorted(recentFiles) self.recentFilesList = ['Recent files'] for fnew in recentFiles: bn = os.path.basename(str(fnew.toUtf8())) if os.path.isfile(str(fnew.toUtf8())) is False: continue if sys.platform != "win32": import uuid uuid._uuid_generate_time = None uuid._uuid_generate_random = None uuid_str = uuid.uuid4().get_hex() else: import msilib uuid_str = msilib.gen_uuid().strip('{').strip('}').replace('-','') self.actionDefinitions[uuid_str] = dict (text=str(fnew.toUtf8()),shortcut = '',signal = 'triggered()',slot = functools.partial(self.openFile,str(fnew.toUtf8()),use_current_style=1,show_wizard_choices=0)) self.recentFilesList.append(uuid_str) #self.menuDefinitions['_file_open'] = ['open',self.recentFilesList,'_file_download','restore_status_from_file',['Edit/show presentation','new_presentation','open_presentation','zip_presentation']] self.menuDefinitions['_file_open'] = ['open',self.recentFilesList,'_file_download',['Edit/show presentation','new_presentation','open_presentation','zip_presentation']] #------------------------------------------------------------------- def saveStatusFile(self,file='',saved_status=None): #------------------------------------------------------------------- if not file: return ext = os.path.splitext(file)[1][1:] # This almost certainly should be elsewhere, I guess. Probably should # emit a signal here and have this in a slot. # # Make sure we save vectors somewhere when we save status. vecs = get_dataobj(object_type='VectorsData') ccp4mg_dir = utils.get_CCP4MG() if sys.platform != "win32": import uuid uuid._uuid_generate_time = None uuid._uuid_generate_random = None uuid_str = uuid.uuid4().get_hex() else: import msilib uuid_str = msilib.gen_uuid().strip('{').strip('}').replace('-','') newDir = os.path.join(ccp4mg_dir,uuid_str) ivec = 0 for vec in vecs: if hasattr(vec,"filename") and vec.filename and len(vec.filename)>2 and vec.filename[0] and vec.filename[1] and vec.filename[2]: print vec.filename vec.save_file(vec.filename[2]) else: print "vectors have no filename!" try: os.makedirs(newDir) except: pass newFName = os.path.join(newDir,"Vectors_"+str(ivec)+".vector") print "Trying to save",newFName vec.save_file(newFName) """ try: newFName = os.path.join(newDir,"Vectors_"+str(ivec)+".vector") print "Trying to save",newFName vec.savefile(newFName) except: pass """ ivec = ivec + 1 if ext == 'pkl': if saved_status: rv = HISTORY().write_pickle_file(filename=file,status=saved_status) if rv: QtGui.QMessageBox.warning(self,'Error saving status file','Error writing file '+file) else: HISTORY().save_status(filename=file) elif file.endswith('.mgpic.py'): PICTUREDEFINITION().save_picture_definition(filename=file) else: handler = MAINWINDOW().getSaveFileTypeHandlerByFullName(file) handler(file) #------------------------------------------------------------------- def loadStatusFile(self,file='',status={},restore_status=-1,restore_view=-1,remove=-1): #------------------------------------------------------------------- #if remove<0: remove = int(self.remove.isChecked()) if os.path.splitext(file)[1] == '.pkl': print 'loadStatusFile',file,restore_status,restore_view rv = HISTORY().get_status_data_files(filename=file) if rv[0]<0: QtGui.QMessageBox.warning(self,'Error reading status file',rv[1]) return elif rv[0]: hints = [utils.get_HOME()] if file: hints.append(os.path.split(file)[0]) nLost,objList,fileDef,nFound = HISTORY().get_status_data_files(file,hints) if nLost == nFound: status_new = HISTORY().edit_status_data_files(file,1,objList,fileDef) if restore_status: DISPLAYTABLE().deleteAllDataObj() exclude_list = [] if not restore_view: exclude_list = ['view'] rv3 = HISTORY().restore_status(restore_data=1,filename='',status=status_new,exclude_list=exclude_list) if restore_status: DISPLAYTABLE().loadAllDataObj() import rebuild rebuild.UpdateDisplay() DISPLAYTABLE().update(all=1) # Stops a wierd bug whereby first name label is blank. return import statusGui lostGui = statusGui.lostFilesGui(self,file) rv2 = lostGui.exec_() if rv2 == QtGui.QDialog.Accepted: objList,fileDefn = lostGui.getFiles() status_new = HISTORY().edit_status_data_files(file,1,objList,fileDefn) if restore_status: DISPLAYTABLE().deleteAllDataObj() exclude_list = [] if not restore_view: exclude_list = ['view'] rv3 = HISTORY().restore_status(restore_data=1,filename='',status=status_new,exclude_list=exclude_list) if restore_status: DISPLAYTABLE().loadAllDataObj() import rebuild rebuild.UpdateDisplay() theDataobjs = get_dataobj(object_type='MolData') for theDO in theDataobjs: if hasattr(theDO,"filename"): theName = os.path.basename(os.path.splitext(theDO.filename[2])[0]) if theName: gdo = DISPLAYTABLE().getDataObj(theDO.name) theDO.renameuniquename(theName,theDO.name) gdo.updateLabel() DISPLAYTABLE().update(all=1) # Stops a wierd bug whereby first name label is blank. retval = QtGui.QMessageBox.question(self, 'Save status file', 'Save the status with new data file names?\n', QtGui.QMessageBox.Save|QtGui.QMessageBox.Cancel) if retval == QtGui.QMessageBox.Cancel: return saveGui = statusGui.guiSaveStatus(self) title = 'Save updated status from file: '+os.path.split(file)[1] saveGui.setWindowTitle(title) saveGui.fileDialog.selectFile(file) self.connect(saveGui,QtCore.SIGNAL('filesSelected'),self.saveStatusFile) rv4 = saveGui.exec_() return else: return if restore_status: DISPLAYTABLE().deleteAllDataObj() self.emit(QtCore.SIGNAL("RestoringFile")) if os.path.splitext(file)[1] == '.pkl' or status: if restore_status: exclude_list = [] if not restore_view: exclude_list = ['view'] rv = HISTORY().restore_status(restore_data=1,filename=file,status=status,exclude_list=exclude_list) elif restore_view: rv = HISTORY().restore_view(filename=file,status=status) if rv == 1: QtGui.QMessageBox.warning(self,'Error reading status file','Error reading '+file) return elif rv == 2: QtGui.QMessageBox.warning(self,'Error reading status file','No data in file '+file) return elif os.path.splitext(file)[1] == '.py': PICTUREDEFINITION().restore_picture_definition(filename=file,keep_current=1) else: self.openFile(file,use_current_style=1) return if restore_status: DISPLAYTABLE().loadAllDataObj() import rebuild rebuild.UpdateDisplay() self.emit(QtCore.SIGNAL("RestoredFile")) def handleRestore(self): import statusGui gui_open = statusGui.guiRestore(parent=self) self.connect(gui_open,QtCore.SIGNAL('filesSelected'),self.loadStatusFile) gui_open.exec_() def handleJSON(self): dump = self.getJSONDump() saveFileDialog = QtGui.QFileDialog() saveFileDialog.setOption(QtGui.QFileDialog.DontUseNativeDialog) saveFileDialog.setFileMode(QtGui.QFileDialog.AnyFile) saveFileDialog.setAcceptMode(QtGui.QFileDialog.AcceptSave) saveFileDialog.setWindowTitle('Save JSON scene description') filter_list = [self.tr("JSON files (*.json)")] saveFileDialog.setNameFilters(filter_list) if saveFileDialog.exec_(): filename = str(saveFileDialog.selectedFiles()[0]) if not filename.lower().endswith('.json'): filename += ".json" saveFile = open(filename,"w+") saveFile.write(dump) saveFile.close() def getJSONDump(self): import json import ArrayToB64 sys.path.append(os.path.join(os.path.dirname(__file__),"..","WebGL")) #FIXME - temporary hack. import mgwebserver t1 = time.time() s = { "title": "Triangles server", "link": "http://localhost:8000/server_client.html", "language": "en" } diff = self.glWidget.RADIUS /2.5/1.25 s["origin"] = [-self.glWidget.rpos[0],-self.glWidget.rpos[1],-self.glWidget.rpos[2]] s["extent"] = [-self.glWidget.rpos[0]-diff, -self.glWidget.rpos[1]-diff, -self.glWidget.rpos[2]-diff, -self.glWidget.rpos[0]+diff, -self.glWidget.rpos[1]+diff, -self.glWidget.rpos[2]+diff] vert_tri = [] norm_tri = [] col_tri = [] idx_tri = [] prim_types = [] sizes = [] visibility = [] display_classes = [] names = [] atoms = [] texts = [] ids = [] display_options = [] map_display_options = [] ciftexts = {} secstr = {} mapGrids = [] import rebuild rebuild.UpdateDisplay() objs = get_dataobj(object_type='MolData') invis = [] for o in objs: if not o.get_visibility(): o.set_visibility(visibility=1) invis.append(o) import rebuild rebuild.UpdateDisplay() for o in objs: dispobjs = o.get_dispobj() display_class = 'NONE' for dispobj in dispobjs: # This line is neccessary to make sure atom list is up to date for invisible objects. dispobj.draw() this_atoms = [] if hasattr(dispobj,"Connectivity"): print dispobj.Connectivity.GetNumberOfAtoms() theAtoms = dispobj.Connectivity.GetAtoms() for iat in range(dispobj.Connectivity.GetNumberOfAtoms()): pcAt = mmdb.getPCAtom(theAtoms,iat) if dispobj.style in ["SPLINE","WORM","FATWORM","VARIABLEWORM"]: if pcAt.name[:] != " CA ": continue anAtom = {} anAtom["x"] = pcAt.x anAtom["y"] = pcAt.y anAtom["z"] = pcAt.z anAtom["charge"] = pcAt.charge anAtom["tempFactor"] = pcAt.tempFactor anAtom["label"] = pcAt.GetAtomID()[0][:] this_atoms.append(anAtom) atoms.append(this_atoms) thisVis = True display_opts = {} if hasattr(dispobj,"graphmod") and dispobj.graphmod is not None and (not (hasattr(dispobj,"unthreadedDraw") and hasattr(dispobj,"SelHandle1") and hasattr(dispobj,"SelHandle2")) or hasattr(dispobj,"surf")): print dispobj.graphmod.obj, len(dispobj.graphmod.obj.GetPrimitives()) if not dispobj.get_visibility(): print dispobj dispobj.set_visibility(visibility=1) dispobj.draw() thisVis = False if hasattr(dispobj.graphmod.obj,"GetSurfacePrimitives"): prims = list(dispobj.graphmod.obj.GetSurfacePrimitives()) else: prims = [] prims.extend(dispobj.graphmod.obj.GetPrimitives()) print dispobj.display_class display_class = dispobj.display_class print dispobj.get_selection_label(), dispobj.get_style_label names.append(dispobj.get_style_label()+' '+dispobj.get_selection_label()[:40]) if hasattr(dispobj,"ElectroColourScheme"): menu1 = mgwebserver.getAtomSelectionMenu(dispobj) menu2 = [("sel2_same_as","Same as other")] menu2.extend(mgwebserver.getAtomSelectionMenu(dispobj)) menu3 = [("electrostatic","Electrostatic potential")] menu3.extend(mgwebserver.getAtomColourMenu(dispobj)) display_opts["Atoms to draw round"] = menu1 display_opts["In context of atoms"] = menu2 display_opts["Colour"] = menu3 else: menu1 = mgwebserver.getAtomSelectionMenu(dispobj) menu2 = mgwebserver.getAtomColourMenu(dispobj) menu2.append(("browser","Colour browser")) menu3 = mgwebserver.getStyleMenu() display_opts["Selection"] = menu1 display_opts["Colour"] = menu2 display_opts["Style"] = menu3 elif hasattr(dispobj,"label_graphmod") and dispobj.label_graphmod is not None and hasattr(dispobj,"unthreadedDraw") and hasattr(dispobj,"SelHandle1") and hasattr(dispobj,"SelHandle2"): print "HBONDS?",len(dispobj.label_graphmod.obj.GetPrimitives()) if not dispobj.get_visibility(): dispobj.set_visibility(visibility=1) dispobj.draw() thisVis = False dispobj.unthreadedDraw() prims = list(dispobj.label_graphmod.obj.GetPrimitives()) print dispobj.display_class display_class = dispobj.display_class print dispobj.SelHandle1.getLabel(), dispobj.SelHandle2.getLabel() names.append("H-bonds "+dispobj.SelHandle1.getLabel()[:40]+" "+dispobj.SelHandle1.getLabel()[:40]) menu1 = mgwebserver.getAtomSelectionMenu(dispobj) menu2 = [("sel2_same_as","Same as other")] menu2.extend(mgwebserver.getAtomSelectionMenu(dispobj)) menu3 = [("compliment","Contrast"),("browser","Colour browser")] display_opts["Atoms from"] = menu1 display_opts["Atoms to"] = menu2 display_opts["Colour"] = menu3 else: print "----------------------------------------",dispobj,"does not have graphmod",dir(dispobj) print hasattr(dispobj,"graphmod") , dispobj.graphmod, (hasattr(dispobj,"unthreadedDraw") and hasattr(dispobj,"SelHandle1") and hasattr(dispobj,"SelHandle2")) , hasattr(dispobj,"surf") print hasattr(dispobj,"graphmod") and dispobj.graphmod is not None and (not (hasattr(dispobj,"unthreadedDraw") and hasattr(dispobj,"SelHandle1") and hasattr(dispobj,"SelHandle2")) or hasattr(dispobj,"surf")) prims = [] names.append("Unknown") this_vert_tri = [] this_norm_tri = [] this_col_tri = [] this_idx_tri = [] this_prim_types = [] this_sizes = [] for prim in prims: prim.generateArrays() if prim.GetNumberOfBufferVertices()>0: this_vert_tri.append(ArrayToB64.FloatArrayToString(prim.GetBufferVertices(),prim.GetNumberOfBufferVertices())) theType = prim.GetPrimitiveTypeAsString() if theType in ["LINES","LINE_LOOP","LINE_STRIP","POINTS","POINTS_SPHERES"]: thisSize = prim.GetSize(); this_sizes_inner = [] for itr in range(prim.GetNumberOfBufferVertices()): this_sizes_inner.append(thisSize) this_sizes.append(this_sizes_inner) if theType in ["LINES","LINE_LOOP","LINE_STRIP","POINTS","POINTS_SPHERES"]: this_norm_tri.append(ArrayToB64.FloatArrayToString(prim.GetBufferNormals(),0)) else: this_norm_tri.append(ArrayToB64.FloatArrayToString(prim.GetBufferNormals(),prim.GetNumberOfBufferVertices())) this_col_tri.append(ArrayToB64.FloatArrayToString(prim.GetBufferColours(),prim.GetNumberOfBufferVertices()*4/3)) this_idx_tri.append(ArrayToB64.UIntArrayToString(prim.GetBufferIndices(),prim.GetNumberOfBufferIndices())) this_prim_types.append(theType) vert_tri.append(this_vert_tri) norm_tri.append(this_norm_tri) col_tri.append(this_col_tri) idx_tri.append(this_idx_tri) prim_types.append(this_prim_types) sizes.append(this_sizes) visibility.append(thisVis) display_classes.append(display_class) display_options.append(display_opts) if hasattr(o,"uuid") and hasattr(dispobj,"uuid"): ids.append(o.uuid+"_"+dispobj.uuid) else: ids.append("unknown unknown") this_texts = [] if hasattr(dispobj,"label_graphmod") and dispobj.label_graphmod is not None and hasattr(dispobj,"unthreadedDraw") and hasattr(dispobj,"SelHandle1") and hasattr(dispobj,"SelHandle2"): if hasattr(dispobj,"Connectivity2") and hasattr(dispobj.Connectivity2,"connected"): for conn in dispobj.Connectivity2.connected: if hasattr(o,"uuid") and hasattr(dispobj,"uuid"): midpoint = pygl_coord.Cartesian.MidPoint(conn.first, conn.second) atext = {} atext["x"] = midpoint.get_x() atext["y"] = midpoint.get_y() atext["z"] = midpoint.get_z() atext["label"] = conn.label atext["mainObjectUUID"] = o.uuid+"_"+dispobj.uuid this_texts.append(atext) texts.append(this_texts) if hasattr(o,"uuid") and hasattr(o,"molHnd"): tfileCIF = tempfile.NamedTemporaryFile(suffix=".cif",prefix="ccp4mg"+str(os.getpid()),delete=False) name = tfileCIF.name tfileCIF.close() o.molHnd.WriteCIFASCII(name) ciftextfile = open(name) ciftext = ciftextfile.readlines() ciftextfile.close() ciftexts[o.uuid] = ciftext secstr[o.uuid] = o.get_attribute('secstr_list') print "Got buffers",time.time()-t1; sys.stdout.flush() mapobjs = get_dataobj(object_type='MapData') doingGrids = False for o in mapobjs: if not o.get_visibility(): o.set_visibility(visibility=1) invis.append(o) import rebuild rebuild.UpdateDisplay() for o in mapobjs: # We have the complete grid with enough info to do contouring in JS. But, we only want one of these per MapData. dispobjs = o.get_dispobj() print dispobjs if len(dispobjs)>0 and doingGrids: mapGrid = {} orthToFracMat_c = xmapview.VectorFloat() fracToOrthMat_c = xmapview.VectorFloat() grid, nCells_x, nCells_y, nCells_z, cellLength_x, cellLength_y, cellLength_z, gridSize, baseX, baseY, baseZ = xmapview.GetCompleteGrid(o.clipper_map.xmap,orthToFracMat_c,fracToOrthMat_c) grid = ArrayToB64.FloatArrayToString(grid,gridSize) orthToFracMat = [] for v in orthToFracMat_c: orthToFracMat.append(v) fracToOrthMat = [] for v in fracToOrthMat_c: fracToOrthMat.append(v) print "base,cmats",baseX,baseY,baseZ,orthToFracMat,fracToOrthMat print "length of grid string",len(grid) mapGrid["grid"] = grid mapGrid["nCells_x"] = nCells_x mapGrid["nCells_y"] = nCells_y mapGrid["nCells_z"] = nCells_z mapGrid["cellLength_x"] = cellLength_x mapGrid["cellLength_y"] = cellLength_y mapGrid["cellLength_z"] = cellLength_z mapGrid["gridSize"] = gridSize mapGrid["baseX"] = nCells_x mapGrid["baseY"] = nCells_y mapGrid["baseZ"] = nCells_z mapGrid["orthToFracMat"] = orthToFracMat mapGrid["fracToOrthMat"] = fracToOrthMat mapGrids.append(mapGrid) display_class = 'MAP' for dispobj in dispobjs: thisVis = True if hasattr(dispobj,"graphmod") and dispobj.graphmod is not None: try: if hasattr(o,"filetype") and o.filetype == "MAP" and hasattr(o,"is_em_map") and o.is_em_map: pass else: dispobj.graphmod.obj.SetCentre(-self.glWidget.rpos[0],-self.glWidget.rpos[1],-self.glWidget.rpos[2]) dispobj.graphmod.rebuild() except: print 'Cant set centre of dispobj.graphmod.obj' #dispobj.draw() print dispobj.graphmod.obj, len(dispobj.graphmod.obj.GetPrimitives()) if not dispobj.get_visibility(): print dispobj dispobj.set_visibility(visibility=1) dispobj.draw() thisVis = False prims = [] prims.extend(dispobj.graphmod.obj.GetPrimitives()) print "Len map prims",len(prims) print dispobj.get_selection_label(), dispobj.get_style_label(),dir(o) names.append(dispobj.get_style_label()+' '+dispobj.get_selection_label()[:40]) atoms.append([]) this_vert_tri = [] this_norm_tri = [] this_col_tri = [] this_idx_tri = [] this_prim_types = [] this_sizes = [] for prim in prims: prim.generateArrays() if prim.GetNumberOfBufferVertices()>0: this_vert_tri.append(ArrayToB64.FloatArrayToString(prim.GetBufferVertices(),prim.GetNumberOfBufferVertices())) theType = prim.GetPrimitiveTypeAsString() if theType in ["LINES","LINE_LOOP","LINE_STRIP","POINTS","POINTS_SPHERES"]: thisSize = prim.GetSize(); for itr in range(prim.GetNumberOfBufferVertices()): this_sizes.append(thisSize) print "map prim type",theType if prim.GetNumberOfBufferVertices()>0: print "Num of real vertices",prim.GetNumberOfBufferVertices() this_vert_tri.append(ArrayToB64.FloatArrayToString(prim.GetBufferVertices(),prim.GetNumberOfBufferVertices())) if theType in ["LINES","LINE_LOOP","LINE_STRIP","POINTS","POINTS_SPHERES"]: this_norm_tri.append(ArrayToB64.FloatArrayToString(prim.GetBufferNormals(),0)) else: this_norm_tri.append(ArrayToB64.FloatArrayToString(prim.GetBufferNormals(),prim.GetNumberOfBufferVertices())) this_col_tri.append(ArrayToB64.FloatArrayToString(prim.GetBufferColours(),prim.GetNumberOfBufferVertices()*4/3)) this_idx_tri.append(ArrayToB64.UIntArrayToString(prim.GetBufferIndices(),prim.GetNumberOfBufferIndices())) this_prim_types.append(theType) display_opts = {} map_display_options.append(display_opts); vert_tri.append(this_vert_tri) norm_tri.append(this_norm_tri) col_tri.append(this_col_tri) idx_tri.append(this_idx_tri) prim_types.append(this_prim_types) sizes.append(this_sizes) visibility.append(thisVis) display_classes.append(display_class) if hasattr(o,"uuid") and hasattr(dispobj,"uuid"): ids.append(o.uuid+"_"+dispobj.uuid) else: ids.append("unknown unknown") s["col_tri"] = col_tri s["norm_tri"] = norm_tri s["vert_tri"] = vert_tri s["idx_tri"] = idx_tri s["prim_types"] = prim_types s["sizes"] = sizes s["visibility"] = visibility s["display_classes"] = display_classes s["display_options"] = display_options s["map_display_options"] = map_display_options s["names"] = names s["atoms"] = atoms s["texts"] = texts s["ids"] = ids s["secstr"] = secstr s["background"] = self.glWidget.getBackground() s["fog"] = self.glWidget.fog_near, self.glWidget.fog_far s["mapGrids"] = mapGrids if self.glWidget.slab_enabled: s["slab"] = self.glWidget.slab_width, self.glWidget.slab_offset else: s["slab"] = 1000., 0. def getXMLStatus(): from lxml import etree import mgpic2xml tfile = tempfile.NamedTemporaryFile(suffix=".mgpic.py",prefix="ccp4mg"+str(os.getpid()),delete=False) name = tfile.name tfile.close() PD().save_picture_definition(filename=name) xml = mgpic2xml.PictDefToEtreeFromFile(name) os.unlink(name) return etree.tostring(xml, pretty_print=True) stat = getXMLStatus() s["status"] = stat s["ciftexts"] = ciftexts print len(col_tri),len(norm_tri),len(vert_tri),len(idx_tri),len(prim_types), len(visibility), len(display_classes), len(display_options), len(names), len(atoms), len(ids), len(texts), len(secstr), len(ciftexts), len(map_display_options), len(sizes) print "Copied buffers to dictionary",time.time()-t1; sys.stdout.flush() dump = json.dumps(s) print "Done json dump",time.time()-t1; sys.stdout.flush() # OK, here we write HTML file containing data dump. try: iobj = 0 for o in objs: dispobjs = o.get_dispobj() for dispobj in dispobjs: dispobj.set_visibility(visibility=int(s["visibility"][iobj])) #print s["visibility"][iobj] dispobj.draw() iobj +=1 for o in mapobjs: dispobjs = o.get_dispobj() for dispobj in dispobjs: dispobj.set_visibility(visibility=int(s["visibility"][iobj])) #print s["visibility"][iobj] dispobj.draw() iobj +=1 for o in invis: o.set_visibility(visibility=0) import rebuild rebuild.UpdateDisplay() except: print "Problem re-hiding objects." return dump; def handleHTML(self): import datetime import zipfile dump = self.getJSONDump() saveFileDialog = QtGui.QFileDialog() saveFileDialog.setOption(QtGui.QFileDialog.DontUseNativeDialog) saveFileDialog.setFileMode(QtGui.QFileDialog.AnyFile) saveFileDialog.setAcceptMode(QtGui.QFileDialog.AcceptSave) saveFileDialog.setWindowTitle('Save HTML/JS Zip archive') filter_list = [self.tr("Zip files (*.zip)")] saveFileDialog.setNameFilters(filter_list) WebGLDir = os.path.join(os.path.dirname(__file__),"..","WebGL") WebGLScripts = ["jquery-1.11.0.min.js", "jquery-ui-1.10.4/ui/jquery-ui.js", "glMatrix.js", "pako-master/dist/pako.min.js", "mgBase64.js", "lines-fragment-shader.js", "lines-vertex-shader.js", "thick-lines-vertex-shader.js", "pointspheres-fragment-shader.js", "pointspheres-vertex-shader.js", "text-fragment-shader.js", "triangle-fragment-shader.js", "triangle-vertex-shader.js", "render-framebuffer-fragment-shader.js", "twodshapes-vertex-shader.js", "twodshapes-fragment-shader.js", "perfect-sphere-fragment-shader.js", "shadow-vertex-shader.js", "shadow-fragment-shader.js", "triangle-shadow-vertex-shader.js", "triangle-shadow-fragment-shader.js", 'twodshapes-shadow-vertex-shader.js', 'perfect-sphere-shadow-fragment-shader.js', 'pointspheres-shadow-vertex-shader.js', 'pointspheres-shadow-fragment-shader.js' ,"mgMaths.js", "mgMiniMol.js", "mgSecStr.js", "fontHeight.js", "mgWebGL.js", "mgWebGLAtomsToPrimitives.js", "jscolor.js","CIsoSurface.js","modal.css","mgWizard.js","mgWebGLReadMap.js"] if saveFileDialog.exec_(): filename = str(saveFileDialog.selectedFiles()[0]) predir = "WebGL-archive-"+datetime.datetime.today().strftime("%d-%m-%y-%H%M") if not filename.lower().endswith('.zip'): filename += ".zip" html = """ CCP4 client only WebGL """ for script in WebGLScripts: html += '\n' html += """

CCP4 client only WebGL

""" with zipfile.ZipFile(filename, 'w') as myzip: for script in WebGLScripts: myzip.write(os.path.join(WebGLDir,script),arcname=os.path.join(predir,"WebGL",script)) myzip.writestr(os.path.join(predir,"webglarchive.html"),html) def handleSaveEnsemble(self): import mmut newManager = mmdb.Manager() iModel = 0 """ model = mmdb.Model() model.thisown = 0 newManager.AddModel(model) """ preamble1 = "" preamble2 = "" theDataobjs = get_dataobj(object_type='MolData') for obj in theDataobjs: if hasattr(obj,"visible") and obj.visible: nChains = pygl_coord.intp() chainTable = mmut.GetChainTable(obj.molHnd,obj.first_nmr_model,nChains) selHnd = obj.molHnd.NewSelection() obj.molHnd.SelectAtoms(selHnd,obj.first_nmr_model,"XXX",mmdb.ANY_RES,"X",mmdb.ANY_RES,"X","X","X","X","X",mmdb.SKEY_NEW ) for dispobj in obj.get_dispobj('MolDisp'): if hasattr(dispobj,"visible") and dispobj.visible: do_selHnd = dispobj.SelHandle.getSelHnd() obj.molHnd.Select(selHnd,mmdb.STYPE_ATOM,do_selHnd,mmdb.SKEY_OR) obj.molHnd.SelectAtoms(selHnd,obj.first_nmr_model,"*",mmdb.ANY_RES,"*",mmdb.ANY_RES,"*","*","*","*","*",mmdb.SKEY_AND ) obj.molHnd.MakeSelIndex(selHnd) #selindexp = pygl_coord.intp() #SelAtoms = mmut.GetAtomSelIndex(obj.molHnd,selHnd,selindexp) #print "Selected",selindexp.value(),"atoms in total",obj.name print "There are",nChains.value(),"chains" newchid = 65 for i in range(nChains.value()): selHndCh = obj.molHnd.NewSelection() chid = mmut.getPCChain(chainTable,i).GetChainID() obj.molHnd.SelectAtoms(selHndCh,obj.first_nmr_model,chid,mmdb.ANY_RES,"*",mmdb.ANY_RES,"*","*","*","*","*",mmdb.SKEY_NEW ) obj.molHnd.Select(selHndCh,mmdb.STYPE_ATOM,selHnd,mmdb.SKEY_AND ) selindexp = pygl_coord.intp() SelAtoms = mmut.GetAtomSelIndex(obj.molHnd,selHndCh,selindexp) print "Selected",selindexp.value(),"atoms from",obj.name,chid if selindexp.value()>0: print "Creating chain",chr(newchid) model = mmdb.Model() model.thisown = 0 newManager.AddModel(model) iModel += 1 newChain = model.GetChainCreate(chr(newchid),True); ncopied = obj.molHnd.CopySelectedAtomsToChain(selHndCh,newChain) print "Copied",ncopied,"to new chain" udd_rmsd_model=obj.molHnd.GetUDDHandle(mmdb.UDR_HIERARCHY,"mrbump_gesamt_multi_rmsd") if udd_rmsd_model>0: udd_rmsd = mmdb.doublep() obj.molHnd.GetUDData(udd_rmsd_model,udd_rmsd) rmsdval = udd_rmsd.value() ftype, shortName, longName = obj.filename preamble1 += "REMARK PHASER ENSEMBLE MODEL "+str(iModel)+" ID "+str(rmsdval) + "\n" preamble2 += "REMARK MODEL "+str(iModel)+": "+os.path.basename(shortName)+", MODEL '', CHAIN "+chid + "\n" else: print "Clearing preambles" preamble1 = None preamble2 = None newchid += 1 obj.molHnd.DeleteSelection(selHndCh) obj.molHnd.DeleteSelection(selHnd) newManager.FinishStructEdit() filters = ["Model coordinate files (*.pdb *.cif *.ent *.brk)"] fd = mgWidgets.MGSaveFileDialog(self,filters=filters) fd.fileDialog.setDefaultSuffix("pdb") fd.setWindowTitle("Save ensemble") def handler(fname=None): if fname is not None: if fname.endswith("cif"): newManager.WriteCIFASCII(fname) else: if (preamble1 is not None) and (preamble2 is not None): tfile = tempfile.NamedTemporaryFile(suffix=".pdb",prefix="ccp4mg"+str(os.getpid()),delete=False) tname = tfile.name tfile.close() os.unlink(tname) newManager.WritePDBASCII(tname) rfile = open(tname) fcontents = rfile.read() rfile.close() ofile = open(fname,"wb+") ofile.write(preamble1) ofile.write(preamble2) ofile.write(fcontents) ofile.close() else: newManager.WritePDBASCII(fname) self.connect(fd,QtCore.SIGNAL('save'),handler) self.connect(fd,QtCore.SIGNAL('save'),fd.close) fd.setModal(True) fd.show() def handleSaveStatus(self): import statusGui gui_open = statusGui.guiSaveStatus(parent=self) self.connect(gui_open,QtCore.SIGNAL('filesSelected'),self.saveStatusFile) gui_open.exec_() def handleCopyClipboard(self): import screenshot print "copy" QtGui.QApplication.instance().clipboard().clear() import MGApplication app = MGApplication.QtApp() fw = app.focusWidget() if hasattr(fw,"hasSelectedText") and callable(fw.hasSelectedText) and fw.hasSelectedText() and hasattr(fw,"selectedText") and callable(fw.selectedText): QtGui.QApplication.instance().clipboard().setText(fw.selectedText()) return size = [self.glWidget.size().width(),self.glWidget.size().height()] dpi=72 pm = PM("screenshot_preferences") tfile = tempfile.NamedTemporaryFile(suffix=".png",prefix="ccp4mg"+str(os.getpid()),delete=False) name = tfile.name tfile.close() os.unlink(name) if sys.platform == "darwin" and QtOpenGL.QGLFramebufferObject.hasOpenGLFramebufferObjects(): print "Using FBOs" rv = screenshot.makeScreenshot(filename=name,size=size,dpi=dpi,use_pbuffer=True) else: rv = screenshot.makeScreenshot(filename=name,size=size,dpi=dpi) pix = QtGui.QPixmap(name) QtGui.QApplication.instance().clipboard().setPixmap(pix) def handleRecentre(self,glide=1,**args): # Note that we are *not* looping over widgets! # This is because default slot for PositionChanged signal # is to move others. This behaviour will change. try: self.centre_mode = PM('centre_mode').getparams()['centre_method'] except: self.centre_mode = self.CENTRE_MODE_EXTENTS total_mass = 0.0 total_maxe = [-1e+7,-1e+7,-1e+7] total_mine = [1e+7,1e+7,1e+7] for widget in self.glWidgets[0:1]: origins = pygl_coord.CartesianVector() dispobjs = get_dispobj(object_type =['MolDisp']) mapdispobjs = get_dispobj(object_type =['MapDisp']) for dispobj in mapdispobjs: if hasattr(dispobj.parent,"is_em_map") and dispobj.parent.is_em_map and dispobj.visible and dispobj.parent.visible: map_orig_cart = dispobj.parent.clipper_map.GetOrigin() map_orig = (map_orig_cart.get_x(),map_orig_cart.get_y(),map_orig_cart.get_z()) radius = dispobj.parent.clipper_map.GetMaxDim() if self.centre_mode != self.CENTRE_MODE_EXTENTS: if self.centre_mode == self.CENTRE_MODE_COORDS: mass = 1.0 # FIXME - we could have a sensible approximation here, based on size. total_mass = total_mass + mass elif self.centre_mode == self.CENTRE_MODE_MASS: mass = 1.0 # FIXME - we could have a sensible approximation here, based on size. total_mass = total_mass + mass else: return # In case self.centre_mode is junk value. origins.append(map_orig_cart*mass) if self.centre_mode == self.CENTRE_MODE_EXTENTS: mine_c = map_orig_cart - pygl_coord.Cartesian(radius,radius,radius) maxe_c = map_orig_cart + pygl_coord.Cartesian(radius,radius,radius) maxe = (maxe_c.get_x(), maxe_c.get_y(), maxe_c.get_z()) mine = (mine_c.get_x(), mine_c.get_y(), mine_c.get_z()) if (mine[0]) < total_mine[0]: total_mine[0] = mine[0] if (mine[1]) < total_mine[1]: total_mine[1] = mine[1] if (mine[2]) < total_mine[2]: total_mine[2] = mine[2] if (maxe[0]) > total_maxe[0]: total_maxe[0] = maxe[0] if (maxe[1]) > total_maxe[1]: total_maxe[1] = maxe[1] if (maxe[2]) > total_maxe[2]: total_maxe[2] = maxe[2] for dispobj in dispobjs: if hasattr(dispobj,"visible") and hasattr(dispobj,"parent") and hasattr(dispobj.parent,"visible") and dispobj.visible and dispobj.parent.visible: if hasattr(dispobj,"SelHandle") and hasattr(dispobj.SelHandle,"getSelHnd") and callable(dispobj.SelHandle.getSelHnd) and hasattr(dispobj.parent,"molHnd") and hasattr(dispobj.parent.molHnd,"CentreOfMass") and callable(dispobj.parent.molHnd.CentreOfMass): # Overly careful? if self.centre_mode != self.CENTRE_MODE_EXTENTS: if self.centre_mode == self.CENTRE_MODE_COORDS: rtd = mmdb.realtype_to_double(dispobj.parent.molHnd.CentreOfCoordinates(dispobj.SelHandle.getSelHnd())) mass = dispobj.parent.molHnd.NumberOfAtoms(dispobj.SelHandle.getSelHnd()) elif self.centre_mode == self.CENTRE_MODE_MASS: rtd = mmdb.realtype_to_double(dispobj.parent.molHnd.CentreOfMass(dispobj.SelHandle.getSelHnd())) mass = dispobj.parent.molHnd.Mass(dispobj.SelHandle.getSelHnd()) else: return # In case self.centre_mode is junk value. total_mass = total_mass + mass cart = pygl_coord.Cartesian(rtd) * mass origins.append(cart) if self.centre_mode == self.CENTRE_MODE_EXTENTS: rtde = dispobj.parent.molHnd.Extent(dispobj.SelHandle.getSelHnd()) mine,maxe = (rtde[0],rtde[1],rtde[2]),(rtde[3],rtde[4],rtde[5]) rtde = () del rtde if hasattr(dispobj,"doBiomolecule") and dispobj.doBiomolecule and hasattr(dispobj.parent,"molHnd"): matrices = dispobj.parent.molHnd.GetBiomoleculeAsMatrices(0,1); mide = ((mine[0]+maxe[0])/2.,(mine[1]+maxe[1])/2.,(mine[2]+maxe[2])/2.) for mat in matrices: midet = mat * pygl_coord.Cartesian(mide) if (midet.get_x()) < total_mine[0]: total_mine[0] = midet.get_x() if (midet.get_y()) < total_mine[1]: total_mine[1] = midet.get_y() if (midet.get_z()) < total_mine[2]: total_mine[2] = midet.get_z() if (midet.get_x()) > total_maxe[0]: total_maxe[0] = midet.get_x() if (midet.get_y()) > total_maxe[1]: total_maxe[1] = midet.get_y() if (midet.get_z()) > total_maxe[2]: total_maxe[2] = midet.get_z() else: if (mine[0]) < total_mine[0]: total_mine[0] = mine[0] if (mine[1]) < total_mine[1]: total_mine[1] = mine[1] if (mine[2]) < total_mine[2]: total_mine[2] = mine[2] if (maxe[0]) > total_maxe[0]: total_maxe[0] = maxe[0] if (maxe[1]) > total_maxe[1]: total_maxe[1] = maxe[1] if (maxe[2]) > total_maxe[2]: total_maxe[2] = maxe[2] if self.centre_mode == self.CENTRE_MODE_EXTENTS: mide = ((total_mine[0]+total_maxe[0])/2.,(total_mine[1]+total_maxe[1])/2.,(total_mine[2]+total_maxe[2])/2.) widget.centreOn(mide,glide=glide) return if len(origins)>0: total_o = pygl_coord.Cartesian(0,0,0) for o in origins: total_o = total_o + o mid = total_o/float(total_mass) widget.centreOn([mid.get_x(), mid.get_y(), mid.get_z()],glide=glide) #------------------------------------------------------------------- def handleCentreOn(self): #------------------------------------------------------------------- gui = self.findChild(guiCentreOn) if gui: print "CentreOn gui already open" gui.show() else: MolData_list = get_dataobj(object_type = 'MolData') if MolData_list: gui = guiCentreOn(parent=self) else: print "No loaded PDB" #------------------------------------------------------------------- def centreOn(self,position=[],molHnd=None,selHnd=-1): #------------------------------------------------------------------- import mmdb2 as mmdb import mmut #print "centreOn position",position,molHnd if position: xx,yy,zz = position else: selindexp = pygl_coord.intp() SelAtoms = mmdb.newPPCAtom() #nSelAtoms = molHnd.GetSelIndex (selHnd,SelAtoms) SelAtoms = mmut.GetAtomSelIndex(molHnd,selHnd,selindexp) nSelAtoms = selindexp.value() if nSelAtoms <= 0: return #print nSelAtoms; sys.stdout.flush() xx = 0.0 yy = 0.0 zz = 0.0 for n in range(0,nSelAtoms): pAtom = mmdb.getPCAtom(SelAtoms,n) xx = xx + pAtom.x yy = yy + pAtom.y zz = zz + pAtom.z xx = xx/nSelAtoms yy = yy/nSelAtoms zz = zz/nSelAtoms #print "centreOn xx,yy,zz",xx,yy,zz #new_centre = pygl_coord.CartesianPtr([xx,yy,zz]) self.glWidget.centreOn([xx,yy,zz]) def dragEnterEvent(self, event): event.accept() def dragMoveEvent(self, event): event.accept() def DealWithOpenFileEvent(self,file): self.openFile(str(file.toAscii()),use_current_style=1) ''' rc = self.pdb.load_file(str(file.toAscii())) go = '' if not rc: go = DrawConnectivity(self.pdb.Connectivity,self.pdb.molHnd,self.pdb.selHnd,self.pdb.nSelAtoms) if go: self.glWidget.SetGO(go,1) ''' def getGLWidgetFractionalCursorPosition(self): widgetPos = self.glWidget.mapFromGlobal(QtGui.QCursor.pos()) widgetSize = self.glWidget.size() xfrac = float(widgetPos.x())/widgetSize.width() yfrac = 1.0-float(widgetPos.y())/widgetSize.height() if xfrac >=1 or xfrac <0 or yfrac >=1 or yfrac < 0: xfrac = 0 yfrac = 0 xfrac = min(0.9, xfrac) yfrac = min(0.9, yfrac) return xfrac,yfrac def DealWithMimeData(self,mimeData,pasteAtCursor=False): if mimeData.hasImage(): ccp4mg_dir = utils.get_CCP4MG() if ccp4mg_dir != "": tfile = tempfile.NamedTemporaryFile(suffix=".png",prefix="ccp4mg"+str(os.getpid()),delete=False,dir=ccp4mg_dir) else: tfile = tempfile.NamedTemporaryFile(suffix=".png",prefix="ccp4mg"+str(os.getpid()),delete=False) name = tfile.name tfile.close() os.unlink(name) image = QtGui.QImage(mimeData.imageData()) image.save(name) rv = self.openFile(name,use_current_style=1,pasteAtCursor=pasteAtCursor) print "Save clipboard image to",name if mimeData.hasText() and not mimeData.hasUrls(): import Legend if pasteAtCursor: xfrac,yfrac = self.getGLWidgetFractionalCursorPosition() legend = Legend.Legend(parent=GL2DMANAGER(),name='Legend',params={"x":xfrac,"y":yfrac}) else: legend = Legend.Legend(parent=GL2DMANAGER(),name='Legend') self.MGDisplayTable.addDispObj(object_type='Legend',name=legend.name,parent_name = GL2DMANAGER().name) legend.set_text("

"+str(mimeData.text().toUtf8()).replace("\n","

")+"

") import rebuild rebuild.UpdateDisplay() rv = 0 for url in mimeData.urls(): self.DealWithUrl(url,pasteAtCursor=pasteAtCursor) return rv def DealWithUrl(self,url=None,pasteAtCursor=False): print url if sys.platform == "darwin" and str(url.scheme())=='file': # Finder gives OS X specific 'NSURL's on Yosemite import platform macver = tuple(platform.mac_ver()[0].split('.')) if macver >= ('10','10','0'): nsurlp = 'file://'+str(url.toLocalFile().toUtf8()) import nsurlutil urlp = nsurlutil.NSURLTOURL(nsurlp) url = QtCore.QUrl(urlp) print "Fixed?",url def downloaded(fname=None,dlfname=None): if not dlfname: return def handler(dlfname=None,fname=None): shutil.copy2(dlfname,fname) self.openFile(fname,use_current_style=1) filters = ["Model coordinate files (*.pdb *.cif *.ent *.brk *.pdb.gz *.cif.gz *.ent.gz *.brk.gz)"] filters.extend(self.customDownloadFilterTypes) fd = mgWidgets.MGSaveFileDialog(self,filters=filters, defaultFileName=fname) fd.setWindowTitle("Save "+fname) self.connect(fd,QtCore.SIGNAL('save'),guiUtils.partialWithSignal(handler,dlfname)) self.connect(fd,QtCore.SIGNAL('save'),fd.close) fd.setModal(True) fd.show() if str(url.scheme())=='file': rv = self.openFile(str(url.toLocalFile().toUtf8()),use_current_style=1,pasteAtCursor=pasteAtCursor,setDefaultDirectory=True) else: import downloadPdb, UtilityThread dpdb = downloadPdb.downloadPdbCore() self.connect(dpdb,QtCore.SIGNAL("DownloadFinished"),guiUtils.partialWithSignal(downloaded,os.path.basename(str(url.path())))) downloadThread = UtilityThread.UtilityThread(functools.partial(dpdb.downloadMain,str(url.toString()))) self.downloadThreads.append(downloadThread) self.connect(downloadThread,QtCore.SIGNAL("finished()"),functools.partial(self.downloadThreads.remove,downloadThread)) downloadThread.start() def handleHelp(self): HELPBROWSER().loadMgHelp('index.html') def openPDF(self,f): QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(f)) def getHelpBrowser(self): # Presently this is called from global_definitions.HELPBROWSER # to create one instance of MGBrowserWindow to show help text if not hasattr(self,'helpGui'): import MGWebBrowser self.helpGui = MGWebBrowser.MGBrowserWindow() self.connect(self.helpGui,QtCore.SIGNAL("CustomMimeTypeRequested"),self.DealWithUrl) self.helpGui.setCustomMimeTypes(["pdb","mtz","ent","zip","pdf"]) self.addFileTypeHandler("pdf",self.openPDF) self.helpGuiD = MGSimpleDialog.MGSimpleDockDialog(defaultDockArea=QtCore.Qt.RightDockWidgetArea,tabify=False) self.helpGuiD.dockWidget.setWidget(self.helpGui) self.helpGuiD.dockWidget.setWindowTitle('CCP4mg Browser') # Set this slightly offset from main window - otherwise usually totally obscures main window #self.helpGui.move( self.x()+10, self.y()-10) self.helpGui.show() self.helpGuiD.UnClose() return self.helpGui def handleAbout(self): if hasattr(self,'about'): if self.about: self.about.UnClose() return import HelpAboutDialog self.about = HelpAboutDialog.HelpAboutDialog(parent=self) def handlePaste(self): import MGApplication app = MGApplication.QtApp() clipboard = app.clipboard() self.DealWithMimeData(clipboard.mimeData(),pasteAtCursor=True) def dropEvent(self, event): rv = self.DealWithMimeData(event.mimeData()) if not rv: event.setDropAction(QtCore.Qt.IgnoreAction) event.accept() else: event.ignore() def toggleAxes(self): state = int(self.findChild(QtGui.QAction,'show_axes').isChecked()) for widget in self.glWidgets: widget.setAxes(state) self.updateGLWindows() def toggleShowScale(self): state = int(self.findChild(QtGui.QAction,'show_scale').isChecked()) for iwidget,widget in zip(range(len(self.glWidgets)),self.glWidgets): if iwidget == 0: widget.setShowScale(state) self.updateGLWindows() def toggleFramerate(self): state = int(self.findChild(QtGui.QAction,'framerate').isChecked()) self.glWidget.show_fps = state def handleZoomSpinChanged(self,val): self.glWidget.RADIUS = val*60. self.glWidget.updateGL() self.ZoomChanged(self.glWidget) def handleZoomChanged(self): self.zoom_spin.blockSignals(True) self.zoom_spin.setValue(self.glWidget.RADIUS/60.) self.zoom_spin.blockSignals(False) def toggleZoomDisplay(self): state = int(self.findChild(QtGui.QAction,'zoom_display').isChecked()) if not hasattr(self,"zoom_spin_all"): self.zoom_spin = QtGui.QDoubleSpinBox() self.zoom_spin.setMinimum(0.01) self.zoom_spin.setMaximum(100000) self.zoom_spin.setSingleStep(0.1) self.connect(self.glWidget,QtCore.SIGNAL("ZoomChanged"),self.handleZoomChanged) self.zoom_spin.setValue(self.glWidget.RADIUS/60.) self.connect(self.zoom_spin,QtCore.SIGNAL("valueChanged(double)"),self.handleZoomSpinChanged) self.zoom_spin_all = QtGui.QWidget() layout = QtGui.QHBoxLayout() self.zoom_spin_all.setContentsMargins(0,0,0,0) layout.setContentsMargins(0,0,0,0) zoom_label = QtGui.QLabel(self.tr("Zoom:")) layout.addWidget(zoom_label) layout.addWidget(self.zoom_spin) self.zoom_spin_all.setLayout(layout) if state: self.statusBar().addPermanentWidget(self.zoom_spin_all) self.zoom_spin_all.show() else: self.statusBar().removeWidget(self.zoom_spin_all) def toggleFSAA(self): state = int(self.findChild(QtGui.QAction,'stereo_on').isChecked()) import MGGLWidget fmt = MGGLWidget.getMaxSampleBuffersFormat() fmt.setStereo(state); fmt.setSampleBuffers(int(self.findChild(QtGui.QAction,'fsaa_on').isChecked())) self.setGLWidgetFormats(fmt,stereoState=state) for dispobj in get_dispobj(): dispobj.set_redraw_text() UPDATEDISPLAY() def toggleFullscreen(self): state = int(self.findChild(QtGui.QAction,'fullscreen').isChecked()) if not state: self.setWindowState(self.windowState()&~QtCore.Qt.WindowFullScreen) self.toolbar.show() self.statusBar().show() else: self.setWindowState(self.windowState()|QtCore.Qt.WindowFullScreen) self.toolbar.hide() self.statusBar().hide() def toggleZalmanStereo(self): state = int(self.findChild(QtGui.QAction,'zalman_stereo_on').isChecked()) for widget in self.glWidgets: widget.setDoZalmanStereo(state) widget.setStereo(state) widget.updateGL() def toggleStereo(self): state = int(self.findChild(QtGui.QAction,'stereo_on').isChecked()) import MGGLWidget fmt = MGGLWidget.getMaxSampleBuffersFormat() fmt.setStereo(state); fmt.setSampleBuffers(int(self.findChild(QtGui.QAction,'fsaa_on').isChecked())) self.setGLWidgetFormats(fmt,stereoState=state) for dispobj in get_dispobj(): dispobj.set_redraw_text() UPDATEDISPLAY() def setGLWidgetFormats(self,fmt,stereoState=False,doZalmanStereo=False): import MGGLWidget newWidgets = [] i=0 positions = [] for widget in self.glWidgets: self.disconnect(widget,QtCore.SIGNAL("TransformObject"),self.MGDisplayTable.handleObjectMoving) newWidget = MGGLWidget.MGGLWidget(self,self.glWidget,format=fmt) if widget.go: newWidget.SetGO(widget.go,1) newWidget.SetOrigin(widget.rpos,1) newWidget.RADIUS = widget.RADIUS newWidget.quat = widget.quat newWidget.show_axes = widget.show_axes newWidget.extra_quat = widget.extra_quat newWidget.setExtraMatrix(widget.getExtraMatrix()) r,g,b = widget.getBackground() newWidget.setBackground(r,g,b) newWidget.setDoubleClickHandler(self.pickEventRecentre) newWidget.setLeftClickHandler(self.labelPickedObject) newWidget.setContextMenuHandler(self.contextMenuHandler) newWidget.setStereo(stereoState) newWidget.setDoZalmanStereo(doZalmanStereo) self.connect(newWidget,QtCore.SIGNAL("QuatChanged"),self.QuatChanged) self.connect(newWidget,QtCore.SIGNAL("ZoomChanged"),self.ZoomChanged) self.connect(newWidget,QtCore.SIGNAL("PositionChanged"),self.PositionChanged) self.connect(newWidget,QtCore.SIGNAL("SizeChanged"),self.SizeChanged) self.connect(newWidget,QtCore.SIGNAL("ViewChanged"),self.GLLeftMouseReleased) self.connect(newWidget,QtCore.SIGNAL("TransformObject"),self.MGDisplayTable.handleObjectMoving) self.connect(newWidget,QtCore.SIGNAL("MouseEntered"),self.showDefaultMessage) newWidgets.append(newWidget) positions.append(self.box_layout.getItemPosition(i)) newWidget.copyShaders(self.glWidgets[0]) i = i + 1 while len(self.glWidgets)>0: glwidget = self.glWidgets.pop() glwidget.updateGL() glwidget.close() glwidget.removeMouseBindings() self.box_layout.removeWidget(glwidget) """ # There is a problem here, lots of bound methods... import gc gc.collect() refs = gc.get_referrers(glwidget) for ref in refs: print ref print """ del glwidget self.glWidgets = newWidgets self.glWidget = newWidgets[0] i = 0 for widget in self.glWidgets: self.box_layout.addWidget(widget,positions[i][0],positions[i][1],positions[i][2],positions[i][3]) widget.reInitializeTextPrims() widget.rebuildAllDisplayObjects(1) widget.updateGL() self.connect(widget,QtCore.SIGNAL("TransformObject"),self.MGDisplayTable.handleObjectMoving) i = i + 1 self.applyGLLighting() def toggleFog(self): state = int(self.findChild(QtGui.QAction,'fog_on').isChecked()) for widget in self.glWidgets: widget.setFog(state) self.updateGLWindows() def toggleSlab(self): state = int(self.findChild(QtGui.QAction,'slab_on').isChecked()) for widget in self.glWidgets: widget.setSlab(state) self.updateGLWindows() def setBackgroundColour(self,mode=''): #print "setBackgroundColour mode",mode if mode == 'other': import mgWidgets self.backgroundGui = mgWidgets.mgColourBrowser(selected_colour='white') self.connect(self.backgroundGui,QtCore.SIGNAL("ColourSelected"),self.setBackgroundColour) self.backgroundGui.setAttribute(QtCore.Qt.WA_DeleteOnClose) else: rgb = MGCOLOUR().RGB255(mode) for widget in self.glWidgets: widget.setBackground(rgb[0],rgb[1],rgb[2]) for dispobj in get_dispobj(): dispobj.set_redraw_text() UPDATEDISPLAY() def setLighting(self,style): import LightingGui style = style[6:] print 'MGMainWindow.setLighting',style params = LightingGui.CUSTOM_STYLE_DEFINITIONS.get(style,{}) self.setLightParams(params) def handleWindowSize(self): window = QtGui.QDialog(self) window.setWindowTitle('Main window size') window.setAttribute(QtCore.Qt.WA_DeleteOnClose) layout = QtGui.QHBoxLayout() label = QtGui.QLabel('Window width') layout.addWidget(label) width = QtGui.QSpinBox(self) width.setRange(0,5000) width.setValue(self.glWidgets[0].size().width()) layout.addWidget(width) label = QtGui.QLabel('height') layout.addWidget(label) height = QtGui.QSpinBox(self) height.setRange(0,5000) height.setValue(self.glWidgets[0].size().height()) layout.addWidget(height) window.setLayout(layout) self.connect(height,QtCore.SIGNAL('valueChanged(int)'),self.setWindowHeight) self.connect(width,QtCore.SIGNAL('valueChanged(int)'),self.setWindowWidth) window.show() def setWindowHeight(self,height): #print "setWindowHeight",height if height >= 150: self.resize(self.width(),self.height()-self.glWidgets[0].height()+height) def setWindowWidth(self,width): #print "setWindowWidth",width if width >= 150: self.resize(self.width()-self.glWidgets[0].width()+width,self.height()) ''' def setLanguage(self, action=None): lang = action.text() translator = QtCore.QTranslator() if lang == "English": translator.load(":/pyqtmg_en") app.installTranslator(translator) print "Load English" elif lang == "Latin": translator.load(":/pyqtmg_la") app.installTranslator(translator) print "Load Latin" else: print "unknown language" ''' def checkIfZalmanStereo(self): try: import MonitorInfo mons = MonitorInfo.getMonitorNames() for m in mons: if m.find('ZM-M220') >-1: return True except: return False return False def drawMenu(self,menuName=''): # Redraw the main window menu on every 'aboutToShow # populateMenu will update checked/enabled status of action menuWidget=self.findChild(QtGui.QMenu,menuName) if not menuWidget: #print "ERROR drawing menu",menuName return menuWidget.clear() menudef = self.getGuiDef(menuName) guiUtils.populateMenu(self,menuWidget,menudef,self.getActionDef) self.toolbar.updateToolBar() def initialiseAnimation(self): # Set up one mechanism to handle animation/movies etc # Applications should use addAnimationHandler/removeAnimationHandler # to register their handler that will be called by default every 1ms self.animation_timer = QtCore.QTimer(self) self.animation_timer.setInterval(100) self.connect(self.animation_timer,QtCore.SIGNAL('timeout()'),self.handle_animation) self.animation_handlers = {} def addAnimationHandler(self,name='',handler=''): # Give a name (that can be used in error message to user) # and a handler #print 'addAnimationHandler',name self.animation_handlers[name] = handler if not self.animation_timer.isActive(): self.animation_timer.start() def removeAnimationHandler(self,name=''): #print 'removeAnimationHandler',name if self.animation_handlers.has_key(name): del self.animation_handlers[name] if not self.animation_handlers and self.animation_timer.isActive(): #print 'removeAnimationHandler stopping' self.animation_timer.stop() return 0 else: return 1 def handle_animation(self,trap_errors=0): redraw = 0 if self.animation_handlers: for name,handler in self.animation_handlers.items(): if trap_errors: try: handler() #redraw = 1 except: print "Error in animation_handler for application",name else: handler() #redraw = 1 if redraw: import rebuild rebuild.UpdateDisplay() def setAnimationInterval(self,delay): if delay>=0 and delay<= 10000 and delay != self.animation_timer.interval(): self.animation_timer.setInterval(delay) def animationInterval(self): return int(self.animation_timer.interval()) def setGLLights(self,lights): self.lights = lights self.applyGLLighting() def applyGLLighting(self): for widget in self.glWidgets: widget.setLights(self.lights) self.emit(QtCore.SIGNAL("LightingChanged")) def initialiseGLWidgets(self,rockParams={}): import MGGLWidget """ fmt = MGGLWidget.getMaxSampleBuffersFormat() self.glWidget = GLWidget(fmt=fmt,parent=self) self.glWidgets = [ self.glWidget ] """ fmt = MGGLWidget.getMaxSampleBuffersFormat() self.glWidget = MGGLWidget.MGGLWidget(format=fmt,parent=self) self.glWidgets = [ self.glWidget ] self.connect(self.glWidget,QtCore.SIGNAL("QuatChanged"),self.QuatChanged) self.connect(self.glWidget,QtCore.SIGNAL("ZoomChanged"),self.ZoomChanged) self.connect(self.glWidget,QtCore.SIGNAL("PositionChanged"),self.PositionChanged) self.connect(self.glWidget,QtCore.SIGNAL("SizeChanged"),self.SizeChanged) self.connect(self.glWidget,QtCore.SIGNAL("MouseEntered"),self.showDefaultMessage) #self.connect(self.glWidget,QtCore.SIGNAL("MousePress"),self.MousePress) self.glWidget.setMouseBindings(self.mouseBindings()) self.glWidget.setContextMenuHandler(self.contextMenuHandler) self.glWidget.setDoubleClickHandler(self.pickEventRecentre) self.glWidget.setLeftClickHandler(self.labelPickedObject) self.rockroll = 0 self.rockcounter = -1 self.rockspeed = rockParams.get('rockspeed',0.5) self.rollspeed = rockParams.get('rollspeed',0.5) self.rollorientation = rockParams.get('rollorientation','y') self.rockangle = rockParams.get('rockangle',20) self.roll_timer = QtCore.QTimer(self) self.connect(self.roll_timer,QtCore.SIGNAL('timeout()'),self.roll_handler) self.savedGLSize = None def roll_handler(self): if not self.glWidgets or len(self.glWidgets)==3: return if self.rockroll == 1: # Rolling if self.rollorientation == 'y': rotQ = pygl_coord.Quat(0,self.rollspeed,0,0) elif self.rollorientation == 'x': rotQ = pygl_coord.Quat(self.rollspeed,0,0,0) else: # Rocking nsteps=float(int(self.rockangle/self.rockspeed)) # steps/quarter cycle self.rockcounter = self.rockcounter+1 if self.rockcounter>nsteps*4: self.rockcounter=0 if self.rockcounter>=nsteps*2: speed = float(self.rockcounter-(nsteps*3))/nsteps *self.rockspeed*2 else: speed = float(nsteps-self.rockcounter)/nsteps *self.rockspeed*2 #print "rock", self.rockcounter,speed if self.rollorientation == 'y': rotQ = pygl_coord.Quat(0,speed,0,0) elif self.rollorientation == 'x': rotQ = pygl_coord.Quat(speed,0,0,0) self.glWidgets[0].quat.postMult(rotQ) self.glWidgets[0].updateGL() if len(self.glWidgets) == 2: self.glWidgets[1].quat.postMult(rotQ) self.glWidgets[1].updateGL() elif len(self.glWidgets) == 3: pass def toggleRockRoll(self,mode): ''' mode == 1 : toggle roll mode == 2: toggle rock ''' if mode == self.rockroll: # ** Ideally should put view back to original orientation # but this could get v. complicated if user is changing view self.rockroll = 0 else: self.rockroll = mode if self.rockroll: self.roll_timer.start(1) else: self.roll_timer.stop() self.rockcounter = -1 # Update the GUI self.findChild(QtGui.QAction,'roll_view').setChecked(self.rockroll==1) self.findChild(QtGui.QAction,'rock_view').setChecked(self.rockroll==2) gui = self.findChild(rockAndRollGUI) if gui: gui.setParams(rockroll=self.rockroll) def rockAndRoll(self): gui = self.findChild(rockAndRollGUI) if not gui: gui = rockAndRollGUI(self) pars = {} for key in ['rockroll','rockspeed','rollspeed','rockangle','rollorientation']: pars[key] = getattr(self,key) gui.setParams( pars ) self.connect(gui,QtCore.SIGNAL('changed'),self.handleRockAndRoll) gui.show() gui.raise_() def handleRockAndRoll(self): gui = self.findChild(rockAndRollGUI) if not gui: return params = gui.getParams() for key in ['rockroll','rockspeed','rollspeed','rockangle','rollorientation']: setattr(self,key,params.get(key)) self.findChild(QtGui.QAction,'roll_view').setChecked(self.rockroll==1) self.findChild(QtGui.QAction,'rock_view').setChecked(self.rockroll==2) if self.rockroll: self.roll_timer.start(1) else: self.roll_timer.stop() self.rockcounter = -1 def GLLeftMouseReleased(self,arg=None): if self.autoSavePosition < len(self.autoSaveView)-1: del self.autoSaveView[self.autoSavePosition+1:] self.autoSaveView.append(GLView(glWidget=self.glWidget)) self.autoSavePosition = len(self.autoSaveView)-1 self.setViewActionsEnabled() def initialiseAutoSaveView(self): self.autoSaveView = [] self.autoSavePosition = 0 self.autoSaveView.append(GLView(glWidget=self.glWidget)) self.forwardAction = guiUtils.createAction('view_forward',self) self.backAction = guiUtils.createAction('view_back',self) self.connect(self.glWidget,QtCore.SIGNAL("ViewChanged"),self.GLLeftMouseReleased) self.setViewActionsEnabled() def viewForward(self,arg=None): if self.autoSavePosition < len(self.autoSaveView)-1: self.autoSavePosition = self.autoSavePosition + 1 self.autoSaveView[self.autoSavePosition].setGLWidget(self.glWidget) self.setViewActionsEnabled() def viewBack(self,arg=None): if self.autoSavePosition > 0: self.autoSavePosition = self.autoSavePosition - 1 self.autoSaveView[self.autoSavePosition].setGLWidget(self.glWidget) self.setViewActionsEnabled() def setViewActionsEnabled(self): if len(self.autoSaveView)>0 and self.autoSavePosition < len(self.autoSaveView)-1: self.forwardAction.setEnabled(True) else: self.forwardAction.setEnabled(False) if len(self.autoSaveView)>0 and self.autoSavePosition >0: self.backAction.setEnabled(True) else: self.backAction.setEnabled(False) def restoreDisplay(self,increment): HISTORY().autoRestore(increment) # edit_list is list [ object_name, object_type, add/delete/update] #print "restoreDisplay edit_list",edit_list doSideBySide = False doThreeWayView = False if len(self.glWidgets) == 2: self.handleSideBySide() doSideBySide = True elif len(self.glWidgets) == 3: self.handleThreeWayView() doThreeWayView = True import rebuild rebuild.UpdateDisplay(auto_save=0) self.updateGLWindows() self.setDisplayActionsEnabled() self.MGDisplayTable.update() # Add the PMs for item in HISTORY().update_gui: if item[0] == 'update_PM': widget = self.findChild(QtGui.QWidget,item[1]) #print "MGMainWindow.restoreDisplay",item,widget if widget: widget.setParams(PM(item[1]).getparams()) elif item[0] == 'delete_PM': widget = self.findChild(QtGui.QWidget,item[1]) #print "MGMainWindow.restoreDisplay",item,widget if widget: widget.window().close() HISTORY().update_gui = [] if doSideBySide: self.handleSideBySide() elif doThreeWayView: self.handleThreeWayView() def viewFrom(self,view_from=''): rotate_x = 0.0 rotate_y = 0.0 rotate_z = 0.0 if view_from == 'left': rotate_y = 90.0 elif view_from == 'right': rotate_y = -90.0 elif view_from == 'top': rotate_x = 90.0 elif view_from == 'bottom': rotate_x = -90.0 elif view_from == 'back-x': rotate_x = 180.0 elif view_from == 'back-y': rotate_y = 180.0 # But this is interesting applied to 3-way view # ?? Just disable the gui # No, no, no !!!! Rotate self.glWidget and let signals do the rest. if len(self.glWidgets) == 3: return for widget in self.glWidgets: widget.setRotation ( rotate_x,rotate_y,rotate_z) self.updateGLWindows() self.GLLeftMouseReleased() def addGraphicsWindowShortcut(self): app = QtGui.QApplication.instance() if app: #print "Calling allWidgets 3" widgets = app.allWidgets() for widget in widgets: if widget != self and hasattr(widget,'isWindow') and callable(widget.isWindow) and widget.isWindow(): graphicsWindowShortcut = QtGui.QShortcut(QtGui.QKeySequence("Ctrl+G"),widget) self.connect(graphicsWindowShortcut,QtCore.SIGNAL('activated()'),self.UnClose) def closeEvent(self,event): app = QtGui.QApplication.instance() if app: #print "Calling allWidgets 4" widgets = app.allWidgets() for widget in widgets: if widget != self and hasattr(widget,'isWindow') and callable(widget.isWindow) and widget.isWindow() and hasattr(widget,'isHidden') and callable(widget.isHidden) : if not widget.isHidden(): event.ignore() self.hide() return event.accept() def UnClose(self): self.show() self.raise_() def mouseBindings(self): if not hasattr(self,'mouse_bindings'): import MouseBindings self.mouse_bindings = {} self.mouse_bindings.update(MouseBindings.DEFAULT) return self.mouse_bindings def setMouseBindings(self,params): self.mouse_bindings = {} self.mouse_bindings.update(params) #print "MGMainWindow.setMouseBindings",self.mouse_bindings for widget in self.glWidgets: widget.setMouseBindings(self.mouse_bindings) #------------------------------------------------------------------- def hideWindows(self,open=0,all_systems=0): #------------------------------------------------------------------- import MGApplication,sys if (not all_systems) and ['darwin'].count(sys.platform): return app = MGApplication.QtApp() glWidget = self.glWidget if open: if not hasattr(self,'hiddenWindows'): return # Restore windows for widget in self.hiddenWindows: widget.show() del self.hiddenWindows else: # Close all possible obscuring widgets widgets = self.findChildren(QtGui.QDialog,"") #print "screenshot",self,widgets if not hasattr(self,'hiddenWindows'): self.hiddenWindows = [] for widget in widgets: if (not [glWidget,self].count(widget)) and \ hasattr(widget,'isHidden') and callable(widget.isHidden) and \ hasattr(widget,'setVisible') and callable(widget.setVisible) and \ hasattr(widget,'isWindow') and callable(widget.isWindow) and widget.isWindow() and \ (not isinstance(widget,QtGui.QProgressDialog)): if not widget.isHidden(): widget.setVisible(False) app.sendPostedEvents() app.processEvents(QtCore.QEventLoop.AllEvents) app.flush() if not hasattr(self,'hiddenWindows'): self.hiddenWindows = [] self.hiddenWindows.append(widget) for repeat in range(0,2): app.sendPostedEvents() app.processEvents(QtCore.QEventLoop.AllEvents) app.flush() import time time.sleep(2) # Oh, dear. And we still can't be sure what window manager has done. #--------------------------------------------------------------------------- def getViewParams(self): #--------------------------------------------------------------------------- if not self.glWidget: return {} params = {} qPtr = self.glWidget.quat.Getdval() tmp = pygl_coord.doublea(1) quatp = tmp.frompointer(qPtr) params['quat']= [] for ii in range(0,4):params['quat'].append(quatp[ii]) params['pos'] = [] for ii in range(0,3): params['pos'].append(self.glWidget.rpos[ii]) params['scale'] = self.glWidget.RADIUS for item in ['fog_enabled','fog_strength','fog_near','fog_far','slab_enabled','slab_width','slab_offset','clip_cap','customClipPlanes','fog_auto','slab_auto']: params[item]=getattr(self.glWidget,item) params['transparency'] = self.glWidget.transparency() return params #--------------------------------------------------------------------------- def setViewParams(self,params={}): #--------------------------------------------------------------------------- if not self.glWidgets: return #print "MAINWINDOW setViewParams glWidgets",self.glWidgets,'params',params if params.has_key('orientation'): if type(params['orientation'])==dict and params['orientation'].has_key('molData') and params['orientation'].has_key('selection'): dataobjs = get_dataobj(object_type ='MolData',name=str(params['orientation']['molData']).replace('-','_')) if len(dataobjs)>0: dataobj = dataobjs[0] selection = params['orientation']['selection'] rv = dataobj.parse_selection(command=selection) if rv[0] == 0 and rv[1] > 0: selHnd = rv[1] pca = dataobj.molHnd.GetPrincipalComponents(selHnd) xcart = pygl_coord.Cartesian(1,0,0) minpca = pygl_coord.Cartesian(pca[1].get_x(),pca[1].get_y(),pca[1].get_z()) maxpca = pygl_coord.Cartesian(pca[0].get_x(),pca[0].get_y(),pca[0].get_z()) print "minpca"; minpca.Print(); print print "maxpca"; maxpca.Print(); print angle = math.acos(pygl_coord.Cartesian.DotProduct(maxpca,xcart))*180/math.pi print "first angle", angle, pygl_coord.Cartesian.DotProduct(maxpca,xcart) if pygl_coord.Cartesian.DotProduct(maxpca,xcart)>0: angle -= 180 if abs(angle)>1e-8: axis = pygl_coord.Cartesian.CrossProduct(maxpca,xcart) axis.normalize() quat = pygl_coord.Quat(axis.get_x(),axis.get_y(),axis.get_z(),1,angle) dvals = quat.dvals() params['quat'] = [dvals[0], dvals[1], dvals[2], dvals[3]] mat = quat.getMatrix() screeny = pygl_coord.Cartesian(0,1,0) minpca = mat*minpca angle = math.acos(pygl_coord.Cartesian.DotProduct(minpca,screeny))*180/math.pi if abs(angle)>1e-8: print "second angle", angle, pygl_coord.Cartesian.DotProduct(minpca,screeny) axis = pygl_coord.Cartesian(1,0,0) if pygl_coord.Cartesian.DotProduct(minpca,screeny)>0: angle -= 180 quat2 = pygl_coord.Quat(axis.get_x(),axis.get_y(),axis.get_z(),1,angle) quat.postMult(quat2) dvals = quat.dvals() params['quat'] = [dvals[0], dvals[1], dvals[2], dvals[3]] else: params['quat'] = [1,0,0,0] else: params['quat'] = [1,0,0,0] else: params['quat'] = [1,0,0,0] else: params['quat'] = params['orientation'] if params.has_key('RADIUS'): params['scale'] = params['RADIUS'] theSize = None if params.has_key('centre_MolData'): dataobjs = get_dataobj(object_type ='MolData',name=str(params['centre_MolData']).replace('-','_')) if len(dataobjs)>0: dataobj = dataobjs[0] if params.has_key('centre_selection'): selection = params['centre_selection'] else: selection = 'all' rv = dataobj.parse_selection(command=selection) if rv[0] == 0 and rv[1] > 0: selHnd = rv[1] rtde = dataobj.molHnd.Extent(selHnd) mine,maxe = (rtde[0],rtde[1],rtde[2]),(rtde[3],rtde[4],rtde[5]) rtde = () del rtde mide = ((mine[0]+maxe[0])/2.,(mine[1]+maxe[1])/2.,(mine[2]+maxe[2])/2.) theSize = max(abs(mine[0]-maxe[0]),abs(mine[1]-maxe[1]),abs(mine[2]-maxe[2])) if hasattr(self,"glWidget"): self.glWidget.centreOn(mide,glide=0) elif params.has_key('pos'): pass elif params.has_key('centre_xyz'): params['pos'] = params['centre_xyz'] elif params.has_key('rpos'): params['pos'] = params['rpos'] if params.has_key('quat'): qPtr = pygl_coord.doublea(4) quat = pygl_coord.Quat() for ii in range(0,4):qPtr[ii]=params['quat'][ii] quat.Setdval(qPtr) for glWidget in self.glWidgets: glWidget.setQuat(quat) for glWidget in self.glWidgets: if params.has_key('pos'): glWidget.setPosition(params['pos']) if params.has_key('zoom'): try: zoom = float(params['zoom']) if zoom>1e-6: glWidget.setZoom(1./zoom*60) except: pass if params.has_key('scale'): if type(params['scale']) == str and 'ang' in params['scale']: try: sc = params['scale'].split()[0] scf = float(sc) # 2.5 is the factor which turns angstroms into CCP4MG's bizarre arbs. glWidget.setZoom(scf*2.5) except: pass elif params['scale'] == 'auto': if theSize: # 2.5 is the factor which turns angstroms into CCP4MG's bizarre arbs. # 1.25 is a fudge factor, which gives a reasonable viewsize. glWidget.setZoom(theSize*2.5*1.25) else: glWidget.setZoom(60) elif params['scale'] == 'auto_contacts': if theSize: import symmetry dum = pygl_coord.Cartesian() point = pygl_coord.Cartesian(glWidget.rpos[0],glWidget.rpos[1],glWidget.rpos[2]) symmetry = symmetry.Symmetry(dataobj.molHnd,selHnd,point,dum,dum,dum,dum,0,0,0,0,50,1) symmSize = symmetry.ExtentSize() if symmSize > theSize: glWidget.setZoom(symmSize*2.5) else: glWidget.setZoom(theSize*2.5*2) else: glWidget.setZoom(60) elif params['scale']>1e-6: glWidget.setZoom(params['scale']) for item in ['fog_enabled','fog_strength','fog_near','fog_far','slab_enabled','slab_width','slab_offset','clip_cap','customClipPlanes','fog_auto','slab_auto']: if params.has_key(item): setattr(glWidget,item,params[item]) #--------------------------------------------------------------------------- def getLightParams(self): #--------------------------------------------------------------------------- params = {} params['nLights'] = len(self.lights) ii = -1 for lightobj in self.lights: ii = ii+1 params[ii] = {} for item in ['position','ambient','specular','diffuse','on']: params[ii][item] = getattr(lightobj,item) #print "getViewParams",params return params #--------------------------------------------------------------------------- def setLightParams(self,params): #--------------------------------------------------------------------------- """ print "Setting light params" for key,val in params.items(): print key,val """ nLights = params.get('nLights',0) #if not nLights: return import opengl,Light self.lights = [] for ii in range(nLights): lightName=getattr(opengl,"GL_LIGHT"+str(ii),'') if lightName: light = Light.Light(lightName,params[ii]['position'],params[ii]['ambient'],params[ii]['specular'],params[ii]['diffuse']) if params[ii]['on']: light.turn_on() self.lights.append(light) self.applyGLLighting() #--------------------------------------------------------------------------- def copyTutorialData(self): #--------------------------------------------------------------------------- text = utils.copyTutorialData() QtGui.QMessageBox.warning(self,'Copying tutorial data',text) #------------------------------------------------------------------- def loadPlugins(self): #------------------------------------------------------------------- import loadPlugins self.plugins = loadPlugins.loadPlugins() class MGMainWindowSimple(QtCore.QObject,MGMainWindowCore): def setDisplayActionsEnabled(self): pass def initialiseAutoSaveDisplay(self): pass #------------------------------------------------------------------- def openFile(self,file='',drawing_style='',use_current_style=0,show_wizard_choices=0,filter=''): #------------------------------------------------------------------- # This should be calling functions from appropariate data modules!! import rebuild,MGGLImage if not os.path.exists(file): return 2 ext = os.path.splitext(file)[1][1:].lower() extgz = None if ext == 'gz': ext2 = os.path.splitext(os.path.splitext(file)[0])[1] if ext2 != '': extgz = (ext2 + '.' + ext)[1:].lower() ''' dir_alias = CCP4DATABASE().aliasForDir(os.path.split(file)[0]) if dir_alias: file_list_def = [dir_alias,os.path.split(file)[1],file] else: file_list_def = ['FULLPATH',file,file] print 'openFile ccp4 alias',file,dir_alias,file_list_def ''' if ext in ['ent','brk','pdb','cif'] or extgz in ['ent.gz','brk.gz','pdb.gz','cif.gz']: if extgz: file = utils.gunzipToNamedFile(file) if (not drawing_style) and use_current_style: drawing_style = PICTUREWIZARD().default_drawing_style if not show_wizard_choices: # Test if this drawing_style absolutely requires user input (if so will return show_wizard_choices = 1) show_wizard_choices,choices = PICTUREWIZARD().read_mgpic_file_choices(drawing_style=drawing_style) #print "openFile drawing_style",show_wizard_choices,drawing_style ndispobj = len(get_dispobj()) import model rv,m = model.openpdbfile( file ) print "openpdbfile ret",rv,m if rv: print "Error opening file",file return 0 m.applyDrawingStyle(drawing_style=drawing_style) rebuild.UpdateDisplay() #print "MGMainWindow.openFile ndispobj",ndispobj if ndispobj == 0: MAINWINDOW().handleRecentre(glide=0) elif ['map','mrc'].count(ext) or ['map.gz','mrc.gz'].count(extgz): if extgz: file = utils.gunzipToNamedFile(file) import map m = map.MapData(filename=file,filetype='MAP') m.loaddata() m.create_contours() xtl = CRYSTALMANAGER().add_object() xtl.set_source(m.name) rebuild.UpdateDisplay() elif ['vector'].count(ext): # Assume it is a vector file for now import VectorsDispobj m = VectorsDispobj.openvectorfile(file) if m: rebuild.UpdateDisplay() elif MGGLImage.supportedReadFormats().count(ext) and ext != "svg": m = MGGLImage.Image(filename = str(file),parent=GL2DMANAGER()) if m.isValid: rebuild.UpdateDisplay() elif file.find('.') > -1: # Is it supported by a plugin? suffixes = getSuffixes(file) for suffix in suffixes: handler = MAINWINDOW().getFileTypeHandler(suffix) if not handler == self.defaultFileTypeHandler: break #print "openFile handler",handler return handler(file) else: # Nothing matched.. return 0 return m def deleteAllDataObj(self): dellist = [] for dataobj in get_dataobj(): if not (hasattr(dataobj,'master_application') and dataobj.master_application): dellist.append(dataobj) for dataobj in dellist: dataobj.delete() if hasattr(dataobj,"close"): dataobj.close() def deleteDataObj(self,name): target = get_dataobj(name=name) #print "deleteDataObj",name,target if target: # Are there any other objects that should be deleted # along with this one (eg Crystal gets deleted with map) dependents = target[0].getDependentsForDeletion() #print 'displayTable deleteDataObj dependents',dependents target[0].delete() if dependents: # In principle there could be a recursion here. for dep in dependents: dep_target = get_dataobj(name=dep) if dep_target: dep_target[0].delete() else: dep_target = get_dispobj(name=dep) if dep_target: dep_target.delete() def initialiseGLWidgets(self,rockParams={}): import MGGLWidget if sys.argv.count('-osmesa'): import MGGLWidgetOSMesa self.glWidget = MGGLWidgetOSMesa.MGGLWidgetOSMesa() self.glWidgets = [ self.glWidget ] return self.glWidget = MGGLWidget.MGGLWidgetSimple() self.glWidgets = [ self.glWidget ] def __init__(self, parent=None,application=None,gui_params={},stereoFormatAvailable=False): QtCore.QObject.__init__(self, parent) MGMainWindowCore.__init__(self, parent,application,gui_params,stereoFormatAvailable) self.extra_handlers = {} self.extra_filters = [] self.initialiseGLWidgets() class MGMainWindow(QtGui.QMainWindow,MGMainWindowCore): def setDisplayActionsEnabled(self): nS = len(HISTORY().autoSavedStatus) nP = HISTORY().autoSavedPosition #print "setDisplayActionsEnabled",nS,nP self.displayForwardAction.setEnabled(nS>0 and nP<(nS-1)) self.displayBackAction.setEnabled(nS>0 and nP>0) def initialiseAutoSaveDisplay(self): self.displayForwardAction = guiUtils.createAction('display_forward',self) self.displayBackAction = guiUtils.createAction('display_back',self) self.setDisplayActionsEnabled() def __init__(self, parent=None,application=None,gui_params={},stereoFormatAvailable=False,dockedDT=False,super_compact=False): QtGui.QMainWindow.__init__(self, parent) MGMainWindowCore.__init__(self, parent,application,gui_params,stereoFormatAvailable) import MGApplication MGApplication._mainWindow = self self.stereoFormatAvailable = stereoFormatAvailable #self.setDockOptions(QtGui.QMainWindow.ForceTabbedDocks) #print "MainWindow gui_params",gui_params self.recentFilesList = ['Recent files'] self.extra_handlers = {} self.directory_handlers = [] self.extra_save_handlers = {} self.extra_filters = [] #self.setAttribute(QtCore.Qt.WA_MacMetalStyle) self.application = application self.setAcceptDrops(1) #print "1"; sys.stdout.flush() icon_file=os.path.join(os.environ["CCP4MG"],"ccp4mg_icon.png") icon = QtGui.QIcon(QtGui.QPixmap(icon_file)) self.setWindowIcon(icon) import version version_string = self.tr("CCP4MG version ") + QtCore.QString(version.ccp4mg_version) self.setWindowTitle(version_string) #print "2"; sys.stdout.flush() self.box_layout = QtGui.QGridLayout() self.box_layout.setSpacing(0) self.box_layout.setContentsMargins(0,0,0,0) self.lights = [] import Light import opengl position = (0.0, 0.0, 60.0) ambient = (0.0, 0.0, 0.0) specular = (1.0, 1.0, 1.0) diffuse = (1.0, 1.0, 1.0) light0 = Light.Light(opengl.GL_LIGHT0,position,ambient,specular,diffuse) light0.turn_on() self.lights.append(light0) self.initialiseGLWidgets(rockParams=gui_params.get('rockParams',{})) null_widget = QtGui.QWidget() null_widget.setLayout(self.box_layout) self.setCentralWidget(null_widget) if sys.platform != "win32": self.box_layout.addWidget(self.glWidget,0,0) #print "2.1"; sys.stdout.flush() #init_ccp4mg_resources() #print "2.2"; sys.stdout.flush() mainLayout = self.layout() #print "3"; sys.stdout.flush() statusBar = self.statusBar() statusBar.showMessage("") self.menuDefinitions = {} self.actionDefinitions = {} self.initializeActionDefinitions() self.initializeMenuDefinitions() self.initialiseAutoSaveView() self.initialiseAutoSaveDisplay() import MGToolBar self.toolbar = MGToolBar.MGToolBar(self,title=self.tr("Toolbar"),params=gui_params.get('main_toolbar',{}),default_actions = self.getGuiDef('main_toolbar_default'),supported_actions= self.getGuiDef('main_toolbar_supported')) self.toolbar.setObjectName("Main Toolbar") self.addToolBar(self.toolbar) self.actionDefinitions['toggle_toolbar'] = dict ( text = 'Toolbar', icon = 'toolbar', shortcut = '', tip = 'Show/hide toolbar', action = self.toolbar.toggleViewAction() ) import re for item in self.getGuiDef('menus'): menudef = self.getGuiDef(item[0]) menuWidget = self.menuBar().addMenu(item[1]) menuWidget.setObjectName(item[0]) if item.count('aboutToShow'): self.drawMenu(item[0]) self.connect(menuWidget,QtCore.SIGNAL("aboutToShow()"),guiUtils.partial(self.drawMenu,item[0])) else: self.drawMenu(item[0]) import displayTable if dockedDT: self.MGDisplayTable = displayTable.MGDisplayTable(docked=True,super_compact=super_compact) self.wMGDisplayTable = displayTable.DispWindowDock(self,MGDisplayTable=self.MGDisplayTable) else: self.MGDisplayTable = displayTable.MGDisplayTable(self) self.wMGDisplayTable = displayTable.DispWindowNoDock(self,MGDisplayTable=self.MGDisplayTable) #self.wMGDisplayTable.show() self.connect(self.glWidget,QtCore.SIGNAL("TransformObject"),self.MGDisplayTable.handleObjectMoving) self.connect(self.MGDisplayTable,QtCore.SIGNAL("DisplayTableChanged"),self.glWidget.calculateShadowExtents) self.connect(self.MGDisplayTable,QtCore.SIGNAL("visibilityChanged"),self.glWidget.calculateShadowExtents) # Initialise wPreferences - but don't draw until required self.wPreferences = None self.addGraphicsWindowShortcut() self.menuDefinitions["Windows"].append("unclose") self.initialiseAnimation() import annotationGui self.autoAnnotate = annotationGui.autoAnnotate() doneLighting = False if sys.platform == "win32": self.glWidget.makeCurrent() # Is this generally safe? if opengl.glGetString(opengl.GL_VENDOR).strip().find('Intel')>-1 \ and opengl.glGetString(opengl.GL_RENDERER).strip().find('Intel Cantiga')>-1 \ and opengl.glGetString(opengl.GL_VERSION).strip().find('2.0.0')>-1: # We have a strange driver which needs to do lighting now or it crashes later. self.applyGLLighting() doneLighting = True import JobControl self.jobControl = JobControl.JobControl(self) if sys.platform == "win32": self.box_layout.addWidget(self.glWidget,0,0) """ if not doneLighting: self.applyGLLighting() """ self.applyStereoPrefs() self.setupRecentList() self.newRestore = True def setUpAskPrevStatus(self): def restorePreviousStatus(): import traceback import rebuild utils.printOutput( "Restoring program status..") try: status = HISTORY().restore_program_status(restore_past_or_prev=True) if not sys.argv.count('-quit'): DISPLAYTABLE().loadAllDataObj() if status: utils.printOutput( "...DONE status: "+str(status)) else: utils.printOutput( "...DONE") except: exc_type, exc_value,exc_tb = sys.exc_info()[:3] sys.stderr.write(str(exc_type)+'\n') sys.stderr.write(str(exc_value)+'\n') traceback.print_tb(exc_tb) rebuild.UpdateDisplay() DISPLAYTABLE().update(all=1) # Stops a wierd bug whereby first name label is blank. if HISTORY().command_line_status: status = HISTORY().restore_program_status(restore_past_or_prev=False) if self.newRestore and not HISTORY().command_line_status and not HISTORY().command_line_picture: status = HISTORY().restore_program_status(restore_past_or_prev=False) try: if HISTORY().check_data_valid_last_program_status(): self.glWidget.hide() self.restoreWidget = QtGui.QWidget() restoreLayout = QtGui.QGridLayout() label = QtGui.QLabel("No data files loaded.
Please use File menu to load data
or button below to restore previous program status.
") restoreLayout.addWidget(label,1,1) label.setAlignment(QtCore.Qt.AlignCenter); restoreButton = QtGui.QToolButton() restoreButton.setText("Restore previous status") restoreIcon = os.path.join(os.environ["CCP4MG"],'qticons','restore.svg') restoreButton.setIcon(QtGui.QIcon(restoreIcon)) restoreButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon); restoreButton.setIconSize(QtCore.QSize(75, 75)) restoreButton.clicked.connect(self.restoreWidget.hide) restoreButton.clicked.connect(self.repaint) restoreButton.clicked.connect(self.showMainDisplay) restoreButton.clicked.connect(restorePreviousStatus) restoreLayout.addWidget(restoreButton,2,1) restoreLayout.itemAtPosition(2,1).setAlignment(QtCore.Qt.AlignCenter) spaceTop = QtGui.QSpacerItem(100,100, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) restoreLayout.addItem(spaceTop,0,0) spaceBot = QtGui.QSpacerItem(100,100, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) restoreLayout.addItem(spaceBot,4,2) self.restoreWidget.setLayout(restoreLayout) self.box_layout.addWidget(self.restoreWidget,1,0) try: filename = os.path.join (utils.get_CCP4MG(),'status','last_exit_status.pkl') if os.path.exists(filename): last_status = HISTORY().load_pickle_file(filename=filename) haveData = False for mode in last_status['Data_list']: if hasattr(last_status[mode],"object_type") and (last_status[mode].object_type == "MolData" or last_status[mode].object_type == "MapData"): haveData = True break for p in last_status["plugins"]: if p == "GeometricObjects": if hasattr(last_status["plugins"]["GeometricObjects"],"has_key") and last_status["plugins"]["GeometricObjects"].has_key("objects"): if len(last_status["plugins"]["GeometricObjects"]["objects"])>0: haveData = True break if p == "SequenceViewer": if hasattr(last_status["plugins"]["SequenceViewer"],"has_key") and last_status["plugins"]["SequenceViewer"].has_key("alignment"): if len(last_status["plugins"]["SequenceViewer"]["alignment"])>0: for seq in last_status["plugins"]["SequenceViewer"]["alignment"]: if hasattr(seq,"seq") and hasattr(seq,"name"): haveData = True break if last_status and hasattr(last_status,"has_key") and last_status.has_key("Legends&Images"): for o in last_status["Legends&Images"].objinsts: if hasattr(o,"params"): if o.params.has_key("filename") or o.params.has_key("selection"): haveData = True break if last_status and hasattr(last_status,"has_key"): for k,v in last_status.items(): if hasattr(v,"object_type") and v.object_type == "VectorsData": haveData = True break if haveData: historyWidget = QtGui.QWidget() historyLayout = QtGui.QGridLayout() historyWidget.setLayout(historyLayout) historyTitle = QtGui.QLabel("Previous status contains:") historyLayout.addWidget(historyTitle,0,0,1,2) idata = 1 for mode in last_status['Data_list']: if last_status.has_key(mode): if hasattr(last_status[mode],"object_type") and (last_status[mode].object_type == "MolData" or last_status[mode].object_type == "MapData"): typeLabel = QtGui.QLabel() if last_status[mode].object_type == "MapData": typeLabel.setText("Map") elif last_status[mode].object_type == "MolData": typeLabel.setText("Model") nameLabel = QtGui.QLabel(last_status[mode].get_filename()[2]) historyLayout.addWidget(typeLabel,idata,0) historyLayout.addWidget(nameLabel,idata,1) idata += 1 if last_status and hasattr(last_status,"has_key") and last_status.has_key("plugins"): for p in last_status["plugins"]: if p == "GeometricObjects": if hasattr(last_status["plugins"]["GeometricObjects"],"has_key") and last_status["plugins"]["GeometricObjects"].has_key("objects"): if len(last_status["plugins"]["GeometricObjects"]["objects"])>0: typeLabel = QtGui.QLabel() typeLabel.setText("Geometric Objects") historyLayout.addWidget(typeLabel,idata,0) nameLabel = QtGui.QLabel("") historyLayout.addWidget(nameLabel,idata,1) idata += 1 if p == "SequenceViewer": if hasattr(last_status["plugins"]["SequenceViewer"],"has_key") and last_status["plugins"]["SequenceViewer"].has_key("alignment"): if len(last_status["plugins"]["SequenceViewer"]["alignment"])>0: for seq in last_status["plugins"]["SequenceViewer"]["alignment"]: if hasattr(seq,"seq") and hasattr(seq,"name"): typeLabel = QtGui.QLabel() typeLabel.setText("Sequence") historyLayout.addWidget(typeLabel,idata,0) nameLabel = QtGui.QLabel(seq.name) historyLayout.addWidget(nameLabel,idata,1) idata += 1 if last_status and hasattr(last_status,"has_key") and last_status.has_key("Legends&Images"): for o in last_status["Legends&Images"].objinsts: if hasattr(o,"params"): if o.params.has_key("filename"): print o.params["filename"] typeLabel = QtGui.QLabel() typeLabel.setText("Image") nameLabel = QtGui.QLabel(o.params["filename"][2]) historyLayout.addWidget(typeLabel,idata,0) historyLayout.addWidget(nameLabel,idata,1) idata += 1 elif o.params.has_key("selection"): print o.params["selection"] typeLabel = QtGui.QLabel() typeLabel.setText("Legend") nameLabel = QtGui.QLabel() nameLabel.setMaximumWidth(250) doc = QtGui.QTextDocument() doc.setHtml(o.params["selection"]) nameLabel.setText(doc.toPlainText()) historyLayout.addWidget(typeLabel,idata,0) historyLayout.addWidget(nameLabel,idata,1) idata += 1 if last_status and hasattr(last_status,"has_key"): for k,v in last_status.items(): if hasattr(v,"object_type") and v.object_type == "VectorsData": typeLabel = QtGui.QLabel() typeLabel.setText("Vectors") nameLabel = QtGui.QLabel(v.filename[2]) historyLayout.addWidget(typeLabel,idata,0) historyLayout.addWidget(nameLabel,idata,1) idata += 1 restoreLayout.addWidget(historyWidget,3,1) except: print "Failed listing old status files" exc_type, exc_value,exc_tb = sys.exc_info()[:3] sys.stderr.write(str(exc_type)+'\n') sys.stderr.write(str(exc_value)+'\n') sys.stderr.write(str(exc_tb.tb_lineno)+'\n') except: print "Failed checking old status" exc_type, exc_value,exc_tb = sys.exc_info()[:3] sys.stderr.write(str(exc_type)+'\n') sys.stderr.write(str(exc_value)+'\n') self.okToSave = False else: self.okToSave = True def showMainDisplay(self): self.glWidget.show() self.glWidget.updateGL() if(hasattr(self,"restoreWidget")): self.restoreWidget.hide() self.okToSave = True QtGui.QApplication.instance().processEvents() #------------------------------------------------------------------- #------------------------------------------------------------------- #------------------------------------------------------------------- class guiOpen(QtGui.QDialog): #------------------------------------------------------------------- #------------------------------------------------------------------- #------------------------------------------------------------------- def addFilters(self,filters): self.filedialog.addFilters(filters) def addFilter(self,filter): self.filedialog.addFilter(filter) def filters(self): return self.filedialog.filters(filters) def setNameFilters(self,filters): self.filedialog.setNameFilters(filters) def __init__(self,parent=None): QtGui.QDialog.__init__(self,parent) self.setObjectName('guiOpen') #print 'guiOpen.__init__' self.setWindowTitle(self.tr("Open file(s)")) layout = QtGui.QVBoxLayout() wiz_layout = QtGui.QHBoxLayout() import pictureWizardGui self.drawingStyle = pictureWizardGui.drawingStyleGui(self) wiz_layout.addWidget(self.drawingStyle) wiz_group = QtGui.QGroupBox('Picture wizard',self) wiz_group_layout = QtGui.QVBoxLayout() widget = QtGui.QRadioButton('Automatic picture setup',self) wiz_group_layout.addWidget(widget) self.show_wizard_choices = QtGui.QRadioButton('Open picture wizard choices',self) wiz_group_layout.addWidget(self.show_wizard_choices) wiz_group.setLayout(wiz_group_layout) self.show_wizard_choices.setChecked(PICTUREWIZARD().show_wizard_choices) widget.setChecked(1-PICTUREWIZARD().show_wizard_choices) self.connect(self.show_wizard_choices,QtCore.SIGNAL('toggled(bool)'),self.update_show_wizard_choices) wiz_layout.addWidget(wiz_group) wiz_layout.addStretch(5) layout.addLayout(wiz_layout) filedialog = mgWidgets.MGFileDialog(self,editAlias=0) layout.addWidget(filedialog) self.filedialog = filedialog.getFileDialog() self.filedialog.setFileMode(self.filedialog.ExistingFiles) self.connect(self.filedialog, QtCore.SIGNAL('filesSelected (const QStringList&)'), self.handleSelection) filter_list = ["Model coordinate files (*.pdb *.cif *.ent *.brk *.pdb.gz *.cif.gz *.ent.gz *.brk.gz)", "CCP4 map files (*.map *.map.gz)", "MRC map files (*.mrc *.mrc.gz)", "CCP4 experimental data files (*.mtz)", "Zipped Presentations (*.ccp4mg_presentation.zip)", "Status files (*.mgpic.py *.pkl)", "CCP4mg vector file (*.vector)" ] # Add the image formats import platform platter = platform.platform() # For some reason, the correct code fails on (some) 64-bit Ubuntus. formats = QtGui.QImageWriter.supportedImageFormats() """ if False and ('Ubuntu' in platter or 'debian-squeeze-sid' in platter) and 'x86_64' in platter: formats = QtGui.QImageWriter.supportedImageFormats() else: import image_info formats = image_info.image_info.GetSupportedWriteFormats() """ image_exts = '(' for format in formats: if str(format).upper()!=str(format): image_exts = image_exts + '*.'+format+' ' image_exts= image_exts[0:-1] + ')' filter_list.append('Image files '+image_exts) self.filedialog.setNameFilters(filter_list) self.setLayout(layout) children = self.filedialog.findChildren(QtGui.QPushButton,"") for child in children: if child.text() == self.tr("&Open"): child.clicked.disconnect() child.clicked.connect(self.openClicked) self.tree = self.filedialog.findChild(QtGui.QTreeView) def openClicked(self): inds = self.tree.selectionModel().selectedIndexes() files = [] for i in inds: if i.column() == 0: files.append(os.path.join(unicode(self.filedialog.directory().absolutePath().toUtf8(),'utf-8'),unicode(i.data().toString()))) self.filedialog.emit(QtCore.SIGNAL('filesSelected (const QStringList&)'),QtCore.QStringList(files)) self.done(0) #------------------------------------------------------------------- def handleSelection(self,selectedFiles): #------------------------------------------------------------------- filter = str(self.filedialog.selectedFilter()) for item in selectedFiles: f = str(item.toUtf8()) self.emit(QtCore.SIGNAL('filesSelected'),f,self.drawingStyle.getStyle(),0,self.show_wizard_choices.isChecked(),filter) self.close() #------------------------------------------------------------------- def update_show_wizard_choices(self,state): #------------------------------------------------------------------- #print 'update_show_wizard_choices',state PICTUREWIZARD().show_wizard_choices= int(state) #------------------------------------------------------------------- def getFileName(self): #------------------------------------------------------------------- if len(self.filedialog.selectedFiles()) > 0: if not os.path.isdir(self.filedialog.selectedFiles()[0]): return self.filedialog.selectedFiles()[0] return None #------------------------------------------------------------------- def useWizard(self): #------------------------------------------------------------------- return self.wizard_radio.isChecked() #------------------------------------------------------------------- #------------------------------------------------------------------- #------------------------------------------------------------------- class guiOpenPresentation( QtGui.QDialog): #------------------------------------------------------------------- #------------------------------------------------------------------- #------------------------------------------------------------------- def __init__(self,parent=None,mode='open',application='presentation'): super(guiOpenPresentation,self).__init__(parent) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setObjectName('dialogPresentation') self.setApp(application) layout = QtGui.QVBoxLayout() filedialog = mgWidgets.MGFileDialog(self) layout.addWidget(filedialog) self.filedialog = filedialog.getFileDialog() if mode == 'zip': filter_list = [self.tr("Zipped presentation directory (*.ccp4mg_presentation.zip)")] else: filter_list = [self.tr("Presentation directory (*.ccp4mg_presentation)")] if mode == 'open': self.filedialog.setFileMode(self.filedialog.DirectoryOnly) else: self.filedialog.setAcceptMode(QtGui.QFileDialog.AcceptSave) #self.filedialog.setDirectory(proj_dir) children = self.filedialog.findChildren(QtGui.QPushButton,"") for child in children: if child.text() == self.tr("&Save"): child.setText(self.tr("&Create")) self.connect(child, QtCore.SIGNAL('pressed()'),self.saveFile) self.filedialog.setNameFilters(filter_list) #self.setSidebar() self.setLayout(layout) self.connect(self.filedialog, QtCore.SIGNAL('filesSelected (const QStringList&)'), self.handleSelection) #------------------------------------------------------------------- def setApp(self,application): #------------------------------------------------------------------- self.setWindowTitle("Open "+application+" directory") self.application = application #------------------------------------------------------------------- def getFileName(self): #------------------------------------------------------------------- if len(self.filedialog.selectedFiles()) > 0: if not os.path.isdir(self.filedialog.selectedFiles()[0]): return self.filedialog.selectedFiles()[0] return None #------------------------------------------------------------------- def handleSelection(self,selectedFiles): #------------------------------------------------------------------- #print "handleSelection drawing_style",self.drawingStyle.getStyle() #filter = str(self.filedialog.selectedFilter()) #print "openGui.handleSelection filter",filter for item in selectedFiles: f = str(item.toUtf8()) self.emit(QtCore.SIGNAL('filesSelected'),f,self.application) self.close() #------------------------------------------------------------------- def saveFile(self): #------------------------------------------------------------------- file = self.filedialog.selectedFiles() if not file: return self.parent().openPresentation(str(file[0].toUtf8()),mode='new',application=self.application) #------------------------------------------------------------------- #------------------------------------------------------------------- #------------------------------------------------------------------- class guiCentreOn(QtGui.QDialog): #------------------------------------------------------------------- #------------------------------------------------------------------- #------------------------------------------------------------------- def __init__(self,parent=None): #print "guiCentreOn",parent QtGui.QDialog.__init__(self,parent) self.setWindowTitle(self.tr("Find, centre on..")) master_layout = QtGui.QVBoxLayout() layout = QtGui.QHBoxLayout() seleLabel = QtGui.QLabel(self.tr('Find'),self) import mgWidgets self.selectionCombo = mgWidgets.mgSelectionCombo(self,multi=1) self.connect(self.selectionCombo, QtCore.SIGNAL('changed'),self.handleCentreOnButton) for item in [seleLabel, self.selectionCombo]: layout.addWidget(item) master_layout.addLayout(layout) layout = QtGui.QHBoxLayout() self.createDispobj = QtGui.QCheckBox('Show atoms if not visible',self) self.createDispobj.setChecked(1) layout.addWidget(self.createDispobj) master_layout.addLayout(layout) buttonBox = QtGui.QDialogButtonBox(self) buttonBox.setOrientation(QtCore.Qt.Horizontal) button = buttonBox.addButton('Centre on',QtGui.QDialogButtonBox.ApplyRole) self.connect(button, QtCore.SIGNAL('clicked()'), self.handleCentreOnButton) master_layout.addWidget(buttonBox) self.setLayout(master_layout) self.show() #------------------------------------------------------------------- def handleCentreOnButton(self): #------------------------------------------------------------------- molobj = self.selectionCombo.getCurrentDataObj() selected = self.selectionCombo.text() #print "selected",molobj,selected ret = molobj.parse_selection(command=selected) if ret[0]!=0: return self.parent().centreOn(molHnd=molobj.molHnd,selHnd=ret[1]) # label first atom in selection atm_ptr=molobj.interpretAtomID(mol=molobj,selHnd=ret[1]) if atm_ptr: dispobj = molobj.findDispobjContainingAtom(atm_ptr=atm_ptr) #print 'handleCentreOnButton',atm_ptr,dispobj if not dispobj and self.createDispobj.isChecked(): dispobj = molobj.add_object(visible=1,object_type='MolDisp',selparams={'select':'cid','cid':selected},styleparams={'style_mode':'CYLINDERS'}) DISPLAYTABLE().addDispObj(molobj.name,object_type='MolDisp',name=dispobj.name) import rebuild rebuild.UpdateDisplay() if dispobj: obj = DISPLAYTABLE().getDispObj(dispobj.name) if obj: obj.set_visibility(1) rv = PICKLABEL().addLabel(atm_ptr=atm_ptr,dispobj=dispobj) if rv: import rebuild rebuild.UpdateDisplay() molobj.molHnd.DeleteSelection(ret[1]) #------------------------------------------------------------------- #------------------------------------------------------------------- #------------------------------------------------------------------- class rockAndRollGUI(QtGui.QDialog): #------------------------------------------------------------------- #------------------------------------------------------------------- #------------------------------------------------------------------- #------------------------------------------------------------------- def __init__(self,parent): #------------------------------------------------------------------- QtGui.QDialog.__init__(self,parent) self.setWindowTitle('Rock and roll') self.setObjectName('rock_n_roll') layout = QtGui.QVBoxLayout() group = QtGui.QButtonGroup(self) group.setObjectName('rockroll') line_layout = QtGui.QHBoxLayout() widget = QtGui.QRadioButton('Roll',self) widget.setObjectName('roll_on') group.addButton(widget) self.connect(widget,QtCore.SIGNAL('clicked()'),self.apply) line_layout.addWidget(widget) widget = QtGui.QLabel('speed') line_layout.addWidget(widget) widget = mgWidgets.mgSlider(QtCore.Qt.Horizontal,self) widget.setRange(-5.0,5.0) widget.setObjectName('rollspeed') self.connect(widget,QtCore.SIGNAL("valueChanged(double)"),self.apply) line_layout.addWidget(widget) line_layout.addStretch() layout.addLayout(line_layout) line_layout = QtGui.QHBoxLayout() widget = QtGui.QRadioButton('Rock',self) widget.setObjectName('rock_on') group.addButton(widget) self.connect(widget,QtCore.SIGNAL('clicked()'),self.apply) line_layout.addStretch() line_layout.addWidget(widget) widget = QtGui.QLabel('speed') line_layout.addWidget(widget) widget = mgWidgets.mgSlider(QtCore.Qt.Horizontal,self) widget.setRange(0.1,5.0) widget.setObjectName('rockspeed') self.connect(widget,QtCore.SIGNAL("valueChanged(double)"),self.apply) line_layout.addWidget(widget) widget = QtGui.QLabel('angle') widget.setToolTip('Maximum rock angle') line_layout.addWidget(widget) widget = mgWidgets.mgSlider(QtCore.Qt.Horizontal,self) widget.setRange(0,90) widget.setObjectName('rockangle') self.connect(widget,QtCore.SIGNAL("valueChanged(double)"),self.apply) line_layout.addWidget(widget) layout.addLayout(line_layout) widget = QtGui.QRadioButton('No motion',self) widget.setObjectName('norockroll') self.connect(widget,QtCore.SIGNAL('clicked()'),self.apply) layout.addWidget(widget) group.addButton(widget) line_layout = QtGui.QHBoxLayout() group = QtGui.QButtonGroup(self) widget = QtGui.QLabel('Rock and roll axis:') line_layout.addWidget(widget) widget = QtGui.QRadioButton('vertical',self) widget.setObjectName('roll_vertical') group.addButton(widget) self.connect(widget,QtCore.SIGNAL('clicked()'),self.apply) line_layout.addWidget(widget) widget = QtGui.QRadioButton('horizontal',self) widget.setObjectName('roll_horizontal') group.addButton(widget) self.connect(widget,QtCore.SIGNAL('clicked()'),self.apply) line_layout.addWidget(widget) line_layout.addStretch() layout.addLayout(line_layout) self.setLayout(layout) #------------------------------------------------------------------- def apply(self): #------------------------------------------------------------------- self.emit(QtCore.SIGNAL("changed")) #------------------------------------------------------------------- def setParams(self,params={},**kw): #------------------------------------------------------------------- params.update(kw) rr = params.get('rockroll',-1) if rr==0: self.findChild(QtGui.QRadioButton,'norockroll').setChecked(1) elif rr==1: self.findChild(QtGui.QRadioButton,'roll_on').setChecked(1) elif rr==2: self.findChild(QtGui.QRadioButton,'rock_on').setChecked(1) for key in ['rockspeed','rollspeed','rockangle']: if params.has_key(key): self.findChild(mgWidgets.mgSlider,key).setValue(params[key]) orientation = params.get('rollorientation','') if orientation: self.findChild(QtGui.QRadioButton,'roll_horizontal').setChecked(orientation=='x') self.findChild(QtGui.QRadioButton,'roll_vertical').setChecked(orientation=='y') #------------------------------------------------------------------- def getParams(self): #------------------------------------------------------------------- pars = {} mode = self.findChild(QtGui.QButtonGroup,'rockroll').checkedButton().objectName() if mode == 'rock_on': imode = 2 elif mode == 'roll_on': imode = 1 else: imode =0 pars['rockroll'] = imode if self.findChild(QtGui.QRadioButton,'roll_horizontal').isChecked(): pars['rollorientation']='x' else: pars['rollorientation']='y' for key in ['rollspeed','rockspeed','rockangle']: pars[key] = self.findChild(mgWidgets.mgSlider,key).value() #print "rockAndRollGUI pars",pars return pars