ViewerFramework-1.5.7~rc1+cvs.20140424/0000755000175000017500000000000012326214476017024 5ustar moellermoellerViewerFramework-1.5.7~rc1+cvs.20140424/MANIFEST.in0000644000175000017500000000204511565032646020564 0ustar moellermoeller# This list all other files to be included in the distribution # which are not python modules # include, exclude.... which are not described in the setup.py. include MANIFEST.in # list of the non python module to be included in the distribution include ViewerFramework/Tkinter.defaults include ViewerFramework/RELNOTES include ViewerFramework/Icons/16x16/* include ViewerFramework/Icons/16x16/CVS/* include ViewerFramework/Icons/22x22/* include ViewerFramework/Icons/22x22/CVS/* include ViewerFramework/Icons/32x32/* include ViewerFramework/Icons/32x32/CVS/* include ViewerFramework/Icons/48x48/* include ViewerFramework/Icons/48x48/CVS/* include ViewerFramework/Icons/64x64/* include ViewerFramework/Icons/64x64/CVS/* include ViewerFramework/Icons/Grid3D/* include ViewerFramework/Icons/Grid3D/CVS/* include ViewerFramework/Icons/* # include all the CVS directories include ViewerFramework/CVS/* include ViewerFramework/Icons/CVS/* include ViewerFramework/ColorMaps/CVS/* include ViewerFramework/Tests/CVS/* include version.py include ViewerFramework/LICENSE ViewerFramework-1.5.7~rc1+cvs.20140424/setup.py0000644000175000017500000000717010405334232020530 0ustar moellermoeller#!/usr/bin/env python from distutils.core import setup from distutils.command.sdist import sdist from distutils.command.install_data import install_data from glob import glob import os pack_name = 'ViewerFramework' ######################################################################## # Had to overwrite the prunrefile_list method of sdist to not # remove automatically the RCS/CVS directory from the distribution. ######################################################################## class modified_sdist(sdist): def prune_file_list(self): """ Prune off branches that might slip into the file list as created by 'read_template()', but really don't belong there: * the build tree (typically 'build') * the release tree itself (only an issue if we ran 'sdist previously with --keep-temp, or it aborted) """ build = self.get_finalized_command('build') base_dir = self.distribution.get_fullname() self.filelist.exclude_pattern(None, prefix=build.build_base) self.filelist.exclude_pattern(None, prefix=base_dir) class modified_install_data(install_data): def run(self): install_cmd = self.get_finalized_command('install') self.install_dir = getattr(install_cmd, 'install_lib') return install_data.run(self) ######################################################################## # list of the python packages to be included in this distribution. # sdist doesn't go recursively into subpackages so they need to be # explicitaly listed. # From these packages only the python modules will be taken packages = ['ViewerFramework', 'ViewerFramework', 'ViewerFramework.Icons', 'ViewerFramework.Tests', 'ViewerFramework.ColorMaps'] # list of the files that are not python packages but are included in the # distribution and need to be installed at the proper place by distutils. # The list in MANIFEST.in lists is needed for including those files in # the distribution, data_files in setup.py is needed to install them # at the right place. data_files = [] ## for dir in ['ViewerFramework', ## 'ViewerFramework/Icons', ## 'ViewerFramework/CVS', ## 'ViewerFramework/Icons/CVS', ## 'ViewerFramework/ColorMaps/CVS', ## 'ViewerFramework/Tests/CVS', ## ]: ## files = [] ## for f in glob(os.path.join(dir, '*')): ## if f[-3:] != '.py' and f[-4:-1] != '.py' and os.path.isfile(f): ## files.append(f) ## data_files.append((dir, files)) def getDataFiles(file_list, directory, names): fs = [] for name in names: ext = os.path.splitext(name)[1] #print directory, name, ext, len(ext) if ext !=".py" and ext !=".pyc": fullname = os.path.join(directory,name) if not os.path.isdir(fullname): fs.append(fullname) if len(fs): file_list.append((directory, fs)) os.path.walk(pack_name, getDataFiles, data_files) # description of what is going to be included in the distribution and # installed. from version import VERSION setup (name = pack_name, version = VERSION, description = "A template to write visualization application", author = 'Molecular Graphics Laboratory', author_email = 'sanner@scripps.edu', download_url = 'http://www.scripps.edu/~sanner/software/packager.html', url = 'http://www.scripps.edu/~sanner/software/index.html', packages = packages, data_files = data_files, cmdclass = {'sdist': modified_sdist, 'install_data': modified_install_data }, ) ViewerFramework-1.5.7~rc1+cvs.20140424/version.py0000644000175000017500000000002011475262417021055 0ustar moellermoellerVERSION="1.5.6" ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/0000755000175000017500000000000012326214513022133 5ustar moellermoellerViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/.packager.py0000644000175000017500000000564607770421005024356 0ustar moellermoeller# The .packager.py is used by the DistTools package to get the files to be # included in a distribution. def getFiles(root, what = 'all', plat=None): """ files <- getFiles(root, what='all', plat=None) files -- list of the files to be included in the download arguments: root -- path to the package. This is used by glob to get all the python modules. what -- string that can be 'all' and 'supported' to specified what files to include in the distribution. By default 'all' the files are added. plat -- platform ('linux2', 'irix646', 'sunos5' etc...) """ from glob import glob import os # 1- Specify the list of all the Python module allPyModule = ["*.py", 'ColorMaps/*.py' ] # 2- Specify the list of the non supported Python module. These files # will be removed from the release of the supported python modules. pynotsupported = [] # 3- Specify the documentation files and directories to be included in the # release docFiles = []#["doc/"] # 4-Specify the extraFiles to be included in the release. extraFiles = ["CVS", 'ColorMaps/CVS', "Icons/","Icons/CVS", "Tkinter.defaults", "RELNOTES"] # 5-Specify the testFiles to be included in the release. testFiles = ["Tests/*.py", "Tests/Data", "Tests/CVS", "Tests/Data/CVS"] ######################################################### ## Where things are done for you . ######################################################### # if some files need to be removed, we need the exact list of the pymodule. if len(pynotsupported): # store the path of the current directory olddir = os.getcwd() os.chdir(root) files = [] # we use glob to get the exact list of files. for p in allPyModule: files = files + glob(p) allPyModule = files files = [] # need to get the list of the files ... no wild card possible. for p in pynotsupported: files = files + glob(p) pynotsupported = files os.chdir(olddir) # Creation of the proper list of files depending on the value of what if what == 'supported' and len(pynotsupported): # need to remove the non supported python files from all the python # files # These are the keys used for to make the releases... supportedFiles = filter(lambda x, l = pynotsupported: not x in l, allPyModule) return supportedFiles + testFiles + extraFiles elif what == 'all' or ( what == 'supported' and not len(pynotsupported)): # Other wise just add the documentation, test and extra files to all # the python modules. allFiles= allPyModule + docFiles + testFiles + extraFiles return allFiles elif what == 'documentation': return docFiles else: return [] ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/LICENSE0000644000175000017500000000435211033233260023136 0ustar moellermoellerThis software is copyrighted by Michel F. Sanner (sanner@scripps.edu) The following terms apply to all files associated with the software unless explicitly disclaimed in individual files. MGLTOOLS SOFTWARE LICENSE AGREEMENT. 1. Grant Of Limited License; Software Use Restrictions. The programs received by you will be used only for NON COMMERCIAL purposes. This license is issued to you as an individual. For COMMERCIAL use done with the software please contact Michel F. Sanner for details about commercial usage license agreements. For any question regarding license agreements, please contact Michel Sanner: TSRI, Molecular Biology Department, TCP 26, 10550 North Torrey Pines Road, La Jolla, CA 92037 sanner@scripps.edu tel (858) 784-7742 fax (858) 784-2341 2. COMMERCIAL USAGE is defined as revenues generating activities. These include using this software for consulting activities and selling applications built on top of, or using this software. Scientific research in an academic environment and teaching are considered NON COMMERCIAL. 3. Copying Restrictions. You will not sell or otherwise distribute commercially these programs or derivatives to any other party, whether with or without consideration. 4. Ownership of Software. You will not obtain, and will not attempt to obtain copyright coverage thereon without the express purpose written consent of The Scripps Research Institute and Dr. Sanner. 5. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 6. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/RELNOTES0000644000175000017500000004752111102417175023322 0ustar moellermoellerViewerFramework RELEASE NOTES ============================= ----------------------------- Release 1.5.4 (November 2008) ----------------------------- VF.py -added RemoveCommand -modified to run without GUI -added save perspective feature -added more help for savePerspective -renamed transformationLogging to Transformation Logging -replaced Sharp Color Boundaries for MSMS -moved grid3d menu to the right -moved preferences into a pickled file. See the new mgltutil.preferences for details. - moved AddAtomsEvent, DeleteAtomsEvent and EditAtomsEvent from ViewerFramework.VF to Pmv.moleculerViewer - fixed imports for these classes in all files - added AddObjectEvent and DeleteObjectEvent to ViewerFramework.VF -sessions are now not dependant on any other session anymore -moved grid3Commands from Pmv to ViewerFramework VFCommand.py - replaced NumberOfUndo with Number of Undo - correct bug when saving twice the current session VFGUI.py - finalized contour settings gui - corrected bug on exit of pmv - added log string for undocking the camera basicCommand.py -added RemoveCommand - made it work with --noGUI - replaced NumberOfUndo with Number of Undo - correct bug when saving twice the current session - moved saving the font to the doit function of ChangeFont - shows confirmation message after command is loaded. customizationCommands.py - moved if item[0] == 'warningMsgFormat' before trapException - moved preferences into a pickled file. See the new mgltutil.preferences for details. - modified guiCallback for SetUserPreference to expand its width and increased hull_height to 800. TODO: could not figure out how to make the height expand on resizing as well. - when adding user preference last used value is used instead of setting the preference over the previously set preference customizeVFGUICommands.py -moved saving fonts to preferences -modified default fonts dejaVuCommands.py - replaced centerScene with Center Scene -corrected assert for color background - fixed bug #999 grid3DCommands.py - added ensureFontCase beecause on windows, font starts with lowercase - added isocontour.setVerboseLevel(0) - fixed bug #1002 - fixed bug #989 - addGrid problem - fixed path problem for orthoslice - added a link to tutorial - added addGridCommand - moved grid3Commands from Pmv to ViewerFramework ----------------------------- Releases 1.4.6 - 1.5.2 (July 2008) ----------------------------- -- moved from Numeric to numpy LICENSE -added LICENSE file VF.py -trying to fix a problem when .mgltools directory (resource folder) can not be created - added ScenarioCommand class to start scenario application from Viewer Framework. - arranged "Browse Commands" -added code that creates scenario director (in 'try: except:'). VFCommand.py - now vision instance is Pmv.vision VFGUI.py -added an argument : cnf = {addScenarioButton: False} to pass to the constructor of the Viewer class, so that the Scenario button is not added to the Viewer's GUI when the Viewer is created by VF (this button will be added th the main button bar of the Molecular Viewer bu scenarioCommand) -added a check for self.VIEWER.autoRedraw before calls to update() (self.ROOT.update()) - now the active scope is the main scope - replaced self.ROOT.winfo_width() with self.ROOT.winfo_reqwidth() in naturalSize to fix the problem on win32 basicCommand.py - added ScenarioCommand class to start scenario application from Viewer Framework. - renamed findAllPackages into findAllPackageNames - arranged "Browse Commands" customizationCommands.py - created read source or molecule command dejaVuCommands.py - correct bug with cartoon rendering helpCommands.py - renamed findAllPackageNames into findAllPackages and repaired full search Icons/64x64/dashboard.png - make sure png are binaries ----------------------------- Release 1.4.5 (May 2007) ----------------------------- New features and bug fixes: VF.py - fixed a bug in Startup Directory preference. - fixed changed userpref.set("Startup Directory"... - added self.GUI.VIEWER.ReallyRedraw() before self.GUI.dockCamera() bug #775 VFGUI.py - when docking, we set only the parameters that are changed - introduced spinOptionMenu -added a check for 'drop_target_register' attribute of self.ROOT (if hasDnD2 is True) - correct handling of the trackball when rebuild/dock/float camera basicCommand.py - added self.vf.recentFiles.add(filename, 'source') to SaveSessionCommand dejaVuCommands.py - corrected background color - added **kw to signature of setbackgroundcolor.dismiss_cb so that it can be called from a setupUndoBefore method - removed self.vf.loadCommand('interactiveCommands', 'setICOM', 'Pmv',) Release 1.4.4 (December 2006) ----------------------------- New features and bug fixes: VF.py - added vi.stopAutoRedraw() and vi.startAutoRedraw() calls to dispatchEvent method. VFCommand.py - replaced == types.StringType with in types.StringTypes to support unicode - fixed the links in the info button to point to appropriate section in http://mgltools.scripps.edu/downloads/tars/releases/doc/ - added posx=None, posy=None arguments to showForm() to allow placing a form on the screen - fixed bug #734 incomplete log string - moved self.addCameraCallback('', self.updateInfoBar) from Pmv interactiveCommands to VFGUI - fixed dockaCamera and floatCamera to restore these bindings - enhenced description of command.onCmdRun hook - moved ICONPATH and ICONSIZES to VFCommands.py - moved Pmv icons from ViewerFramework VFGUI.py - renamed reCamera in rebuiltCamera - camera size doesn't change anymore when camera is rebuilt - repaired stereo_buffers (was not working with the new docking) - put back code to restore all '' and '' event handlers when camea is docked or floated - fixed dockaCamera and floatCamera to restore these bindings basicCommand.py -added code in save session command when npr outline mode is on graph controlpoints and sensitivity are saved customizationCommands.py - replaced read molecule with read python or session script dejaVuCommands.py - repaired stereo_buffers (was not working with the new docking) - added tooltip for setCartoonOutlines iCommand - added setNPRparams command - now, after a cancel the tile rendering gui make sure the height and width values respect the aspect ratio of the actual opengl context. - removed undocking when tile rendering and extent opengl cam to the max for tile rendering. Release 1.4.3 (September 2006) ------------------------------ New features: - reduced self.ROOT.minsize to width = 200, height = 200 - added Viewer.suspenRedraw - added self.vf.GUI.ROOT.config(cursor='watch') in BrowseCommandsCommand.guiCallback - now we print the exception in SourceCommand - the stereo icon now has a triangle to indicate the menu Release 1.4.2 (May 2006) ------------------------ Changes and bug fixes: -self.ROOT.bind('t', self.VIEWER.toggleTransformRootOnly) -replaced SimpleDialog with tkMessageBox.askokcanel -replaced addToolBar with configureToolBar -added self.VIEWER.GUI.top.master.protocol("WM_DELETE_WINDOW",self.showHideDejaVuGUI) -removed placeholder in the InfoBar customizationCommands.py - added 'mode':'both'to global dict used to execute Python script so that sesions can be restored customizeVFGUICommands.py -fixed a bug in undo command for MESSAGE_BOX -replaced buttonRoot with Toolbar -Moved menues from File --> customize into File --> Preferences dejaVuCommands.py -repaired tile-renderer -added red-green stereo color separation -introduced STEREO COLOR SEPARATION - made the colormapGUI not an instance variable inthe showCMGUI command but rather have doit return the instance - changed colorByProperties and colorByexpression get the returned value - removed global variable newvar from SaveImage command. and added new transparentbg keyword argument to the command -fixed the problem in SetCameraSize when MESSAGE_BOX is not packed Release 1.4.1(March 2006) _____________________________________________________________________________ What's new since rel 1.3alpha2: -------------------------------- -In VF,getOnAddObjectCmd method added, made sure the geometry name is unique in self.geoms and in parent.children.Renamed createGeom method of GeomContainer to addGeom and changed it signature to remove the first argument (geomName). Updated the files in Pmv and AutoDockTools to call addGeom(geom, cmd). Added a trapExceptions attribute to ViewerFramework constructor. Defaults to True (i.e. commands run in a a try and exceptions are displayed). Should be set to False when running tests that assert that an exception is raised. -In VFCommand,createGeom method of GeomContainer is renamed to addGeom and changed it signature to remove the first argument (geomName). Updated the files in Pmv and AutoDockTools to call addGeom(geom, cmd).Added virtual updateGeom(self, event, geomList) for updating geometries belonging to a command upon ModificationEvents. -In VFGUI,belowCamera method is added to place the menu window under the camera when the camera is floating.Added naturalSize method to VFGUI.Made VFGUI to resize the Pmv main window to the right initial size.Made self.vwrCanvasFloating Toplevel transient for VFGUI.ROOT so that the camera iconizes along with the molecular viewer.Camera and Viewer x buttons when clicked prompts whether to quit or not. -In basicCommand,added check button,scrolledtextbox in browseCommands widget to display documentation depending up on selection(command or module or pacakge) -In dejaVuCommands: *constraint widget is added to render large image to comstraint aspect ratio of camera; *added Viewer.stopTileRendering() method; *added cite button to saveImage widget and to select transparent back ground; *added class "ColorGeomsByName" which allows the user to choose a color for geometries selected by name via regular expressions. However, did not add this command to the commandList at the end of the module so it is not automatically loaded. -In helpCommands, show documentationCommand now shows command and its documentation only. -In customizationCommands, changed SaveSessionCommand to call vi.getViewerStateDefinitionCode and vi.getObjectsStateDefinitionCode directly instead of calling vi.Exit.logScene. Now vi.Exit calls saveSession. Bug Fixes: --------- -VF: *added passing parent geoemetry as arguement. *modified tryto to raise idlelib shell on exceptions and removed check for trapExceptions *added newlines in if else one liners *made width and height default values None in VF.getUserInput *moved updateCommand from specific command to the bacse class *deleted self.geomUpdateFuncs from GeomContainer. This attribute was used previously to store a function to be called to update a given geometry. *removed line that decremented self.commandNestingLevel in except clause in tryto. This was causing failing tests to hang because the commandLock was never released. *added self.cmdUpdatesGeom = {} attribute to geom container to store what command updates what geometry. *modified createGeom(self, geomName, geom, func) to createGeom(self, geomName, geom, cmd=None). Rather than passign a function to update the geoemtry we now pass the command creating the geometry. If changes occured cmd.updateGeom will be called. *added transformedCoordinatesWithInstances(self, hits) method to compute transformed coordinates for pick.hits. Used in dejavuCommands CenterSceneOnVertices. *Load automatically the showCitation command *removed trapExceptions user preference -VFCommand: *reorganized and updated the documentation. Description of a command and its methods is now under the command class -VFGUI: *made VFGUI.getGeom() return a list of 4 int instead of 4 strings *replaced ScrolledText by Pmw.ScrolledText in class msg_box *removed body frame in class msg_box *changed self.ROOT.geometry('%sx%s+%s+%s' to self.ROOT.geometry('%dx%d+%d+%d' *call vf.naturalSize after changing font size *made height of msg_box 10 *Restoring the callbacks associated to the KeyPress and KeyRelease event when docking and floating the camera. These callbacks were lost *Restored the Modifier/ICOM which was lost when added the dock/float camera. *Save the fog state to restaure it along with the camera state when docking/floating the camera. The Depthcueing is not lost any longer when docking the camera.... *Fixed Message box to expand with the menus. -basicCommand: *loadmodule and loadcommand are modified such that they show the modules as browseCommands(using FindModulesInPackage instead of cmdlib and modlib).Modified BrowseCommands such that documentation will be displayed *added a comment about instance matrices that need to be considered *added traceback.print_exc() *Fixed the browseCommands by adding a optional argument event=None to the displayCmds_cb and displayMods_cb callback functions. When clicking on "Enter" an exception was raised. *Fixed the doit of browseCommands when a command is not found it doesn't crash any longer but loads the other commands. -customizationCommands: *added deprecation warning in setUserPeref command for trapExceptions -customizeVFGUICommands: *fixed bug in changFont, naturalSize is actualyl in vf.GUI not vf *call vf.naturalSize after changing font size *added naturalSize method to VFGUI -dejaVuCommands: *added VFGUI.isCameraFloating() method *renamed Viewer.enableTileRendering Viewer.startTileRendering tile rendering now switched to not autoRedraw mode *Fixed RenderLargeImageCommand and made sure we use square tiles, undock and redock the camera if it was docked *replaced ScrolledText by Pmw.ScrolledText in class msg_box *removed body frame in class msg_box *renamed DejaVu menu 3D Graphics *fixed CenterSceneOnVertices to work with instances *added some comments *Changed some code in relation to the position of the camera. *Changed self.ROOT.geometry('%sx%s+%s+%s' to self.ROOT.geometry('%dx%d+%d+%d'). *added a button cite in the widget *moved saveImage command from Pmv.fileCommands and added a check button for Tranparent background -helpCommands: *fixed Load Commands to widget to expand properly *modified helpCommand to show onlyloaded commands and their documentation -serverCommands.py: *StartWebControlServer command imported Pmv and did nothing with it but creating a bad dependency on Pmv, removedit and replaces Pmv in documentation by ViewerFramework -test_VF: *added test for new constructor option: trapExceptions. fixed bugs in old tests. *Added a function to test the restoration of the state when docking/floating the cameras. _____________________________________________________________________________ Release rel 1.3alpha2 (10/20/2004) _____________________________________________________________________________ What's new since rel 1.2beta1: -------------------------------- - The camera can now either be docked or floating. In the latter the camera is separated from the menu bar. - The loadCommands and loadModule commands are not logged as browseCommands. These commands will disappear in the release 1.3 - A SearchCommand has been implemented and can be found under the Help menu. This commands allows the user to type a string which will be matched against either the name of the commands, the name of the modules, the documentation string or everything. - The former documentationCommands module is now helpCommands module. - Renamed ViPEr Vision. - Implemented a new API between Pmv and Vision (formally ViPEr) - added new attribute self.visionAPI to /ViewerFramework/VF.py - New commands in the dejavuCommands module: RenderLargeImages command allows the user to save an image bigger than the screen SetCameraSize command allows the user to modify the size, and the offset of the camera. - New serverCommands module implementing a set of commands to start and connect to a server. This will allow to start MGLTools applications from a web page. - Add to the inputforms a HELP button which will display the documentation page of the command. - The Warning message pop up now display the name of the command creating the message. - Added a new optional argument verbose (False)to the MoleculeViewer, ViewerFramework and ViewerFrameworkGUI to suppress DejaVu.Viewer's print statments. - Added a new button to the info bar to open the DejaVu GUI. This button is located to the right of the Information Box. - The VFGUI object has: - two new attributes selfscreenWidth and self.screenHeight - a new Geometry(width, height, xoffset=None, yoffset=None) method which configures the DejaVu camera to have the given height and width. The given xoffset and yoffset specify the upper left corner of the GUI. It returns the width and height of camera. Bug Fixes since rel 1.2beta1: -------------------------------- - Fixed the ShowHideGUISection commands. Now the gui section can be hidden and shown and they are repacked in the right order. - The quit_cb of the ExitCommands now calls the Exit method of the viewer which destroys the Camera properly. - Fixed numerous bugs in picker.py - Fixed the busy Icons problem by: Implementing a new SetIdleLight method in VFGUI which : - set the previousState - change the busyIcon to the given state - set the currentState to the new state. Adding a new flag suspendIdleLight when turn on True the state of the busyIcon cannot be modified. - The askFileOpen and asfFileSave method now return relative path These methods also have a new argument relative=True that can be used to specify if the path should be relative or not. - modified constructor of ViewerFramework to overwrite DopIck method for all cameras Release rel 1.2beta1 (12/15/2003) _____________________________________________________________________________ What's new since rel 1.2alpha (09/18/2003): - VF and VFCommand: worked on sourceCommand and undoCommand to use the right local and global IT IS NOW REQUIRED TO USE self. to refere to the molecule viewer's attributes in scripts. - VF: added progress bar to status bar - VF: Added the new browseCommands to the viewer under the "File" menu - VFCommand: A command now stores the last used values of the optional arguments of the doit into a dictionary called self.lastUsedValues. This dictionary is created and initialized by introspection in the constructor. It is then updated each time the command is called in the doitWrapper. This dictionary is used rather than the default value by the picking command for example. This dictionary never contains neither the negate nor the only args. - basicCommands: Implemented a new command browseCommands to load dynamically module or command in the viewer. This command will search your path for packages, subpackages and python modules containing the 'initModule' which describes a module implementing commands. This command will replace the loadModule and loadCommand in the next release. Replace in your script: self.loadCommand("displayCommands", ['displayLines', 'displayCPK'], "Pmv") by self.browseCommands("displayCommands", commands=['displayLines', 'displayCPK'], package="Pmv") and self.loadModule('displayCommands', 'Pmv') by self.browseCommands("diplayCommands", package="Pmv") look at the _pmvrc as well for more examples. Bug Fixes since rel 1.2alpha (09/18/2003): - VF: fixed GeomContainer.delete to only remove the 'master' geometry of the molecule in the Viewer's TreeWidget - VFGUI: removed X Y W and H entries from InfoBar becaues the callback updating them was creating all the beeping - basicCommands: Fixed the logScene methods to log the transformation of the objects properly. - customizationCommands: Fixed the undo of the BindAction - dejaVuCommands: Fixed the signature of the __call__ to match the signature of the colorMapEditor in the colorMapEditor Changes since rel 1.2alpha (09/18/2003): Known Issues: Backwards INCOMPATIBLE Changes since rel 1.2alpha (09/18/2003): ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Tkinter.defaults0000644000175000017500000000037311165235752025317 0ustar moellermoeller#*font: Arial 14 #*background: #FF0000 #*foreground: #FF0000 #*highlightForeground: #00FF00 #*highlightBackground: #0000FF #*activeForeground: #00FFFF #*activeBackground: #FF00FF #*selectColor: #FF00FF *font: LKLUG 10 #*font: "Letter Gothic" 14 bold ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/VF.py0000644000175000017500000020015112223370105023013 0ustar moellermoeller############################################################################# # # Author: Michel F. SANNER # # Copyright: M. Sanner TSRI 2000 # # revision: Guillaume Vareille # ######################################################################### # # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/VF.py,v 1.218 2013/10/03 22:31:33 annao Exp $ # # $Id: VF.py,v 1.218 2013/10/03 22:31:33 annao Exp $ # """defines base classe ViewerFramework The ViewerFramework class can be subclassed to create applications that use a DejaVu Camera object to display 3D geometries. In the following we'll call Viewer a class derived from ViewerFramework. The design features of the viewer framework include: - extensibility: new commands can be written by subclassing the VFCommand base class. - dynamically configurable: commands (or set of commands called modules) can be loaded dynamically from libraries. - Commands loaded into an application can create their own GUI elements (menus, cascading menus, buttons, sliders, etc...). The viewer framework provides support for the creation of such GUI elements. - Commands can be invoked either through the GUI or throught the Python Shell. - Macros provide a lightweight mechanism to add simple commands. In fact any Python function can be added as a Macro - Support for logging of commands: this allows to record and play back a session. - documentation: the module and command documentation is provided in the source code. This documentation can be extracted using existing tools and made available in various formats including HTML and man pages. The document ation is also accessible through the application's Help command which uses Python's introspection capabilities to retrieve the documentation. A ViewerFramework always has at least one menu bar called "menuRoot" and at least one buttonbar called "Toolbar". The geometried displayed in a Viewer can be stored in objects derived from the base class GeometryContainer. This container holds a dictionnary of geometries where the keys are the geometry's name and the values instances of DejaVu Geometries. Commands: Commands for an application derived from ViewerFramework can be developped by sub-classing the VFCommand base class (see VFCommand overview).The class VFCommandGUI allows to define GUI to be associated with a command. Command can be added dynamically to an application using the AddCommand command of the ViewerFramework. example: # derive a new command class ExitCommand(Command): doit(self): import sys sys.exit() # get a CommandGUI object g = CommandGUI() # add information to create a pull-down menu in a menu bar called # 'MoVi' under a menu-button called 'File' with a menu Command called # 'Exit'. We also specify that we want a separator to appear above # this entry in the menu g.addMenuCommand('MoVi', 'File', 'Exit', separatorAbove=1) # add an instance of an ExitCommand with the alias 'myExit' to a viewer # v. This will automatically add the menu bar, the menu button # (if necessary) the menu entry and bind the default callback function v.addCommand( ExitCommand(), 'myExit', g ) The command is immediately operational and can be invoked through the pull down menu OR using the Python shell: v.myExit() CommandGUI objects allow to specify what type of GUI a command should have. It is possible to create pull-down menu entries, buttons of different kinds etc.. Modules: A bunch of related commands can be groupped into a module. A module is a .py file that defines a number of commands and provides a functions called initModule(viewer) used to register the module with an instance of a viewer. When a module is added to a viewer, the .py file is imported and the initModule function is executed. Usually this functions instanciates a number of command objects and their CommandGUI objects and adds them to the viewer. """ import os, string, warnings import traceback, sys, glob, time class VFEvent: """Base class for ViewerFramework events. """ def __init__(self, arg=None, objects=[], *args, **kw): """ """ self.arg = arg self.objects = objects self.args = args self.kw = kw if len(args): self.args = args if len(kw): for k,v in kw.items(): setattr(self, k, v) class AddObjectEvent(VFEvent): pass class DeleteObjectEvent(VFEvent): pass class LogEvent(VFEvent): """created each time a log string is written to the log""" def __init__(self, logstr): """ """ self.logstr = logstr class ModificationEvent: def __init__(self, action, arg=None, objects=[]): """ """ self.action = action self.arg = arg self.objects = objects class GeomContainer: """Class to hold geometries to be shown in a viewer. This class provides a dictionnary called geoms in which the name of a DejaVu geometry is the key to access that particular geometry object Geometries can be added using the addGeometry method. """ def __init__(self, viewer=None): """constructor of the geometry container""" ## Dictionary of geometries used to display atoms from that molecule ## using sticks, balls, CPK spheres etc ... self.geoms = {} self.VIEWER = viewer # DejaVu Viewer object self.masterGeom = None ## Dictionary linking geom names to cmds which updates texture coords ## for the current set of coordinates self.texCoordsLookup = {} self.updateTexCoords = {} def delete(self): """Function to remove self.geoms['master'] and self.geoms['selectionSpheres'] from the viewer when deleted""" # switch the object and descendant to protected=False for c in self.geoms['master'].AllObjects(): c.protected = False if self.VIEWER: self.VIEWER.RemoveObject(self.geoms['master']) #for item in self.geoms.values(): # item.delete() # if item.children!=[]: # self.VIEWER.RemoveObject(item) def addGeom(self, geom, parent=None, redo=False): """ This method should be called to add a molecule-specific geometry. geom -- DejaVu Geom instance parent -- parent geometry, if not specified we use self.masterGeom """ if parent is None: parent = self.masterGeom # we need to make sure the geometry name is unique in self.geoms # and in parent.children nameUsed=False geomName = geom.name for object in parent.children: if object.name==geomName: nameUsed=True break if nameUsed or self.geoms.has_key(geomName): newName = geomName+str(len(self.geoms)) geom.name = newName warnings.warn("renaming geometry %s to %s"%(geomName, newName))#, stacklevel=14) self.geoms[geomName]=geom # add the geometry to the viewer. At this point the name should be # unique in both the parent geoemtry and the geomContainer.geoms dict if self.VIEWER: self.VIEWER.AddObject( geom, parent=parent, redo=redo) else: parent.children.append(geom) geom.parent = parent geom.fullName = parent.fullName+'|'+geom.name #from DejaVu.Labels import Labels from DejaVu.Spheres import Spheres ## from ViewerFramework.gui import InputFormDescr from mglutil.gui.InputForm.Tk.gui import InputFormDescr from mglutil.util.callback import CallBackFunction from mglutil.util.packageFilePath import findResourceFile, getResourceFolderWithVersion try: from ViewerFramework.VFGUI import ViewerFrameworkGUI except: pass from ViewerFramework.VFCommand import Command,CommandGUI,InteractiveCmdCaller # Import basic commands. from ViewerFramework.basicCommand import loadCommandCommand, loadMacroCommand from ViewerFramework.basicCommand import ShellCommand, ShellCommandGUI, ExitCommand from ViewerFramework.basicCommand import loadModuleCommand from ViewerFramework.basicCommand import BrowseCommandsCommand, RemoveCommand from ViewerFramework.basicCommand import SaveSessionCommand, SaveSessionCommandGUI from ViewerFramework.helpCommands import helpCommand try: from comm import Comm except: pass from DejaVu import Viewer from DejaVu.Camera import Camera import types, Tkinter import thread import os, sys, traceback import tkMessageBox from mglutil.preferences import UserPreference class ViewerFramework: """ Base class for applications providing a 3D geometry Viewer based on a DejaVu Camera object along with support for adding GUI and commands dynamically. """ def freeze(self): self.__frozen = True def unfreeze(self): self.__frozen = False def frozen(self): return self.__frozen == True def __init__(self, title='ViewerFrameWork', logMode='no', libraries=[], gui=1, resourceFile = '_vfrc', viewerClass=Viewer, master=None, guiVisible=1, withShell=1, verbose=True, trapExceptions=True): """ Construct an instance of a ViewerFramework object with: - an instance of a VFGUI that provides support for adding to the GUI of the application - a dictionnary of commands - a list of commands that create geometry - a list of objects to be displayed - a dictionary of colorMaps * logMode can be: 'no': for no loging of commands at all 'overwrite': the log files overwrite the one from the previous session 'unique': the log file name include the date and time * libraries is a list of names of Python package that provide a cmdlib.py and modlib.py - trapExceptions should be set to False when creating a ViewerFramework for testing, such that exception are seen by the testing framework """ self.__frozen = False self.hasGui = gui self.embeded=False self.cmdHistory = [] # history of command [(cmd, args, kw)] global __debug__ self.withShell = withShell self.trapExceptions = trapExceptions #self.__debug__ = 0 # create a socket communication object try: self.socketComm = Comm() self.webControl = Comm() self.cmdQueue = None # queue of command comming from server except: self.socketComm = None self.webControl = None self.timeUsedForLastCmd = 0. # -1 when command fails assert logMode in ['no', 'overwrite', 'unique'] self.resourceFile = resourceFile self.commands = {} # dictionnary of command added to a Viewer self.userpref = UserPreference() #self.removableCommands = UserPreference(os.path.dirname(self.resourceFile), 'commands') self.userpref.add('Sharp Color Boundaries for MSMS', 'sharp', ('sharp', 'blur'), doc="""Specifies color boundaries for msms surface [sharp or blur] (will not modify already displayed msms surfaces, only new surfaces will be affected)""", category="DejaVu") #Warning: changing the cursor tends to make the window flash.""") # Interface to Visual Programming Environment, if available self.visionAPI = None if self.hasGui : try: # does this package exists? from Vision.API import VisionInterface # create empty object. Note that this will be filled with life # when the visionCommand is executed self.visionAPI = VisionInterface() except: pass self.objects = [] # list of objects self.colorMaps = {} # available colorMaps self.colorMapCt = 0 # used to make sure names are unique self.undoCmdStack = [] # list of strings used to undo # lock needs to be acquired before object can be added self.objectsLock = thread.allocate_lock() # lock needs to be acquired before topcommands can be run self.commandsLock = thread.allocate_lock() # nexted commands counter self.commandNestingLevel = 0 # place holder for a list of command that can be carried out each time # an object is added to the application # every entry is a tuple (function, args_tuple, kw_dict) self.onAddObjectCmds = [] # list of commands that have an onRemoveMol self.cmdsWithOnAddObj = [] # list of commands that have an onAddMol self.cmdsWithOnRemoveObj = [] # dict cmd:[cm1, cmd2, ... cmdn]. When cmd runs the onCmdRun method # of all cmds in the list will be called with the arguments passed # to cmd self.cmdsWithOnRun = {} # list of commands that have an onExit self.cmdsWithOnExit = [] self.firstPerspectiveSet = True self.logMode = logMode self.libraries = libraries + ['ViewerFramework'] self.topNegateCmds = [] # used in Command.doitWrapper() to accumulate negation commands # for sub commands of a top command # you cannot create a GUI and have it visible. if not self.hasGui: self.guiVisible=0 else: self.guiVisible=guiVisible self.master=master if gui: self.GUI = ViewerFrameworkGUI(self, title=title, viewerClass=viewerClass, root=master, withShell=withShell, verbose=verbose) self.GUI.VIEWER.suspendRedraw = True self.viewSelectionIcon = 'cross' # or 'spheres' or 'labels' self.userpref.add('Show Progress Bar', 'hide', ['show','hide'], doc = """When set to 'show' the progress bar is displayed. When set to 'hide', the progress bar widget is widthdrawn, but can be redisplayed by choosing 'show' again.""", category='Viewer', callbackFunc=[self.GUI.showHideProgressBar_CB], ) if gui: cbList = [self.GUI.logUserPref_cb,] else: cbList = [] #if gui: # self.guiSupport = __import__( "DejaVu.ViewerFramework.gui", globals(), # locals(), ['gui']) if gui and self.guiVisible==0: # if gui == 1 but self.guiVisible == 0: the gui is created but # withdrawn immediatly self.GUI.ROOT.withdraw() if self.withShell: # Uses the pyshell as the interpreter when the VFGUI is hidden. self.GUI.pyshell.top.deiconify() self.viewSelectionIcon = 'cross' # or 'spheres' or 'labels' self.userpref.add( 'Transformation Logging', 'no', validValues = ['no', 'continuous', 'final'], callbackFunc = cbList, doc="""Define when transformation get logged.\n'no' : never; 'continuous': after every transformation; 'final': when the Exit command is called""") self.userpref.add( 'Visual Picking Feedback', 1, [0, 1], category="DejaVu", callbackFunc = [self.SetVisualPickingFeedBack,], doc="""When set to 1 a sphere is drawn at picked vertex""") self.userpref.add( 'Fill Selection Box', 1, [0,1], category="DejaVu", callbackFunc = [self.fillSelectionBoxPref_cb], doc="""Set this option to 1 to have the program draw a solid selection box after 'fillSelectionBoxDelay' miliseconds without a motion""") self.userpref.add( 'Fill Selection Box Delay', 200, category="DejaVu", validateFunc = self.fillDelayValidate, callbackFunc = [self.fillSelectionBoxDelayPref_cb], doc="""Delay in miliseconds after which the selection box turns solid if the 'fillSelectionBox' is set. Valide values are >0 and <10000""") self.userpref.add( 'Warning Message Format', 'pop-up', ['pop-up', 'printed'], callbackFunc = [self.setWarningMsgFormat], category="Viewer", doc="""Set format for warning messages. valid values are 'pop-up' and 'printed'""") self._cwd = os.getcwd() self.userpref.add( 'Startup Directory', self._cwd, validateFunc = self.startupDirValidate, callbackFunc = [self.startupDirPref_cb], doc="""Startup Directory uses os.chdir to change the startup directory. Startup Directory is set to current working directory by default.""") rcFolder = getResourceFolderWithVersion() self.rcFolder = rcFolder self.userpref.add( 'Log Mode', 'no', ['no', 'overwrite', 'unique'], callbackFunc = [self.setLogMode], category="Viewer", doc="""Set the log mode which can be one of the following: no - do not log the commands. overwrite - stores the log in mvAll.log.py. unique - stores the log in mvAll_$time.log.py. log.py files are stored in resource folder located under ~/.mgltools/$Version """) self.userpref.add( 'Command History Depth', 500, validateFunc=self.commmandHistoryValidate, #callbackFunc = [] doc="Set Command Hsistory Depth - number of commands kept in the command history list and displayed in the MESSAGE BOX") if self.hasGui: # add an interactive command caller self.ICmdCaller = InteractiveCmdCaller( self ) # remove DejaVu's default picking behavior vi = self.GUI.VIEWER vi.RemovePickingCallback(vi.unsolicitedPick) # overwrite the Camera's DoPick method to set the proper pickLevel # based on the interactive command that will be called for the # current modifier configuration for c in vi.cameras: c.DoPick = self.DoPick self.addBasicCommands() if self.hasGui: from mglutil.util.recentFiles import RecentFiles fileMenu = self.GUI.menuBars['menuRoot'].menubuttons['File'].menu rcFile = rcFolder if rcFile: rcFile += os.sep + 'Pmv' + os.sep + "recent.pkl" self.recentFiles = RecentFiles( self, fileMenu, filePath=rcFile, menuLabel='Recent Files', index=2) self.logMode = 'no' self.GUI.dockCamera() self.logMode = logMode # load out default interactive command which prints out object names self.ICmdCaller.setCommands( self.printGeometryName ) self.ICmdCaller.go() if gui: self.userpref.add( 'Icon Size', 'medium', ['very small', 'small', 'medium', 'large', 'very large'], callbackFunc = [self.SetIconSize,], category="Viewer", doc="""Sets the size of icons for the Toolbar.""") self.userpref.add( 'Save Perspective on Exit', 'yes', validValues = ['yes', 'no'], doc="""Saves GUI perspective on Exit. The following features are saved: GUI geometry, and whether camera is docked or not. """) self.GUI.VIEWER.suspendRedraw = False self.GUI.VIEWER.currentCamera.height = 600 # dictionary of event:[functions]. functions will be called by # self.dispatchEvent self.eventListeners = {} self.userpref.saveDefaults() self.userpref.loadSettings() if self.userpref.has_key('Save Perspective on Exit') and self.userpref['Save Perspective on Exit']['value'] == 'yes': self.restorePerspective() #self.GUI.VIEWER.ReallyRedraw() def registerListener(self, event, function): """registers a function to be called for a given event. event has to be a class subclassing VFEvent """ assert issubclass(event, VFEvent) assert callable(function) if not self.eventListeners.has_key(event): self.eventListeners[event] = [function] else: if function in self.eventListeners[event]: warnings.warn('function %s already registered for event %s'%( function,event)) else: self.eventListeners[event].append(function) def dispatchEvent(self, event): """call all registered listeners for this event type """ assert isinstance(event, VFEvent) if self.eventListeners.has_key(event.__class__): if self.hasGui: vi=self.GUI.VIEWER autoRedraw = vi.autoRedraw vi.stopAutoRedraw() for func in self.eventListeners[event.__class__]: func(event) if autoRedraw: vi.startAutoRedraw() else: for func in self.eventListeners[event.__class__]: func(event) def DoPick(self, x, y, x1=None, y1=None, type=None, event=None): vi = self.GUI.VIEWER def getType(vf, mod): cmd = vf.ICmdCaller.commands.value[mod] if cmd: vf.ICmdCaller.currentModifier = mod vf.ICmdCaller.getObjects = cmd.getObjects return cmd.pickLevel else: return None if vi.isShift(): type = getType(self, 'Shift_L') elif vi.isControl(): type = getType(self, 'Control_L') elif vi.isAlt(): type = getType(self, 'Alt_L') else: type = getType(self, None) if type: return Camera.DoPick(vi.currentCamera, x, y, x1, y1, type, event) else: from DejaVu.Camera import PickObject return PickObject('pick', self.GUI.VIEWER.currentCamera) def clients_cb(self, client, data): """get called every time a client sends a message""" import sys sys.stdout.write('%s sent %s\n'%(client,data) ) #exec(data) def embedInto(self, hostApp,debug=0): """ function to define an hostapplication, take the string name of the application """ if self.hasGui: raise RuntiomeError("VF with GUI cannot be embedded") from ViewerFramework.hostApp import HostApp self.hostApp = HostApp(self, hostApp, debug=debug) self.embeded=True def sendViewerState (self, event=None): # get call every so often when this PMV is a server state1 = self.GUI.VIEWER.getViewerStateDefinitionCode( 'self.GUI.VIEWER', withMode=False) state2 = self.GUI.VIEWER.getObjectsStateDefinitionCode( 'self.GUI.VIEWER', withMode=False) if self.socketComm is not None and len(self.socketComm.clients): cmdString = """""" for line in state1: cmdString += line for line in state2: cmdString += line self.socketComm.sendToClients(cmdString) self.GUI.ROOT.after(500, self.sendViewerState) def runServerCommands (self, event=None): # get call every so often when this PMV is a client of a server if not self.cmdQueue.empty(): cmd = self.cmdQueue.get(False) # do not block if queue empty if cmd: #if pmv is embedded without a gui in a third application #have to parse the command and remove all cmd that imply GUI if self.embedded : #mesg=cmd[1] mesg=self.hostApp.driver.parsePmvStates(cmd[1]) exec(mesg, {'self':self}) #print 'client executing', cmd else : exec(cmd[1]) if not self.embeded : #if embeded the runServerCommand is handle by a thread define by the hosAppli class self.GUI.ROOT.after(10, self.runServerCommands) def updateIMD(self): """get called every time the server we are connected to sends a message what about more than one molecule attached currently under develppment """ from Pmv.moleculeViewer import EditAtomsEvent #print "pause",self.imd.pause if self.imd.mindy: #print "ok update mindy" self.imd.updateMindy() if self.hasGui and self.imd.gui : self.GUI.VIEWER.OneRedraw() self.GUI.VIEWER.update() self.GUI.ROOT.after(1, self.updateIMD) else : if not self.imd.pause: self.imd.lock.acquire() coord = self.imd.imd_coords[:] self.imd.lock.release() if coord != None: #how many mol if type(self.imd.mol) is list : b=0 for i,m in enumerate(self.imd.mol) : n1 = len(m.allAtoms.coords) self.imd.mol.allAtoms.updateCoords(coord[b:n1], self.imd.slot[i]) b=n1 else : self.imd.mol.allAtoms.updateCoords(coord, self.imd.slot) import DejaVu if DejaVu.enableVBO : if type(self.imd.mol) is list : b=0 for i,m in enumerate(self.imd.mol) : N=len(m.geomContainer.geoms['cpk'].vertexSet.vertices.array) m.geomContainer.geoms['cpk'].vertexSet.vertices.array[:]=coord[b:N] b=N else : N=len(self.imd.mol.geomContainer.geoms['cpk'].vertexSet.vertices.array) self.imd.mol.geomContainer.geoms['cpk'].vertexSet.vertices.array[:]=coord[:N] #self.GUI.VIEWER.OneRedraw() #self.GUI.VIEWER.update() else : from Pmv.moleculeViewer import EditAtomsEvent if type(self.imd.mol) is list : for i,m in enumerate(self.imd.mol) : event = EditAtomsEvent('coords', m.allAtoms) self.dispatchEvent(event) else : event = EditAtomsEvent('coords', self.imd.mol.allAtoms) self.dispatchEvent(event) #self.imd.mol.geomContainer.geoms['balls'].Set(vertices=coord) #self.imd.mol.geomContainer.geoms['sticks'].Set(vertices=coord.tolist()) #self.imd.mol.geomContainer.geoms['lines'].Set(vertices=coord) #self.imd.mol.geomContainer.geoms['bonds'].Set(vertices=coord) #self.imd.mol.geomContainer.geoms['cpk'].Set(vertices=coord) if self.handler.isinited : self.handler.getForces(None) self.handler.updateArrow() #""" if self.hasGui and self.imd.gui : self.GUI.VIEWER.OneRedraw() self.GUI.VIEWER.update() self.GUI.ROOT.after(5, self.updateIMD) #self.GUI.ROOT.after(10, self.updateIMD) def server_cb(self, server, data): """get called every time the server we are connected to sends a message""" import sys #sys.stderr.write('server %s sent> %s'%(server,data) ) self.cmdQueue.put( (server,data) ) #exec(data) # cannot exec because we are not in main thread # and Tkitner is not thread safe #self.GUI.VIEWER.Redraw() def drawSelectionRectangle(self, event): c = self.GUI.VIEWER.currentCamera c.drawSelectionRectangle(event) def initSelectionRectangle(self, event): c = self.GUI.VIEWER.currentCamera c.initSelectionRectangle(event) def endSelectionRectangle(self, event): c = self.GUI.VIEWER.currentCamera c.endSelectionRectangle(event) def fillSelectionBoxPref_cb(self, name, old, new): if self.hasGui: for c in self.GUI.VIEWER.cameras: c.fillSelectionBox = new def fillDelayValidate(self, value): return (value > 0 and value < 10000) def commmandHistoryValidate(self, value): try: val = int(value) if val >-1: return 1 else: return 0 except: return 0 def fillSelectionBoxDelayPref_cb(self, name, old, new): if self.hasGui: for c in self.GUI.VIEWER.cameras: c.fillDelay = new def SetVisualPickingFeedBack(self, name, old, new): if self.hasGui: self.GUI.VIEWER.showPickedVertex = new def SetIconSize(self, name, old, new): if self.hasGui: self.GUI.configureToolBar(iconsize=new) def startupDirPref_cb(self, name, old, new): if not os.path.isdir(new): if not hasattr(self,'setUserPreference') and not hasattr(self.setUserPreference, 'form'): return root = self.setUserPreference.form.root from tkMessageBox import showerror showerror("Invalid Startup Directory", "Directory %s "%new + " does not exists. Please select a valid Directory", parent=root) from tkFileDialog import askdirectory dir = askdirectory(parent=root, title='Please select startup directory') if dir: os.chdir(dir) self.userpref.data["Startup Directory"]['value'] = dir w=self.setUserPreference.form.descr.entryByName[name]['widget'] w.setentry(dir) #this removes updateGUI so that wrong new is not shown self.userpref.data["Startup Directory"]['callbackFunc'].pop(-1) else: self.userpref.set("Startup Directory", old) else: os.chdir(new) def startupDirValidate(self, value): return 1 def restorePerspective(self): if not self.hasGui: return if self.resourceFile: rcFile = os.path.join(os.path.split(self.resourceFile)[0], "perspective") else: rcFolder = getResourceFolderWithVersion() rcFile = os.path.join(rcFolder, "ViewerFramework", "perspective") if os.path.exists(rcFile): try: self.source(rcFile, globalNames=1, log=1) return True except Exception, inst: print inst, rcFile return def tryOpenFileInWrite(self, filename): try: self.logAllFile = open( filename, 'w' ) from Support.version import __version__ from mglutil import __revision__ self.logAllFile.write("# Pmv version %s revision %s\n"%(__version__, __revision__)) return 1 except: try: from mglutil.util.packageFilePath import getResourceFolderWithVersion rc = getResourceFolderWithVersion() self.logAllFile = open(rc + os.sep + filename, 'w' ) except: return 0 def customize(self, file=None): """if a file is specified, this files gets sourced, else we look for the file specified in self.resourceFile in the following directories: 1 - current directory 2 - user's home directory 3 - the package to which this instance belongs to """ #print 'ZZZZZZZZZZZZZZZZZZZZZZZZ' #import traceback #traceback.print_stack() if file is not None: if not os.path.exists(file): return self.source(file, globalNames=1, log=0) return resourceFileLocation = findResourceFile(self, resourceFile=self.resourceFile) if resourceFileLocation.has_key('currentdir') and \ not resourceFileLocation['currentdir'] is None: path = resourceFileLocation['currentdir'] elif resourceFileLocation.has_key('home') and \ not resourceFileLocation['home'] is None: path = resourceFileLocation['home'] elif resourceFileLocation.has_key('package') and \ not resourceFileLocation['package'] is None: path = resourceFileLocation['package'] else: return self.source(path, globalNames=1, log=0) path = os.path.split(path)[-1] if os.path.exists(path): self.source(path, globalNames=1, log=0) return def after(func, *args, **kw): """method to run a thread enabled command and wait for its completion. relies on the command to release a lock called self.done only works for commands, not for macros """ lock = thread.allocate_lock() lock.acquire() func.private_threadDone = lock apply( func, args, kw ) func.waitForCompletion() def getLog(self): """ generate log strings for all commands so far """ logs = [] i = 0 for cmd, args, kw in self.cmdHistory: try: log = cmd.logString( *args, **kw)+'\n' except: log = '#failed to create log for %d in self.cmdHistory: %s\n'%( i, cmd.name) logs.append(log) i += 1 return logs def addCmdToHistory(self, cmd, args, kw): """ append a command to the history of commands """ #print "ADDING Command to history", cmd.name self.cmdHistory.append( (cmd, args, kw)) maxLen = self.userpref['Command History Depth']['value'] lenCmds = len(self.cmdHistory) if maxLen>0 and lenCmds > maxLen: #print "maxLen", maxLen, lenCmds self.cmdHistory = self.cmdHistory[-maxLen:] if self.hasGui: nremoved = lenCmds-maxLen # update text in the message box message_box = self.GUI.MESSAGE_BOX nlines = float(nremoved+1) try: message_box.tx.delete('1.0', str(nlines)) except: pass def log(self, cmdString=''): """append command to logfile FIXME: this should also get whatever is typed in the PythonShell """ if self.logMode == 'no': return if cmdString[-1]!='\n': cmdString = cmdString + '\n' if hasattr(self, 'logAllFile'): self.logAllFile.write( cmdString ) self.logAllFile.flush() if self.socketComm is not None and len(self.socketComm.clients): #is it really need? cmdString=cmdString.replace("log=0","log=1") self.socketComm.sendToClients(cmdString) self.dispatchEvent( LogEvent( cmdString ) ) ## if self.selectLog: ## self.logSelectFile.write( cmdString ) def tryto(self, command, *args, **kw ): """result <- tryto(command, *args, **kw ) if an exception is raised print traceback and continue """ self.commandNestingLevel = self.commandNestingLevel + 1 try: if self.commandNestingLevel==1: self.commandsLock.acquire() if not self.trapExceptions: # we are running tests and want exceptions not to be caught result = command( *args, **kw ) else: # exception should be caught and displayed try: result = command( *args, **kw ) except: print 'ERROR *********************************************' if self.guiVisible==1 and self.withShell: self.GUI.pyshell.top.deiconify() self.GUI.ROOT.config(cursor='') self.GUI.VIEWER.master.config(cursor='') self.GUI.MESSAGE_BOX.tx.component('text').config(cursor='xterm') traceback.print_exc() sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info() result = 'ERROR' # sets cursors back to normal finally: if self.commandNestingLevel==1: self.commandsLock.release() self.commandNestingLevel = self.commandNestingLevel - 1 return result def message(self, str, NL=1): """ write into the message box """ if self.hasGui: self.GUI.message(str,NL) else: print str def unsolicitedPick(self, pick): """treat and unsollicited picking event""" vi = self.GUI.VIEWER if vi.isShift() or vi.isControl(): vi.unsolicitedPick(pick) else: #print picked geometry for k in pick.hits.keys(): self.message(k) def addBasicCommands(self): """Create a frame to hold menu and button bars""" from ViewerFramework.dejaVuCommands import PrintGeometryName, \ SetCameraSizeCommand, SetCamSizeGUI # Basic command that needs to be added manually. self.addCommand( PrintGeometryName(), 'printGeometryName ', None ) g = CommandGUI() g.addMenuCommand('menuRoot', 'File', 'Browse Commands', separatorAbove=1, ) self.addCommand( BrowseCommandsCommand(), 'browseCommands', g) self.addCommand( SetCameraSizeCommand(), 'setCameraSize', SetCamSizeGUI) from ViewerFramework.basicCommand import UndoCommand, \ ResetUndoCommand, NEWUndoCommand, RedoCommand # g = CommandGUI() # g.addMenuCommand('menuRoot', 'File', 'Remove Command') # self.addCommand( RemoveCommand(), 'removeCommand', g) from mglutil.util.packageFilePath import getResourceFolderWithVersion self.vfResourcePath = getResourceFolderWithVersion() if self.vfResourcePath is not None: self.vfResourcePath += os.sep + "ViewerFramework" if not os.path.isdir(self.vfResourcePath): try: os.mkdir(self.vfResourcePath) except Exception, inst: print inst txt="Cannot create the Resource Folder %s" %self.vfResourcePath self.vfResourcePath = None g = CommandGUI() g.addMenuCommand('menuRoot', 'Edit', 'Undo ', index=0) g.addToolBar('Undo', icon1 = '_undo.gif', icon2 = 'undo.gif', type = 'ToolBarButton',state = 'disabled', balloonhelp = 'Undo', index = 1) self.addCommand( NEWUndoCommand(), 'NEWundo', g) g = CommandGUI() g.addMenuCommand('menuRoot', 'Edit', 'Redo ', index=1) g.addToolBar('Redo', icon1 = '_redo.gif', icon2 = 'redo.gif', type = 'ToolBarButton',state = 'disabled', balloonhelp = 'Redo', index = 2) self.addCommand( RedoCommand(), 'redo', g) # keep old undo command for now for backward compatibility self.addCommand( UndoCommand(), 'undo', None ) self.addCommand( ResetUndoCommand(), 'resetUndo ', None) g = CommandGUI() #g.addMenuCommand('menuRoot', 'File', 'Load Command') self.addCommand( loadCommandCommand(), 'loadCommand', g) g = CommandGUI() #g.addMenuCommand('menuRoot', 'File', 'Load Module') self.addCommand( loadModuleCommand(), 'loadModule', g) g = CommandGUI() g.addMenuCommand('menuRoot', 'File', 'Load Macros', separatorBelow=1) self.addCommand( loadMacroCommand(), 'loadMacro', g) # Load Source command from customizationCommands module: self.browseCommands('customizationCommands', commands=['source',], package='ViewerFramework', topCommand=0) # force the creation of the default buttonbar and PyShell checkbutton # by viewing the Python Shell widget if self.withShell: self.addCommand( ShellCommand(), 'Shell', ShellCommandGUI ) # add the default 'Help' menubutton in the default menubar if self.hasGui: bar = self.GUI.menuBars['menuRoot'] help = self.GUI.addMenuButton( bar, 'Help', {}, {'side':'right'}) self.GUI.addMenuButton( bar, 'Grid3D', {}, {'side':'right'}) try: import grid3DCommands self.browseCommands("grid3DCommands", package="ViewerFramework", topCommand=0) except Exception, inst: print inst print "Cannot import grid3DCommands. Disabling grid3DCommands..." #self.GUI.ROOT.after(1500, self.removeCommand.loadCommands) # load helpCommand and searchForCmd self.browseCommands('helpCommands', commands=['helpCommand','searchForCmd', 'citeThisScene', 'showCitation'], package='ViewerFramework', topCommand = 0) # load SetUserPreference and setOnAddObjectCmds Commands self.browseCommands('customizationCommands', commands=['setUserPreference', 'setOnAddObjectCommands'], package='ViewerFramework', topCommand = 0) # load ChangeVFGUIvisGUI and SetOnAddObjectCmds Command self.browseCommands('customizeVFGUICommands', package='ViewerFramework', topCommand = 0) self.addCommand( SaveSessionCommand(), 'saveSession ', SaveSessionCommandGUI) # Add the Exit command under File g = CommandGUI() g.addMenuCommand('menuRoot', 'File', 'Exit', separatorAbove=1) self.addCommand( ExitCommand(), 'Exit', g ) # load object transformation, camera transformation, # light transformation, Clipping Plane transformation, # CenterGeom, centerScene commands self.browseCommands("dejaVuCommands", commands=[ 'transformObject', 'transformCamera', 'setObject', 'setCamera', 'setLight', 'setClip', 'addClipPlane', 'centerGeom', 'centerScene', 'centerSceneOnVertices', 'alignGeomsnogui','alignGeoms', 'toggleStereo', 'centerSceneOnPickedPixel'], package='ViewerFramework', topCommand = 0) def validInstance(self, classList, obj): """Checks whether an object is an instance of one the classes in the list""" ok = 0 for Klass in classList: if isinstance(obj, Klass): OK=1 break return OK def getOnAddObjectCmd(self): """ returns a copy of the list of commands currently executed when a new object is added """ return self.onAddObjectCmds[:] def addOnAddObjectCmd(self, cmd, args=[], kw={}): """ adds a command to the list of commands currently executed when a new object is added """ assert callable(cmd) assert type(args)==types.TupleType or type(args)==types.ListType assert type(kw)==types.DictType assert cmd.flag & Command.objArgOnly kw['topCommand'] = 0 kw['setupNegate'] = 0 if type(args)==types.ListType: args = tuple(args) self.onAddObjectCmds.append( (cmd, args, kw) ) def removeOnAddObjectCmd(self, cmd): """ removes a command to the list of commands currently executed when a new object is added """ for com in self.onAddObjectCmds: if com[0]==cmd: self.onAddObjectCmds.remove(com) return com print 'WARNING: command %s not found'%cmd.name return None def addObject(self, name, obj, geomContainer=None): """Add an object to a Viewer""" #print 'acquiring addObject lock' self.objectsLock.acquire() self.objects.append(obj) self.objectsLock.release() #print 'releasing addObject lock' ## if geomContainer is None: ## obj.geomContainer = GeomContainer( self.GUI.VIEWER ) ## else: ## obj.geomContainer = geomContainer obj.geomContainer = geomContainer # prepare progress bar lenCommands = len(self.cmdsWithOnAddObj) if self.hasGui: self.GUI.configureProgressBar(init=1, mode='increment', max=lenCommands, progressformat='ratio', labeltext='call initGeom methods') #call initGeom method of all commands creating geometry from time import time #t0 = time() for com in self.cmdsWithOnAddObj: com.onAddObjectToViewer(obj) #t1 = time() #print 'INITI', com, t1-t0 #check for gui if self.hasGui: self.GUI.updateProgressBar() # now set progress bar back to '%' format if self.hasGui: self.GUI.configureProgressBar(progressformat='percent') # prepare progress bar lenCommands = len(self.onAddObjectCmds) #call functions that need to be called on object #t0 = time() for com in self.onAddObjectCmds: com[2]['redraw']=0 com[2]['log']=0 #t1 = time() #print 'INITI2', com, t1-t0 com[0]( *((obj,)+com[1]), **com[2] ) # note we have to re-configure the progress bar because doitWrapper # will overwrite the mode to 'percent' #check for gui if self.hasGui: self.GUI.configureProgressBar(init=1, mode='increment', max=lenCommands, progressformat='ratio', labeltext='call geom functions') self.GUI.updateProgressBar() if self.hasGui: # now set progress bar back to '%' format self.GUI.configureProgressBar(progressformat='percent') # create add object event event = AddObjectEvent(objects=[obj]) self.dispatchEvent(event) if self.hasGui: self.centerScene(topCommand=0) self.GUI.VIEWER.Redraw() def removeObject(self, obj, undoable=False): """Remove an object from a Viewer""" #1 Delete the obj from the list of objects. del(self.objects[self.objects.index(obj)]) # call onRemoveMol method of all commands creating geometry # To remove geometries created by these commands from the VIEWER ## MS chose to cerate undoableDelete__ variable in VF to let cmd's ## onRemoveObjectFromViewer method decide what to do when delete is ## undoable. Passign undoable into th method would require changing ## the signature in each implementation when onyl a hand full do ## something s[pecial when undoable is True self.undoableDelete__ = undoable for com in self.cmdsWithOnRemoveObj: self.tryto( com.onRemoveObjectFromViewer, (obj) ) del self.undoableDelete__ # clean up the managedGeometries list if obj.geomContainer: for cmd in self.commands.values(): if len(cmd.managedGeometries)==0: continue geomList = [] for g in cmd.managedGeometries: if hasattr(g, 'mol') and g.mol==obj: continue geomList.append(g) cmd.managedGeometries = geomList # remove everything created in the geomContainer associated to the # mol we want to destroy, if obj.geomContainer: obj.geomContainer.delete() # create remove object event event = DeleteObjectEvent(objects=[obj]) self.dispatchEvent(event) def addColorMap(self, colorMap): from DejaVu.colorMap import ColorMap assert isinstance(colorMap, ColorMap) if self.colorMaps.has_key('colorMap.name'): warnings.warn('invalid attemp to replace an existing colormap') else: self.colorMaps[colorMap.name] = colorMap def addCommandProxy(self, commandProxy): """To make startup time faster this function add GUI elements without importing and loading the full dependiencies for a command """ if self.hasGui: gui = commandProxy.gui if gui is not None: gui.register(self, commandProxy) gui.registered = True def addCommand(self, command, name, gui=None): """ Add a command to a viewer. arguments: command: Command instance name: string gui: optional CommandGUI object objectType: optional type of object for which we need to add geoms geomDescr: optional dictionary of 'name:objectType' items name is used to create an alias for the command in the viewer if a gui is specified, call gui.register to add the gui to the viewer """ #print "addCommand", name, command assert isinstance(command, Command) # happens because of dependencies if name in self.commands.keys(): return self.commands[name] error = self.tryto(command.checkDependencies, self) if error=='ERROR': print '\nWARNING: dependency check failed for command %s' % name return ## def download_cb(): ## import os ## os.system('netscape http://www.scripps.edu/pub/olson-web/people/scoon/login.html &') ## def Ok_cb(idf): ## idf.form.destroy() ## tb = traceback.extract_tb(sys.exc_traceback) ## from gui import InputFormDescr, CallBackFunction ## import Tkinter ## idf = InputFormDescr("Missing dependencies !") ## idf.append({'widgetType': Tkinter.Label, ## 'text':"%s can't be loaded, needs %s module" ## % (tb[1][-1][7:],command.__class__.__name__), ## 'gridcfg':{'columnspan':2}}) ## idf.append({'widgetType':Tkinter.Button, 'text':'OK', ## 'command':CallBackFunction(Ok_cb, idf), ## 'gridcfg':{'sticky':Tkinter.W+Tkinter.E}}) ## idf.append({'widgetType':Tkinter.Button, 'text':'Download', ## 'command':download_cb, ## 'gridcfg':{'row':-1, 'sticky':Tkinter.W+Tkinter.E, ## 'columnspan':5 }}) ## form = self.getUserInput(idf, modal=0, blocking=0) ## self.warningMsg(title = "Missing dependencies !", ## message = "%s can't be loaded, needs %s module" ## % (tb[1][-1][7:],command.__class__.__name__)) ## return command.vf = self name = string.strip(name) name = string.replace(name, ' ', '_') self.commands[name] = command command.name=name command.undoMenuString=name # string used to change menu entry for Undo command.undoMenuStringPrefix='' # prefix used to change menu entry for Undo setattr(self, name, command) #exec ( 'self.%s = command' % name ) if self.hasGui: if gui is not None: assert isinstance(gui, CommandGUI) gui.register(self, command) gui.registered = True #call the onAddCmdToViewer method of the new command command.onAddCmdToViewer() for c in self.commands.values(): c.onAddNewCmd(command) #if hasattr(command, 'onAddObjectToViewer'): # if callable(command.onAddObjectToViewer): # self.cmdsWithOnAddObj.append(command) # for o in self.objects: # command.onAddObjectToViewer(o) if hasattr(command, 'onRemoveObjectFromViewer'): if callable(command.onRemoveObjectFromViewer): self.cmdsWithOnRemoveObj.append(command) if hasattr(command, 'onExitFromViewer'): if callable(command.onExitFromViewer): self.cmdsWithOnExit.append(command) def updateGeomContainers(self, objectType, geomDescr): """To be called when a new command that requires geometry is add to a viewer. This method loops over existing objects to create the required geometry for already existing objects""" for o in self.objects: if not isinstance(object, objectType): continue o.geomContainer.addGeom( geomDescr ) def askFileOpen(self, idir=None, ifile=None, types=None, title='Open', relative=True, parent=None, multiple=False): """filename <- askFileOpen( idir, ifile, types, title) if the viewer is run with a gui this function displays a file browser else it askes for a file name idir: optional inital directory ifile: optional initial filename types: list of tuples [('PDB files','*.pdb'),] title: widget's title relative: when set to True the file name is realtive to the directory where the application has been started multiple: allow selecting multiple files returns: a filename ot None if the Cancel button """ if self.hasGui: if parent: file = self.GUI.askFileOpen(parent, idir=idir, ifile=ifile, types=types, title=title, multiple=multiple) else: file = self.GUI.askFileOpen( self.GUI.ROOT, idir=idir, ifile=ifile, types=types, title=title, multiple=multiple) if file is () or file is None: # this is returned if one click on the file list and # then clicks Cancel return else: default = '' if idir: default = idir if ifile: default = os.path.join( default, ifile ) file = raw_input("file name [%s] :"%default) if file=='': if default != '' and os.path.exists(file): file = default if multiple is False: fpath,fname = os.path.split(file) if relative and file and os.path.abspath(os.path.curdir) == fpath: file = os.path.join( os.path.curdir, file[len(os.path.abspath(os.path.curdir))+1:]) return file else: files = [] for f in file: fpath,fname = os.path.split(f) if relative and f and os.path.abspath(os.path.curdir) == fpath: f = os.path.join(os.path.curdir, f[len(os.path.abspath(os.path.curdir))+1:]) files.append(f) return files def askFileSave(self, idir=None, ifile=None, types=None, title='Save', relative=True, defaultextension=None): if self.hasGui: file = self.GUI.askFileSave(self.GUI.ROOT, idir=idir, ifile=ifile, types=types, title=title, defaultextension=defaultextension) if file is () or file is None: # this is returned if one clcik on the file list and # then clicks Cancel return else: default = '' if idir: default = idir if ifile: default = os.path.join( default, ifile ) file = raw_input("file name [%s] :"%default) if file=='': if default != '' and os.path.exists(file): file = default fpath,fname = os.path.split(file) if relative and file and os.path.abspath(os.path.curdir) == fpath: file = os.path.join(os.path.curdir, file[len(os.path.abspath(os.path.curdir))+1:]) return file def setLogMode(self, name, oldval, newval): "Sets the Lig Mode" self.logMode = newval # open log file for all commands if self.logMode == 'unique': import time t = time.localtime(time.time()) fname1 = 'mvAll_%04d-%02d-%02d_%02d-%02d-%02d.log.py'%(t[0],t[1],t[2],t[3],t[4],t[5]) fname1 = os.path.join(self.rcFolder, fname1) if self.hasGui: self.GUI.ROOT.after_idle(self.clearOldLogs) elif self.logMode == 'overwrite': fname1 = os.path.join(self.rcFolder, 'mvAll.log.py') if self.logMode != 'no': flag = self.tryOpenFileInWrite(fname1) while flag == 0: idf = InputFormDescr(title = 'Directory not writable ...') variable = Tkinter.StringVar() idf.append({'name':'noLog','widgetType': Tkinter.Radiobutton, 'text':'noLog','variable':variable, 'value':'noLog','defaultValue':'noLog', 'gridcfg':{'sticky':Tkinter.W}}) idf.append({'name':'browse','widgetType': 'SaveButton', 'typeofwidget':Tkinter.Radiobutton, 'types':[ ('Python Files', '*.py')], 'title':'Choose a log File...', 'text':'browse', 'variable':variable, 'defaultValue':'noLog', 'value':'browse', 'gridcfg':{'sticky':Tkinter.W}}) self.GUI.ROOT.deiconify() self.GUI.ROOT.update() result = self.getUserInput(idf) if result == {}: self.GUI.ROOT.destroy() return elif result['noLog'] == 'noLog': self.logMode = 'no' flag = 1 elif result['noLog'] == 'browse' and result.has_key('browse'): assert not result['browse'] in [''] flag = self.tryOpenFileInWrite(result['browse']) elif result['noLog'] == 'browse' and not result.has_key('browse'): print "you didn't enter a proper file name try again" flag = 0 def setWarningMsgFormat(self, name, oldval, newval): """ newval can be either 'pop-up' or 'printed'""" self.messageFormat = newval def warningMsg(self, msg, title='WARNING: ', parent = None): """None <- warningMsg(msg)""" if type(title) is not types.StringType: title = 'WARNING: ' if self.hasGui and self.messageFormat=='pop-up': tkMessageBox.showwarning(title, msg,parent = parent) else: sys.stdout.write(title+msg+'\n') def askOkCancelMsg(self, msg): """None <- okCancelMsg(msg)""" if self.hasGui: return tkMessageBox.askyesno('expand selection', msg) else: val = raw_input('anser [0]/1: '+msg+'\n') if val=='1': return 1 else: return 0 ## FIXME .. do we need this ? def errorMsg(self, msg, errtype=RuntimeError): """None <- errorMsg(errorType, msg)""" if self.hasGui: tkMessageBox.showerror(msg) raise errtype(msg) def getUserInput(self, formDescription, master=None, root=None, modal=0, blocking=1, defaultDirection = 'row', closeWithWindow = 1, okCfg={'text':'OK'}, cancelCfg={'text':'Cancel'}, initFunc=None, scrolledFrame=0, width=None, height=None, okcancel=1, onDestroy = None, postCreationFunc=None, postUsingFormFunc=None): """val[] <- getUserInput(formDescription) Returns a list of values obtained either from an InputForm or by prompting the user for values """ ## from gui import InputForm, InputFormDescr from mglutil.gui.InputForm.Tk.gui import InputForm, InputFormDescr assert isinstance(formDescription, InputFormDescr) if self.hasGui: if master==None: master = self.GUI.ROOT #root = self.GUI.getCmdsParamsMaster() #if not postCreationFunc: # postCreationFunc = self.GUI.getAfterCreatingFormFunc() #if not postUsingFormFunc: # postUsingFormFunc = self.GUI.getAfterUsingFormFunc() form = InputForm(master, root, formDescription, modal=modal, blocking=blocking, defaultDirection=defaultDirection, closeWithWindow=closeWithWindow, okCfg=okCfg, cancelCfg=cancelCfg, initFunc=initFunc, scrolledFrame=scrolledFrame, width=width, height=height, okcancel=okcancel, onDestroy=onDestroy) if form.ownsRoot: geom = form.root.geometry() # make sure the upper left dorner is visible w = string.split(geom, '+') changepos = 0 if w[1][0]=='-': posx = '+50' changepos=1 else: posx = '+'+w[1] if w[2][0]=='-': posy ='+50' changepos=1 else: posy = '+'+w[2] if changepos: form.root.geometry(posx+posy) if postCreationFunc: postCreationFunc(form.root) if not (modal or blocking): return form else: values = form.go() if postUsingFormFunc: postUsingFormFunc(form.root) return values else: self.warningMsg("nogui InputForm not yet implemented") def transformedCoordinatesWithInstances(self, hits): """ hist is pick.hits = {geom: [(vertexInd, intance),...]} This function will use the instance information to return a list of transformed coordinates """ # FIXME this is in DejaVu.VIewer and should go away here vt = [] for geom, values in hits.items(): coords = geom.vertexSet.vertices.array for vert, instance in values: M = geom.GetMatrix(geom.LastParentBeforeRoot(), instance[1:]) pt = coords[vert] ptx = M[0][0]*pt[0]+M[0][1]*pt[1]+M[0][2]*pt[2]+M[0][3] pty = M[1][0]*pt[0]+M[1][1]*pt[1]+M[1][2]*pt[2]+M[1][3] ptz = M[2][0]*pt[0]+M[2][1]*pt[1]+M[2][2]*pt[2]+M[2][3] vt.append( (ptx, pty, ptz) ) return vt def clearOldLogs(self): currentTime = time.time() for file in glob.glob(os.path.join(self.rcFolder, "*.log.py")): stats = os.stat(file) if currentTime - stats[8] > 3000000: #~month os.remove(file) if __name__ == '__main__': v = ViewerFramework() import pdb ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/VFCommand.py0000644000175000017500000017257312223370164024337 0ustar moellermoeller## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by ############################################################################# # # Author: Michel F. SANNER # # Copyright: M. Sanner TSRI 2000 # ############################################################################# """ This module implements the following classes Command : base class to implement commands for application derived from ViewerFramework. CommandGUI: class describing the GUI associated with a command. (menu, button etc...) ICOM : Base class to implement Picking command for application dercived from ViewerFramework. Picking command are bound to the picking event. """ # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/VFCommand.py,v 1.117 2013/10/03 22:32:20 annao Exp $ # # $Id: VFCommand.py,v 1.117 2013/10/03 22:32:20 annao Exp $ # import numpy.oldnumeric as Numeric import os, types, string, Tkinter,Pmw, warnings #, webbrowser import tkMessageBox from time import time, sleep ## from ViewerFramework.gui import InputFormDescr from mglutil.gui.InputForm.Tk.gui import InputFormDescr from mglutil.util.callback import CallBackFunction from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ListChooser from DejaVu.Geom import Geom from DejaVu.colorMap import ColorMap from mglutil.util.packageFilePath import findFilePath ICONPATH = findFilePath('Icons', 'ViewerFramework') ICONSIZES = { 'very small':'16x16', 'small':'22x22', 'medium':'32x32', 'large':'48x48', 'very large':'64x64', } class ActiveObject: """An ActiveObject is an object that is capable to call a number of functions whenever it changes, These function take 2 arguments, newValue and oldValue. WARNING: the callback function should NOT trigger setting of the value. If it did the program goes into an endless loop. """ def __init__(self, value, type=None): self.value = value self.type = type self.callbacks = [] self.private_threadDone = None # lock used commands running in threads def waitForCompletion(self): # used for commands running in threads while (1): if not self.private_threadDone.locked(): return sleep(0.01) def AddCallback(self, callback): """Add a callback fuction""" assert callable(callback) # Here we should also check that callback has exactly 2 arguments self.callbacks.append(callback) def FindFunctionByName(self, funcName, funcList): """find a function with a given name in a list of functions""" for f in funcList: if f.__name__==funcName: return f return None def HasCallback(self, callback): """Check whether a function is registered as a callback for an event """ if type(callback) in types.StringTypes: callback = self.FindFunctionByName(callback, self.callbacks) if callback is None: return 0 assert callable(callback) for f in self.callbacks: if f==callback: return 1 return 0 def RemoveCallback(self, func): """Delete function func from the list of callbacks for eventType""" if type(func)==type('string'): func = self.FindFunctionByName(func, self.callbacks ) if func is None: return self.callbacks.remove(func) def Set(self, value): oldvalue = self.value self.value = value self.callCallbacks(value, oldvalue) def callCallbacks(self, value, oldvalue): for f in self.callbacks: f(value, oldvalue) class ICOM: """Mixin class used to specify that a command is usable interactively, i.e. be called for each picking operation """ def __init__(self): self.pickLevel = 'vertices' def getObjects(self, pick): return pick.hits def initICOM(self, modifier): """gets called when the ICOM is registered using the set method of the interactiveCommandCaller.""" pass def startICOM(self): """gets called every time this command is about to be run becuase of a picking event. It is called just before the Pick is converted into objects.""" pass def stopICOM(self): """gets called when this command stops being bound to picking here one should withdraw forms mainly""" pass # # We still have the problem of not being able to pick vertices and parts # at the same time. This implies that interactive commands assigned to # some modifiers might not get called is the picking level isnot right # class InteractiveCmdCaller: """Object used to bind interactive commands to picking operations. - self.commands is a dictionnary: modifier:cmd. - self.pickerLevel reflects and sets the DejaVu picking level to 'vertices' or 'parts'. - self.getObject is a function called with the pick object to return a list of picked objects. """ def __init__(self, vf): self.vf = vf # viewer application # commands for pick (i.e button down and up without move) self.commands = ActiveObject({None:None, 'Shift_L':None, 'Control_L':None, 'Alt_L':None}) # commands for pick (i.e button down and up after move) self.commands2 = ActiveObject({None:None, 'Shift_L':None, 'Control_L':None, 'Alt_L':None}) self.getObjects = None self.currentModifier = None self.running = 0 def _setCommands(self, command, modifier=None, mode=None): if command: assert isinstance(command, ICOM) if mode == 'pick': ao = self.commands elif mode == 'drag select': ao = self.commands2 else: raise ValueError("ERROR: mode can only be 'pick' or 'drag select' got %s"%mode) if ao.value[modifier]: ao.value[modifier].stopICOM() oldvalue = ao.value[modifier] else: oldvalue = None if command: command.initICOM(modifier) ao.value[modifier] = command elif oldvalue: ao.value[modifier]= None ao.callCallbacks(command, modifier) def setCommands(self, command, modifier=None, mode=None): if mode is None: self._setCommands(command, modifier, 'pick') self._setCommands(command, modifier, 'drag select') else: self._setCommands(command, modifier, mode) def go(self): if self.running: return self.running = 1 if self.vf.hasGui: vi = self.vf.GUI.VIEWER vi.SetPickingCallback(self.pickObject_cb) def pickObject_cb(self, pick): # self.getObjects was set in ViewerFramework.DoPick if pick.mode=='pick': cmd = self.commands.value[self.currentModifier] else: cmd = self.commands2.value[self.currentModifier] if cmd: cmd.startICOM() objects = cmd.getObjects(pick) if objects and len(objects): self.execCmd(objects, cmd) def execCmd(self, objects, cmd): # self.currentModifer was set in ViewerFramework.DoPick #cmd = self.commands.value[self.currentModifier] #if cmd: if hasattr(cmd, 'getLastUsedValues'): defaultValues = cmd.getLastUsedValues('default') else: defaultValues = {} # ignore lastusedValue of negate as it might have been set by # control panel and in interactive commands we do call the # display or undisplay, slect or deselect command explicitly if defaultValues.has_key('negate'): del defaultValues['negate'] cmd( *(objects,), **defaultValues) #cmd(objects) class CommandGUI: """Object allowing to define the GUI to be associated with a Command object. Currently there are two possible types of GUI: either menu type or button type. The Command class provides a method 'customizeGUI' allowing individual commands to configure their GUI """ menuEntryTypes = ['command', 'cascade', 'checkbutton', 'radiobutton'] def __init__(self): # menu related stuff self.menu = None self.menuBar = None self.menuButton = None self.menuCascade = None self.menuDict = {} #self.menuBarCfg = {'borderwidth':2, 'relief':'raised'} self.menuBarCfg = {'borderframe':0, 'horizscrollbar_width':7, 'vscrollmode':'none', 'frame_relief':'groove', 'frame_borderwidth':0,} self.menuBarPack = {'side':'top', 'expand':1, 'fill':'x'} self.menuButtonCfg = {} self.menuButtonPack = {'side':'left', 'padx':"1m"} self.menuEntryLabelCfg = {} # checkbutton related stuff self.checkbutton = None #self.checkbuttonBarCfg = {'borderwidth':2, 'relief':'raised'} self.checkbuttonBarCfg = {'borderframe':0, 'horizscrollbar_width':7, 'vscrollmode':'none', 'frame_relief':'raised', 'frame_borderwidth':0,} self.checkbuttonBarPack = {'side':'bottom', 'expand':1, 'fill':'x'} self.checkbuttonCfg = {} self.checkbuttonPack = {'side':'left', 'padx':"1m"} self.checkbuttonDict = {} # radiobutton related stuff self.radiobutton = None #self.radiobuttonBarCfg = {'borderwidth':2, 'relief':'raised'} self.radiobuttonBarCfg = {'borderframe':0, 'horizscrollbar_width':7, 'vscrollmode':'none', 'frame_relief':'raised', 'frame_borderwidth':0,} self.radiobuttonBarPack = {'side':'bottom', 'expand':1, 'fill':'x'} self.radiobuttonCfg = {} self.radiobuttonPack = {'side':'left', 'padx':"1m"} self.radiobuttonDict = {} # button related stuff self.button = None #self.buttonBarCfg = {'borderwidth':2, 'relief':'raised'} self.buttonBarCfg = {'borderframe':0, 'horizscrollbar_width':7, 'vscrollmode':'none', 'frame_relief':'raised', 'frame_borderwidth':0,} self.buttonBarPack = {'side':'bottom', 'expand':1, 'fill':'x'} self.buttonCfg = {} self.buttonPack = {'side':'left', 'padx':"1m"} self.buttonDict = {} # Distionary holding Toolbar related stuff self.toolbarDict = {} # toplevel related stuff # toplevel related stuff #there may be more than one self.topLevels = [] self.registered = False def addCheckbutton(self, BarName, ButtonName, cb=None ): self.checkbuttonDict['barName'] = BarName self.checkbuttonDict['buttonName'] = ButtonName self.checkbuttonDict['cb'] = cb self.checkbutton = (self.checkbuttonBarCfg, self.checkbuttonBarPack, self.checkbuttonCfg, self.checkbuttonPack, self.checkbuttonDict ) def addRadiobutton(self, BarName, ButtonName, cb=None ): self.radiobuttonDict['barName'] = BarName self.radiobuttonDict['buttonName'] = ButtonName self.radiobuttonDict['cb'] = cb self.radiobutton = (self.radiobuttonBarCfg, self.radiobuttonBarPack, self.radiobuttonCfg, self.radiobuttonPack, self.radiobuttonDict ) def addButton(self, BarName, ButtonName, cb=None ): self.buttonDict['barName'] = BarName self.buttonDict['buttonName'] = ButtonName self.buttonDict['cb'] = cb self.button = (self.buttonBarCfg, self.buttonBarPack, self.buttonCfg, self.buttonPack, self.buttonDict ) def addMenuCommand(self, menuBarName, menuButtonName, menuEntryLabel, cb=None, index = -1, cascadeName = None, menuEntryIndex=None, menuEntryType='command', separatorAbove=0, separatorBelow=0, separatorAboveCascade=0, separatorBelowCascade=0, before=None, after=None, image=None, cascadeIndex=-1, cascadeBefore=None, cascadeAfter=None, ): """Add a menu item""" assert menuEntryType in self.menuEntryTypes if cb is not None: assert callable(cb) self.menuDict['menuBarName']= menuBarName self.menuDict['menuButtonName']= menuButtonName self.menuDict['menuEntryLabel']= menuEntryLabel self.menuDict['menuCascadeName']= cascadeName self.menuDict['menuEntryType'] = menuEntryType self.menuDict['separatorAbove'] = separatorAbove self.menuDict['separatorBelow'] = separatorBelow self.menuDict['separatorAboveCascade'] = separatorAboveCascade self.menuDict['separatorBelowCascade'] = separatorBelowCascade self.menuDict['cb'] = cb self.menuDict['index'] = index self.menuDict['before'] = before self.menuDict['after'] = after self.menuDict['image'] = image self.menuDict['cascadeIndex'] = cascadeIndex self.menuDict['cascadeBefore'] = cascadeBefore self.menuDict['cascadeAfter'] = cascadeAfter self.menu = (self.menuBarCfg, self.menuBarPack, self.menuButtonCfg, self.menuButtonPack, self.menuEntryLabelCfg, self.menuDict ) def addToolBar(self, name, cb=None, icon1=None, icon2=None, icon_dir=ICONPATH, type='Checkbutton', radioLabels=None, radioValues=None, radioInitialValue=None, state='normal', variable=None, balloonhelp='', index=0): """Adds a Toolbar item""" self.toolbarDict['name'] = name self.toolbarDict['cb'] = cb self.toolbarDict['icon1'] = icon1 self.toolbarDict['icon2'] = icon2 self.toolbarDict['icon_dir'] = icon_dir self.toolbarDict['type'] = type self.toolbarDict['state'] = state self.toolbarDict['balloonhelp'] = balloonhelp self.toolbarDict['index'] = index self.toolbarDict['variable'] = variable self.toolbarDict['radioLabels'] = radioLabels self.toolbarDict['radioValues'] = radioValues self.toolbarDict['radioInitialValue'] = radioInitialValue if radioLabels and radioValues: assert len(radioLabels) == len(radioValues) def register(self, viewer, cmd=None): if not viewer.hasGui: return cb = None if cmd: self.cmd = cmd cmd.GUI = self cb = cmd.guiCallback if self.registered: return if self.menu is not None: viewer.GUI.addCommandMenuGUI(self, cb) if self.checkbutton is not None: viewer.GUI.addCheckbuttonMenuGUI(self, cb) if self.button is not None: viewer.GUI.addButtonMenuGUI(self, cb) if self.radiobutton is not None: viewer.GUI.addradiobuttonMenuGUI(self, cb) if self.toolbarDict: viewer.GUI.addtoolbarDictGUI(self, cb) for m in self.topLevels: viewer.GUI.addCommandToplevelGUI(self) class Command: """ Base class for adding commands to a Viewer derived from ViewerFramework Classes derived from that class can be added to a viewer using the addCommand method. Commands are derived from the VFCommand base class and should implement or overwrite the following methods: __init__(self, func=None) The constructor has to be overwritten to set the self.flag attribute properly. self.objArgOnly is turned on when the doit only has one required argument which is the current selection. This will automatically make this command a Picking command self.negateKw is turned on when the doit method takes a boolean flag negate which makes this command undoable. __call__(self, *args, **kw): Entrypoint to the command from the command line. It overloads calling the object (command) as a function, which enables calling an instance of a command as a method of a viewer once it it has been loaded. Typically, this method checks the arguments supplied and calls the doitWrapper method with the arguments supplied. This method needs to have the same signature than the doit. A documentation string supplying the following information will be displayed in a tooltip when calling the command from the python idle shell. This documentation string should provide the synopsis of the command and a description of the arguments. guiCallback(self, event=None, *args, **kw): This method is bound by default as the callback of the GUI item associated with the command. It is the entrypoint of the command through the GUI. It typically creates an inputform allowing the user to specify any argument required for the command. The command method showForm is typically called with the name of the form to be created and a bunch of optional argument described later. Once all the parameters are known, the doitWrapper method is called to carry out the command. The old behavior was to call self.vf.getUserInput. The showForm method is a command method and replace the getUserInput method of the ViewerFramework. Although some commands still implement the getUserInput mechanism. buildFormDescr(self, formName): This method typically creates the inputform descriptor used by the guiCallback method to get user input for the command. The formName is a string which will be used as a key in the cmdForms dictionary to store the form information. This method is called by self.showForm This method returns an instance of an InputFormDescr which is the object describing a inputform in ViewerFramework. More information can be found in mglutil/gui/InputForm/Tk/gui.py For an example see: ViewerFramework.basicCommand.BrowseCommandsCommand: This command creates a non modal non blocking form setLastUsedValues(self, **kw): This method can be used to set the values to that appear in the GUI getLastUsedValues(self): Returns the values fo the parameters for the command doit(self, *args, **kw): This method does the actual work. It should not implement any functionality that should be available outside the application for scripting purposes. This method should call such functions or object. negateCmdBefore(self, *args, **kw): negateCmdAfter(self, *args, **kw): replaces setUpUndoBefore to create thecommands that negate the current command setUpUndoBefore(self, *args, **kw): OBSOLETE setUpUndoAfter(self, *args, **kw): OBSOLETE Typically this method should be implemented if the command is undoable. It should have the same signature than the doit and the __call__ method. Of course, one is free to overwrite any of these methods and for instance rename doit using a more appropriate name. But, when doing so, the programmer has to overwrite both __call__ and guiCallback to call the right method to carry out the work. Besides these methods which are required to be implemented in a command there are the following optional methods: strArg(self, arg): Method to turn a command argument into a string. Used by the log method to generate a log string for the command. This method can be overwritten or extended by classes subclassing Command in order to handle properly instances of objects defined by the application when not handled properly by the base class. checkDependencies(): This method called when command is loaded. It typically checks for dependencies and if all the dependencies are not found the command won't be loaded. onAddCmdToViewer(): (previously initCommand) onAddCmdToViewer is called once when a command is loaded into a Viewer. Typically, this method : takes care of dependencies (i.e. load other commands that might be required) creates/initializes variables. see ViewerFramework.basicCommand.py UndoCommand for an example customizeGUI(self): (obsolete) method allowing to modify the GUI associated with a command onAddObjectToViewer(self, obj): (previously named initGeom) When a command is loaded that implements an onAddObjectToViewer function,this function id called for every object present in the application. Once the command is loaded, this function will be called for every new object added to the application. In general, onAddObjectToViewer is used by a command to add a new geometry to the geometry container of an object. It is also where picking events and building arrays of colors specific to each geometry can be registered. onRemoveObjectFromViewer(self, obj): In python if all references to an object are not deleted, memory space occupied by that object even after its deletion is not freed. This function will be called for every object removed (deleted) from the application. When references to an object are created inside a command which are not related to the geomContainer of the object, in order to prevent memory leak this command has to implement an onRemoveObjectFromViewer to delete those references. onCmdRun(self, cmd, *args, **kw): if the list in self.vf.cmdsWithOnRun[cmd] holds this command, each time cmd runs command.onCmdRun will be called if callListener is true The following methods are helper methods. log(self, *args, **kw): Method to log a command. args provides a list of positional arguments and kw is a dictionary of named arguments. This method loops over both args and kw and builds a string representation of their values. When a class is passed as one the arguments, an additional command is logged to load that class. This method also sets the command's lastCmdLog member. showForm(self, *args, **kw): If the inputForm object associated with the given formName already exists than it just deiconify the forms unless the force argument is set to true. Otherwise, showForm calls buildFormDescr with the given formName, then it creates an instance of InputForm with the given parameters and stores this object in the cmdForms dictionary, where the key is the formName and the value the InputForm object. (see the showForm documentation string for the description of the arguments) If a command generates geometries to be displayed in the camera, it is expected to create the geometry objects and add them to the appropriate GeometryContainer. The geometry should be be added to the molecule's geometry container using the .addGeom method of the geometry container. If the geoemtry should be updated uon modification events (i.e. atoms addition, deletion or editing) the command should pass itself as the 3rd argument to gcontainer.addGeom(). This will trigger the updateGeom method to be called upon modification events. if the default modification event method is not applicable, a command can overwrite it. def updateGeom(self, event, geomList): the event is a ViewerFramework.VF.ModificationEvent instance geomList is a list of geometries to be updated check out Pmv/mvCommand for an example of updateGeom working for several Pmv display commands A Python module implementing commands should implement the following at the end of the file so the commands are loadable in the application using the browseCommands command. commandList -- which is a list of dictionaries containing the following: 'name': command name (string) used as an alias to invoke the command from the commandline. 'cmd' : Command Class 'gui' : Typically is a commandGUI object but can be None if no GUI is associated with the Command An initModule method def initModule(viewer): for dict in commandList: viewer.addCommand(dict['cmd'], dict['name'], dict['gui']) This method will be used by the browseCommands command to load the given module into the application but also to determine which modules implement commands. """ objArgOnly = 1 negateKw = 2 def __init__(self, func=None): self.vf=None self.GUI=None self.name = '' self.lastCmdLog = [] self.flag = 0 self.busyCursor = 'watch' self.timeUsedForLastRun = 0. # -1 when command fails self.cmdForms = {} if func: self.func = func else: self.func = self.doit self.lastUsedValues = {} # key is formName, values is dict of defaults self.lastUsedValues['default'] = self.getValNamedArgs() # initialize list of callbacks which are called in beforeDoit() # and afterDoit() self.callbacksBefore = [] # contains tuples of (method, args, kw) self.callbacksAfter = [] # contains tuples of (method, args, kw) self.managedGeometries = [] # list of geometries 'owned' by this # command, used in updateGeoms self.createEvents = True # set to False to avoid command from issuing events self.undoStack = [] # SD Oct 2010 # self.undoStack stores objects needed to perform undo. # This replaces the need to store nodes and string representation for the undo log. self.objectState = {} def setLastUsedValues(self, formName='default', **kw): form = self.cmdForms.get(formName, None) values = self.lastUsedValues[formName] for k,v in kw.items(): if values.has_key(k): values[k] = v if form is None: values[k] = v else: widget = form.descr.entryByName[k]['widget'] if hasattr(widget, 'set'): widget.set(v) elif hasattr(widget, 'setvalue'): widget.setvalue(v) elif hasattr(widget, 'selectitem'): widget.selectitem(v) elif hasattr(widget, 'invoke'): try: widget.invoke(v) except: widget.invoke() else: print "Could not set the value of ", k, v def getLastUsedValues(self, formName='default', **kw): """Return dictionary of last used values """ return self.lastUsedValues[formName].copy() def updateGeom(self, event): """ Methad used to update geoemtries created by this command upon ModificationEvents. The event is a ViewerFramework.VF.ModificationEvent instance check out Pmv/mvCommand for an example of updateGeom working for several Pmv display commands """ return def warningMsg(self, msg): """ Method to display a popup window with a warning message, the title of the pop up window is the name of the command """ title = '%s WARNING'%self.name self.vf.warningMsg(msg, title=title) def getValNamedArgs(self): """ """ from inspect import getargspec args = getargspec(self.__call__.im_func) allNames = args[0][1:] defaultValues = args[3] if defaultValues is None: defaultValues = [] nbNamesArgs = len(defaultValues) posArgsNames = args[0][1:-nbNamesArgs] d = {} for name, val in zip(args[0][-nbNamesArgs:], defaultValues): d[name] = val return d #def __repr__(self): # return 'self.'+self.name def onAddCmdToViewer(self): """ method called when an instance of this command is added to the viewer. This enable viewer-addition time initializations""" pass def onAddNewCmd(self, newcommand): """ method called whenever a new command is added to the viewer """ pass def onCmdRun(self, command, *args, **kw): """ if the list in self.vf.cmdsWithOnRun[cmd] holds this command, each time cmd runs this method will be called """ pass def handleForgetUndo(self, *args, **kw): """ Gets called when this command falls off the undo list """ pass def setupUndoBefore(self, *args, **kw): """ This method is used to build a set of commands that will negate the effects of the current command. This is used to support Undo and Redo operations """ print "WARNING: %s.setupUndoBefore() is deprecated. Use negateCmdBefore()" % self.name return self.negateCmdBefore(*args, **kw) def negateCmdBefore(self, *args, **kw): """ This method returns a list of 'negate' commands . This method should have the same signature than the __call__. When this string is executed it should undo the actions of this command. The 'negate'commands will be appended to the self.vf.undo.cmdStac list if the command is successfuly carried out. This method handles only commands with the negateKw. Other commands have to overwrite it. """ # we handle commands that have a negate keyword argument if self.flag & self.negateKw: if kw.has_key('negate'): kw['negate'] = not kw['negate'] else: kw['negate'] = 1 if not kw['negate']: # negate off for undo ==> prefix with 'un' name = 'un'+self.name else: name = self.name return ([ (self, args, kw) ], name) ## def NEWaddUndoCall(self, cmdList, name ): ## """ ## Add an undo command to the stack of this command ## cmdList is a list of 3-tuples [( func, *args, **kw)] ## self.undo() will be added to the framework's undoCmdStack if the self ## executed successfully. self.undo will call all funcs in the cmdList ## """ ## #if not self.vf.undoOn: ## # return ## self.NEWundo.cmdStack.append( (cmdList, name) ) ## def undo(self, redo=False): ## """ ## pop cmdList from stack and execute each cmd in cmdlList ## """ ## if redo: ## stack = self.redoStack ## else: ## stack = self.undoStack ## if stack: ## cmdList, name = stack.pop() ## self.inUndo = True ## for cmd, args, kw in cmdList: ## cmd( *args, **kw) ## self.inUndo = False ## else: ## raise RunTimeError('Undo called for %s when undo stack is empty'%\ ## self.name) ## def addUndoCall(self, args, kw, name ): ## """build an undo command as a string using name as the name of the ## command args and kw provide arguments to that command. The string ## is appended to self.undoCmds which will be added to the undoCmdStack ## by afterDoit if the command is successfully executed""" ## self.undoStack.append([args, kw]) ## self.undoCmds = self.undoCmds + "self."+name+".undo()" + '\n' ## #import traceback;traceback.print_stack() ## def undo(self): ## if self.undoStack: ## args1, kw1 = self.undoStack.pop() ## self.doitWrapper(log=0, setupUndo=0, *args1, **kw1) ## else: ## self.doitWrapper(log=0, setupUndo=0) def setupUndoAfter(self, *args, **kw): print "WARNING: %s.setupUndoAfter() is deprecated. Use negateCmdAfter()" % self.name return self.negateCmdAfter(*args, **kw) def negateCmdAfter(self, *args, **kw): """A chance to modify negate commands after the command was carried out""" return None def beforeDoit(self, args, kw, log, busyIdle, topCommand): """called before specialized doit method is called""" if self.vf.hasGui: if busyIdle: self.vf.GUI.busy(self.busyCursor) if log and topCommand: w1 = self.vf.showHideGUI.getWidget('MESSAGE_BOX') if w1.winfo_ismapped(): if self.lastCmdLog and log: self.vf.message( self.lastCmdLog[-1] ) # call callbacks for cb, args, kw in self.callbacksBefore: if callable(cb): apply(cb, args, kw) def afterDoit(self, args, kw, busyIdle): """called after specialized doit method is called""" # calls the cleanup methods after the doit has been called. self.cleanup() if self.vf.hasGui: if busyIdle: self.vf.GUI.idle() if kw.has_key('redraw') : if kw['redraw']: self.vf.GUI.VIEWER.Redraw() # call callbacks for cb, args1, kw1 in self.callbacksAfter: if callable(cb): kw.update(kw1) cb(*(args+args1), **kw) def doitWrapper(self, *args, **kw): """wrapper of doit() to call beforeDoit and afterDoit()""" if self.vf.frozen(): return # negateCmds will hold commands to negate this command negateCmds = None if kw.has_key('redraw'): redraw = kw['redraw'] del kw['redraw'] else: redraw = 0 #print "doitWrapper:", self.name, # when called with topCommand=0, then log=0, busyIdle=0 and if kw.has_key('topCommand'): topCommand = kw['topCommand'] del kw['topCommand'] else: topCommand = 1 # setupNegate is True by default # when False we will not call negateCmdBefore and negateCmdAfter if kw.has_key('setupNegate'): setupNegate = kw['setupNegate'] del kw['setupNegate'] else: setupNegate = True if topCommand: self.vf.topNegateCmds = [] # used to accumulate negation commands for sub commands of this top command if kw.has_key('createEvents'): self.createEvents = kw.pop('createEvents') if topCommand: log = busyIdle = 1 else: log = busyIdle = 0 callListener = 1 if kw.has_key('log'): log = kw['log'] del kw['log'] if kw.has_key('callListener'): callListener = kw['callListener'] del kw['callListener'] if kw.has_key('setupUndo'): del kw['setupUndo'] print 'WARNING: setupUndo is deprecated, fix command', self.name if kw.has_key('busyIdle'): busyIdle = kw['busyIdle'] del kw['busyIdle'] # build log string here because will be messaged to gui if log and self.vf.hasGui: w1 = self.vf.showHideGUI.getWidget('MESSAGE_BOX') if w1.winfo_ismapped(): kw['log']=0 logst = self.logString( *args, **kw) if logst is None: log = False else: self.lastCmdLog.append(logst) del kw['log'] # initialize the progress bar, set it to 'percent' mode if self.vf.hasGui and busyIdle: self.vf.GUI.VIEWER.currentCamera.pushCursor('busy') gui = self.vf.GUI gui.configureProgressBar(mode='percent', labeltext=self.name) gui.updateProgressBar(progress=0) # set to 0% self.beforeDoit(args, kw, log, busyIdle, topCommand) if setupNegate and self.vf.userpref['Number of Undo']['value']>0: negateCmds = self.negateCmdBefore( *args, **kw ) if negateCmds and topCommand == False: for cmd in negateCmds[0]: if not cmd[-1].has_key("topCommand"): cmd[-1]["topCommand"] = topCommand # Update self.lastUsedValues defaultValues = self.lastUsedValues['default'] for key, value in kw.items(): if defaultValues.has_key(key): defaultValues[key] = value t1 = time() result = apply( self.vf.tryto, (self.func,)+args, kw ) t2 = time() # call onCmdRun of listeners #if callListener and self.vf.cmdsWithOnRun.has_key(self): # for listener in self.vf.cmdsWithOnRun[self]: # apply( listener.onCmdRun, (self,)+args, kw ) # after run, set the progress bar to 100% and write 'Done' if self.vf.hasGui and busyIdle: # Need to set the mode of your progress bar to percent # so that once the command is done it always displays Done 100%. # This is done because of floating value problems. gui.configureProgressBar(labeltext='Done', mode='percent', progressformat='percent') if gui.progressBar.mode == 'percent': gui.updateProgressBar(progress=100) # set to 100% if result != 'ERROR': self.timeUsedForLastRun = t2 - t1 kw['redraw'] = redraw if topCommand and log: self.vf.addCmdToHistory( self, args, kw) if log and self.vf.logMode != 'no': kw['log'] = log if self.lastCmdLog: # Only log if self.lastCmdLog is not None. self.vf.log( self.lastCmdLog[-1]) self.lastCmdLog.remove(self.lastCmdLog[-1]) # if self.vf.userpref['Number of Undo']['value']==0 we do not do anything for undo/redo if self.vf.userpref['Number of Undo']['value']>0: if setupNegate: negateCmdsAfter = self.negateCmdAfter( *args, **kw ) if negateCmdsAfter is not None: negateCmds = negateCmdsAfter if topCommand == False: for cmd in negateCmds[0]: if not cmd[-1].has_key("topCommand"): cmd[-1]["topCommand"] = topCommand # self.vf.NEWundo.inUndo is set to the number of commands that need to run to perform 1 Undo op # it is set to -1 when we are not performign an Undo inUndo = self.vf.NEWundo.inUndo # self.vf.redo.inUndo is set to the number of commands that need to run to perform 1 Redo op # it is set to -1 when we are not performign an Redo inRedo = self.vf.redo.inUndo if inUndo==-1 and inRedo==-1: # not doing Undo or Redo # we are running a command not triggered by undo or Redo # we add the negation of this command to the undo stack if topCommand: name = self.name if negateCmds: # add the negation for te top command tot he list self.vf.topNegateCmds.extend( negateCmds[0] ) name = negateCmds[1] if len(self.vf.topNegateCmds): # if the list of negations is not empty add it to Undo if kw.has_key('negate'): if kw['negate']: name = "un"+self.name self.vf.NEWundo.addUndoCall( *(self.vf.topNegateCmds, name) ) self.vf.topNegateCmds = [] elif negateCmds: # a negation of the current command is available # we need to accumulate the negation commands self.vf.topNegateCmds.extend( negateCmds[0] ) else: # at this point we are either looping over command for an Undo or a Redo if inUndo==-1: # inRedo is NOT -1 so we are in Redo mode if inRedo == 0 and negateCmds: # this comamnd is the last one in the list for this Redo OP self.vf.redo._cmdList[0].extend( negateCmds[0] ) # we add its negation to the list self.vf.NEWundo.addUndoCall( *self.vf.redo._cmdList ) # we put the ist on the undo stack else: if negateCmds: self.vf.redo._cmdList[0].extend( negateCmds[0] ) # this command is not the last one else: # inUndo is NOT -1 so we are in Undo mode if inUndo == 0 and negateCmds: # this comamnd is the last one in the list for this Undo OP self.vf.NEWundo._cmdList[0].extend( negateCmds[0] ) self.vf.redo.addUndoCall(*self.vf.NEWundo._cmdList ) else: if negateCmds: self.vf.NEWundo._cmdList[0].extend( negateCmds[0] ) else: self.timeUsedForLastRun = -1. self.vf.timeUsedForLastCmd = self.timeUsedForLastRun if self.vf.hasGui and busyIdle: self.vf.GUI.VIEWER.currentCamera.popCursor() if self.vf.hasGui and self.vf.GUI.ROOT is not None: t = '%.3f'%self.vf.timeUsedForLastCmd self.vf.GUI.lastCmdTime.configure(text=t) self.afterDoit(args, kw, busyIdle) negateCmds = None return result def doit(self, *args, **kw): """virtual method. Has to be implemented by the sub classes""" pass def cleanup(self, *args, **kw): """ virtual method. Has to be implemented by sub classes if some things need to be clean up after doit has been executed. Will be called by doitWrapper""" pass def checkDependencies(self, vf): """virtual method. Has to be implemented by the sub classes. Method called when command is loaded, if all the dependencies are not found the command won't be loaded.""" pass def strArg(self, arg): before = "" if type(arg) is types.ListType or type(arg) is types.TupleType: seenBefore = {} # used to save only once each before line needed if type(arg) is types.ListType: argstr = "[" endstr = "], " else: argstr = "(" endstr = ",), " for a in arg: astr, before = self._strArg(a) argstr += astr if before is not None: seenBefore[before] = True # if condition is needed to fix bug #734 "incomplete log string" if len(argstr) > 1: argstr = argstr[:-2]+endstr else: argstr = argstr+endstr for s in seenBefore.keys(): before += s+'\n' return argstr, before elif type(arg) is types.DictionaryType: seenBefore = {} # used to save only once each before line needed # d = {'k1':5, 'k2':6, 'k3':7, 'k8':14} argstr = "{" endstr = "}, " if len(arg)==0: #special handling for empty dictionary return "{}, ", before for key, value in arg.items(): astr, before = self._strArg(key) if before is not None: seenBefore[before] = True argstr += astr[:-2] + ':' astr, before = self._strArg(value) if before is not None: seenBefore[before] = True argstr += astr[:-2] + ',' argstr = argstr[:-1]+endstr return argstr, before else: # not a sequence return self._strArg(arg) def _strArg(self, arg): """ Method to turn a command argument into a string, FIXME describe what types of arguments are handled """ from mglutil.util.misc import isInstance if type(arg)==types.ClassType: before = 'from %s import %s'%(arg.__module__, arg.__name__) return arg.__name__+', ', before #elif type(arg)==types.InstanceType: elif isInstance(arg) is True: if isinstance(arg, Command): return 'self.'+arg.name+', ', None elif isinstance(arg, Geom): return "'"+arg.fullName+"', ", None elif isinstance(arg, ColorMap): return "'"+arg.name+"', ", None elif hasattr(arg, 'returnStringRepr'): # the returnStringRepr method has to be implemented by # the instance class and needs to return # the before string which can be None but usually is the # from module import class string # and the argst which is also a string allowing the # instanciation of the object. before, argst = arg.returnStringRepr() return argst+', ', before try: import cPickle pickle = cPickle before = 'import cPickle; pickle = cPickle' except: import pickle before = 'import pickle' self.vf.log( before ) sp = pickle.dumps(arg) # Add a \ so when the string is written in a file the \ or \n # are not interpreted. pl1 = string.replace(sp, '\\', '\\\\') picklelog = string.replace(pl1, '\n', '\\n') return 'pickle.loads("' + picklelog + '"), ', before elif type(arg) in types.StringTypes: arg1 = string.replace(arg, '\n', '\\n') if string.find(arg, "'") != -1: return '"'+ arg1 + '",', None else: return "'" + arg1 + "', ", None elif type(arg)==Numeric.ArrayType: before = 'from numpy.oldnumeric import array\n' #arg = arg.tolist() return repr(arg)+ ', ', before else: return str(arg) + ', ', None # FIXME seems unnecessary, one can simply override the strarg method ## def getLogArgs(self, args, kw): ## """hook for programers to modify arguments before they get logged""" ## return args, kw def buildLogArgList(self, args, kw): """build and return the log string representing the arguments a list of python statements called before is also built. This list has to be exec'ed to make sure the log can be played back""" if self.vf is None: return argString = '' ## args, kw = self.getLogArgs( args, kw ) before = [] for arg in args: s, bef = self.strArg(arg) argString = argString + s if bef is not None: before.append(bef) for name,value in kw.items(): s, bef = self.strArg(value) argString = argString + '%s=%s'%(name, s) if bef is not None: before.append(bef) return '('+argString[:-2]+')', before # remove last ", " def logString(self, *args, **kw): """build and return the log string""" argString, before = self.buildLogArgList(args, kw) log = '' for l in before: log = log + l + '\n' log = log + 'self.' + self.name + argString return log # this method will disappear after all commands are updated def log(self, *args, **kw): """ Method to log a command. args provides a list of positional arguments. kw is a dictionary of named arguments. """ import traceback traceback.print_strack() print 'VFCommand.log STILL USED' if self.vf.logMode == 'no': return logStr = apply( self.logString, args, kw) self.vf.log( logStr ) def __call__(self, *args, **kw): """None <- commandName( *args, **kw)""" return apply( self.doitWrapper, args, kw) def tkCb(self, event=None): """Call back function for calling this command from a Tkevent for instance key combinations""" self() def getArguments(self, *args, **kw): """This is where GUIs can be used to ask for arguments. This function shoudl always return a tuple (args and a dictionary kw)""" if self.flag & self.objArgOnly: args = (self.vf.getSelection(),) else: args = () return args, kw def guiCallback(self, event=None, log=None, redraw=None, master=None): """Default callback function called by the gui""" kw = {} if log!=None: kw['log']=log if redraw!=None: kw['redraw']=redraw args, kw = apply( self.getArguments, (), kw) if not kw.has_key('redraw'): kw['redraw']=1 if not kw.has_key('log'): kw['log']=1 if event: return apply( self.doitWrapper, (event,)+args, kw ) else: return apply( self.doitWrapper, args, kw ) def getHelp(self): modName = self.__module__ pName = modName.split('.')[0] path = __import__(modName).__path__[0] docDir = os.path.split(path)[0] cName = '%s'%self.__class__ docHTML = '%s-class.html'%cName docPath = os.path.join(docDir, 'doc') if not os.path.exists(docPath): urlHelp = "http://mgltools.scripps.edu/api/" urlHelp += "%s"%modName.split('.')[0] urlHelp = urlHelp + "/" + docHTML else: urlHelp = os.path.join(docPath, docHTML) return urlHelp def showForm(self, formName='default', force=0, master=None, root=None, modal=0, blocking=1, defaultDirection='row', closeWithWindow=1, okCfg={'text':'OK'}, cancelCfg={'text':'Cancel'}, initFunc=None, scrolledFrame=0, width=100, height=200, okcancel=1, onDestroy=None, okOnEnter=False, help=None, posx=None, posy=None, postCreationFunc=None, postUsingFormFunc=None): """ val/form <- getUserInput(self, formName, force=0, master=None, root=None, modal=0, blocking=1, defaultDirection='row', closeWithWindow=1, okCfg={'text':'OK'}, cancelCfg={'text':'Cancel'}, initFunc=None, scrolledFrame=0, width=100, height=200, okcancel=1, onDestroy=None, help=None, posx=None, posy=None, postCreationFunc=None) MAKE SURE that the list of arguments passed to showForm is up to date with the list of arguments of the InputForm constructor. showForm will return either the dictionary of values (name of the widget: value of the widget) if the form has a OK/CANCEL button or the form object itself. required arguments: formName -- String which will be given to buildFormDescr. It refers to the name of the inputform to be created. optional arguments : ms APRIL 2012 : TherE is some confusion here: root is really the frame in which the widget will be constructed. master is only use to set transient (i.e. when master is iconified, the form is iconified too) master -- is master is iconified the form will iconify too. Obsolete now since form now appear in the default master. Was introduced to palce forms in dashboard root -- if root is not specified a Tkinter.TopLevel will be created. modal -- Flag specifying if the form is modal or not. When a form is modal it grabs the focus and only releases it when the form is dismissed. When a form is modal an OK and a CANCEL button will be automatically added to the form. (default = 1) blocking -- Flag specifying if the form is blocking or not. When set to 1 the form is blocking and the calling code will be stopped until the form is dismissed. An OK and a CANCEL button will be automatically added to the form. (default = 0) defaultDirection -- ('row', 'col') specifies the direction in which widgets are gridded into the form by default. (default='row') closeWithWindow -- Flag specifying whether or not the form should be minimized/maximized when the master window is. (default=1) okCfg -- dictionnary specifying the configuration of the OK button. if a callback function is specified using the keyword command this callback will be added to the default callback Ok_cb cancelCfg -- dictionnary specifying the configuration of the CANCEL button if a callback function is specified using the keyword command this callback will be added to the default callback Ok_cb initFunc -- specifies a function to initialize the form. onDestroy -- specifies a function to be called when using the close widget of a window. okcancel -- Boolean Flag to specify whether or not to create the OK and CANCEL button. scrolledFrame -- Flag when set to 1 the main frame is a scrollable frame else it is static Frame (default 0) width -- specifies the width of the main frame (400) height -- specifies the height of the main frame. (200) help -- specifies the web adress to a help page. If this is provided a Help (?) button will be created which will open a web browser to the given adress. By default help URL is: http://www.scripps.edu/~sanner/software/help/PACKNAME/doc/moduleName.html#guiCallback Which is the documentation generated by Happydoc from the code's documentation strings. posy posy position wher the form is displayed postCreationFunc -- can be a function that will be called after the form is created but before we block if blocking for instance to make an animation. it will be called with form.root as an argument. postUsingFormFunc -- will be called after the user clicks on ok or cancel. """ from mglutil.gui.InputForm.Tk.gui import InputForm, InputFormDescr if self.vf.hasGui: #if self.cmdForms.has_key(formName): form = self.cmdForms.get(formName, None) #if force==1 or (root and form and root!=form.root): if root and form and root!=form.root: self.cmdForms[formName].destroy() #del self.cmdForms[formName] #if not self.cmdForms.has_key(formName): if True: formDescription = self.buildFormDescr(formName) if formDescription is None: val = {} return val if master==None: master = self.vf.GUI.ROOT if help is None: help = self.getHelp() #root = self.vf.GUI.getCmdsParamsMaster() #if not postCreationFunc: # postCreationFunc = self.vf.GUI.getAfterCreatingFormFunc() #if not postUsingFormFunc: # postUsingFormFunc = self.vf.GUI.getAfterUsingFormFunc() form = InputForm(master, root, formDescription, modal=modal, blocking=blocking, defaultDirection=defaultDirection, closeWithWindow=closeWithWindow, okCfg=okCfg, cancelCfg= cancelCfg, scrolledFrame=scrolledFrame, width=width,height=height,initFunc=initFunc, okcancel=okcancel, onDestroy=onDestroy, help=help, okOnEnter=okOnEnter) #form.root.bind('', form.Cancel_cb) if form.ownsRoot: if posx and posy: form.root.geometry("+%d+%d"%(posx,posy)) else: geom = form.root.geometry() # make sure the upper left dorner is visible w = string.split(geom, '+') changepos = 0 if w[1][0]=='-': posx = '+50' changepos=1 else: posx = '+'+w[1] if w[2][0]=='-': posy ='+50' changepos=1 else: posy = '+'+w[2] if changepos: form.root.geometry(posx+posy) # MS removed caching of forms as it created problems repacking # the form in the notebook in dashboard. The second time it # put the form on to of the tab self.cmdForms[formName] = form if postCreationFunc: postCreationFunc(form.root) if not (modal or blocking): form.go() return form else: values = form.go() if postUsingFormFunc: postUsingFormFunc(form.root) return values else: form = self.cmdForms[formName] form.deiconify() if form.ownsRoot: if posx and posy: form.root.geometry("+%d+%d"%(posx,posy)) else: # move form to middle of ViewerFramework GUI geom = self.vf.GUI.ROOT.geometry() # make sure the upper left dorner is visible dum,x0,y0 = geom.split('+') w,h = [int(x) for x in dum.split('x')] posx = int(x0)+(w/2) posy = int(y0)+15 form.root.geometry("+%d+%d"%(posx,posy)) if postCreationFunc: postCreationFunc(form.root) if not (modal or blocking): return form else: values = form.go() if postUsingFormFunc: postUsingFormFunc(form.root) return values else: self.warningMsg("nogui InputForm not yet implemented") def buildFormDescr(self, formName): """ descr <- buildFormDescr(self, formName): this virtual method is implemented in the classes derived from Command. This is where the inputFormDescr is created and the description of the widgets appended. If a command has several inputForm buildFormDescr should build all the inputFormDescr and you do a if / elif check to know which one to create. formName : string name of the form corresponding to this descr. """ pass def customizeGUI(self): """gets called by register method of the CommandGUI object after the gui for a command has been added to a viewer's GUI. It allows each command to set the configuration of the widgets in its GUI. Here is how to get to the widgets: # find the mneu bar name barName = self.GUI.menuDict['menuBarName'] # find the bar itsel bar = self.vf.GUI.menuBars[barName] # find the button name buttonName = self.GUI.menuDict['menuButtonName'] # find the button itself button = bar.menubuttons[buttonName] # find the entry name entryName = self.GUI.menuDict['menuEntryLabel'] # configure the entry name n = button.menu n.entryconfig(n.index(entryName), background = 'red' ) """ pass def addCallbackBefore(self, cb, *args, **kw): """ add a callback to be called before the doit method is executed""" assert callable(cb) self.callbacksBefore.append( (cb, args, kw) ) def addCallbackAfter(self, cb, *args, **kw): """ add a callback to be called after the doit method was executed""" assert callable(cb) self.callbacksAfter.append( (cb, args, kw) ) class CommandProxy(object): def __init__(self, vf, gui): self.command = None self.vf = vf self.gui = gui def guiCallback(self, event=None, log=None, redraw=None): pass ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/VFGUI.py0000644000175000017500000023427012155436464023410 0ustar moellermoeller############################################################################# # # Author: Michel F. SANNER # # Copyright: M. Sanner TSRI 2000 # ############################################################################# """ This module implements the class viewerFrameworkGUI. This class provides support for extending the GUI of a Viewer derived from the ViewerFramework base class """ # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/VFGUI.py,v 1.196 2013/06/10 20:55:16 annao Exp $ # # $Id: VFGUI.py,v 1.196 2013/06/10 20:55:16 annao Exp $ # import Tkinter, thread, string, Pmw, types from PIL import Image, ImageTk try: from TkinterDnD2 import COPY hasDnD2 = True except ImportError: hasDnD2 = False try: from DejaVu.Viewer import Viewer except ValueError: print "Can't find a suitable Viewer\n" import tkFileDialog from mglutil.util.misc import ensureFontCase from mglutil.util.callback import CallbackFunction from mglutil.util.packageFilePath import findFilePath from mglutil.gui.BasicWidgets.Tk.progressBar import ProgressBar, \ ProgressBarConf, ProgressBarUpd from mglutil.util.packageFilePath import getResourceFolderWithVersion import ViewerFramework, os from VFCommand import CommandGUI, ICONSIZES, ICONPATH from VF import VFEvent class RaiseToolPageEvent(VFEvent): pass class msg_box(Tkinter.Frame): """ message box with scrollable text """ def __init__(self, master=None, txt='', w=80, h=8): Tkinter.Frame.__init__(self, master) self.tx = Pmw.ScrolledText(self, usehullsize=1, hull_height=300) self.tx.pack(expand=1, fill='both', anchor='s') self.pack(side='bottom', expand=1, fill='both') # insert initial message self.tx.insert('end', txt) def append(self, str): """ insert at the end of the list """ self.tx.insert('end', str) self.tx.yview('end') def clear(self): self.tx.clear() def setText(self, text): self.tx.setvalue(text) self.tx.yview('end') import sys from mglutil.util.idleUtil import getShell class ViewerFrameworkGUI: """This class builds the GUI for the MoleculeViewer Class. The GUI consists of a Frame, containing 1 or more menuBars, a canvas holding the 3-D camera instance and a message box. Methods addMenuBar, addMenu and addMenuCommand modify the menuBars.""" def beforeRebuildDpyLists(self): if self.VIEWER.autoRedraw: self.VIEWER.currentCamera.update_idletasks() self.busyRedraw() def afterRedraw(self): if self.VIEWER.lastFrameTime: frameRate = 1./self.VIEWER.lastFrameTime else: frameRate = self.VIEWER.lastFrameTime self.frameRateTk.configure(text="%4.1f"%(frameRate)) def afterRebuildDpyLists(self): if self.suspendLight is False: self.setIdleLight(self.previousState) def dialog(self): # t="Do you wish to Quit?" # from SimpleDialog import SimpleDialog # d = SimpleDialog(self.ROOT, text=t, # buttons=["Quit","Cancel"], # default=0, title="Quit?") # ok=d.go() import tkMessageBox ok = tkMessageBox.askokcancel("Quit?","Do you Wish to Quit?") if ok: self.quit_cb() else: return # def keydown(self,event): # if event.keysym == 'Shift_L': # print 'Shift_l' # self.vf.setICOM(self.vf.select, modifier=None, log=0) # # #'Shift_R', 'Control_L', 'Control_R', # # 'Alt_L', 'Alt_R']: # #print 'key down' # # def keyup(self,event): # self.vf.setICOM(self.vf.printNodeNames, modifier=None, log=0) # #print 'key up' # def Enter_cb(self, event=None): # self.ROOT.focus_set() # self.ROOT.bind('', self.keydown) # self.ROOT.bind('', self.keyup) # # def Leave_cb(self, event=None): # self.ROOT.unbind('') # self.ROOT.unbind('') def softquit_cb(self): #print "ViewerFrameworkGUI.softquit_cb" #self.vf.GUI.ROOT.option_clear() # set .GUI.registered to false for each command to force the GUI # to be created again if another ViewerFramework is created for cmd in self.vf.commands.items(): if cmd[1].GUI: cmd[1].GUI.registered=False for com in self.vf.cmdsWithOnExit: com.onExitFromViewer() for c in self.VIEWER.cameras: c.eventManager.RemoveCallback('', c.Map) c.eventManager.RemoveCallback('', c.Expose) c.eventManager.RemoveCallback('', c.Expose) c.eventManager.RemoveCallback('', c.Enter_cb) if hasattr(self.vf, 'logAllFile'): rcFolder = getResourceFolderWithVersion() dirList = os.listdir(rcFolder) import time lTimeNow = time.time() for fname in dirList: if fname.startswith('mvAll_') \ and ( fname.endswith('.log.py') or fname.endswith('.log.py~') ) \ and self.vf.logAllFile.name.endswith(fname) is False: #so we keep last ten days current session files lDecomposedCurrentLogFilename = fname.strip('mvAll_') lDecomposedCurrentLogFilename = lDecomposedCurrentLogFilename.rstrip('.log.py') lDecomposedCurrentLogFilename = lDecomposedCurrentLogFilename.replace('-', ' ') lDecomposedCurrentLogFilename = lDecomposedCurrentLogFilename.replace('_', ' ') #print "lDecomposedCurrentLogFilename", lDecomposedCurrentLogFilename lTime = time.strptime(lDecomposedCurrentLogFilename, "%Y %m %d %H %M %S") lTimeDifference = lTimeNow - time.mktime(lTime) #print "lTimeDifference", lTimeDifference if lTimeDifference > 3600*24*10 : #so we keep last ten days current session files os.remove(os.path.join(rcFolder,fname)) self.vf.logAllFile.close() if hasattr(self.vf, 'logSelectFile'): self.vf.logSelectFile.close() if self.vf.userpref.has_key('Save Perspective on Exit'): logPerspective = self.vf.userpref['Save Perspective on Exit']['value'] if logPerspective == 'yes': self.vf.Exit.savePerspective() if self.pyshell: self.pyshell._close() self.VIEWER.Exit() if self.VIEWER.autoRedraw: self.ROOT.update() # this test is a hack to stop a tclerror when destroying ROOT in continuity if hasattr(self,'dontDestroyRoot'): self.ROOT = None else: self.ROOT.quit() self.ROOT.destroy() self.ROOT = None def quit_cb(self): #print "ViewerFrameworkGUI.quit_cb" self.softquit_cb() # added to kill python shell if self.withShell: try: sys.exit(0) finally: os._exit(0) # this is needed to avoid Tracebacks else: sys.stdin.__exit__() # hack to really exit code.interact ## def getCmdsParamsMaster(self): ## if self.cmdsParamsMaster is None: ## self.cmdsParamsMaster = Tkinter.Toplevel(self.root) ## return self.cmdsParamsMaster ## def setCmdsParamsMaster(self, master): ## assert isinstance(master, (Tkinter.Tk, Tkinter.Toplevel, ## Tkinter.Frame)) ## self.cmdsParamsMaster = master ## def getAfterCreatingFormFunc(self): ## return self.afterCreatingFormFunc ## def setAfterCreatingFormFunc(self, func): ## assert callable(func) ## self.afterCreatingFormFunc = func ## def getAfterUsingFormFunc(self): ## return self.afterUsingFormFunc ## def setAfterUsingFormFunc(self, func): ## assert callable(func) ## self.afterUsingFormFunc = func def forgetMainForm(self): self.mainNoteBook.forget() def packMainForm(self): self.mainNoteBook.pack(side='top', fill='both', expand=1) def __init__(self, viewer, title='ViewerFramework', root=None, tro=1, viewerClass=None, withShell=1, verbose=True): """Construct a ViewerFrameworkGUI for the ViewerFramework 'viewer', tro is TransformRootOnly for viewer""" self.vf = viewer self.TITLE = title self.ICONDIR = os.path.join(ICONPATH, '32x32') self.toolbarList = [] self.toolbarCheckbuttons = {} ## self.cmdsParamsMaster = None # This will be a frame in which the forms ## # for commands will be displayed ## self.afterCreatingFormFunc = None ## self.afterUsingFormFunc = None if root == None: if hasDnD2: try: from TkinterDnD2 import TkinterDnD self.ROOT = TkinterDnD.Tk() except ImportError: self.ROOT = Tkinter.Tk() else: self.ROOT = Tkinter.Tk() if sys.platform=='darwin': self.ROOT.geometry("600x200+20+20") else: self.ROOT.geometry("+20+20") else: assert isinstance(root, Tkinter.Tk) or \ isinstance(root, Tkinter.Toplevel) or \ isinstance(root, Tkinter.Frame) or \ isinstance(root, Tkinter.Canvas) self.ROOT = root #self.ROOT.bind('', self.Enter_cb) #self.ROOT.bind('', self.Leave_cb) self.ROOT.minsize(width = 200, height = 200) if isinstance(self.ROOT, Tkinter.Tk) or \ isinstance(self.ROOT, Tkinter.Toplevel): # bind to the close box self.ROOT.protocol("WM_DELETE_WINDOW", self.dialog) # give a title self.ROOT.title(self.TITLE) # HOW DO I UPDATE THIS RIGHT AWAY... swidth = self.ROOT.winfo_screenwidth() sheight = self.ROOT.winfo_screenheight() self.ROOT.maxsize(swidth-50, sheight-50) # set font size based on screen resolution (Jeff 02/02) # use highest priority (i.e. 100) to make sure that # ChangeFont.getCurrentFont() gets this font priority=100 #if self.ROOT.winfo_screenwidth() < 1280: # self.ROOT.option_add( # '*font',(ensureFontCase('helvetica'), 12, 'normal'), priority) #else: self.ROOT.option_add( '*font',(ensureFontCase('helvetica'), 10, 'normal'), priority) filePath = findFilePath(fileName = 'Tkinter.defaults', packageName = 'ViewerFramework') if filePath: #self.ROOT.option_readfile('./Tkinter.defaults') self.ROOT.option_readfile(filePath) # create a paned widget ## self.pw = Pmw.PanedWidget(self.ROOT, ## orient='horizontal', ## hull_borderwidth = 1, ## hull_relief = 'sunken') ## self.aboveCamPane = self.pw.add('above', min = .1, max = .1) ## self.cameraPane = self.pw.add('camera', min = .1, max = .1) ## self.belowCamPane = self.pw.add('below', min = .1, max = .1) self.menuBars={} # dictionary of menubars and buttonbars # create frame to hold menubars and buttonbars self.mBarFrame = Tkinter.Frame(self.ROOT, borderwidth=2, relief='raised') self.mBarFrame.pack(side='top', expand=0, fill='x') ## ## self.ROOT is the main container in which we added a frame ## for menu bars packed at the top ## ## Here we create a Frame under the menu bar that applications ## can use to place their widgets ## We keep track of who is using this space (by packing itseld ## inside self.mainAreaUser. The main area user has to have a method ## user.forgetMainForm() which can be called by another user when it ## wants to use the are # master for placing widgets such as the NoteBook with 3D widgets # vision etc. self.mainAreaMaster = Tkinter.Frame(self.ROOT) self.mainAreaMaster.pack(side='top', fill='both', expand=1) # create the mainNotebook in mainArea self.mainNoteBook = Pmw.NoteBook(self.mainAreaMaster, tabpos=None) self.packMainForm() # remember that the 3D view is usign the main area self.mainAreaUser = self # create the page for 3D View in mainNoteBook #self.mainButtonBarTabVar = Tkinter.StringVar() View3DMaster = self.mainNoteBook.add('3D View') # add a notebook where the dockedCamera used to be #self.view3DButtonBarMaster = Tkinter.Frame(View3DMaster) #self.view3DButtonBarMaster.pack(side='top', fill='x', expand=0) #cb = CallbackFunction(self.mainNoteBook.selectpage, '3D View') #button = Tkinter.Radiobutton( # self.view3DButtonBarMaster, # command=cb, width=10, # var=self.mainButtonBarTabVar, # value='Tools', indicatoron=False, # text='3D', font=('Helvetica', '', 10), padx=3, pady=0) #button.pack(side='left', anchor='w') # create a paned widget to hold workspace and sequence widget self.VPane = Pmw.PanedWidget( View3DMaster, orient='vertical', hull_relief='sunken',) self.VPane.pack(anchor='n', expand=1, fill='both') self.workspaceM = self.VPane.add('Workspace', min=200) #self.workspaceM.pack(anchor='n', expand=1, fill='both') # workspace is a paned widget in which to pack the camera and # other panes such a tools GUI self.workspace = Pmw.PanedWidget( self.workspaceM, orient='horizontal', hull_relief='sunken', separatorthickness=4, separatorrelief='flat', handlesize=0) #hull_width=width, hull_height=height) self.workspace.pack(anchor='n', expand=1, fill='both') # add a pane for tools such as dashboards and styles self.toolsNoteBookMaster = self.workspace.add('ToolsNoteBook', min=10)#, size=.4) # add a pane for camera dockCamMaster = self.workspace.add('DockedCamera', min=100)#, size=.6) # configure separator self.workspace.component('separator-1').configure(bg='#ADAF63') # add button to collapse tools area filename = os.path.join(ICONPATH, 'leftarrow1.png') self.collapsePhoto = ImageTk.PhotoImage(file=filename) filename = os.path.join(ICONPATH, 'rightarrow1.png') self.expandPhoto = ImageTk.PhotoImage(file=filename) self.toolsButtonBarMaster = Tkinter.Frame(self.toolsNoteBookMaster) self.toolsButtonBarMaster.pack(fill='x', expand=0, side='top') self.toolsButtonBarTabVar = Tkinter.StringVar() self.collapseToolsW = Tkinter.Button( self.toolsButtonBarMaster, image=self.collapsePhoto, command=self.collapseTools) self.collapseToolsW.pack(side='left', anchor='w') # add a notebook in the tools area self.toolsNoteBook = Pmw.NoteBook( self.toolsNoteBookMaster, tabpos=None, raisecommand=self.raiseToolPage) self.toolsNoteBook.pack(fill='both', expand=1, padx=1, pady=1) # create a frame for the docked camera self.vwrCanvasDocked = Tkinter.Frame(dockCamMaster, width=500, height=200) self.vwrCanvasDocked.pack(side='left', anchor='nw', expand=1, fill='both') self.vwrCanvasDocked.forget() self.vwrCanvasFloating = Tkinter.Toplevel(width=600, height=600) self.vwrCanvasFloating.withdraw() self.vwrCanvasFloating.update_idletasks() self.vwrCanvasFloating.transient(self.ROOT) # build a 3D window VIEWER_root = Tkinter.Toplevel() VIEWER_root.withdraw() self.VIEWER = viewerClass( self.vwrCanvasFloating, 1, autoRedraw=True, verbose=verbose,guiMaster=VIEWER_root,) #cnf = {"addScenarioButton": False}) ## we suspend redraw here to avoid added geoemtries from ## triggering unneeded redraws self.VIEWER.suspendRedraw = True self.VIEWER.TransformRootOnly(tro) # create Geom container for misc geoms from DejaVu.Geom import Geom miscGeom = Geom("misc", shape=(0,0), pickable=0, protected=True) miscGeom.isScalable = 0 miscGeom.animatable = False self.VIEWER.AddObject(miscGeom) self.miscGeom = miscGeom # used to make sure only main thread handles expose events import thread self.mainThread = thread.get_ident() # add the InfoBar self.infoBar = Tkinter.Frame(self.ROOT,relief = 'sunken', bd = 1) self.infoBar.pack(side='bottom', fill='x') Tkinter.Label(self.infoBar, text="Mod.:").pack(side='left') self.icomLabelMod=Tkinter.Label(self.infoBar, text="None", width=8, relief='sunken', borderwidth=1, anchor='w') self.icomLabelMod.pack(side='left') Tkinter.Label(self.infoBar, text="Time:").pack(side='left') self.lastCmdTime=Tkinter.Label(self.infoBar, text="0.0", width=6, relief='sunken', borderwidth=1, anchor='w') self.lastCmdTime.pack(side='left') Tkinter.Label(self.infoBar, text="Selected:").pack(side='left') self.pickLabel=Tkinter.Label(self.infoBar, text="None", width=15, relief='sunken', borderwidth=1, anchor='w', cursor='hand2') self.pickLabel.pack(side='left') # add DejaVu GUI Checkbutton to Toolbar toolbarDict = {} toolbarDict['name'] = 'DejaVu_GUI' toolbarDict['type'] = 'Checkbutton' toolbarDict['icon1'] = '3Dgeom.gif' toolbarDict['icon_dir'] = ICONPATH toolbarDict['balloonhelp'] = 'DejaVu GUI' toolbarDict['index'] = 4 toolbarDict['cmdcb'] = self.showHideDejaVuGUI self.DejaVuGUIVariable = Tkinter.IntVar() toolbarDict['variable'] = self.DejaVuGUIVariable self.toolbarList.append(toolbarDict) self.VIEWER.GUI.top.master.title('DejaVu GUI') self.VIEWER.GUI.top.master.protocol("WM_DELETE_WINDOW",self.showHideDejaVuGUI) # add Float Camera Checkbutton to Toolbar toolbarDict = {} toolbarDict['name'] = 'Float_Camera' toolbarDict['type'] = 'Checkbutton' toolbarDict['icon1'] = 'float.gif' toolbarDict['icon_dir'] = ICONPATH toolbarDict['balloonhelp'] = 'Float Camera' toolbarDict['index'] = 3 toolbarDict['cmdcb'] = self.floatCamera_cb self.floatCamVariable = Tkinter.IntVar() self.floatCamVariable.set(1) toolbarDict['variable'] = self.floatCamVariable self.toolbarList.append(toolbarDict) # add the busy indicator self.currentState = self.previousState = 'idle' # can be 'busy' or 'redraw' or 'idle' # flag when turn on the idle light cannot be changed self.suspendLight = False self.busyLight=Tkinter.Frame(self.infoBar, relief=Tkinter.SUNKEN, borderwidth=1) self.suspendLight = False self.idleImage = os.path.join(self.ICONDIR,'idle.gif') self.redrawImage = os.path.join(self.ICONDIR,'redraw.gif') self.busyImage = os.path.join(self.ICONDIR,'busy.gif') self.busyIcon = Tkinter.PhotoImage(file=self.idleImage, master=self.ROOT) self.busyCanvas = Tkinter.Canvas(self.busyLight, width=self.busyIcon.width(), height=self.busyIcon.height() - 4 ) self.busyCanvas.create_image(0, 0, anchor = Tkinter.NW, image=self.busyIcon) self.busyCanvas.pack() self.busyLight.pack(side='right') # add the frameRate indicator self.frameRateTk=Tkinter.Label(self.infoBar, relief=Tkinter.SUNKEN, borderwidth=1, width=5, text="00.0") self.frameRateTk.pack(side='right') Tkinter.Label(self.infoBar, text="FR:").pack(side='right') # spinOptionMenu lSpinTuple = ('Spin off', 'Spin', 'Bounce', 'Oscillate', 'Show settings') def spinOptionMenuFunc(val): lSpinVar = self.VIEWER.currentCamera.trackball.spinVar.get() self.VIEWER.currentCamera.trackball.lastSpinVar = 0 if val == 'Show settings': self.VIEWER.currentCamera.trackball.showSpinGui() self.spinOptionMenu.invoke(lSpinVar) else: lSpinItems = {'Spin off':0, 'Spin':1, 'Bounce':2, 'Oscillate':3 } if lSpinVar != lSpinItems[val]: self.VIEWER.currentCamera.trackball.spinVar.set(lSpinItems[val]) self.VIEWER.currentCamera.trackball.toggleCycle(docb=False) from DejaVu import defaultSpinningMode self.spinOptionMenu = Pmw.OptionMenu( self.infoBar, initialitem=lSpinTuple[defaultSpinningMode], command=spinOptionMenuFunc, items=lSpinTuple, menubutton_pady=0, ) self.VIEWER.spinCallBack = self.spinOptionMenu.invoke self.spinOptionMenu.pack(side='right') self.VIEWER.beforeRebuildDpyLists = self.beforeRebuildDpyLists self.VIEWER.afterRebuildDpyLists = self.afterRebuildDpyLists self.VIEWER.afterRedraw = self.afterRedraw self.screenHeight = self.ROOT.winfo_screenheight() self.screenWidth = self.ROOT.winfo_screenwidth() # scrollable text to log the events self.MESSAGE_BOX = None self.set_up_message_box('') # create the Python shell self.withShell = withShell if self.withShell: self.pyshell = getShell(self.mainThread, rootTk = self.ROOT, enable_shell=True, enable_edit=False, debug=False) self.pyshell.menubar.children['file'].delete('Close','Exit') self.pyshell.menubar.children['file'].add_command( label='Clear Ouput', command=self.clearPyShell ) # hide it self.pyshell.top.withdraw() self.pyshell.begin() else: self.pyshell = None Tkinter._default_root = self.ROOT #FIXME this won't work when we have multiple cameras #self.ehm = self.VIEWER.cameras[0].eventManager # stack to store name of current cursor before setting a newOne self.oldcursor = [] # instanciate the progress bar widget and 2 callable objects self.progressBar = ProgressBar(master=self.infoBar, labelside=None, width=150, height=15, mode='percent') self.progressBarConf = ProgressBarConf(self.progressBar) self.progressBarUpd = ProgressBarUpd(self.progressBar) # Position the floating camera above the menu bar and set # its width to the width -100 of the menu. cam = self.VIEWER.currentCamera import DejaVu if isinstance(cam,DejaVu.Camera.Camera): self.VIEWER.currentCamera.frame.master.protocol("WM_DELETE_WINDOW",self.camdialog) cposx = cam.winfo_x() cposy = cam.winfo_y() posx, posy, w, h = self.getGeom() camwidth = w - 150 if camwidth <=0 : camwidth = 500 cam.Set(rootx=posx, rooty=posy, width=camwidth) camheight = cam.winfo_height() # need to make sure that this is not outside of the screen. #self.setGeom(posx, posy+camheight+80, int(w), int(h)+50) self.ROOT.geometry('+%s+%s' % ( posx, posy+camheight+8) ) self.naturalSize() self.VIEWER.suspendRedraw = False self.addCameraCallback('', self.updateInfoBar) self.addCameraCallback('',self.updateInfoBar) if hasDnD2: if hasattr(self.ROOT, "drop_target_register"): self.ROOT.drop_target_register('*') # make root drop target self.ROOT.dnd_bind('<>', self.drop) # drop call back def raiseToolPage(self, page): # create an event when page is selected in the Tools notebook event = RaiseToolPageEvent( page) self.vf.dispatchEvent( event ) def collapseTools(self, event=None): # get starting width self.toolsNoteBookMasterWidth = width = self.toolsNoteBookMaster.winfo_width() workspace = self.workspace nbSteps = 10. w = self.collapseToolsW.winfo_width() dx = (width-w)/(nbSteps-1) for i in range(int(nbSteps)): w = width - i*dx workspace.configurepane('ToolsNoteBook', size=int(w)) self.collapseToolsW.configure(image=self.expandPhoto, command=self.expandTools) def expandTools(self, event=None): width = self.toolsNoteBookMasterWidth if width is None: return workspace = self.workspace nbSteps = 10 dx = (width-10)/(nbSteps-1) for i in range(nbSteps): w = 10 + i*dx workspace.configurepane('ToolsNoteBook', size=int(w)) self.collapseToolsW.configure(image=self.collapsePhoto, command=self.collapseTools) def drop_cb(self, files): # to be overriden for f in files: print f def drop(self, event): #print 'Dropped file(s):', type(event.data), event.data if event.data: # windows file name with space are between { } if '{' in event.data: files = [] file = '' for c in event.data: if c=='{': continue if c=='}': files.append(file) file = '' continue file+=c else: files = event.data.split() self.drop_cb(files) return COPY def updateInfoBar(self, event=None): vi = self.VIEWER if vi.isShift(): mod='Shift_L' elif vi.isControl(): mod='Control_L' elif vi.isAlt(): mod='Alt_L' else: mod=None self.icomLabelMod.configure( text=str(mod) ) def naturalSize(self): self.ROOT.update() w = self.ROOT.winfo_reqwidth() h = self.ROOT.winfo_reqheight() self.ROOT.geometry('%dx%d' % ( w, h) ) def removeCameraCallback(self, event, function): """ Remove function as a call back to the event handler managers of all cameras """ for c in self.VIEWER.cameras: c.eventManager.RemoveCallback(event, function) def addCameraCallback(self, event, function): """Add function as a call back to the event handler managers of all cameras """ for c in self.VIEWER.cameras: c.eventManager.AddCallback(event, function) def isCameraFloating(self): """returns true id camera is floating and false if it is docked """ return self.floatCamVariable.get()==1 def rebuildCamera(self, stereo=None): #print "rebuildCamera" vi = self.VIEWER vi.stopAutoRedraw() # get the position and the height of the camera cam = vi.currentCamera camx = cam.rootx camy = cam.rooty camheight = cam.height camwidth = cam.width # save the currentCamera camera state camState = cam.getState() fogState = cam.fog.getState() camCallbacks = cam.eventManager.eventHandlers if stereo is None: if cam.stereoMode == 'STEREO_BUFFERS': stereo = 'native' else: stereo = 'none' # get the camera canvas if self.vwrCanvasDocked.winfo_ismapped(): lCameraCanvas = self.vwrCanvasDocked else: lCameraCanvas = self.vwrCanvasFloating # withdraw the trackball gui (because it belongs to the camera) cam.trackball.hideSpinGui() vi.removeAllTheDisplayListsExceptTemplatesAndVBO() for g in vi.rootObject.AllObjects(): if hasattr(g, 'templateDSPL'): g.deleteTemplate() # Create a new camera in lCameraCanvas lNewCam = vi.AddCamera(master=lCameraCanvas, stereo=stereo, num=cam.num) for g in vi.rootObject.AllObjects(): if hasattr(g, 'templateDSPL'): g.makeTemplate() # attach the new trackball gui to the viewergui vi.GUI.spinMenuButton.configure(command=lNewCam.trackball.toggleSpinGui) lNewCam.trackball.set(cam.trackball) # Delete the previous camera lNewCamIndex = len(vi.cameras) - 1 lNewCam.shareCTXWith = vi.cameras[0].shareCTXWith lNewCam.shareCTXWith.remove(lNewCam) lNewCam.shareCTXWith.append(vi.cameras[0]) del(vi.cameras[0].shareCTXWith) lNewCam.SelectCamera() cam.Set(height=vi.cameras[0].height, width=vi.cameras[0].width) lCamTemp = vi.cameras[0] vi.cameras[0] = vi.cameras[lNewCamIndex] vi.cameras[lNewCamIndex] = lCamTemp vi.DeleteCamera(vi.cameras[lNewCamIndex]) cam = vi.currentCamera # Restore the light model vi.lightModel.apply() for l in vi.lights: if l.enabled: l.apply() # Restore the state of the camera lNewCamState = cam.getState() for key, value in lNewCamState.items(): if camState.has_key(key) and value == camState[key]: camState.pop(key) apply(cam.Set,(1, 0), camState ) apply(cam.fog.Set,(), fogState) vi.startAutoRedraw() cam.Expose() #to update projection cam.Enter_cb() # as current Camera events = ['', ''] for event in events: for cb in camCallbacks[event]: if not cb in cam.eventManager.eventHandlers[event]: self.addCameraCallback(event, cb) # Overwrite the Camera DoPick by the viewerFramework DoPick method. cam.DoPick = self.vf.DoPick def floatCamera_cb(self, event=None): if self.floatCamVariable.get()==1: self.floatCamera() else: self.dockCamera() def dockCamera(self, stereo=None): #print "dockCamera" # to avoid going twice in the func at startup as it creates # problems if _pmvrc contains a call to dockCamera() if self.vwrCanvasDocked.winfo_ismapped() == 0 \ and self.vwrCanvasFloating.winfo_ismapped() == 0 \ and self.floatCamVariable.get() == 0 : return if self.vwrCanvasDocked.winfo_ismapped(): # the camera is already docked return else: if self.floatCamVariable.get() == 1: self.floatCamVariable.set(0) vi = self.VIEWER vi.stopAutoRedraw() # get the position and the height of the floating camera cam = vi.currentCamera camx = cam.rootx camy = cam.rooty camheight = cam.height camwidth = cam.width # the currentCamera is floating # save the floating camera state camState = cam.getState() fogState = cam.fog.getState() camCallbacks = cam.eventManager.eventHandlers if stereo is None: if cam.stereoMode == 'STEREO_BUFFERS': stereo = 'native' else: stereo = 'none' self.vwrCanvasFloating.withdraw() # withdraw the trackball gui (because it belongs to the camera) cam.trackball.hideSpinGui() # Create a new camera in vwrCanvasDocked lNewCam = vi.AddCamera(master=self.vwrCanvasDocked, stereo=stereo, num=cam.num) # attach the new trackball gui to the viewergui vi.GUI.spinMenuButton.configure(command=lNewCam.trackball.toggleSpinGui) lNewCam.trackball.set(cam.trackball) # Delete the floating camera lNewCamIndex = len(vi.cameras) - 1 #lNewCam = vi.cameras[lNewCamIndex] lNewCam.shareCTXWith = vi.cameras[0].shareCTXWith lNewCam.shareCTXWith.remove(lNewCam) lNewCam.shareCTXWith.append(vi.cameras[0]) del(vi.cameras[0].shareCTXWith) lNewCam.SelectCamera() cam.Set(height=vi.cameras[0].height, width=vi.cameras[0].width) lCamTemp = vi.cameras[0] vi.cameras[0] = vi.cameras[lNewCamIndex] vi.cameras[lNewCamIndex] = lCamTemp vi.DeleteCamera(vi.cameras[lNewCamIndex]) cam = vi.currentCamera # Restore the state of the floating camera lNewCamState = cam.getState() for key, value in lNewCamState.items(): if camState.has_key(key) and value == camState[key]: camState.pop(key) apply(cam.Set,(1, 0),camState ) apply(cam.fog.Set,(), fogState) vi.startAutoRedraw() ## MS no longer needed as camera is in its own pane ## # See if infobar then need to pack it before infobar. ## if hasattr(self,'infoBar'): ## infobar = self.infoBar ## w1 = self.vf.showHideGUI.getWidget('MESSAGE_BOX') ## if w1.winfo_ismapped(): ## self.vwrCanvasDocked.pack(before=w1,anchor='n', ## expand=1, fill='both') ## elif infobar.winfo_ismapped(): ## self.vwrCanvasDocked.pack(before=infobar,anchor='n', ## expand=1, fill='both') ## else: ## self.vwrCanvasDocked.pack(anchor='n', expand=1, fill='both') ## else: ## self.vwrCanvasDocked.pack(anchor='n',expand=1, fill='both') # see if text messages box is visible w1 = self.vf.showHideGUI.getWidget('MESSAGE_BOX') if w1.winfo_ismapped(): self.vwrCanvasDocked.pack(before=w1,anchor='n', expand=1, fill='both') else: self.vwrCanvasDocked.pack(anchor='n',expand=1, fill='both') cam.Expose() #to update projection cam.Enter_cb() # as current Camera #self.addCameraCallback('', self.updateInfoBar) #self.addCameraCallback('',self.updateInfoBar) events = ['', ''] for event in events: for cb in camCallbacks[event]: if not cb in cam.eventManager.eventHandlers[event]: self.addCameraCallback(event, cb) # Overwrite the Camera DoPick by the viewerFramework DoPick method. cam.DoPick = self.vf.DoPick # Need to reposition and resize the menubar. menux, menuy, menuw, menuh = self.getGeom() width = max(menuw, camwidth) height = menuh + camheight self.setGeom(camx, 0, width, height) crooty = menuy+menuh-30 cam.Set(rootx=camx, rooty=crooty, width=width, height=camheight) if self.vf.logMode != 'no': txt = "self.GUI.dockCamera(stereo=\""+str(stereo)+"\")" self.vf.log(txt) self.MESSAGE_BOX.append(txt+"\n") def camdialog(self): import tkMessageBox ok = tkMessageBox.askokcancel("Quit camdialog?","Do you Wish to Quit?") if ok: self.quit_cb() else: return def floatCamera(self, stereo=None, parent=None): if parent is None: vwrCanvasFloating = self.vwrCanvasFloating if vwrCanvasFloating.winfo_ismapped(): return else: if self.floatCamVariable.get()==0: self.floatCamVariable.set(1) else: vwrCanvasFloating = parent vi = self.VIEWER vi.stopAutoRedraw() # the currentCamera is docking # save the docking camera state cam = vi.currentCamera camState = cam.getState() fogState = cam.fog.getState() camCallbacks = cam.eventManager.eventHandlers if stereo is None: if cam.stereoMode == 'STEREO_BUFFERS': stereo = 'native' else: stereo = 'none' self.vwrCanvasDocked.forget() # withdraw the trackball gui (because it belongs to the camera) cam.trackball.hideSpinGui() # Create a new camera in vwrCanvasFloating lNewCam = vi.AddCamera(master=vwrCanvasFloating, stereo=stereo, num=cam.num) # attach the new trackball gui to the viewergui vi.GUI.spinMenuButton.configure(command=lNewCam.trackball.toggleSpinGui) lNewCam.trackball.set(cam.trackball) # Delete the floating camera lNewCamIndex = len(vi.cameras) - 1 #lNewCam = vi.cameras[lNewCamIndex] lNewCam.shareCTXWith = vi.cameras[0].shareCTXWith lNewCam.shareCTXWith.remove(lNewCam) lNewCam.shareCTXWith.append(vi.cameras[0]) del(vi.cameras[0].shareCTXWith) lNewCam.SelectCamera() lNewCam.Set(height=vi.cameras[0].height, width=vi.cameras[0].width) lCamTemp = vi.cameras[0] vi.cameras[0] = vi.cameras[lNewCamIndex] vi.cameras[lNewCamIndex] = lCamTemp vi.DeleteCamera(vi.cameras[lNewCamIndex]) cam = vi.currentCamera # Restore the state of the docking camera lNewCamState = cam.getState() for key, value in lNewCamState.items(): if camState.has_key(key) and value == camState[key]: camState.pop(key) apply(cam.Set,(1, 0),camState ) apply(cam.fog.Set,(), fogState) vi.startAutoRedraw() vwrCanvasFloating.deiconify() cam.Expose() # for to update projection cam.Enter_cb(None) # for as current Camera # Overwrite the Camera DoPick by the viewerFramework DoPick method. cam.DoPick = self.vf.DoPick # Need to reposition and resize the menu bar and the camera # get the position and the height of the floating camera camx = cam.rootx camy = cam.rooty camheight = cam.height camwidth = cam.width menux, menuy, menuw, menuh = self.getGeom() width = menuw height = menuh - camheight rooty = menuy + camheight + 35 #35 leaves space for window decoration rootx = menux #cam.Set(rootx=rootx, rooty=menuy+1) cam.Enter_cb() #self.addCameraCallback('', self.updateInfoBar) #self.addCameraCallback('',self.updateInfoBar) events = ['', ''] for event in events: for cb in camCallbacks[event]: if not cb in cam.eventManager.eventHandlers[event]: self.addCameraCallback(event, cb) self.setGeom(rootx, rooty, width, self.ROOT.winfo_reqheight()) cam.frame.master.protocol("WM_DELETE_WINDOW",self.camdialog) if self.vf.logMode != 'no': txt = "self.GUI.floatCamera(stereo=\""+str(stereo)+"\")" self.vf.log(txt) self.MESSAGE_BOX.append(txt+"\n") def showHideDejaVuGUI(self): """show and hide the original DejaVu GUI.""" if self.VIEWER.GUI.shown: self.VIEWER.GUI.withdraw() self.DejaVuGUIVariable.set(0) else: self.VIEWER.GUI.deiconify() self.DejaVuGUIVariable.set(1) def geometry(self, width, height, xoffset=None, yoffset=None): """(width, height) <- geometry(width, height, xoffset=None, yoffset=None) configure the DejaVu camera to have the given height and width the xoffset and yoffset specify the upper left corner of the GUI """ vi = self.VIEWER cam = vi.cameras[0] # get dimensions of top window master = cam.frame.master.master dims = map(int, ((master.geometry()).split('+')[0]).split('x')) # first we set the width because it migh change the height of menus # we add 6 for the 2x3 camera border pixels geomstring = "%dx%d"%(width+6, dims[1]) if xoffset is not None: geomstring += "+%d"%xoffset if yoffset is not None: geomstring += "+%d"%yoffset # set the cam width and x,y offset vi.master.master.geometry(geomstring) cam.update() # compute the difference between the cam height and the top window # height dy = dims[1] - cam.height geomstring = "%dx%d"%(width+6, height+dy) vi.master.master.geometry(geomstring) cam.update() return cam.width, cam.height def showHideProgressBar_CB(self, name, oldvalue, value): #this callback is called when the user preference is set if value == 'hide': self.progressBar.hide() elif value == 'show': self.progressBar.show() def clearPyShell(self, event=None): self.pyshell.text.delete("1.0", "end-1c") def TB_cb(self, event=None): on = self.toolbarCheckbuttons['MESSAGE_BOX']['Variable'].get() self.vf.showHideGUI('MESSAGE_BOX', on) ## def setGeometryX(self): ## v = self.geometryX.get() ## x, y, w, h = self.getGeom() ## if v: ## self.setGeom( v, y, w, h) ## else: ## self.geometryX.setentry(x) ## def setGeometryY(self): ## v = self.geometryY.get() ## x, y, w, h = self.getGeom() ## if v: ## self.setGeom( x, v, w, h) ## else: ## self.geometryY.setentry(y) ## def setGeometryW(self): ## v = self.geometryW.get() ## x, y, w, h = self.getGeom() ## if v: ## self.setGeom( x, y, v, h) ## else: ## self.geometryW.setentry(w) ## def setGeometryH(self): ## v = self.geometryH.get() ## x, y, w, h = self.getGeom() ## if v: ## self.setGeom( x, y, w, v) ## else: ## self.geometryH.setentry(h) def setGeom(self, posx, posy, width, height): self.ROOT.geometry('%dx%d+%d+%d' % (width, height, posx, posy) ) def getGeom(self): geom = self.ROOT.winfo_geometry() size, x, y = string.split(geom, '+') w, h = string.split(size, 'x') return int(x), int(y), int(w), int(h) def belowCamera(self): """ move the menu window under the Camera """ if self.isCameraFloating(): menux, menuy, menuw, menuh = self.getGeom() camgeom = self.VIEWER.cameras[0].winfo_toplevel().geometry() camw, rest = camgeom.split('x') camw = int(camw) camh, camx, camy = [int(n) for n in rest.split('+')] screenh = self.ROOT.winfo_screenheight() if camy+camh+menuh+25 < screenh: self.setGeom(camx, camy+camh+25,menuw, menuh) else: diff = camy+camh+menuh+25-screenh self.setGeom(camx, camy+camh+25-diff,menuw, menuh) ## this configure was causing all the beeping on resize ## and was only use to update the X, Y W and H entries ## so I removed them ## def configure_cb(self, event=None): ## x, y, w, h = self.getGeom() ## self.geometryX.setentry(x) ## self.geometryY.setentry(y) ## self.geometryW.setentry(w) ## self.geometryH.setentry(h) def setIdleLight(self, state): if self.ROOT is None: return from os import path self.previousState = path.basename(self.busyIcon.cget('file'))[:-4] if state == 'idle': self.suspendLight = True # turn led green self.busyIcon.config(file=self.idleImage) if self.VIEWER.autoRedraw: self.busyCanvas.update() self.suspendLight = False if self.ROOT is None: return self.ROOT.config(cursor='') self.VIEWER.master.config(cursor='') self.MESSAGE_BOX.tx.component('text').config(cursor='xterm') elif state == 'busy': self.ROOT.config(cursor='watch') self.VIEWER.master.config(cursor='watch') self.MESSAGE_BOX.tx.component('text').config(cursor='watch') self.suspendLight = True # turn led red self.busyIcon.config(file=self.busyImage) if self.VIEWER.autoRedraw: self.busyCanvas.update() self.suspendLight = False elif state == 'redraw': self.ROOT.config(cursor='watch') self.VIEWER.master.config(cursor='watch') self.MESSAGE_BOX.tx.component('text').config(cursor='watch') self.suspendLight = True # turn led purple self.busyIcon.config(file=self.redrawImage) if self.VIEWER.autoRedraw: self.busyCanvas.update() self.suspendLight = False self.currentState = path.basename(self.busyIcon.cget('file'))[:-4] def setCursor(self, newCursor): """Set the cursor. list can be found in /usr/include/X11/cursorfont.h but remove the leading 'XC_' string""" if self.vf.userpref['changeCursor']['value']: c = self.vwrCanvasDocked.cget('cursor') self.vwrCanvasDocked.configure(cursor=newCursor) return c else: return '' def busyRedraw(self, cursor=None): self.setIdleLight('redraw') def busy(self, cursor=None): self.setIdleLight('busy') def idle(self): self.setIdleLight('idle') def configureProgressBar(self, **kw): # configure progress bar such as mode and max, size etc apply(self.progressBar.configure, (), kw) def updateProgressBar(self, progress=None): # set the progress bar to a given value self.progressBar.set(progress) def setShiftFlag(self,event): self.shiftFlag=1 def unSetShiftFlag(self,event): if event.state == 513: self.logScale(event) self.shiftFlag=0 def logUserPref_cb(self, name,old, new): if new=='continuous': # Bind all the Keys Releases to be able to log transformations. self.shiftFlag=0 self.pendingLog = [] self.addCameraCallback("", self.logRotation) self.addCameraCallback("", self.logTranslation) self.addCameraCallback("",self.logTranslation) self.addCameraCallback("", self.logScale) self.addCameraCallback("", self.logPivot) self.addCameraCallback("", self.setShiftFlag) self.addCameraCallback("", self.setShiftFlag) self.addCameraCallback("", self.setShiftFlag) self.addCameraCallback("", self.unSetShiftFlag) ## self.ehm.AddCallback("", self.logRotation) ## self.ehm.AddCallback("", self.logTranslation) ## self.ehm.AddCallback("",self.logTranslation) ## self.ehm.AddCallback("", self.logScale) ## self.ehm.AddCallback("", self.logPivot) ## self.ehm.AddCallback("", self.setShiftFlag) ## self.ehm.AddCallback("", self.setShiftFlag) ## self.ehm.AddCallback("", self.setShiftFlag) ## self.ehm.AddCallback("", self.unSetShiftFlag) if os.name == 'nt': #sys.platform == 'win32': self.addCameraCallback("", self.logFOV) else: self.addCameraCallback("", self.logFOV) self.addCameraCallback("", self.logFOV) elif old=='continuous': self.removeCameraCallback("", self.logRotation) self.removeCameraCallback("", self.logTranslation) self.removeCameraCallback("", self.logTranslation) self.removeCameraCallback("", self.logScale) self.removeCameraCallback("", self.logPivot) self.removeCameraCallback("", self.setShiftFlag) self.removeCameraCallback("", self.setShiftFlag) self.removeCameraCallback("", self.setShiftFlag) self.removeCameraCallback("", self.unSetShiftFlag) if os.name == 'nt': #sys.platform == 'win32': self.removeCameraCallback("", self.logFOV) else: self.removeCameraCallback("", self.logFOV) self.removeCameraCallback("", self.logFOV) ## self.ehm.RemoveCallback("", self.logRotation) ## self.ehm.RemoveCallback("", self.logTranslation) ## self.ehm.RemoveCallback("", ## self.logTranslation) ## self.ehm.RemoveCallback("", self.logScale) ## self.ehm.RemoveCallback("", self.logPivot) ## self.ehm.RemoveCallback("", self.setShiftFlag) ## self.ehm.RemoveCallback("", self.setShiftFlag) ## self.ehm.RemoveCallback("", self.setShiftFlag) ## self.ehm.RemoveCallback("", self.unSetShiftFlag) def logRotation(self, event): mode = self.VIEWER.currentCamera.currentTransfMode #if self.pendingLog and self.pendingLog[0] != 'rotation': # self.vf.log(self.pendingLog[-1]) # self.pendingLog = [] if mode == 'Object': obj = self.VIEWER.currentObject if self.pendingLog and \ (self.pendingLog[1] != 'object' or \ self.pendingLog[2]!=obj.name): self.vf.log(self.pendingLog[-1]) log = "self.transformObject('rotation', '%s', matrix=(%9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f),log=0)"%((obj.name,)+tuple(obj.rotation)) self.pendingLog = ["rotation","object",obj.name,log] elif mode == 'Clip': clip = self.VIEWER.currentClip if self.pendingLog and \ (self.pendingLog[1] != 'clip' or \ self.pendingLog[2]!=clip.name): self.vf.log(self.pendingLog[-1]) log = "self.setClip('%s', ratation=(%9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f),log = 0)"%((clip.name,)+tuple(clip.rotation)) self.pendingLog = ["rotation","clip",clip.name,log] elif mode == 'Camera': cam = self.VIEWER.currentCamera if self.pendingLog and \ (self.pendingLog[1] != 'camera' or \ self.pendingLog[2]!=cam.name): self.vf.log(self.pendingLog[-1]) log = "self.setCamera('%s', rotation=(%9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f),log = 0)"%((cam.name,)+tuple(cam.rotation)) self.pendingLog = ["rotation","camera",cam.name,log] elif mode == 'Light': light = self.VIEWER.currentLight if self.pendingLog and \ (self.pendingLog[1] != 'light' or \ self.pendingLog[2]!=light.name): self.vf.log(self.pendingLog[-1]) if not light.positional: log = "self.setLight('%s', direction=(%9.3f, %9.3f, %9.3f, %9.3f),log = 0)"%((light.name,)+tuple(light.direction)) self.pendingLog = ["rotation","light",light.name, log] elif mode == 'Texture': print 'log rotation Texture' self.vf.log(self.pendingLog[-1]) def logTranslation(self, event): mode = self.VIEWER.currentCamera.currentTransfMode ## if self.pendingLog and self.pendingLog[0] != 'translation': ## self.vf.log(self.pendingLog[-1]) ## self.pendingLog = [] if mode == 'Object': obj = self.VIEWER.currentObject if self.pendingLog and \ (self.pendingLog[1] != 'object' or \ self.pendingLog[2]!=obj.name): self.vf.log(self.pendingLog[-1]) log = "self.transformObject('translation', '%s', matrix=(%9.3f, %9.3f, %9.3f), log=0 )"%((obj.name,)+tuple(obj.translation)) self.pendingLog = ["translation","object",obj.name,log] elif mode == 'Clip': clip = self.VIEWER.currentClip if self.pendingLog and \ (self.pendingLog[1] != 'clip' or \ self.pendingLog[2]!=clip.name): self.vf.log(self.pendingLog[-1]) log="self.setClip('%s', translation=(%9.3f, %9.3f, %9.3f), log=0 )"%((clip.name,)+tuple(clip.translation)) self.pendingLog = ["translation","clip",clip.name,log] elif mode == 'Camera': cam = self.VIEWER.currentCamera if self.pendingLog and \ (self.pendingLog[1] != 'camera' or \ self.pendingLog[2]!=cam.name): self.vf.log(self.pendingLog[-1]) log = "self.setCamera('%s', translation=(%9.3f, %9.3f, %9.3f), log=0 )"%((cam.name,)+tuple(cam.translation)) self.pendingLog = ["translation","camera",cam.name,log] elif mode == 'Texture': print 'log translationtion Texture' self.vf.log(self.pendingLog[-1]) def logScale(self, event): mode = self.VIEWER.currentCamera.currentTransfMode ## if self.pendingLog and self.pendingLog[0] != 'scale': ## self.vf.log(self.pendingLog[-1]) ## self.pendingLog = [] if mode == 'Object': obj = self.VIEWER.currentObject if self.pendingLog and \ (self.pendingLog[1] != 'object' or \ self.pendingLog[2]!=obj.name): self.vf.log(self.pendingLog[-1]) log = "self.transformObject('scale', '%s', matrix=(%2.7f, %2.7f, %2.7f), log=0 )"%((obj.name,)+tuple(obj.scale)) self.pendingLog = ["scale","object",obj.name,log] elif mode == 'Clip': clip= self.VIEWER.currentClip if self.pendingLog and \ (self.pendingLog[1] != 'clip' or \ self.pendingLog[2]!=clip.name): self.vf.log(self.pendingLog[-1]) log = "self.setClip('%s', scale=(%2.7f, %2.7f, %2.7f), log=0 )"%((clip.name,)+tuple(clip.scale)) self.pendingLog = ["scale","clip",clip.name,log] elif mode == 'Camera': camera = self.VIEWER.currentCamera if self.pendingLog and \ (self.pendingLog[1] != 'camera' or \ self.pendingLog[2]!=camera.name): self.vf.log(self.pendingLog[-1]) log = "self.setCamera('%s', scale=(%2.7f, %2.7f, %2.7f), log=0 )"%((camera.name,)+tuple(camera.scale)) self.pendingLog = ["scale","camera",camera.name,log] elif mode == 'Texture': print 'log scale Texture' self.vf.log(self.pendingLog[-1]) def logPivot(self, event): mode = self.VIEWER.currentCamera.currentTransfMode ## if self.pendingLog and self.pendingLog[0] != 'pivot': ## self.vf.log(self.pendingLog[-1]) ## self.pendingLog = [] if mode == 'Object': obj = self.VIEWER.currentObject if self.pendingLog and \ (self.pendingLog[1] != 'object' or \ self.pendingLog[2]!=obj.name): self.vf.log(self.pendingLog[-1]) log = "self.transformObject('pivot', '%s', matrix=(%9.3f, %9.3f, %9.3f), log=0 )"%((obj.name,)+tuple(obj.pivot)) self.pendingLog = ["pivot","object",obj.name,log] self.vf.log(self.pendingLog[-1]) def logFOV(self, event): cam = self.VIEWER.currentCamera log = "self.transformCamera('fov', matrix=%6.3f, log=0 )"%(cam.fovy) self.vf.log(log) def set_up_message_box(self, welcome_message=''): """ set up the message box with a welcome message """ # already defined : retreat if self.MESSAGE_BOX != None: return self.MESSAGE_BOX = msg_box(self.ROOT, welcome_message) self.MESSAGE_BOX.forget() toolbarDict = {} toolbarDict['name'] = 'MESSAGE_BOX' toolbarDict['type'] = 'Checkbutton' toolbarDict['icon1'] = 'textBox.gif' toolbarDict['icon_dir'] = ICONPATH toolbarDict['balloonhelp'] = 'Message Box' toolbarDict['index'] = 2 toolbarDict['variable'] = None toolbarDict['cmdcb'] = self.TB_cb self.toolbarList.append(toolbarDict) def configMenuEntry(self, menuButton, menuEntry, **kw): """Method to modify the Tkinter properties of a menu entry""" index = menuButton.menu.index(menuEntry) apply( menuButton.menu.entryconfig, (index,), kw ) def message(self, str, NL=1): """ write into the message box """ if thread.get_ident()==self.mainThread: if NL: str = str+'\n' self.MESSAGE_BOX.append(str) else: print str def addMenuBar(self, name, kw={}, kw2={}): """add a menu bar to a viewer""" # Description of the frame mbar = apply(Pmw.ScrolledFrame, (self.mBarFrame,), kw) self.mbar = mbar #mbar = apply( Tkinter.Frame, (self.mBarFrame,) , kw) apply( mbar.pack, (), kw2) # this line is needed, else root menu hase huge padding mbar.component('frame').pack() self.menuBars[name] = mbar mbar.menubuttons = {} mbar.checkbuttons = {} mbar.radiobuttons = {} mbar.buttons = {} return mbar def addMenuButton(self, mbar, name, kw={}, kw2={}): """add a pull down menu to a menu bar""" #create menu button kw['text'] = name #kw['font'] = (ensureFontCase('helvetica'), 14) import Pmw if isinstance(mbar, Pmw.ScrolledFrame): menuB = apply( Tkinter.Menubutton, (mbar.interior(),), kw ) else: menuB = apply( Tkinter.Menubutton, (mbar,), kw ) apply( menuB.pack, (), kw2) #create pull down menuB.menu = Tkinter.Menu(menuB) mbar.menubuttons[name] = menuB # attach pull down menu to button menuB['menu'] = menuB.menu return menuB def addMenuCommand(self, menu, name, cb, index, after, before, image, kw={}): """ add a command entry to a pull down menu menu is a Tk menu bar name is the string of the menu entry cb is the callback to be called index is the rank in the menu after is a string of the menu entry after which to insert before is a string of the menu entry before which to insert image is a tring that point to a gif image index defaults to -1 which adds at the end. If an index != -1 is provided it will be used, else before i sused if specified, else after is used """ assert callable(cb) kw['label'] = name kw['command'] = cb #print name if index is -1: #if after: print name, 'AFTER', after, index if after is not None: #try: index = menu.index(after)+1 #except: # pass #if after: print name, 'AFTER', after, index #if before: print name, 'BEFORE', before, index if before is not None: try: index = menu.index(before)-1 except: pass #if before: print name, 'BEFORE', before, index if image is not None: import Image, ImageTk image = Image.open(image) image1 = ImageTk.PhotoImage(image, master=menu.master) kw['image'] = image1 if index==-1: apply( menu.add_command, (), kw) else: apply( menu.insert_command, (index,), kw ) def addCheckbutton(self, bar, name, cb, var, kw={}, kw2={}): """add a Checkbutton command to a menubar""" kw['text'] = name kw['command'] = cb kw['var'] = var if isinstance(bar, Pmw.ScrolledFrame): button = apply( Tkinter.Checkbutton, (bar.interior(),), kw) else: button = apply( Tkinter.Checkbutton, (bar,), kw) apply( button.pack, (), kw2) bar.checkbuttons[name] = button def addRadiobutton(self, bar, name, cb, var, kw={}, kw2={}): """add a Radiobutton command to a menubar""" kw['text'] = name kw['command'] = cb kw['var'] = var if isinstance(bar, Pmw.ScrolledFrame): button = apply( Tkinter.Radiobutton, (bar.interior(),), kw) else: button = apply( Tkinter.Radiobutton, (bar,), kw) apply( button.pack, (), kw2) bar.radiobuttons[name] = button def addButton(self, bar, name, cb, kw={}, kw2={}): """add a Button command to a menubar""" kw['text'] = name kw['command'] = cb if isinstance(bar, Pmw.ScrolledFrame): button = apply( Tkinter.Button, (bar.interior(),), kw) else: button = apply( Tkinter.Button, (bar,), kw) apply( button.pack, (), kw2) bar.buttons[name] = button def addCommandToplevelGUI(self): """add a toplevel""" pass def addCommandMenuGUI(self, cmdGUI, cmdcb): """add the menus for a Command to the current set of menus""" assert isinstance(cmdGUI, CommandGUI) gui = cmdGUI.menu # get the menu bar, create it if necessary barname = gui[5]['menuBarName'] if barname != None: if barname in self.menuBars.keys(): bar = self.menuBars[gui[5]['menuBarName']] else: bar = self.addMenuBar(barname, gui[0], gui[1]) else: bar = self.menuBars[self.menuBars.keys()[0]] cmdGUI.menuBar=bar # get the menuButton, create if if necessary menuname = gui[5]['menuButtonName'] if menuname != None: if menuname in bar.menubuttons.keys(): but = bar.menubuttons[gui[5]['menuButtonName']] else: but = self.addMenuButton(bar, menuname, gui[2], gui[3]) else: but = bar.menubuttons[bar.buttons.keys()[0]] cmdGUI.menuButton=but # check wether this entry should go into a cascade cname = gui[5]['menuCascadeName'] #if menuname=='File': # print 'ADDING', gui[5]['menuEntryLabel'], cname, gui[5]['cascadeIndex'] if cname is not None: index = gui[5]['cascadeIndex'] before = gui[5]['cascadeBefore'] after = gui[5]['cascadeAfter'] if index is -1: if after is not None: try: index = but.menu.index(after)+1 except: pass if before is not None: try: index = but.menu.index(before)-1 except: pass if gui[5]['separatorAboveCascade']==1: #print ' separatore above cascade', but.menu.add_separator() if but.menu.children.has_key(cname): menu = but.menu.children[cname] else: menu = Tkinter.Menu(but.menu) #print 'ADDING cascade %s at %d'%(cname, index) if index==-1: but.menu.add_cascade( label=cname, menu=menu ) else: but.menu.insert_cascade( index, label=cname, menu=menu ) # save this entry in the children dict but.menu.children[cname] = menu else: menu = but.menu if gui[5]['separatorAbove']==1: menu.add_separator() if gui[5]['separatorBelow']==1: sepBelow=1 else: sepBelow=0 # find out the call back function we need to call cb = gui[5]['cb'] if cb is None: cb = cmdcb if gui[5]['menuEntryType']=='command': self.addMenuCommand( menu, gui[5]['menuEntryLabel'], cb, gui[5]['index'], gui[5]['after'], gui[5]['before'], gui[5]['image'], gui[4] ) elif gui[5]['menuEntryType']=='checkbutton': cmdGUI.menuCheckbuttonVar = Tkinter.IntVar() cmdGUI.menuCheckbuttonVar.set(0) gui[4]['label'] = gui[5]['menuEntryLabel'] gui[4]['command'] = cb gui[4]['variable'] = cmdGUI.menuCheckbuttonVar index = gui[5]['index'] if index == -1: menu.add_checkbutton(gui[4]) else: menu.insert(index, 'checkbutton', gui[4]) if sepBelow: menu.add_separator() if gui[5]['separatorBelowCascade']==1: but.menu.add_separator() def addCheckbuttonMenuGUI(self, cmdGUI, cmdcb=None): """add the menus for a Command to the current set of menus""" assert isinstance(cmdGUI, CommandGUI) gui = cmdGUI.checkbutton cmdGUI.checkbuttonVar = Tkinter.IntVar() cmdGUI.checkbuttonVar.set(0) # get the menu bar, create it if necessary barname = gui[4]['barName'] if barname != None: if barname in self.menuBars.keys(): bar = self.menuBars[gui[4]['barName']] else: bar = self.addMenuBar(barname, gui[0], gui[1]) else: bar = self.menuBars[self.menuBars.keys()[0]] cmdGUI.menuBar=bar # find out the call back function we need to call cb = gui[4]['cb'] if cb is None: cb = cmdcb # add the button name = gui[4]['buttonName'] self.addCheckbutton( bar, name, cb, cmdGUI.checkbuttonVar, gui[2], gui[3]) def addRadiobuttonMenuGUI(self, cmdGUI, cmdcb=None): """add the menus for a Radiobutton to the current set of menus""" assert isinstance(cmdGUI, CommandGUI) gui = cmdGUI.radiobutton cmdGUI.radiobuttonVar = Tkinter.IntVar() cmdGUI.radiobuttonVar.set(0) # get the menu bar, create it if necessary barname = gui[4]['barName'] if barname != None: if barname in self.menuBars.keys(): bar = self.menuBars[gui[4]['barName']] else: bar = self.addMenuBar(barname, gui[0], gui[1]) else: bar = self.menuBars[self.menuBars.keys()[0]] cmdGUI.menuBar=bar # find out the call back function we need to call cb = gui[4]['cb'] if cb is None: cb = cmdcb # add the button name = gui[4]['buttonName'] self.addRadiobutton( bar, name, cb, cmdGUI.radiobuttonVar, gui[2], gui[3]) def addButtonMenuGUI(self, cmdGUI, cmdcb=None): """add the menus for a Button to the current set of menus""" assert isinstance(cmdGUI, CommandGUI) gui = cmdGUI.button # get the menu bar, create it if necessary barname = gui[4]['barName'] if barname != None: if barname in self.menuBars.keys(): bar = self.menuBars[gui[4]['barName']] else: bar = self.addMenuBar(barname, gui[0], gui[1]) else: bar = self.menuBars[self.menuBars.keys()[0]] cmdGUI.menuBar=bar # find out the call back function we need to call cb = gui[4]['cb'] if cb is None: cb = cmdcb # add the button name = gui[4]['buttonName'] self.addButton( bar, name, cb, gui[2], gui[3]) def setObjLabel(self, event): self.objLab.configure(text="current molecule:" + self.current.name) def askFileOpen(self, master, idir = None, ifile=None, types=None, title='open', multiple=False): file = fileOpenAsk(master, idir, ifile, types,title, multiple) return file def askFileSave(self, master, idir=None, ifile=None, types = None, title='Save', defaultextension=None): file = fileSaveAsk(master, idir, ifile, types, title, defaultextension=defaultextension) return file def addtoolbarDictGUI(self,cmdGUI, cmdcb=None): cmdGUI.toolbarDict['cmdcb'] = cmdcb self.toolbarList.append(cmdGUI.toolbarDict) self.configureToolBar(resizeGUI=False) def configureToolBar(self, iconsize='medium', resizeGUI = True): """ Adds a tool bar Optional iconsize parameter can be passed that currently is either small (22x22) or large (32x32) """ from mglutil.gui.BasicWidgets.Tk.toolbarbutton import ToolBarButton if self.menuBars.has_key('Toolbar'): self.menuBars['Toolbar']._frame.toolbarButtonDict = {} slaves = self.menuBars['Toolbar']._frame.slaves() self.menuBars['Toolbar']._frame.spare = [] for slave in slaves: if isinstance( slave, (ToolBarButton,Tkinter.Checkbutton) ): slave.destroy() else: self.menuBars['Toolbar']._frame.spare.append(slave) slave.pack_forget() else: self.addMenuBar( 'Toolbar', {'borderframe':0, 'horizscrollbar_width':7, 'vscrollmode':'none', 'frame_relief':'groove', 'vertflex':'shrink', 'frame_borderwidth':1,}, {'side':'top', 'expand':1, 'fill':'x'}) self.iconsize = iconsize iconsizedir = ICONSIZES[iconsize] h_w = int(iconsizedir[:2]) decorated = [(dict_['index'], dict_) for dict_ in self.toolbarList if dict_['type']=='Checkbutton' or dict_['type']=='MenuRadiobutton'] decorated.sort() Sorted_Checkbuttons = [dict_ for (key, dict_) in decorated] decorated = [(dict_['index'], dict_) for dict_ in self.toolbarList if dict_['type']=='ToolBarButton'] decorated.sort() Sorted_ToolBarButtons = [dict_ for (key, dict_) in decorated] for item in Sorted_ToolBarButtons: ToolBarButton(None, self.menuBars['Toolbar']._frame, name = item['name'], icon1 = item['icon1'], state = item['state'], icon2 = item['icon2'], height = h_w, width = h_w, command = item['cmdcb'], padx=2, pady=2, balloonhelp=item['balloonhelp'], iconpath=item['icon_dir'] + os.sep + iconsizedir) tmp_txt = 'sep.gif' ToolBarButton(None, self.menuBars['Toolbar']._frame, name = 'sep1', icon1 = tmp_txt, state = 'disabled', pady=2, height=h_w, width=5, iconpath=ICONPATH + os.sep + iconsizedir) bar = self.menuBars['Toolbar'] self.toolbarCheckbuttons = {} for item in Sorted_Checkbuttons: tmpDict = {} try: item['icon_dir'] + os.sep + iconsizedir except: import pdb pdb.set_trace() iconfile = os.path.join(item['icon_dir'] + os.sep + iconsizedir,item['icon1']) head, ext = os.path.splitext(iconfile) if ext == '.gif': Icon = Tkinter.PhotoImage(file=iconfile, master=self.ROOT) else: image = Image.open(iconfile) Icon = ImageTk.PhotoImage(image=image, master=self.ROOT) tmpDict['Icon'] = Icon if item['type'] == 'Checkbutton': if item['variable']: Variable = item['variable'] else: Variable = Tkinter.IntVar() tmpDict['Variable'] = Variable Checkbutton = Tkinter.Checkbutton(bar.interior(), image=Icon, indicatoron=0, variable=Variable, command=item['cmdcb'], ) elif item['type'] == 'MenuRadiobutton': if item['variable']: Variable = item['variable'] else: Variable = Tkinter.StringVar() tmpDict['Variable'] = Variable Checkbutton = Tkinter.Menubutton( bar.interior(), image=Icon, indicatoron=0, #relief='raised' ) self.radioMenu = Tkinter.Menu(Checkbutton, tearoff=0) for i in range( len(item['radioLabels'])): self.radioMenu.add_radiobutton( label=item['radioLabels'][i], value=item['radioValues'][i], variable=Variable, command=item['cmdcb'] ) Variable.set(item['radioInitialValue']) Checkbutton['menu']= self.radioMenu Checkbutton.pack(side='left') Checkbutton.ballon = Pmw.Balloon(self.ROOT) Checkbutton.ballon.bind(Checkbutton,item['balloonhelp'] ) tmpDict['Checkbutton'] = Checkbutton self.toolbarCheckbuttons[item['name']] = tmpDict tmp_txt = 'sep.gif' ToolBarButton(None, self.menuBars['Toolbar']._frame, name = 'sep2', icon1 = tmp_txt, state = 'disabled', padx=1, pady=2, height=h_w, width=5, iconpath=ICONPATH + os.sep + iconsizedir) # if hasattr(self.menuBars['Toolbar']._frame,'spare'): # for repack in self.menuBars['Toolbar']._frame.spare: # repack.pack(side='left') self.menuBars['Toolbar']._frame.pack() if resizeGUI: top = self.ROOT.winfo_toplevel() geom = top.geometry() geom = geom.split('x') self.menuBars['Toolbar']._frame.update() winfo_width = self.menuBars['Toolbar']._frame.winfo_width() if int(geom[0]) < winfo_width + 10: geom[0] = str(winfo_width + 10) top.geometry(geom[0]+'x'+geom[1]) def fileOpenAsk(master, idir=None, ifile=None, types=None, title='Open', multiple=False): if types is None: types = [ ('All files', '*') ] if multiple: result = tkFileDialog.askopenfilenames( parent = master, filetypes=types, initialdir=idir, initialfile=ifile, title=title) # askopenfilenames() on Windows Python2.6 has a bug: it returns # a unicode instead of a tuple of filenames if type(result) == unicode: if master: result = master.tk.splitlist(result) else: import Tkinter master = Tkinter.Tk() master.withdraw() result = master.tk.splitlist(result) master.destroy() return result else: result = tkFileDialog.askopenfilename( parent = master, filetypes=types, initialdir=idir, initialfile=ifile, title=title) if isinstance(result, tuple): # "Cancel" was pressed return None else: return result def fileSaveAsk(master, idir=None, ifile=None, types = None, title='Save', defaultextension=None): if types is None: types = [ ('All files', '*') ] file = tkFileDialog.asksaveasfilename( parent = master, filetypes=types, initialdir=idir, initialfile=ifile, title=title, defaultextension=defaultextension) if file=='': file = None return file def dirChoose(master, idir=None, title='Choose Directory'): from mglutil.gui.BasicWidgets.Tk.dirDialog import askdirectory dirpath = askdirectory( initialdir=idir,title=title) if dirpath=='': dirpath = None return dirpath def dirCreate(master, idir=None, title='Create Directory'): from mglutil.gui.BasicWidgets.Tk.dirDialog import createdirectory dirpath = createdirectory( initialdir=idir,title=title) if dirpath=='': dirpath = None return dirpath if __name__=="__main__": pass ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/__init__.py0000644000175000017500000000061011415211476024244 0ustar moellermoeller# # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/__init__.py,v 1.20 2010/07/07 23:52:30 annao Exp $ # # $Id: __init__.py,v 1.20 2010/07/07 23:52:30 annao Exp $ # packageContainsVFCommands = 1 CRITICAL_DEPENDENCIES = ['DejaVu', 'mglutil','Pmw', 'numpy', 'opengltk', 'Support'] NONCRITICAL_DEPENDENCIES = ['Vision','PIL', 'Pmv', 'Volume', 'UTpackages', 'MolKit', 'TkinterDnD2'] ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/basicCommand.py0000644000175000017500000027062212212465071025077 0ustar moellermoeller## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by ############################################################################ # # Author: Michel F. SANNER # # Copyright: M. Sanner TSRI 2000 # ############################################################################# """ Module implementing the basic commands that are present when instanciating a ViewerFramework class or ViewerFramework derived class. - loadCommandCommand - loadModuleCommand - loadMacroCommand - ExitCommand - ShellCommand - UndoCommand - ResetUndoCommand. """ # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/basicCommand.py,v 1.154 2013/09/06 23:50:17 sanner Exp $ # # $Id: basicCommand.py,v 1.154 2013/09/06 23:50:17 sanner Exp $ # import os, sys, subprocess from mglutil.gui.InputForm.Tk.gui import InputFormDescr from mglutil.util.callback import CallBackFunction from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ListChooser, \ LoadButton, kbScrolledListBox from mglutil.util.packageFilePath import findFilePath, \ findModulesInPackage, getResourceFolderWithVersion import types, Tkinter, Pmw, os, sys, traceback from string import join import tkMessageBox from ViewerFramework.VFCommand import Command, CommandGUI import warnings import string commandslist=[] cmd_docslist={} def findAllVFPackages(): """Returns a list of package names found in sys.path""" packages = {} for p in ['.']+sys.path: flagline = [] if not os.path.exists(p) or not os.path.isdir(p): continue files = os.listdir(p) for f in files: pdir = os.path.join(p, f) if not os.path.isdir(pdir): continue if os.path.exists( os.path.join( pdir, '__init__.py')) : fptr =open("%s/__init__.py" %pdir) Lines = fptr.readlines() flagline =filter(lambda x:x.startswith("packageContainsVFCommands"),Lines) if not flagline ==[]: if not packages.has_key(f): packages[f] = pdir return packages class NEWUndoCommand(Command): """pops undo string from the stack and executes it in the ViewerFrameworks scope \nPackage : ViewerFramework \nModule : basicCommand.py \nClass : UndoCommand \nCommand : Undo \nSynopsis:\n None <- Undo() """ def validateUserPref(self, value): try: val = int(value) if val >-1: return 1 else: return 0 except: return 0 def onAddCmdToViewer(self): doc = """Number of commands that can be undone""" if self.vf.hasGui: TButton = self.vf.GUI.menuBars['Toolbar']._frame.toolbarButtonDict['Undo'] self.balloon = Pmw.Balloon(self.vf.GUI.ROOT) self.balloon.bind(TButton, 'Undo') self.setLabel() self.vf.userpref.add( 'Number of Undo', 100, validateFunc=self.validateUserPref, doc=doc) def addUndoCall(self, cmdList, name): #print self.name, "addUndoCall for:", name # FIXME handle user pref self.cmdStack.append( (cmdList, name) ) maxLen = self.vf.userpref['Number of Undo']['value'] if maxLen>0 and len(self.cmdStack)>maxLen: forget = self.cmdStack[:-maxLen] self.cmdStack = self.cmdStack[-maxLen:] for cmdList, name in forget: for cmd, args, kw in cmdList: if hasattr(cmd, "handleForgetUndo"): cmd.handleForgetUndo(*args, **kw) self.setLabel() def doit(self, **kw): """ pop cmdList from stack and execute each cmd in cmdlList """ stack = self.cmdStack if stack: cmdList, name = stack.pop() ncmds = len(cmdList) self._cmdList = ([], name) # this list will gather undoCommands generated during the undo for i, (cmd, args, kw) in enumerate(cmdList): self.inUndo = ncmds-i-1 cmd( *args, **kw) self._cmdList = () # this list will gather undoCommands generated during the undo #self.inUndo = True #for cmd, args, kw in cmdList: # cmd( *args, **kw) #self.inUndo = False self.inUndo = -1 else: self.vf.warningMsg('ERROR: Undo called for %s when undo stack is empty'%\ self.name) #raise RuntimeError('Undo called for %s when undo stack is empty'%\ # self.name) self.setLabel() def __init__(self, func=None): Command.__init__(self, func) # cmdStack is a list of tuples providing 1-a list of commands to execute and 2 a name for this operation # the list of commands is in the following format [ (cmd, *args, **kw) ] self.cmdStack = [] self.inUndo = -1 # will be 0 or a positive integer while we are executing command(s) to undo last operation. self._cmdList = () # this tuple will contain a list that will collect negation of commands during a loop over commands # corresponding to an Undo (or Redo in subclassed command) def __call__(self, **kw): """None<---NEWundo() """ self.doitWrapper(topCommand=0, log=0, busyIdle=1) def guiCallback(self, event=None): self.doitWrapper(topCommand=0, log=0, busyIdle=1) def setLabel(self): """change menu entry label to show command name""" if not self.vf.hasGui: return cmdmenuEntry = self.GUI.menu[4]['label'] if len(self.cmdStack)==0: state = 'disabled' label = 'Undo ' if self.vf.GUI.menuBars.has_key('Toolbar'): TButton = self.vf.GUI.menuBars['Toolbar']._frame.toolbarButtonDict['Undo'] TButton.disable() self.balloon.bind(TButton, label) #rebind other functions from toolbarbutton TButton.bind("", TButton.buttonEnter, '+') TButton.bind("", TButton.buttonLeave, '+') TButton.bind("", TButton.buttonDown) TButton.bind("", TButton.buttonUp) else: state='normal' label = 'Undo ' + self.cmdStack[-1][1] if self.vf.GUI.menuBars.has_key('Toolbar'): TButton = self.vf.GUI.menuBars['Toolbar']._frame.toolbarButtonDict['Undo'] TButton.enable() self.balloon.bind(TButton, label) #rebind other functions from toolbarbutton TButton.bind("", TButton.buttonEnter, '+') TButton.bind("", TButton.buttonLeave, '+') TButton.bind("", TButton.buttonDown) TButton.bind("", TButton.buttonUp) self.vf.GUI.configMenuEntry(self.GUI.menuButton, cmdmenuEntry, label=label, state=state) self.GUI.menu[4]['label']=label def resetCmdStack(self): #remove all items from self.cmdStack if len(self.cmdStack): del(self.cmdStack) self.cmdStack = [] self.setLabel() class RedoCommand(NEWUndoCommand): """pops redo cmdList from the stack and executes it in the ViewerFrameworks scope \nPackage : ViewerFramework \nModule : basicCommand.py \nClass : RedoCommand \nCommand : Undo \nSynopsis:\n None <- Undo() """ def setLabel(self): """change menu entry label to show command name""" if not self.vf.hasGui: return cmdmenuEntry = self.GUI.menu[4]['label'] if len(self.cmdStack)==0: state = 'disabled' label = 'Redo ' if self.vf.GUI.menuBars.has_key('Toolbar'): TButton = self.vf.GUI.menuBars['Toolbar']._frame.toolbarButtonDict['Redo'] TButton.disable() self.balloon.bind(TButton, label) #rebind other functions from toolbarbutton TButton.bind("", TButton.buttonEnter, '+') TButton.bind("", TButton.buttonLeave, '+') TButton.bind("", TButton.buttonDown) TButton.bind("", TButton.buttonUp) else: state='normal' label = 'Redo ' + self.cmdStack[-1][1] if self.vf.GUI.menuBars.has_key('Toolbar'): TButton = self.vf.GUI.menuBars['Toolbar']._frame.toolbarButtonDict['Redo'] TButton.enable() self.balloon.bind(TButton, label) #rebind other functions from toolbarbutton TButton.bind("", TButton.buttonEnter, '+') TButton.bind("", TButton.buttonLeave, '+') TButton.bind("", TButton.buttonDown) TButton.bind("", TButton.buttonUp) self.vf.GUI.configMenuEntry(self.GUI.menuButton, cmdmenuEntry, label=label, state=state) self.GUI.menu[4]['label']=label class UndoCommand(Command): """pops undo string from the stack and executes it in the ViewerFrameworks scope \nPackage : ViewerFramework \nModule : basicCommand.py \nClass : UndoCommand \nCommand : Undo \nSynopsis:\n None <- Undo() """ def __init__(self, func=None): Command.__init__(self, func) self.ctr = 1 # used to assure unique keys for _undoArgs self._undoArgs = {} # this dict is used to save large Python objects # that we do not want to turn into strings def get_ctr(self): #used to build unique '_undoArg_#' strings #cannot simply use len(self_undoArgs)+1 #because some entries may have been removed # for instance, using len(self_undoArgs)+1 only # add 1: _undoArg_1, add another: _undoArg_2 # remove _undoArg_1 # next addition would replicate _undoArg_2 if not len(self._undoArgs): self.ctr = 1 else: self.ctr += 1 return self.ctr def saveUndoArg(self, arg): """Add arg to self._undoArgs under a unique name and returns this name """ name = '_undoArg_%d'%len(self._undoArgs) i = 1 while self._undoArgs.has_key(name): name = '_undoArg_%d'%(self.get_ctr()) i += 1 self._undoArgs[name] = arg return name def validateUserPref(self, value): try: val = int(value) if val >-1: return 1 else: return 0 except: return 0 def onAddCmdToViewer(self): doc = """Number of commands that can be undone""" return if self.vf.hasGui: TButton = self.vf.GUI.menuBars['Toolbar']._frame.toolbarButtonDict['Undo'] self.balloon = Pmw.Balloon(self.vf.GUI.ROOT) self.balloon.bind(TButton, 'Undo') self.setLabel() self.vf.userpref.add( 'Number of Undo', 100, validateFunc=self.validateUserPref, doc=doc) def doit(self): if len(self.vf.undoCmdStack): command = self.vf.undoCmdStack.pop()[0] localDict = {'self':self.vf} localDict.update( self._undoArgs ) # add undoArgs to local dict exec( command, sys.modules['__main__'].__dict__, localDict) # remove _undoArg_%d used by this command from self._undoArgs dict ind = command.find('_undoArg_') while ind != -1 and ind < len(command)-10: name = command[ind: ind+9] end = ind+9 # add digits following string while command[end].isdigit(): name += command[end] end +=1 nodes = self._undoArgs[name] del self._undoArgs[name] new_start = ind + len(name) ind = command[new_start:].find('_undoArg_') if ind!=-1: ind = ind + new_start #exec( command, self.vf.__dict__ ) self.setLabel() def guiCallback(self, event=None): self.doitWrapper(topCommand=0, log=0, busyIdle=1) def __call__(self, **kw): """None<---Undo() """ self.doitWrapper(topCommand=0, log=0, busyIdle=1) def addEntry(self, undoString, menuString): self.vf.undoCmdStack.append( (undoString, menuString) ) maxLen = self.vf.userpref['Number of Undo']['value'] if maxLen>0 and len(self.vf.undoCmdStack)>maxLen: self.vf.undoCmdStack = self.vf.undoCmdStack[-maxLen:] self.vf.undo.setLabel() def setLabel(self): """change menu entry label to show command name""" return if not self.vf.hasGui: return cmdmenuEntry = self.GUI.menu[4]['label'] if len(self.vf.undoCmdStack)==0: state = 'disabled' label = 'Undo ' if self.vf.GUI.menuBars.has_key('Toolbar'): TButton = self.vf.GUI.menuBars['Toolbar']._frame.toolbarButtonDict['Undo'] TButton.disable() #if hasattr(self,'balloon'): # self.balloon.destroy() #self.balloon = Pmw.Balloon(self.vf.GUI.ROOT) #self.balloon.bind(TButton, 'Undo') #rebind other functions from toolbarbutton TButton.bind("", TButton.buttonEnter, '+') TButton.bind("", TButton.buttonLeave, '+') TButton.bind("", TButton.buttonDown) TButton.bind("", TButton.buttonUp) else: state='normal' label = 'Undo ' + self.vf.undoCmdStack[-1][1] if self.vf.GUI.menuBars.has_key('Toolbar'): TButton = self.vf.GUI.menuBars['Toolbar']._frame.toolbarButtonDict['Undo'] TButton.enable() #if hasattr(self,'balloon'): # self.balloon.destroy() #self.balloon = Pmw.Balloon(self.vf.GUI.ROOT) self.balloon.bind(TButton, label) #rebind other functions from toolbarbutton TButton.bind("", TButton.buttonEnter, '+') TButton.bind("", TButton.buttonLeave, '+') TButton.bind("", TButton.buttonDown) TButton.bind("", TButton.buttonUp) self.vf.GUI.configMenuEntry(self.GUI.menuButton, cmdmenuEntry, label=label, state=state) self.GUI.menu[4]['label']=label class RemoveCommand(Command): def loadCommands(self): for key in self.vf.removableCommands.settings: try: self.vf.browseCommands.doit(key, self.vf.removableCommands.settings[key][0], self.vf.removableCommands.settings[key][1]) except Exception, inst: print __file__, inst def guiCallback(self): idf = InputFormDescr(title='Remove Command') idf.append({'name':'cmd', 'widgetType':kbScrolledListBox, 'wcfg':{'items':self.vf.removableCommands.settings.keys(), 'listbox_exportselection':0, 'listbox_selectmode':'extended', 'labelpos':'nw', 'label_text':'Available commands:', #'dblclickcommand':self.loadCmd_cb, #'selectioncommand':self.displayCmd_cb, }, 'gridcfg':{'sticky':'wesn', 'row':-1}}) val = self.vf.getUserInput(idf, modal=1, blocking=1) if val: self.vf.removableCommands.settings.pop(val['cmd'][0]) self.vf.removableCommands.saveAllSettings() txt = "You need to restart for the changes to take effect." tkMessageBox.showinfo("Restart is Needed", txt) class ResetUndoCommand(Command): """ Class to reset Undo() \nPackage : ViewerFramework \nModule : basicCommand.py \nClass : ResetUndoCommand \nCommand : resetUndo \nSynopsis:\n None<---resetUndo() """ def doit(self): self.vf.undoCmdStack = [] self.vf.undo._undoArgs = {} # reset dict used to save large Python objects self.vf.undo.setLabel() for command in self.vf.commands: if hasattr(command, 'command'): # added to handle 'computeSheet2D' case command.undoStack = [] def __call__(self, **kw): """None<---resetUndo() """ apply( self.doitWrapper, (), kw ) class BrowseCommandsCommand(Command): """Command to load dynamically either modules or individual commands in the viewer. \nPackage : ViewerFramework \nModule : basicCommand.py \nClass : BrowseCommandsCommand \nCommand : browseCommands \nSynopsis:\n None <-- browseCommands(module, commands=None, package=None, **kw) \nRequired Arguements:\n module --- name of the module(eg:colorCommands) \nOptional Arguements:\n commnads --- one list of commands to load \npackage --- name of the package to which module belongs(eg:Pmv,Vision) """ def __init__(self, func=None): Command.__init__(self, func) self.allPack = {} self.packMod = {} self.allPackFlag = False self.txtGUI = "" def doit(self, module, commands=None, package=None, removable=False): # if removable: # self.vf.removableCommands.settings[module] = [commands, package] # self.vf.removableCommands.saveAllSettings() # If the package is not specified the default is the first library global commandslist,cmd_docslist if package is None: package = self.vf.libraries[0] importName = package + '.' + module try: mod = __import__(importName, globals(), locals(), [module]) except: if self.cmdForms.has_key('loadCmds') and \ self.cmdForms['loadCmds'].f.winfo_toplevel().wm_state() == \ 'normal': self.vf.warningMsg("ERROR: Could not load module %s"%module, parent = self.cmdForms['loadCmds'].root) elif self.vf.loadModule.cmdForms.has_key('loadModule') and \ self.vf.loadModule.cmdForms['loadModule'].f.winfo_toplevel().wm_state() == \ 'normal': self.vf.warningMsg("ERROR: Could not load module %s"%module, parent = self.vf.loadModule.cmdForms['loadModule'].root) else: self.vf.warningMsg("ERROR: Could not load module %s"%module) traceback.print_exc() return 'ERROR' if commands is None: if hasattr(mod,"initModule"): if self.vf.hasGui : mod.initModule(self.vf) else : #if there is noGUI and if we want to have multiple session of mv #need to instanciate new commands, and not use the global dictionay commandList if hasattr(mod, 'commandList'): for d in mod.commandList: d['cmd'] = d['cmd'].__class__() #print "load all comands ", d['cmd'], d['name'], d['gui'] self.vf.addCommand( d['cmd'], d['name'], d['gui']) else : print mod if hasattr(mod, 'commandList'): for x in mod.commandList: cmd=x['name'] c=x['cmd'] #print 'CCCCCCC', cmd if cmd not in cmd_docslist: if hasattr(c,'__doc__'): cmd_docslist[cmd]=c.__doc__ if x['gui']: if x['gui'].menuDict: if len(self.txtGUI) < 800: self.txtGUI += "\n"+x['gui'].menuDict['menuButtonName'] if x['gui'].menuDict['menuCascadeName']: self.txtGUI += "->"+ x['gui'].menuDict['menuCascadeName'] self.txtGUI += "->"+x['gui'].menuDict['menuEntryLabel'] if cmd not in commandslist: commandslist.append(cmd) #print 'ZZZZZZZZZZZZ', mod else: if self.cmdForms.has_key('loadCmds') and \ self.cmdForms['loadCmds'].f.winfo_toplevel().wm_state() == \ 'normal': self.vf.warningMsg("ERROR: Could not load module %s"%module, parent = self.cmdForms['loadCmds'].root) elif self.vf.loadModule.cmdForms.has_key('loadModule') and \ self.vf.loadModule.cmdForms['loadModule'].f.winfo_toplevel().wm_state() == \ 'normal': self.vf.warningMsg("ERROR: Could not load module %s"%module, parent = self.vf.loadModule.cmdForms['loadModule'].root) else: self.vf.warningMsg("ERROR: Could not load module %s"%module) return "ERROR" else: if not type(commands) in [types.ListType, types.TupleType]: commands = [commands,] if not hasattr(mod, 'commandList'): return for cmd in commands: d = filter(lambda x: x['name'] == cmd, mod.commandList) if len(d) == 0: self.vf.warningMsg("Command %s not found in module %s.%s"% (cmd, package, module)) continue d = d[0] if cmd not in cmd_docslist: if hasattr(d['cmd'],'__doc__'): cmd_docslist[cmd]=d['cmd'].__doc__ if cmd not in commandslist: commandslist.append(cmd) if not self.vf.hasGui : #if there is noGUI and if we want to have multiple session of mv #need to instanciate new commands, and not use the global dictionay commandList #print "load specific comands ", d['cmd'], d['name'], d['gui'] d['cmd'] = d['cmd'].__class__() self.vf.addCommand(d['cmd'], d['name'], d['gui']) def __call__(self, module, commands=None, package=None, **kw): """None<---browseCommands(module, commands=None, package=None, **kw) \nmodule --- name of the module(eg:colorCommands) \ncommnads --- one list of commands to load \npackage --- name of the package to which module belongs(eg:Pmv,Vision) """ kw['commands'] = commands kw['package'] = package apply(self.doitWrapper, (module,), kw ) def buildFormDescr(self, formName): import Tkinter if not formName == 'loadCmds': return idf = InputFormDescr(title='Load Modules and Commands') pname = self.vf.libraries #when Pvv.startpvvCommnads is loaded some how Volume.Pvv is considered #as seperate package and is added to packages list in the widget #To avoid this packages having '.' are removed for p in pname: if '.' in p: ind = pname.index(p) del pname[ind] idf.append({'name':'packList', 'widgetType':kbScrolledListBox, 'wcfg':{'items':pname, #'defaultValue':pname[0], 'listbox_exportselection':0, 'labelpos':'nw', 'label_text':'Select a package:', #'dblclickcommand':self.loadMod_cb, 'selectioncommand':self.displayMod_cb }, 'gridcfg':{'sticky':'wesn'}}) idf.append({'name':'modList', 'widgetType':kbScrolledListBox, 'wcfg':{'items':[], 'listbox_exportselection':0, 'labelpos':'nw', 'label_text':'Select a module:', #'dblclickcommand':self.loadMod_cb, 'selectioncommand':self.displayCmds_cb, }, 'gridcfg':{'sticky':'wesn', 'row':-1}}) idf.append({'name':'cmdList', 'widgetType':kbScrolledListBox, 'wcfg':{'items':[], 'listbox_exportselection':0, 'listbox_selectmode':'extended', 'labelpos':'nw', 'label_text':'Available commands:', #'dblclickcommand':self.loadCmd_cb, 'selectioncommand':self.displayCmd_cb, }, 'gridcfg':{'sticky':'wesn', 'row':-1}}) # idf.append({'name':'docbutton', # 'widgetType':Tkinter.Checkbutton, # #'parent':'DOCGROUP', # 'defaultValue':0, # 'wcfg':{'text':'Show documentation', # 'onvalue':1, # 'offvalue':0, # 'command':self.showdoc_cb, # 'variable':Tkinter.IntVar()}, # 'gridcfg':{'sticky':'nw','columnspan':3}}) idf.append({'name':'DOCGROUP', 'widgetType':Pmw.Group, 'container':{'DOCGROUP':"w.interior()"}, 'collapsedsize':0, 'wcfg':{'tag_text':'Description'}, 'gridcfg':{'sticky':'wnse', 'columnspan':3}}) idf.append({'name':'doclist', 'widgetType':kbScrolledListBox, 'parent':'DOCGROUP', 'wcfg':{'items':[], 'listbox_exportselection':0, 'listbox_selectmode':'extended', }, 'gridcfg':{'sticky':'wesn', 'columnspan':3}}) idf.append({'name':'allPacks', 'widgetType':Tkinter.Button, 'wcfg':{'text':'Show all packages', 'command':self.allPacks_cb}, 'gridcfg':{'sticky':'ew'}}) idf.append({'name':'loadMod', 'widgetType':Tkinter.Button, 'wcfg':{'text':'Load selected module', 'command':self.loadMod_cb}, 'gridcfg':{'sticky':'ew', 'row':-1}}) # idf.append({'name':'loadCmd', # 'widgetType':Tkinter.Button, # 'wcfg':{'text':'Load Command', # 'command':self.loadCmd_cb}, # 'gridcfg':{'sticky':'ew', 'row':-1}}) idf.append({'name':'dismiss', 'widgetType':Tkinter.Button, 'wcfg':{'text':'Dismiss', 'command':self.dismiss_cb}, 'gridcfg':{'sticky':'ew', 'row':-1}}) # idf.append({'name':'dismiss', # 'widgetType':Tkinter.Button, # 'wcfg':{'text':'DISMISS', # 'command':self.dismiss_cb, # }, # 'gridcfg':{'sticky':Tkinter.E+Tkinter.W,'columnspan':3}}) return idf def guiCallback(self): self.vf.GUI.ROOT.config(cursor='watch') self.vf.GUI.ROOT.update() if self.allPack == {}: self.allPack = findAllVFPackages() val = self.showForm('loadCmds', force=1,modal=0,blocking=0) ebn = self.cmdForms['loadCmds'].descr.entryByName # docb=ebn['docbutton']['widget'] # var=ebn['docbutton']['wcfg']['variable'].get() # if var==0: # dg=ebn['DOCGROUP']['widget'] # dg.collapse() self.vf.GUI.ROOT.config(cursor='') def dismiss_cb(self, event=None): self.cmdForms['loadCmds'].withdraw() def allPacks_cb(self, event=None): ebn = self.cmdForms['loadCmds'].descr.entryByName packW = ebn['packList']['widget'] if not self.allPackFlag: packName = self.allPack.keys() packW.setlist(packName) ebn['allPacks']['widget'].configure(text='Show default packages') self.allPackFlag = True else: packName = self.vf.libraries packW.setlist(packName) ebn['allPacks']['widget'].configure(text='Show all packages') self.allPackFlag = False ebn['modList']['widget'].clear() ebn['cmdList']['widget'].clear() # def showdoc_cb(self,event=None): # #when a show documentation is on and a module is selected then # #expands dg else dg is collapsed # ebn = self.cmdForms['loadCmds'].descr.entryByName # docb=ebn['docbutton']['widget'] # var=ebn['docbutton']['wcfg']['variable'].get() # dg=ebn['DOCGROUP']['widget'] # docw=ebn['doclist']['widget'] # packW = ebn['packList']['widget'] # psel=packW.getcurselection() # if var==0: # dg.collapse() # if var==1 and psel: # if docw.size()>0: # dg.expand() def displayMod_cb(self, event=None): #print "displayMod_cb" # c = self.cmdForms['loadCmds'].mf.cget('cursor') # self.cmdForms['loadCmds'].mf.configure(cursor='watch') # self.cmdForms['loadCmds'].mf.update_idletasks() ebn = self.cmdForms['loadCmds'].descr.entryByName # docb=ebn['docbutton']['widget'] # var=ebn['docbutton']['wcfg']['variable'].get() # dg = ebn['DOCGROUP']['widget'] # dg.collapse() packW = ebn['packList']['widget'] packs = packW.getcurselection() if len(packs) == 0: return packName = packs[0] if not self.packMod.has_key(packName): package = self.allPack[packName] self.packMod[packName] = findModulesInPackage(package,"^def initModule",fileNameFilters=['Command']) self.currentPack = packName modNames = [] for key, value in self.packMod[packName].items(): pathPack = key.split(os.path.sep) if pathPack[-1] == packName: newModName = map(lambda x: x[:-3], value) #for mname in newModName: #if "Command" not in mname : #ind = newModName.index(mname) #del newModName[ind] modNames = modNames+newModName else: pIndex = pathPack.index(packName) prefix = join(pathPack[pIndex+1:], '.') newModName = map(lambda x: "%s.%s"%(prefix, x[:-3]), value) #for mname in newModName: #if "Command" not in mname : #ind = newModName.index(mname) #del newModName[ind] modNames = modNames+newModName modNames.sort() modW = ebn['modList']['widget'] modW.setlist(modNames) # and clear contents in self.libraryGUI cmdW = ebn['cmdList']['widget'] cmdW.clear() m = __import__(packName, globals(), locals(),[]) d = [] docstring=m.__doc__ #d.append(m.__doc__) docw = ebn['doclist']['widget'] docw.clear() #formatting documentation. if docstring!=None : if '\n' in docstring: x = string.split(docstring,"\n") for i in x: if i !='': d.append(i) if len(d)>8: docw.configure(listbox_height=8) else: docw.configure(listbox_height=len(d)) else: x = string.split(docstring," ") #formatting documenation if len(x)>10: docw.configure(listbox_height=len(x)/10) else: docw.configure(listbox_height=1) docw.setlist(d) # self.cmdForms['loadCmds'].mf.configure(cursor=c) #when show documentation on after selcting a package #dg is expanded to show documenttation #if var==1 and docw.size()>0: ##if docw.size()>0: ## dg.expand() def displayCmds_cb(self, event=None): #print "displayCmds_cb" global cmd_docslist self.cmdForms['loadCmds'].mf.update_idletasks() ebn = self.cmdForms['loadCmds'].descr.entryByName dg = ebn['DOCGROUP']['widget'] dg.collapse() cmdW = ebn['cmdList']['widget'] cmdW.clear() # docb=ebn['docbutton']['widget'] # var=ebn['docbutton']['wcfg']['variable'].get() modName = ebn['modList']['widget'].getcurselection() if modName == (0 or ()): return else: modName = modName[0] importName = self.currentPack + '.' + modName try: m = __import__(importName, globals(), locals(),['commandList']) except: return if not hasattr(m, 'commandList'): return cmdNames = map(lambda x: x['name'], m.commandList) cmdNames.sort() if modName: self.var=1 d =[] docstring =m.__doc__ import string docw = ebn['doclist']['widget'] docw.clear() if docstring!=None : if '\n' in docstring: x = string.split(docstring,"\n") for i in x: if i !='': d.append(i) #formatting documenation if len(d)>8: docw.configure(listbox_height=8) else: docw.configure(listbox_height=len(d)) else: d.append(docstring) x = string.split(docstring," ") #formatting documenation if len(x)>10: docw.configure(listbox_height=len(x)/10) else: docw.configure(listbox_height=1) docw.setlist(d) CmdName=ebn['cmdList']['widget'].getcurselection() cmdW.setlist(cmdNames) #when show documentation is on after selcting a module or a command #dg is expanded to show documenttation #if var==1 and docw.size()>0: if docw.size()>0: dg.expand() def displayCmd_cb(self, event=None): #print "displayCmd_cb" global cmd_docslist self.cmdForms['loadCmds'].mf.update_idletasks() ebn = self.cmdForms['loadCmds'].descr.entryByName dg = ebn['DOCGROUP']['widget'] dg.collapse() # docb=ebn['docbutton']['widget'] # var=ebn['docbutton']['wcfg']['variable'].get() modName = ebn['modList']['widget'].getcurselection() if modName == (0 or ()): return else: modName = modName[0] importName = self.currentPack + '.' + modName try: m = __import__(importName, globals(), locals(),['commandList']) except: self.warningMsg("ERROR: Cannot find commands for %s"%modName) return if not hasattr(m, 'commandList'): return cmdNames = map(lambda x: x['name'], m.commandList) cmdNames.sort() if modName: self.var=1 d =[] docstring =m.__doc__ import string docw = ebn['doclist']['widget'] docw.clear() if docstring!=None : if '\n' in docstring: x = string.split(docstring,"\n") for i in x: if i !='': d.append(i) #formatting documenation if len(d)>8: docw.configure(listbox_height=8) else: docw.configure(listbox_height=len(d)) else: d.append(docstring) x = string.split(docstring," ") #formatting documenation if len(x)>10: docw.configure(listbox_height=len(x)/10) else: docw.configure(listbox_height=1) docw.setlist(d) cmdW = ebn['cmdList']['widget'] CmdName=ebn['cmdList']['widget'].getcurselection() cmdW.setlist(cmdNames) if len(CmdName)!=0: for i in m.commandList: if i['name']==CmdName[0]: c = i['cmd'] if CmdName[0] in cmdNames: ind= cmdNames.index(CmdName[0]) cmdW.selection_clear() cmdW.selection_set(ind) d =[] docstring=c.__doc__ docw = ebn['doclist']['widget'] docw.clear() if CmdName[0] not in cmd_docslist.keys(): cmd_docslist[CmdName[0]]=d import string if docstring!=None : if '\n' in docstring: x = string.split(docstring,"\n") for i in x: if i !='': d.append(i) if len(d)>8: docw.configure(listbox_height=8) else: docw.configure(listbox_height=len(d)) else: d.append(docstring) x = string.split(docstring," ") if len(x)>10: docw.configure(listbox_height=len(x)/10) else: docw.configure(listbox_height=1) docw.setlist(d) #when show documentation is on after selcting a module or a command #dg is expanded to show documenttation #if var==1 and docw.size()>0: if docw.size()>0: dg.expand() def loadMod_cb(self, event=None): ebn = self.cmdForms['loadCmds'].descr.entryByName selMod = ebn['modList']['widget'].getcurselection() if len(selMod)==0: return else: self.txtGUI = "" apply(self.doitWrapper, ( selMod[0],), {'commands':None, 'package':self.currentPack, 'removable':True}) self.dismiss_cb(None) if self.txtGUI: self.txtGUI = "\n Access this command via:\n"+self.txtGUI tkMessageBox.showinfo("Load Module", selMod[0]+" loaded successfully!\n"+self.txtGUI) # def loadCmd_cb(self, event=None): # ebn = self.cmdForms['loadCmds'].descr.entryByName # selCmds = ebn['cmdList']['widget'].getcurselection() # selMod = ebn['modList']['widget'].getcurselection() # if len(selCmds)==0: return # else: # apply(self.doitWrapper, (selMod[0],), {'commands':selCmds, # 'package':self.currentPack}) class loadModuleCommand(Command): """Command to load dynamically modules to the Viewer import the file called name.py and execute the function initModule defined in that file Raises a ValueError exception if initModule is not defined \nPackage : ViewerFramework \nModule : basicCommand.py \nClass : loadModuleCommand \nCommand : loadModule \nSynopsis:\n None<--loadModule(filename, package=None, **kw) \nRequired Arguements:\n filename --- name of the module \nOptional Arguements:\n package --- name of the package to which filename belongs """ active = 0 def doit(self, filename, package): # This is NOT called because we call browseCommand()" if package is None: _package = filename else: _package = "%s.%s"%(package, filename) try: mod = __import__( _package, globals(), locals(), ['initModule']) if hasattr(mod, 'initModule') or not callable(mod.initModule): mod.initModule(self.vf) else: self.vf.warningMsg('module %s has not initModule function') except ImportError: self.vf.warningMsg('module %s could not be imported'%_package) ## if package is None: ## _package = filename ## else: ## _package = "%s.%s"%(package, filename) ## module = self.vf.tryto( __import__ , _package, globals(), locals(), ## [filename]) ## if module=='ERROR': ## print '\nWARNING: Could not load module %s' % filename ## return def __call__(self, filename, package=None, **kw): """None<---loadModule(filename, package=None, **kw) \nRequired Arguements:\n filename --- name of the module \nOptional Arguements:\n package --- name of the package to which filename belongs """ if package==None: package=self.vf.libraries[0] if not kw.has_key('redraw'): kw['redraw'] = 0 kw['package'] = package apply(self.vf.browseCommands, (filename,), kw) #apply( self.doitWrapper, (filename, package), kw ) def loadModule_cb(self, event=None): # c = self.cmdForms['loadModule'].mf.cget('cursor') # self.cmdForms['loadModule'].mf.configure(cursor='watch') # self.cmdForms['loadModule'].mf.update_idletasks() ebn = self.cmdForms['loadModule'].descr.entryByName moduleName = ebn['Module List']['widget'].get() package = ebn['package']['widget'].get() if moduleName: self.vf.browseCommands(moduleName[0], package=package, redraw=0) # self.cmdForms['loadModule'].mf.configure(cursor=c) def loadModules(self, package, library=None): modNames = [] doc = [] self.filenames={} self.allPack={} self.allPack=findAllVFPackages() if package is None: return [], [] if not self.filenames.has_key(package): pack=self.allPack[package] #finding modules in a package self.filenames[pack] =findModulesInPackage(pack,"^def initModule",fileNameFilters=['Command']) # dictionary of files keys=widget, values = filename for key, value in self.filenames[pack].items(): pathPack = key.split(os.path.sep) if pathPack[-1] == package: newModName = map(lambda x: x[:-3], value) #for mname in newModName: #if not modulename has Command in it delete from the #modules list #if "Command" not in mname : #ind = newModName.index(mname) #del newModName[ind] #if "Command" in mname : if hasattr(newModName,"__doc__"): doc.append(newModName.__doc__) else: doc.append(None) modNames = modNames + newModName else: pIndex = pathPack.index(package) prefix = join(pathPack[pIndex+1:], '.') newModName = map(lambda x: "%s.%s"%(prefix, x[:-3]), value) #for mname in newModName: #if not modulename has Command in it delete from the #modules list #if "Command" not in mname : #ind = newModName.index(mname) #del newModName[ind] if hasattr(newModName,"__doc__"): doc.append(newModName.__doc__) else: doc.append(None) modNames = modNames + newModName modNames.sort() return modNames, doc def package_cb(self, event=None): ebn = self.cmdForms['loadModule'].descr.entryByName pack = ebn['package']['widget'].get() names, docs = self.loadModules(pack) w = ebn['Module List']['widget'] w.clear() for n,d in map(None, names, docs): w.insert('end', n, d) def buildFormDescr(self, formName): """create the cascade menu for selecting modules to be loaded""" if not formName == 'loadModule':return ifd = InputFormDescr(title='Load command Modules') names, docs = self.loadModules(self.vf.libraries[0]) entries = map(lambda x: (x, None), names) pname=self.vf.libraries for p in pname: if '.' in p: ind = pname.index(p) del pname[ind] ifd.append({ 'name':'package', 'widgetType': Pmw.ComboBox, 'defaultValue': pname[0], 'wcfg':{ 'labelpos':'nw', 'label_text':'Package:', 'selectioncommand': self.package_cb, 'scrolledlist_items':pname }, 'gridcfg':{'sticky':'ew', 'padx':2, 'pady':1} }) ifd.append({'name': 'Module List', 'widgetType':ListChooser, 'wcfg':{ 'title':'Choose a module', 'entries': entries, 'lbwcfg':{'width':27,'height':10}, 'command':self.loadModule_cb, 'commandEvent':"" }, 'gridcfg':{'sticky':Tkinter.E+Tkinter.W} }) ifd.append({'name': 'Load Module', 'widgetType':Tkinter.Button, 'wcfg':{'text':'Load Module', 'command': self.loadModule_cb, 'bd':6}, 'gridcfg':{'sticky':Tkinter.E+Tkinter.W}, }) ifd.append({'widgetType':Tkinter.Button, 'wcfg':{'text':'Dismiss', 'command': self.Dismiss_cb}, 'gridcfg':{'sticky':Tkinter.E+Tkinter.W}}) return ifd def Dismiss_cb(self): self.cmdForms['loadModule'].withdraw() self.active = 0 def guiCallback(self, event=None): if self.active: return self.active = 1 form = self.showForm('loadModule', force=1,modal=0,blocking=0) form.root.protocol('WM_DELETE_WINDOW',self.Dismiss_cb) class loadCommandCommand(loadModuleCommand): """Command to load dynamically individual commands in the Viewer. \nPackage : ViewerFramework \nModule : basicCommand.py \nClass : loadCommandCommand \nCommand : loadCommand \nSynopsis:\n None <- loadCommand(moduleName, commandsName, package=None, gui=None) \nRequired Arguements:\n moduleName --- name of the module to be loaded commandsName --- name of the Command or list of Commands \nOptional Arguements:\n package --- name of the package to which filename belongs """ active = 0 def doit(self, module, commands, package=None, gui=None): """Load a command instance with the given alias and gui""" if package is None: package = self.vf.libraries[0] if not type(commands)!=types.ListType: commands = [commands,] for command in commands: cmd, name, gui = self.getDefaults(package, module, command) if cmd is None: print 'Could not add %s.%s.%s'%(package, module, command) continue self.vf.addCommand( cmd, name, gui ) def guiCallback(self, event=None): if self.active: return self.active = 1 form = self.showForm('loadCommand', force=1,modal=0,blocking=0) form.root.protocol('WM_DELETE_WINDOW',self.Dismiss_cb) def package_cb(self, event=None): # Get Package. ebn = self.cmdForms['loadCommand'].descr.entryByName pack = ebn['package']['widget'].get() # Get Modules for the new package and update the listChooser. names, docs = self.loadModules(pack) mw = ebn['Module List']['widget'] mw.clear() for n in names: mw.insert('end',n) mw.set(names[0]) # Get Commands for the first module and update the listChooser cw = ebn['Command List']['widget'] cw.clear() cmds = self.getModuleCmds(modName=names[0], package=pack) if cmds==None: return for cmd in map(lambda x: x[0],cmds): cw.insert('end', cmd) def Dismiss_cb(self): self.cmdForms['loadCommand'].withdraw() self.active = 0 def __call__(self, moduleName, commandsName, package=None, gui=None, **kw): """None <- loadCommand(moduleName, commandsName, package=None, gui=None) \nRequired Arguements:\n moduleName --- name of the module to be loaded commandsName --- name of the Command or list of Commands \nOptional Arguements:\n package --- name of the package to which filename belongs """ kw['package'] = package #kw['gui'] = gui #apply(self.doitWrapper, (moduleName, commandsName), kw) kw['commands']=commandsName apply(self.vf.browseCommands, (moduleName,), kw) def getDefaults(self, package, filename, commandName): if package is None: _package = filename else: _package = "%s.%s"%(package, filename) mod = self.vf.tryto(__import__,_package, globals(), locals(), [filename]) if mod=='ERROR': print '\nERROR: Could not load module %s.%s' % (_package, filename) return None,None,None for d in mod.commandList: if d['name']==commandName: break if d['name']!=commandName: print '\nERROR: command %s not found in module %s.%s\n' % \ (commandName, package, filename) return None,None,None return d['cmd'], d['name'], d['gui'] def loadCmd_cb(self, event=None): # c = self.cmdForms['loadCommand'].mf.cget('cursor') # self.cmdForms['loadCommand'].mf.configure(cursor='watch') # self.cmdForms['loadCommand'].mf.update_idletasks() ebn = self.cmdForms['loadCommand'].descr.entryByName module = ebn['Module List']['widget'].get() commands = ebn['Command List']['widget'].get() package = ebn['package']['widget'].get() if commands: kw = {'package': package} #apply(self.doitWrapper, (module, commands), kw) kw['commands'] = commands apply(self.vf.browseCommands, (module[0],), kw) # self.cmdForms['loadCommand'].mf.configure(cursor=c) def getModuleCmds(self, modName=None, package=None): """ Callback method of the module chooser to get the corresponding commands: """ filename = modName if package is None: _package = filename else: _package = "%s.%s"%(package, filename) try: mod = __import__(_package,globals(),locals(),['commandList']) except: self.vf.warningMsg("ERROR: Could not load module %s "%filename) return "ERROR" if hasattr(mod,"initModule"): mod.initModule(self.vf) else: self.vf.warningMsg("ERROR: Could not load module %s"%filename) return if not hasattr(mod, 'commandList'): cmdEntries = [] else: cmdsName = map(lambda x: x['name'], mod.commandList) cmdsName.sort() cmdEntries = map(lambda x: (x,None), cmdsName) return cmdEntries def modChooser_cb(self, event=None): """CallBack method that gets called when clicking on an entry of the mocule cjooser.""" ebn = self.cmdForms['loadCommand'].descr.entryByName modChooser = ebn['Module List']['widget'] filename = modChooser.get()[0] package = ebn['package']['widget'].get() cmdEntries = self.getModuleCmds(modName=filename, package=package) cmdChooser = ebn['Command List']['widget'] cmdChooser.clear() #cmdEntries should be a list if there are no commands for a module then getModuleCmds returns None or Error in that case cmdEntries is made equal to emptylist if cmdEntries=="ERROR" or cmdEntries==None: cmdEntries=[] map(cmdChooser.add, cmdEntries) def buildFormDescr(self, formName): """Create the pulldown menu and Listchooser to let for the selection of commands.""" if not formName == 'loadCommand': return ifd = InputFormDescr(title='Load Individual Commands') moduleNames, docs = self.loadModules(self.vf.libraries[0]) moduleNames.sort() moduleEntries = map(lambda x: (x, None), moduleNames) pname = self.vf.libraries for p in pname: if '.' in p: ind = pname.index(p) del pname[ind] ifd.append({ 'name':'package', 'widgetType': Pmw.ComboBox, 'defaultValue': pname[0], 'wcfg':{ 'labelpos':'nw', 'label_text':'Package:', 'selectioncommand': self.package_cb, 'scrolledlist_items':pname }, 'gridcfg':{'columnspan':2,'sticky':'ew', 'padx':2, 'pady':1} }) ifd.append({'name': 'Module List', 'widgetType':ListChooser, 'wcfg':{'title':'Choose a module', 'entries': moduleEntries, 'lbwcfg':{ 'width':25, 'height':10, 'exportselection':0}, 'command':self.modChooser_cb, }, 'gridcfg':{'sticky':'ew'} } ) CmdEntries = [] ifd.append({'name': 'Command List', 'widgetType':ListChooser, 'wcfg':{'title':'Choose a command', 'mode':'multiple', 'entries': CmdEntries, 'command':self.loadCmd_cb, 'commandEvent':"", 'lbwcfg':{'width':25,'height':10, 'exportselection':0} }, 'gridcfg':{'row':-1,'sticky':'we'} } ) ifd.append({'name': 'Load Command', 'widgetType':Tkinter.Button, 'wcfg':{'text':'Load Command', 'bd':6, 'command': self.loadCmd_cb}, 'gridcfg':{'columnspan':2,'sticky':'ew'}, }) ifd.append({'widgetType':Tkinter.Button, 'wcfg':{'text':'Dismiss', 'command': self.Dismiss_cb}, 'gridcfg':{'columnspan':2,'sticky':'ew'}}) return ifd class loadMacroCommand(Command): """Command to load dynamically macro commands. \nPackage : ViewerFramework \nModule : basicCommand.py \nClass : loadMacroCommand \nCommand : loadMacro \nSynopsis:\n None<---loadMacro(macroName, macroFile, menuBar='menuRoot', menuButton='Macros', menuEntry=None, cascade=None, **kw) """ active = 0 def getMacros(self, file): """load all macro functions from a given file""" names = [] macros = [] doc = [] #if not os.path.exists(file) : return names, macros, doc _dir, file = os.path.split(file) if file[-3:]=='.py': file = file[:-3] import sys sys.path.insert(0, _dir) m = __import__(file, globals(), locals(), []) sys.path = sys.path[1:] #m.__dict__['self'] = self.vf setattr(m, 'self', self.vf) import types for key, value in m.__dict__.items(): if type(value) == types.FunctionType: names.append(key) macros.append(value) doc.append(value.__doc__) return names, macros, doc def loadMacLib_cb(self, filename): """Call back function for 'Open Macro library' button""" ebn = self.cmdForms['loadMacro'].descr.entryByName ebn['openMacLib']['widget'].button.configure(relief='sunken') names, macros, docs = self.getMacros(filename) self.macroFile = filename self.macNames = names self.macMacros = macros self.macDoc = docs # Get a handle to the listchooser widget lc = ebn['macros']['widget'] lc.clear() if len(names) == len(docs): entries = map(lambda x, y: (x, y), names, docs) else: entries = map(lambda x: (x, None), names) map(lc.add, entries) ebn['openMacLib']['widget'].button.configure(relief='raised') # set cascade name to libary Name - "mac" w = ebn['cascade']['widget'] w.delete(0, 'end') w.insert(0, os.path.split(filename)[1][:-3]) def setDefaultEntryName(self, event=None): """Call back function for the listchooser showing macros. gets the name of the currently selected macro and puts it in the entry type in""" # enable add button ebn = self.cmdForms['loadMacro'].descr.entryByName ebn['loadMacro']['widget'].configure(state='normal') # put default name into name entry val = ebn['macros']['widget'].get() w = ebn['menuentry']['widget'] w.delete(0, 'end') w.insert(0, val[0]) #self.selectedMac = val[0] def loadMacro_cb(self, event=None): ebn = self.cmdForms['loadMacro'].descr.entryByName bar = ebn['menubar']['widget'].get() menub = ebn['menubutton']['widget'].get() name = ebn['menuentry']['widget'].get() cascade = ebn['cascade']['widget'].get() if cascade=='': cascade=None lc = ebn['macros']['widget'] macNames = lc.get() if len(macNames) != 0: macName = macNames[0] #macIndex = self.macNames.index(self.selectedMac) #macFunc = self.macMacros[macIndex] self.doitWrapper(macName, self.macroFile, menuBar=bar, menuButton=menub, menuEntry=name, cascade=cascade) ###self.addMacro(macFunc, bar, menub, name, cascade) ebn['openMacLib']['widget'].button.configure(relief='raised') def dismiss_cb(self): self.cmdForms['loadMacro'].withdraw() self.active = 0 def buildFormDescr(self, formName): if not formName=='loadMacro': return None ifd = InputFormDescr(title='Load Macros') if len(self.vf.libraries) is None: modu = __import__('ViewerFramework') else: modu = __import__(self.vf.libraries[0]) idir = os.path.split(modu.__file__)[0] + '/Macros' if not os.path.exists(idir): idir = None # 0 ifd.append({'widgetType':LoadButton, 'name':'openMacLib', 'wcfg':{'buttonType':Tkinter.Button, 'title':'Open Macro Library...', 'types':[('Macro Module Library', '*Mac.py'), ('Any Python Function', '*.py')], 'callback':self.loadMacLib_cb, 'idir':idir, 'widgetwcfg':{'text':'Open Macro Library'}}, 'gridcfg':{'sticky':'we'}}) # 1 ifd.append({'name':'macros', 'widgetType':ListChooser, 'wcfg':{'title':'Choose a macro', 'command':self.setDefaultEntryName, 'title':'Choose a macro'}, 'gridcfg':{'sticky':Tkinter.E+Tkinter.W}} ) # 2 ifd.append({'widgetType':Tkinter.Entry, 'name':'menubar', 'defaultValue':'menuRoot', 'wcfg':{'label':'menu bar'}, 'gridcfg':{'sticky':Tkinter.E} }) # 3 ifd.append({'widgetType':Tkinter.Entry, 'name':'menubutton', 'defaultValue':'Macros', 'wcfg':{'label':'menu button'}, 'gridcfg':{'sticky':Tkinter.E} }) # 4 ifd.append({'widgetType':Tkinter.Entry, 'name':'menuentry', 'defaultValue':'', 'wcfg':{'label':'menu entry'}, 'gridcfg':{'sticky':Tkinter.E} }) # 5 ifd.append({'widgetType':Tkinter.Entry, 'name':'cascade', 'defaultValue':'', 'wcfg':{'label':'cascade'}, 'gridcfg':{'sticky':Tkinter.E} }) # 6 ifd.append({'name': 'loadMacro', 'widgetType':Tkinter.Button, 'wcfg':{'text':'Load Macro', 'bd':6,'command': self.loadMacro_cb}, 'gridcfg':{'sticky':Tkinter.E+Tkinter.W}, }) # 7 ifd.append({'widgetType':Tkinter.Button, 'wcfg':{'text':'Dismiss', 'command': self.dismiss_cb}}) return ifd def guiCallback(self, event=None): if self.active: return self.active = 1 val = self.showForm("loadMacro", force=1,modal=0,blocking=0) ebn = self.cmdForms['loadMacro'].descr.entryByName ebn['loadMacro']['widget'].configure(state='disabled') def __call__(self, macroName, macroFile, menuBar='menuRoot', menuButton='Macros', menuEntry=None, cascade=None, **kw): """None<---loadMacro(macroName, macroFile, menuBar='menuRoot', menuButton='Macros', menuEntry=None, cascade=None, **kw) """ self.doitWrapper(macroName, macroFile, menuBar=menuBar, menuButton=menuButton, menuEntry=menuEntry, cascade=cascade) def doit(self, macroName, macroFile, menuBar='menuRoot', menuButton='Macros', menuEntry=None, cascade=None): if not hasattr(self, 'macroFile') or macroFile != self.macroFile: names, macros, docs = self.getMacros(macroFile) else: names = self.macNames macros = self.macMacros docs = self.macDoc if len(names) == 0 or len(macros)==0 or len(docs)==0: return macIndex = names.index(macroName) macro = macros[macIndex] from VFCommand import Command, CommandGUI c = Command(func=macro) g = CommandGUI() if cascade: g.addMenuCommand(menuBar, menuButton, menuEntry, cascadeName=cascade) else: g.addMenuCommand(menuBar, menuButton, menuEntry) self.vf.addCommand(c, macro.__name__, g) ## class loadMacroCommand(Command): ## """ ## Command to load dynamically macro commands. ## Using the Gui the user can open a macro file. The macros available in ## that file are then displayed in a list chooser. When a macro is selected ## in the listchooser, its documentation string is deisplayed and a default ## name for the macro in the viewer is suggested. The user can also specify ## a menuBar, a menuButton as well as an optional cascade name. ## """ ## active = 0 ## def getMacros(self, file): ## """load all macro functions from file""" ## self.file = file ## _dir, file = os.path.split(file) ## if file[-3:]=='.py': file = file[:-3] ## import sys ## sys.path.insert(0, _dir) ## m = __import__(file, globals(), locals(), []) ## sys.path = sys.path[1:] ## m.__dict__['self'] = self.vf ## import types ## names = [] ## macros = [] ## doc = [] ## for key,value in m.__dict__.items(): ## if type(value)==types.FunctionType: ## names.append(key) ## macros.append(value) ## doc.append(value.__doc__) ## return names, macros, doc ## def loadMacLib_cb(self, filename): ## """Call back function for 'Open Macro library' button""" ## # self.ifd[0]['widget'] is the 'Open Macro Library' button ## self.ifd[0]['widget'].configure(relief='sunken') ## #file = os.path.split(filename)[1][:-3] ## names, macros, docs = self.getMacros(filename) ## self.macNames = names ## self.macMacros = macros ## self.macDoc = docs ## # Get a handle to the listchooser widget ## lc = self.ifd[1]['widget'] ## lc.clear() ## if len(names) == len(docs): ## entries = map(lambda x, y: (x, y), names, docs) ## else: ## entries = map(lambda x: (x, None), names) ## map(lc.add, entries) ## self.ifd[0]['widget'].configure(relief='raised') ## # set cascade name to libary Name - "mac" ## w = self.ifd[5]['widget'] ## w.delete(0, 'end') ## w.insert(0, os.path.split(filename)[1][:-3]) ## def setDefaultEntryName(self, event=None): ## """Call back function for the listchooser showing macros. ## gets the name of the currently selected macro and puts it in the entry ## type in""" ## # enable add button ## self.ifd.entryByName['Load Macro']['widget'].configure(state='normal') ## # put default name into name entry ## val = self.ifd[1]['widget'].get() ## w = self.ifd[4]['widget'] ## w.delete(0, 'end') ## w.insert(0, val[0]) ## self.selectedMac = val[0] ## def addMacro(self, macro, menuBar, menuButton, name, cascade=None): ## from VFCommand import Command, CommandGUI ## c = Command(func=macro) ## g = CommandGUI() ## if cascade: ## g.addMenuCommand(menuBar, menuButton, name, cascadeName=cascade) ## else: ## g.addMenuCommand(menuBar, menuButton, name) ## self.vf.addCommand(c, macro.__name__, g) ## ## g.register(self.vf) ## self.log(file=self.file, macroName=macro.__name__, menuBar=menuBar, ## menuButton=menuButton, name=name, cascade=cascade) ## def loadMacro_cb(self, event=None): ## bar = self.ifd[2]['widget'].get() ## menub = self.ifd[3]['widget'].get() ## name = self.ifd[4]['widget'].get() ## cascade = self.ifd[5]['widget'].get() ## if cascade=='': cascade=None ## macIndex = self.macNames.index(self.selectedMac) ## macFunc = self.macMacros[macIndex] ## self.addMacro(macFunc, bar, menub, name, cascade) ## self.ifd[0]['widget'].configure(relief='raised') ## def customizeGUI(self): ## """create the cascade menu for selecting modules to be loaded""" ## self.selectedMac = '' ## # create the for descriptor ## ifd = self.ifd = InputFormDescr(title='Load macro commands') ## if len(self.vf.libraries) is None: ## modu = __import__('ViewerFramework') ## else: ## modu = __import__(self.vf.libraries[0]) ## idir = os.path.split(modu.__file__)[0] + '/Macros' ## if not os.path.exists(idir): ## idir = None ## ifd.append( {'widgetType':'OpenButton', 'text':'Open Macro library ...', ## 'types':[('Macro Module Library', '*Mac.py'), ## ('Any Python Function', '*.py')], ## 'idir':idir, ## 'title':'Open Macro File', ## 'callback': self.loadMacLib_cb } ) ## ifd.append({'title':'Choose a macro', ## 'widgetType':ListChooser, ## 'wcfg':{ ## 'command':self.setDefaultEntryName, ## 'title':'Choose a macro'}, ## 'gridcfg':{'sticky':Tkinter.E+Tkinter.W}} ) ## ifd.append({'widgetType':Tkinter.Entry, ## 'defaultValue':'menuRoot', ## 'wcfg':{'label':'menu bar'}, ## 'gridcfg':{'sticky':Tkinter.E} ## }) ## ifd.append({'widgetType':Tkinter.Entry, ## 'defaultValue':'Macros', ## 'wcfg':{'label':'menu button'}, ## 'gridcfg':{'sticky':Tkinter.E} ## }) ## ifd.append({'widgetType':Tkinter.Entry, ## 'defaultValue':'', ## 'wcfg':{'label':'menu entry'}, ## 'gridcfg':{'sticky':Tkinter.E} ## }) ## ifd.append({'widgetType':Tkinter.Entry, ## 'defaultValue':'', ## 'wcfg':{'label':'cascade'}, ## 'gridcfg':{'sticky':Tkinter.E} ## }) ## ifd.append({'name': 'Load Macro', ## 'widgetType':Tkinter.Button, ## 'text':'Load Macro', ## 'wcfg':{'bd':6}, ## 'gridcfg':{'sticky':Tkinter.E+Tkinter.W}, ## 'command': self.loadMacro_cb}) ## ifd.append({'widgetType':Tkinter.Button, ## 'text':'Dismiss', ## 'command': self.Dismiss_cb}) ## def Dismiss_cb(self): ## #self.cmdForms['loadMacro'].withdraw() ## self.ifd.form.destroy() ## self.active = 0 ## def guiCallback(self, event=None, file=None): ## if self.active: return ## self.active = 1 ## self.customizeGUI() ## self.form = self.vf.getUserInput(self.ifd, modal=0, blocking=0) ## self.ifd.entryByName['Load Macro']['widget'].configure(state='disabled') ## if file: self.loadMacLib_cb(file) ## def __call__(self, file=None, macroName=None, menuBar='menuRoot', ## menuButton='Macros', name=None, cascade=None): ## """file=None, macroName=None, menuBar='menuRoot', menuButton='Macros', ## name=None, cascade=None""" ## if not macroName: self.guiCallback(file=file) ## else: ## if file[-3:]=='.py': file = file[:-3] ## names, macros, docs = self.getMacros(file) ## i = names.index(macroName) ## if name==None: name=macroName ## self.addMacro(macros[i], menuBar, menuButton, name, cascade) class ShellCommand(Command): """Command to show/Hide the Python shell. \nPackage : ViewerFramework \nModule : basicCommand.py \nClass : ShellCommand \nCommand : Shell \nSynopsis:\n None<---Shell() """ def onAddCmdToViewer(self): if self.vf.hasGui: self.vf.GUI.pyshell.top.protocol('WM_DELETE_WINDOW', self.vf.Shell.onDestroy) def show(self): self.vf.GUI.pyshell.top.deiconify() def hide(self): self.vf.GUI.pyshell.top.withdraw() def __call__(self, *args): """None<---Shell() """ if args[0]: self.show() self.vf.GUI.toolbarCheckbuttons['Shell']['Variable'].set(1) else: self.hide() self.vf.GUI.toolbarCheckbuttons['Shell']['Variable'].set(0) def guiCallback(self): on = self.vf.GUI.toolbarCheckbuttons['Shell']['Variable'].get() if on: self.show() else: self.hide() def onDestroy(self): self.vf.GUI.toolbarCheckbuttons['Shell']['Variable'].set(0) self.hide() ShellCommandGUI = CommandGUI() ShellCommandGUI.addToolBar('Shell', icon1='PyShell.gif', balloonhelp='Python IDLE Shell', index=1) class SaveSessionCommand(Command): """Command to allow the user to save the session as it is in a file. It logs all the transformation. \nPackage : Pmv \nModule : customizationCommands.py \nClass : SaveSessionCommand """ def logString(self, *args, **kw): """return None as log string as we don't want to log this """ pass def guiCallback(self, event=None): ### FIXME all the logs should be in a stack and not in a file. if self.vf.logMode == 'no': self.vf.warningMsg("No log information because logMode was set to no.") return newfile = self.vf.askFileSave(types = [ ('Pmv sesion files', '*.psf'), ('all files', '*.py')], defaultextension=".psf", title = 'Save Session in File:') if not newfile is None: self.doitWrapper(newfile, redraw=0) def doit(self, filename): #print "SaveSessionCommand.doit" ext = os.path.splitext(filename)[1].lower() if ext=='.psf': self.vf.saveFullSession(filename) else: import shutil # get the current log. if hasattr(self.vf, 'logAllFile'): logFileName = self.vf.logAllFile.name self.vf.logAllFile.close() if filename!=logFileName: shutil.copy(logFileName, filename) self.vf.logAllFile = open(logFileName,'a') # Add to it the transformation log. logFile = open(filename,'a') vi = self.vf.GUI.VIEWER code = vi.getViewerStateDefinitionCode('self.GUI.VIEWER') code.extend( vi.getObjectsStateDefinitionCode('self.GUI.VIEWER') ) if code: for line in code: logFile.write(line) if vi.GUI.contourTk.get(): controlpoints=vi.GUI.curvetool.getControlPoints() sensitivity=vi.GUI.d1scalewheel.get() logFile.write("self.GUI.VIEWER.GUI.curvetool.setControlPoints(%s)" %controlpoints) logFile.write("\n") logFile.write("self.GUI.VIEWER.GUI.curvetool.setSensitivity(%s)" %sensitivity) #sceneLog = self.vf.Exit.logScene() #for l in sceneLog: # l1 = l+'\n' # logFile.write(l1) logFile.close() if hasattr(self.vf, 'recentFiles'): self.vf.recentFiles.add(filename, 'readSourceMolecule') # SaveSessionCommand Command GUI SaveSessionCommandGUI = CommandGUI() SaveSessionCommandGUI.addMenuCommand( 'menuRoot', 'File', 'Current Session', index=2, cascadeName='Save', cascadeIndex=2, separatorAboveCascade=1) SaveSessionCommandGUI.addToolBar('Save', icon1='filesave.gif', type='ToolBarButton', balloonhelp='Save Session', index=1) class ExitCommand(Command): """Command to destroy application \nPackage : ViewerFramework \nModule : basicCommand.py \nClass : ExitCommand \nCommand : Exit \nSynopsis:\n None<---Exit(ask) \nask = Flag when set to 1 a form asking you if you really want to quit will popup, it will quit directly if set to 0 """ def onAddCmdToViewer(self): import warnings if self.vf.hasGui: self.vf.GUI.ROOT.protocol('WM_DELETE_WINDOW',self.askquit) def logObjectTransformations(self, object): warnings.warn( "logObjectTransformations is deprecated", DeprecationWarning, stacklevel=2) log = [] # FIXME won't work with instance matrices mat = object.GetMatrix(object) import numpy.oldnumeric as Numeric log.append("self.transformObject('rotation', '%s', matrix=%s,log=0)"%(object.fullName,tuple(object.rotation))) log.append("self.transformObject('translation', '%s', matrix=%s, log=0 )"%(object.fullName, tuple(object.translation))) log.append("self.transformObject('scale', '%s', matrix=%s, log=0 )"%(object.fullName,tuple(object.scale))) log.append("self.transformObject('pivot', '%s', matrix=%s, log=0 )"%(object.fullName,tuple(object.pivot))) return log def logObjectMaterial(self, object): warnings.warn("logObjectMaterial is deprecated", DeprecationWarning, stacklevel=2) log = [] from opengltk.OpenGL import GL log.append("from opengltk.OpenGL import GL") mat = object.materials[GL.GL_FRONT] log.append("self.setObject('%s', materials=%s, propName='ambi', matBind=%d)" % (object.fullName, repr(mat.prop[0])[6:-5],mat.binding[0])) log.append("self.setObject('%s', materials=%s, propName='diff', matBind=%d)" % (object.fullName, repr(mat.prop[1])[6:-5],mat.binding[1])) log.append("self.setObject('%s', materials=%s, propName='emis', matBind=%d)" % (object.fullName, repr(mat.prop[2])[6:-5],mat.binding[2])) log.append("self.setObject('%s', materials=%s, propName='spec', matBind=%d)" % (object.fullName, repr(mat.prop[3])[6:-5],mat.binding[3])) log.append("self.setObject('%s', materials=%s, propName='shini', matBind=%d)" % (object.fullName, repr(mat.prop[4])[6:-5],mat.binding[4])) mat = object.materials[GL.GL_BACK] log.append("self.setObject('%s', materials=%s, polyFace=GL.GL_BACK,propName='ambi', matBind=%d)" % (object.fullName, repr(mat.prop[0])[6:-5],mat.binding[0])) log.append("self.setObject('%s', materials=%s, polyFace=GL.GL_BACK,propName='diff', matBind=%d)" % (object.fullName, repr(mat.prop[1])[6:-5],mat.binding[1])) log.append("self.setObject('%s', materials=%s, polyFace=GL.GL_BACK,propName='spec', matBind=%d)" % (object.fullName, repr(mat.prop[2])[6:-5],mat.binding[2])) log.append("self.setObject('%s', materials=%s, polyFace=GL.GL_BACK,propName='emis', matBind=%d)" % (object.fullName, repr(mat.prop[3])[6:-5],mat.binding[3])) log.append("self.setObject('%s', materials=%s, polyFace=GL.GL_BACK,propName='shini', matBind=%d)" % (object.fullName, repr(mat.prop[4])[6:-5],mat.binding[4])) return log def logCameraTransformations(self, camera): warnings.warn("logCameraTransformations is deprecated", DeprecationWarning, stacklevel=2) logStr = "self.setCamera('%s', \n"%camera.name logStr = logStr + "rotation=(%9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f),\n"%tuple(camera.rotation) logStr=logStr + "translation=(%9.3f, %9.3f, %9.3f),\n"%tuple(camera.translation) logStr = logStr + "scale=(%9.3f, %9.3f, %9.3f),\n"%tuple(camera.scale) logStr = logStr + "pivot=(%9.3f, %9.3f, %9.3f),\n"%tuple(camera.pivot) logStr = logStr + "lookAt=(%9.3f, %9.3f, %9.3f),\n"%tuple(camera.lookAt) logStr = logStr + "lookFrom=(%9.3f, %9.3f, %9.3f),\n"%tuple(camera.lookFrom) logStr = logStr + "direction=(%9.3f, %9.3f, %9.3f))"%tuple(camera.direction) return logStr+'\n' def logCameraProp(self, camera): warnings.warn("logCameraProp is deprecated", DeprecationWarning, stacklevel=2) logStr = "self.setCamera('%s', \n"%camera.name logStr = logStr + "width=%d, height=%d, rootx=%d, rooty=%d,"%\ (camera.width, camera.height, camera.rootx, camera.rooty) logStr = logStr + "fov=%f, near=%f, far=%f,"%\ (camera.fovy, camera.near, camera.far) logStr = logStr + "color=(%6.3f,%6.3f,%6.3f,%6.3f))"%\ tuple(camera.backgroundColor) return logStr+'\n' def logLightTransformations(self, light): warnings.warn("logLightTransformations is deprecated", DeprecationWarning, stacklevel=2) logStr = "self.setLight('%s', \n"%light.name logStr = logStr + "rotation=(%9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f),\n"%tuple(light.rotation) logStr = logStr + "translation=(%9.3f, %9.3f, %9.3f),\n"%tuple(light.translation) logStr = logStr + "scale=(%9.3f, %9.3f, %9.3f),\n"%tuple(light.scale) logStr = logStr + "pivot=(%9.3f, %9.3f, %9.3f),\n"%tuple(light.pivot) logStr = logStr + "direction=(%9.3f,%9.3f,%9.3f,%9.3f))"%tuple(light.direction) return logStr+'\n' def logLightProp(self, light): warnings.warn("logLightProp is deprecated", DeprecationWarning, stacklevel=2) logStr = "self.setLight('%s', \n"%light.name logStr = logStr + "enable=%d, visible=%d, length=%f,\n"%\ (light.enabled, light.visible, light.length) logStr = logStr + "ambient=(%6.3f,%6.3f,%6.3f,%6.3f),\n"%\ tuple(light.ambient) logStr = logStr + "specular=(%6.3f,%6.3f,%6.3f,%6.3f),\n"%\ tuple(light.specular) logStr = logStr + "diffuse=(%6.3f,%6.3f,%6.3f,%6.3f))\n"%\ tuple(light.diffuse) return logStr+'\n' def logClipTransformations(self, clip): warnings.warn("logClipTransformations is deprecated", DeprecationWarning, stacklevel=2) logStr = "self.setClip('%s', \n"%clip.name logStr = logStr + "rotation=(%9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f, %9.3f),\n"%tuple(clip.rotation) logStr = logStr + "translation=(%9.3f, %9.3f, %9.3f),\n"%tuple(clip.translation) logStr = logStr + "scale=(%9.3f, %9.3f, %9.3f),\n"%tuple(clip.scale) logStr = logStr + "pivot=(%9.3f, %9.3f, %9.3f))\n"%tuple(clip.pivot) return logStr+'\n' def logClipProp(self, clip): warnings.warn("logClipProp is deprecated", DeprecationWarning, stacklevel=2) logStr = "self.setClip('%s', \n"%clip.name logStr = logStr + "visible=%d, lineWidth=%f,\n"%\ (clip.visible, clip.lineWidth) logStr = logStr + "color=(%6.3f,%6.3f,%6.3f,%6.3f))\n"%\ tuple(clip.color) return logStr+'\n' def logAddClipPlanes(self, object): warnings.warn("logAddClipPlanes is deprecated", DeprecationWarning, stacklevel=2) log = [] for c in object.clipP: log.append("self.addClipPlane('%s','%s', %d, %d)\n"%\ (object.fullName, c.name, object.clipSide[c.num], 0)) for c in object.clipPI: log.append("self.addClipPlane('%s','%s', %d, %d)\n"%\ (object.fullName, c.name, object.clipSide[c.num], 1)) return log def logScene(self): warnings.warn("logScene is deprecated", DeprecationWarning, stacklevel=2) log = [] vi = self.vf.GUI.VIEWER for c in vi.cameras: if c._modified: log.append(self.logCameraTransformations(c)) log.append(self.logCameraProp(c)) for l in vi.lights: if l._modified: log.append(self.logLightTransformations(l)) log.append(self.logLightProp(l)) for c in vi.clipP: if c._modified: log.append(self.logClipTransformations(c)) log.append(self.logClipProp(c)) root = self.vf.GUI.VIEWER.rootObject for o in root.AllObjects(): if not o.transformIsIdentity(): log.extend(self.logObjectTransformations(o)) if o._modified: log.extend(self.logAddClipPlanes(o)) log.extend(self.logObjectMaterial(o)) # Trigger a Viewer Redraw at the end. log.append("self.GUI.VIEWER.Redraw()") return log def savePerspective(self): if self.vf.resourceFile: rcFile = os.path.join(os.path.split(self.vf.resourceFile)[0], "perspective") else: rcFolder = getResourceFolderWithVersion() rcFile = os.path.join(rcFolder, "ViewerFramework", "perspective") try: rcFile = open(rcFile, 'w') except Exception, inst: #to avoid "IOError: [Errno 116] Stale NFS file handle" error message when running the tests return if self.vf.GUI.floatCamVariable.get(): rcFile.write("self.GUI.floatCamera()\n") geom = self.vf.GUI.vwrCanvasFloating.geometry() dum,x0,y0 = geom.split('+') w,h = [int(x) for x in dum.split('x')] rcFile.write("self.setCameraSize(%s, %s, xoffset=%s, yoffset=%s)\n"%(w,h,x0,y0)) xywh = self.vf.GUI.getGeom() #make sure that xywh are within screen coordinates if xywh[0]+xywh[2] > self.vf.GUI.ROOT.winfo_screenwidth() or\ xywh[1]+xywh[3] > self.vf.GUI.ROOT.winfo_screenheight(): rcFile.write("#"+str(xywh)+"\n") else: rcFile.write("self.GUI.setGeom"+str(xywh)+"\n") # txt = self.vf.GUI.MESSAGE_BOX.tx.get().split("\n") # if len(txt) > 5: # txt = txt[5:] # linesToWrite = [] # for line in txt: # if line.startswith("self.browseCommands"): # linesToWrite.append(line) # linesToWrite = set(linesToWrite) # for line in linesToWrite: # line = line.replace('log=0','log=1') # rcFile.write(line) # rcFile.write("\n") rcFile.close() def __call__(self, ask, **kw): """None <- Exit(ask, **kw) \nask = Flag when set to 1 a form asking you if you really want to quit will popup, it will quit directly if set to 0. """ kw['redraw'] = 0 kw['log'] = 0 kw['busyIdle'] = 0 apply(self.doitWrapper, (ask,),kw) def doit(self, ask): logPref = self.vf.userpref['Transformation Logging']['value'] if logPref == 'continuous': if hasattr(self.vf.GUI,'pendingLog') and self.vf.GUI.pendingLog: self.vf.log(self.vf.GUI.pendingLog[-1]) if self.vf.userpref.has_key('Save Perspective on Exit'): logPerspective = self.vf.userpref['Save Perspective on Exit']['value'] if logPerspective == 'yes': self.savePerspective() elif logPref == 'final': #changed 10/24/2005-RH ##code = self.logScene() #vi = self.vf.GUI.VIEWER #code = vi.getViewerStateDefinitionCode('self.GUI.VIEWER') #code.extend( vi.getObjectsStateDefinitionCode('self.GUI.VIEWER') ) #if code: # for line in code: # self.vf.log(line) if hasattr(self.vf, 'logAllFile'): self.vf.saveSession(self.vf.logAllFile.name) if ask: ## from ViewerFramework.gui import InputFormDescr # from mglutil.gui.InputForm.Tk.gui import InputFormDescr # self.idf = InputFormDescr(title='Do you wish to Quit?') # self.idf.append({'widgetType':Tkinter.Button, # 'wcfg':{'text':'QUIT', # 'width':10, # 'command':self.quit_cb}, # 'gridcfg':{'sticky':'we'}}) # # self.idf.append({'widgetType':Tkinter.Button, # 'wcfg':{'text':'CANCEL', # 'width':10, # 'command':self.cancel_cb}, # 'gridcfg':{'sticky':'we', 'row':-1}}) # val = self.vf.getUserInput(self.idf, modal=1, blocking=0, # okcancel=0) self.vf.GUI.ROOT.after(10,self.askquit) else: self.quit_cb() def quit_cb(self): #print "ExitComand.quit_cb" self.vf.GUI.softquit_cb() def cancel_cb(self): form = self.idf.form form.root.destroy() return def guiCallback(self): #print "ExitComand.guiCallback" self.doitWrapper(1, redraw=0, log=0) def askquit(self): #print "ExitComand.askquit" import tkMessageBox ok = tkMessageBox.askokcancel("Quit?","Do you Wish to Quit?") if ok: if hasattr(self.vf, 'openedSessions'): import shutil for folder in self.vf.openedSessions: print 'removing session directory', folder shutil.rmtree(folder) self.afterDoit = None self.vf.GUI.ROOT.after(10,self.vf.GUI.quit_cb) class customAnimationCommand(Command): """Command to start Custom Animation notebook widget """ def __init__(self, func=None): Command.__init__(self, func) self.root = None self.animNB = None def guiCallback(self): self.startCustomAnim_cb() def __call__(self, **kw): """None <- customAnimation""" add = kw.get('add', None) if add is None: add = 1 else: assert add in (0, 1) if self.vf.GUI.toolbarCheckbuttons.has_key('customAnimation'): self.vf.GUI.toolbarCheckbuttons['customAnimation']['Variable'].set(add) self.startCustomAnim_cb() def startCustomAnim_cb(self): on = self.vf.GUI.toolbarCheckbuttons['customAnimation']['Variable'].get() if on: if not self.animNB: from Pmv.scenarioInterface.animationGUI import AnimationNotebook self.root = Tkinter.Toplevel() self.root.title('Custom Animation') self.root.protocol("WM_DELETE_WINDOW", self.hide_cb) vi = self.vf.GUI.VIEWER self.animNB = AnimationNotebook(self.vf, self.root) else: self.show_cb() else: self.hide_cb() def hide_cb(self): if self.root: self.root.withdraw() self.vf.GUI.toolbarCheckbuttons['customAnimation']['Variable'].set(0) def show_cb(self, event=None): if self.root: self.root.deiconify() self.vf.GUI.toolbarCheckbuttons['customAnimation']['Variable'].set(1) def onAddCmdToViewer(self): if self.vf.hasGui: # add a page for scenario page = self.scenarioMaster = self.vf.GUI.toolsNoteBook.add("AniMol") from Pmv.scenarioInterface.animationGUI import AnimationNotebook self.animNB = AnimationNotebook(self.vf, page) button = Tkinter.Radiobutton( self.vf.GUI.toolsButtonBarMaster, width=10, var=self.vf.GUI.toolsButtonBarTabVar, value='Scenario', indicatoron=False, text='Scenario', font=('Helvetica', '', 10), padx=3, pady=0) button.pack(side='left', anchor='w') #button = self.vf.GUI.toolsNoteBook.tab(1) button.configure(command=self.adjustWidth) def adjustWidth(self): self.vf.GUI.toolsNoteBook.selectpage(1) self.vf.GUI.workspace.configurepane('ToolsNoteBook',size=self.animNB.master.winfo_width()) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/cmdlib.py0000644000175000017500000000544507364114342023754 0ustar moellermoellercmdlist = [ ("ViewerFramework","customizationCommands","setUserPreference",""" Command providing a GUI to allow the user to set available\n userPreference."""), ("ViewerFramework","customizationCommands","setOnAddObjectCommands","""Command to specify commands that have to be carried out when an object\n is added to the application. Only the commands that have been loaded so\n far in the application will appear in the GUI. Commands are applied in\n the order they have been selected.\n """), ("ViewerFramework","customizationCommands","saveSession","""Command to allow the user to save the session as it is in a file.\n It copies the .pmvrc in that file and also log all the transformation."""), ("ViewerFramework","customizationCommands","source","""\n Command to source a command file\n """), ("ViewerFramework","customizeVFGUICommands","changeFont",""" Command to change font of the VFGUI"""), ("ViewerFramework","customizeVFGUICommands","showHideGUI",""" Command to change which parts of the VFGUI are visible"""), ("ViewerFramework","customizeVFGUICommands","bindAction",""""""), ("ViewerFramework","customizeVFGUICommands","hideGUI","""\n Allow to Hide the ViewerFrameworkGUI at any time """), ("ViewerFramework","customizeVFGUICommands","showGUI","""\n Allow to show the ViewerFrameworkGUI at any time"""), ("ViewerFramework","dejaVuCommands","transformObject",""""""), ("ViewerFramework","dejaVuCommands","setObject",""""""), ("ViewerFramework","dejaVuCommands","setCamera",""""""), ("ViewerFramework","dejaVuCommands","setLight",""""""), ("ViewerFramework","dejaVuCommands","setClip",""""""), ("ViewerFramework","dejaVuCommands","addClipPlane",""""""), ("ViewerFramework","dejaVuCommands","centerGeom",""""""), ("ViewerFramework","dejaVuCommands","viewPoints","""None <- view(name, mode='save' or 'restore')\n Command to save current transformation of root node\n """), ("ViewerFramework","dejaVuCommands","centerScene","""None <- centerScene()\n Command to scale and translate the scene to make it fit in the view frustum\n """), ("ViewerFramework","dejaVuCommands","rotateScene","""None <- rotateScene(axis, stepSize, nbSteps)\n Command to rotate the scene about an arbitrary axis nbSteps times\n (default full turn) by stepSize degrees (default 5)\n """), ("ViewerFramework","dejaVuCommands","printGeometryName",""""""), ("ViewerFramework","dejaVuCommands","startContinuousPicking","""Start the contiguous selection mode"""), ("ViewerFramework","dejaVuCommands","stopContinuousPicking",""""""), ("ViewerFramework","documentationCommands","helpCommand",""""""), ("ViewerFramework","serverCommands","startServer",""" This class implements methods to start a server"""), ("ViewerFramework","serverCommands","connectToServer",""" This class implements method to connect to a server."""), ] ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/comm.py0000644000175000017500000001776111162221106023445 0ustar moellermoeller############################################################################# # # Author: Michel F. SANNER # # Copyright: M. Sanner TSRI 2000 # ############################################################################# # # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/comm.py,v 1.6 2009/03/24 18:11:18 sanner Exp $ # # $Id: comm.py,v 1.6 2009/03/24 18:11:18 sanner Exp $ # """ COMM module Author: Michel F. Sanner Date: Oct 11 2000 This module implements the Comm class that provides bi-directional communication over sockets. The Comm object provides server functionality, accepting connections from multiple clients (each client is handled by a separate thread). the comm object also provides client side functionality, allowing a Comm object to connect to an existing server. A - Server side After a Comm object has been created, the startServer method can be called to create a socket (self.serverSocket) and find a free port to which this socket will be bound. The port is stored in self.port By calling the acceptClients(func, maxConnections) one can allow the server to accept connection from clients. 'func' will be called for each message sreceived from clients. FIXME: calling func should probably set a lock. acceptClients works in its own thread. When a client connects, a new thread is started to handle input from this client (listenToClient()) and the client is added to the Comm's clients dictionary. The client dictionary uses the client's name as a key and stores the socket and the address created by accept. hangupClient(name, client) can be called to terminate a connection with a specific client. sendToClients(message) can be used to send a string to all connected clients B - Client side A comm object can be used to connect to a running server using the connectToServer(self, host, port, func). host cane be a host name or an IP address (as string). If the connection is successful a new thread is started to listen to the server and 'func' will be called with all messages comming from that server. disconnectFromServer(self, clientSocket) can be called to disconnect fropm a server. 'clientSocket' can be a socket or a """ import sys, time from socket import * import thread, types class Comm: def __init__(self): self.verbose = 1 # set to 0 to get rid of printing # server related members self.clients = {} # dictionary of clients, # key is the host name+address bound to the socket # on the other end of the connection # value is (conn, addr) tuple self.port = None # port used by server to accept connections self.serverSocket = None # socket used by server to accpet conenctions self.maxConnections = 5 # maximum number of conenctions allowed # client related members self.serverSockets = {} # dictionary of servers, key is the server's # name, value is the socket created for this # connection def getPort(self, socket, base=50000): """find the first free port above base""" port = base while(1): try: socket.bind( ( '', port)) return port except: import traceback traceback.print_exc() port = port + 1 print port ## ## server side def startServer(self, port=None): self.serverSocket = s = socket(AF_INET, SOCK_STREAM) if port is None: self.port = self.getPort(s) else: self.port = port def acceptClients(self, func, maxConnections=5): self.maxConnections = maxConnections self.serverSocket.listen(maxConnections) if self.verbose: print "server ready, listening to port ", self.port while 1: conn, addr = self.serverSocket.accept() name = gethostbyaddr(conn.getpeername()[0])[0] + str(addr[1]) self.clients[name] = ( conn, addr ) if self.verbose: print 'Connected by', name, '\n' thread.start_new(self.listenToClient, (name, conn, func)) def listenToClient(self, name, client, func): while (1): data = client.recv(1024) if data=='': if self.verbose: print 'Connection closed by client' self.hangupClient(client) return MSGLEN = int(data) #print 'FFFFF client receving', MSGLEN msg = '' while len(msg) < MSGLEN: chunk = client.recv(MSGLEN-len(msg)) if chunk == '': if self.verbose: print 'Connection closed by client' self.hangupClient(client) return msg = msg + chunk #print 'client received', len(msg) func(name, msg) def hangupClient(self, client): if type(client) == types.StringType: cl = self.clients[client][0] else: cl = client client = None for key, value in self.clients.items(): if value[0]==cl: client = key break if client is None: raise ValueError, "client not found" cl.close() del self.clients[client] def sendToClients(self, message): """send a messaqe to all clients""" #print 'server sending to client', message for c in self.clients.values(): print 'server sending', len(message), '%020d'%len(message) c[0].send('%020d'%len(message)) c[0].send(message) def getClients(self): """send a messaqe to all clients""" return self.clients.keys() ## ## client side def connectToServer(self, host, port, func): """become a client of a server specified using host and port, func will be called to handle messages from server """ host = gethostbyname(host) serverSocket = socket(AF_INET, SOCK_STREAM) serverSocket.connect( ( host, port)) name = gethostbyaddr(serverSocket.getpeername()[0])[0]+str(port) self.serverSockets[name] = serverSocket thread.start_new(self.listenToServer, (name, serverSocket, func)) def listenToServer(self, name, client, func): while (1): data = client.recv(20) print 'client receives', data MSGLEN = int(data) #print 'FFFFF client receving', MSGLEN msg = '' while len(msg) < MSGLEN: chunk = client.recv(MSGLEN-len(msg)) if chunk == '': if self.verbose: print 'Connection closed by server' self.disconnectFromServer(client) return msg = msg + chunk #print 'client received', len(msg) func(name, msg) def disconnectFromServer(self, server): if type(server) == types.StringType: cl = self.serverSockets[server] else: cl = server server = None for key, values in self.serverSockets.items(): if values==cl: server = key break if server is None: raise ValueError, "server not found" cl.shutdown(2) cl.close() del self.serverSockets[server] def getServers(self): """send a messaqe to all servers""" return self.serverSockets.keys() if __name__ == '__main__': com = Comm() com.startServer() #com.acceptClients() def foo1(client, data): print 'client %s sent> %s'%(client,data) thread.start_new(com.acceptClients, (foo1,)) def foo(server, data): print 'server %s sent> %s'%(server,data) #com.connectToServer('', 50008, foo) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/customizationCommands.py0000644000175000017500000006242611547675640027131 0ustar moellermoeller## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by ############################################################################# # # Author: Michel F. SANNER, Sophie Coon # # Copyright: M. Sanner TSRI 2000 # ############################################################################# """ This module implements a set of class to customize a ViewerFramework application: SetUserPreference SetOnAddObjectCmds """ # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/customizationCommands.py,v 1.58 2011/04/08 21:18:24 sargis Exp $ # # $Id: customizationCommands.py,v 1.58 2011/04/08 21:18:24 sargis Exp $ # from ViewerFramework.VFCommand import Command, CommandGUI ## from ViewerFramework.gui import InputFormDescr from mglutil.gui.InputForm.Tk.gui import InputFormDescr from mglutil.util.packageFilePath import findResourceFile from mglutil.util.callback import CallBackFunction from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ListChooser import Pmw, Tkinter, types, os import sys import warnings import tkMessageBox ## class SetCmdParam(Command): ## """ Command providing an GUI for the user to set the parameter to use ## as default when using the command as interactive commands or ## setOnAddCmdObj....""" ## def buildFormDescr(self, formName): ## if formName=='setParam': ## cmdNames = filter(lambda x, self = self: ## self.vf.commands[x].flag & self.objArgOnly, ## self.vf.commands.keys()) ## cmdNames.sort() ## cmdEntries = map(lambda x: (x, None), cmdNames) ## idf = InputFormDescr(title='Set default parameters') ## idf.append({'name':'cmdlist', ## 'widgetType':ListChooser, ## 'tooltip':"""list of the commands loaded so far in the ## application which can be applied to the object ## when loaded in the application""", ## 'wcfg':{'entries':cmdEntries, ## 'mode':'single', ## 'command':self.showDocString, ## 'lbwcfg':{'exportselection':0}, ## 'title':'Available commands'}, ## 'gridcfg':{'sticky':'wens', 'row':0, 'column':0 ## ,'rowspan':3}}) ## ## idf.append({'name':'cmdstring', ## ## 'widgetType':Pmw.EntryField, ## ## idf.append({'name':'label', ## ## 'widgetType' ## return idf ## def showDocString(self, event=None): ## ebn = self.cmdForms['setParam'].descr.entryByName ## lb = ebn['cmdlist']['widget'] ## cmdName=lb.get()[0] ## cmdString = self.vf.commands[cmdName].__call__.__doc__ ## print 'here', cmdString ## def guiCallback(self): ## self.showForm('setParam', modal=0, scrolledFrame=0, blocking=0) class SetUserPreference(Command): """ Command providing a GUI to allow the user to set available userPreference. \nPackage : Pmv \nModule : customizationCommands.py \nClass : SetUserPreference \nCommand : setUserPreference \nSynopsis:\n None <--- setUserPreference(item, kw**) """ def set_cb(self,key): """ Method to set the userPreference to the given new value for the current session. """ descr = self.form.descr result = filter(lambda x, k = key: x.has_key('name') \ and x['name']== k, descr) assert len(result)==1 value = result[0]['widget'].get() self.doitWrapper((key,value), redraw=0) def testType(self,value,key): """ Method testing the type of the userpreference. the combobox returns a string""" if type(value) is types.TupleType: value = value[0] if isinstance(self.vf.userpref[key]['value'], types.IntType): try: value = int(value) except: value = None elif isinstance(self.vf.userpref[key]['value'], types.FloatType): try: value = float(value) except: value = None return value def doit(self, item): """ Method taking the tuple (key,value) and set the corresponding preference to the given value.""" if item[0] == 'trapExceptions': warnings.warn('trapExceptions user preference is deprecated', DeprecationWarning, stacklevel=2) return #add other transformation where if item[0] == 'warningMsgFormat': item = ('Warning Message Format', item[1]) if not item[0] in self.vf.userpref: warnings.warn(item[0]+' user preference is deprecated. Please update your resource files.', DeprecationWarning) return assert type(item) is types.TupleType and len(item)==2 logItems = [] key ,value= item value = self.testType(value,key) if value is None: return if self.vf.userpref[key]['value']==value: return self.vf.userpref.set(key,value) #apply(self.log,(item,)) def __call__(self, item, **kw): """None <--- setUserPreference(item, kw**) """ assert type(item) is types.TupleType and len(item)==2 apply(self.doitWrapper, (item,), kw) def dismissForm(self): self.form.destroy() def dismissSmallForm(self): self.smallForm.destroy() def info_cb(self, doc): """Method providing a gui to display the documentation describing the userpreference.""" tkMessageBox.showinfo("Documentation", doc, parent=self.form.root) def default_cb(self, key): """ Method that will make the userpref a default meaning it writes a log in the .pmvrc if existing and creates one if not, in that case a file browser opens and sets it to the given value for the current session..""" # here should pop up a file browser to allow the user to save self.set_cb(key) descr = self.form.descr result = filter(lambda x, k = key: x.has_key('name') \ and x['name']== k, descr) assert len(result)==1 value = result[0]['widget'].get() value = self.testType(value,key) self.vf.userpref.saveSingleSetting(key, value) def updateGUI(self, name,oldvalue, newvalue): """ Callback added to all the userpref so the Gui is updated when userpref is modified.""" if str(self.vf.userpref[name]['value']) != str(oldvalue): w = self.form.descr.entryByName[name]['widget'] #val = str(newvalue) if isinstance(w, Pmw.ComboBox): w.selectitem(newvalue) elif isinstance(w,Pmw.EntryField): w.setentry(str(newvalue)) def guiCallback(self): idf = InputFormDescr(title ="Set User Preferences") categoryList = ['General'] for value in self.vf.userpref.values(): if not value['category'] in categoryList: categoryList.append(value['category']) widgetType = {'widgetType':Pmw.NoteBook, 'name':'prefNotebook', 'container':{}, 'wcfg':{'borderwidth':2}, 'componentcfg':[], 'gridcfg':{'sticky':'we'}, } for item in categoryList: widgetType['container'][item] = "w.page('"+item+"')" widgetType['componentcfg'].append({'name':item, 'cfg':{}}) idf.append(widgetType) for item in categoryList: idf.append({'name':item+"Group", 'widgetType':Pmw.Group, 'parent':item, 'container':{item+'Group':'w.interior()'}, 'wcfg':{'tag_text':item}, 'gridcfg':{'sticky':'wne'} }) for key, value in self.vf.userpref.items(): if not self.updateGUI in self.vf.userpref[key]['callbackFunc']: self.vf.userpref.addCallback(key,self.updateGUI) # put a label to have more space between the widget Maybe # could replace it by using the options padx and pady. group = value['category']+"Group" idf.append({'widgetType':Tkinter.Label, 'parent':group, 'wcfg':{'text':''}, 'gridcfg':{'sticky':'we','columnspan':3}}) if value.has_key('validValues') and value['validValues']: idf.append({'widgetType':Pmw.ComboBox, 'parent':group, 'name':key, 'defaultValue':value['value'], 'wcfg':{'label_text':key, 'labelpos':'n', 'scrolledlist_items': value['validValues'] }, 'gridcfg':{'sticky':'wens'}}) else: if value.has_key('validateFunc') and value['validateFunc']: def valid(value, func=value['validateFunc']): test = func(value) if test == 1: return Pmw.OK else: return Pmw.PARTIAL idf.append({'widgetType':Pmw.EntryField, 'parent':group, 'name':key, 'wcfg':{'label_text':key, 'labelpos':'n', 'value': value['value'], 'validate':{'validator': valid}}, 'gridcfg':{'sticky':'wens'}}) else: idf.append({'widgetType':Pmw.EntryField, 'parent':group, 'name':key, 'wcfg':{'label_text':key, 'labelpos':'n'}, 'gridcfg':{'sticky':'wens'}}) idf.append({'widgetType':Tkinter.Button, 'parent':group, 'wcfg':{'bitmap':'info', 'width':50, 'height':40, 'padx':10, 'command':CallBackFunction(self.info_cb, value['doc'])}, 'gridcfg':{'row':-1,'sticky':'wens'}}) idf.append({'widgetType':Tkinter.Button, 'parent':group, 'wcfg':{'text':'Make \nDefault', 'padx':10, 'command':CallBackFunction(self.default_cb, key)}, 'gridcfg':{'row':-1,'sticky':'wens'}}) idf.append({'widgetType':Tkinter.Button, 'parent':group, 'wcfg':{'text':'Set', 'padx':10, 'height':2, 'width':5, 'command':CallBackFunction(self.set_cb, key)}, 'gridcfg':{'row':-1,'sticky':'wens'}}) idf.append({'widgetType':Tkinter.Button, 'wcfg':{'text':'Dismiss', 'command':self.dismissForm}, 'gridcfg':{'sticky':'we','columnspan':4}}) self.form = self.vf.getUserInput(idf, modal=0, blocking=0) class SetOnAddObjectCmds(Command): """Command to specify commands that have to be carried out when an object is added to the application. Only the commands that have been loaded so far in the application will appear in the GUI. Commands are applied in the order they have been selected. \nPackage : Pmv \nModule : customizationCommands.py \nClass : SetOnAddObjectCmds """ def dismissForm(self): self.form.destroy() def doit(self, cmds): """Method that add/remove the command from the onAddObjectCmds list""" oldCmds = map(lambda x: x[0], self.vf.onAddObjectCmds) newCmds = map(lambda x, vfcommands = self.vf.commands: vfcommands[x], cmds) map(self.vf.removeOnAddObjectCmd, oldCmds) map(self.vf.addOnAddObjectCmd, newCmds) def buildFormDescr(self,formName): if formName == 'choosecmd': cmdNames = filter(lambda x, self = self: self.vf.commands[x].flag & self.objArgOnly, self.vf.commands.keys()) cmdNames.sort() cmdEntries = map(lambda x: (x, None), cmdNames) onAddCmds = map(lambda x: x[0], self.vf.onAddObjectCmds) cmdToApplyNames = [] cmdToApplyNames = filter(lambda x, vf=self.vf, onAddCmds=onAddCmds: vf.commands[x] in onAddCmds, cmdNames) cmdtoapply = map(lambda x: (x, None), cmdToApplyNames) idf = InputFormDescr(title ="Cmds called after adding an object") idf.append({'name':'cmdlist', 'widgetType':ListChooser, 'tooltip':"""list of the commands loaded so far in the application which can be applied to the object when loaded in the application""", 'wcfg':{'entries':cmdEntries, 'mode':'extended', 'lbwcfg':{'exportselection':0}, 'title':'Available commands'}, 'gridcfg':{'sticky':'wens', 'row':0, 'column':0 ,'rowspan':3}}) idf.append({'name':'add', 'widgetType':Tkinter.Button, 'tooltip':""" Add the selected command from to the list of commands to be applied to the object when loaded in the application""", 'wcfg':{'text':'>>','command':self.add_cb}, 'gridcfg':{'row':0,'column':1,'rowspan':3 }}) idf.append({'name':'cmdtoapply', 'widgetType':ListChooser, 'tooltip':"""list of the commands the user chose to apply to the object when loaded in the application""", 'wcfg':{'entries':cmdtoapply, 'mode':'single', 'lbwcfg':{'exportselection':0}, 'title':'Commands to be applied'}, 'gridcfg':{'sticky':'we', 'row':0, 'column':2,'rowspan':3}}) idf.append({'name':'remove', 'widgetType':Tkinter.Button, 'tooltip':""" Remove the selected entry from the commands to be applied to the object when loaded in the application""", 'wcfg':{'text':'REMOVE','width':10, 'command':self.remove_cb}, 'gridcfg':{'sticky':'we','row':0, 'column':3}}) idf.append({'name':'oneup', 'widgetType':Tkinter.Button, 'tooltip':"""Move the selected entry up one entry""", 'wcfg':{'text':'Move up','width':10, 'command':self.moveup_cb}, 'gridcfg':{'sticky':'we','row':1,'column':3}}) idf.append({'name':'onedown', 'widgetType':Tkinter.Button, 'tooltip':"""Move the selected entry down one entry""", 'wcfg':{'text':'Move down','width':10, 'command':self.movedown_cb}, 'gridcfg':{'sticky':'we','row':2,'column':3}}) return idf def movedown_cb(self): ebn = self.cmdForms['choosecmd'].descr.entryByName lb2 = ebn['cmdtoapply']['widget'] sel = lb2.get() if not sel: return sel = sel[0] selIndex = lb2.entries.index((sel,None)) if selIndex == len(lb2.entries)-1: return lb2.remove(sel) lb2.insert(selIndex+1, sel) lb2.select(sel) def moveup_cb(self): ebn = self.cmdForms['choosecmd'].descr.entryByName lb2 = ebn['cmdtoapply']['widget'] sel = lb2.get() if not sel: return sel = sel[0] selIndex = lb2.entries.index((sel,None)) if selIndex == 0: return lb2.remove(sel) lb2.insert(selIndex-1, sel) lb2.select(sel) def add_cb(self): ebn = self.cmdForms['choosecmd'].descr.entryByName lb1 = ebn['cmdlist']['widget'] lb2 = ebn['cmdtoapply']['widget'] for name in lb1.get(): if (name,None) in lb2.entries: continue lb2.add((name,None)) def remove_cb(self): ebn = self.cmdForms['choosecmd'].descr.entryByName lb2 = ebn['cmdtoapply']['widget'] sel = lb2.get() if sel: lb2.remove(sel[0]) def guiCallback(self): # Need to check if some new commands have been added... if self.cmdForms.has_key('choosecmd'): cmdNames = filter(lambda x, self = self: self.vf.commands[x].flag & self.objArgOnly, self.vf.commands.keys()) cmdNames.sort() ebn = self.cmdForms['choosecmd'].descr.entryByName w = ebn['cmdlist']['widget'] w.clear() w.setlist(map(lambda x: (x, None), cmdNames)) val = self.showForm('choosecmd', force=0) ebn = self.cmdForms['choosecmd'].descr.entryByName cmds = map(lambda x: x[0], ebn['cmdtoapply']['widget'].entries) self.doitWrapper(cmds) ##class SaveSessionCommand(Command): ## """Command to allow the user to save the session as it is in a file. ## It copies the .pmvrc in that file and also log all the transformation. ## \nPackage : Pmv ## \nModule : customizationCommands.py ## \nClass : SaveSessionCommand ## """ ## def guiCallback(self): ## ### FIXME all the logs should be in a stack and not in a file. ## if self.vf.logMode == 'no': ## self.vf.warningMsg("No log information because logMode was set to no.") ## return ## newfile = self.vf.askFileSave(types = [('all files','*.*')], ## title = 'Save Session in File:') ## if not newfile is None: ## self.doitWrapper(newfile, redraw=0) ## def doit(self, filename): ## import shutil ## # get the current log. ## logFileName = self.vf.logAllFile.name ## self.vf.logAllFile.close() ## if filename!=logFileName: ## shutil.copy(logFileName, filename) ## self.vf.logAllFile = open(logFileName,'a') ## # Add to it the transformation log. ## logFile = open(filename,'a') ## vi = self.vf.GUI.VIEWER ## code = vi.getViewerStateDefinitionCode('self.GUI.VIEWER') ## code.extend( vi.getObjectsStateDefinitionCode('self.GUI.VIEWER') ) ## if code: ## for line in code: ## logFile.write(line) ## #sceneLog = self.vf.Exit.logScene() ## #for l in sceneLog: ## # l1 = l+'\n' ## # logFile.write(l1) ## logFile.close() class SourceCommand(Command): """Command to source a command file \nPackage : Pmv \nModule : customizationCommands.py \nClass : SourceCommand \nCommand : source \nSynopsis:\n None<---source(filename) """ def __init__(self, func=None): Command.__init__(self, func) self.currentlySourcedFiles = [] def logString(self, *args, **kw): """build and return the log string """ argString, before = self.buildLogArgList(args, kw) log = '' for l in before: log = log + l + '\n' f = open(args[0]) lines = f.readlines() f.close() for line in lines: if line.startswith("if mode=='viewer' or mode=='both'"): # we don't want to log the viewer and object state, # it will be added at the end of the log anyway break log += line return log def doit(self, filename, globalNames=1): # if globalNames==1 the objects defined in the file will be # visible in the main interpreter if filename in self.currentlySourcedFiles: print 'WARNING: %s is already being sourced'%filename print ' skipping to avoid endless loop' return if filename.endswith('_pmvrc'): llogMode = self.vf.logMode self.vf.logMode = 'no' self.currentlySourcedFiles.append(filename) ## # check that this files does not source itself (endless loops) ## f = open(filename) ## lines = f.readlines() ## f.close() ## import re ## pat = re.compile('.*source.*'+filename+'.*') ## for l in lines: ## if pat.search(l): ## self.vf.warningMsg('file %s is sourcing itself. This would lead to an endless loop'%filename) ## return 'ERROR' # make self know while executing filename glob = {'self':self.vf, 'mode':'both'} # if we pass loaclDict Vision macros defined explicitely in alog file # do not build .. strang scope problem try: execfile( filename, glob)#, localDict) except Exception, e: self.currentlySourcedFiles = self.currentlySourcedFiles[:-1] import warnings, traceback # print the exception traceback.print_exc() # print a warning warnings.warn('the exception reported above occured while sourcing **** '+filename+' ****') self.currentlySourcedFiles = self.currentlySourcedFiles[:-1] if globalNames: # all global objects created in filename are now in glob # we remove self and update the interpreter's main dict del glob['self'] sys.modules['__main__'].__dict__.update(glob) if filename.endswith('_pmvrc'): self.vf.logMode = llogMode def __call__(self, filename, **kw): """None<---source(filename,**kw) """ apply(self.doitWrapper, (filename,), kw) def guiCallback(self, event=None,): name = self.vf.__class__.__name__ file = self.vf.askFileOpen(types=[('%s scripts'%name, '*.py'), ('Resource file','*.rc'), ('All Files', '*.*')], title="read %s script file:"%name) if file: self.doitWrapper(file, redraw=0) if hasattr(self.vf, 'recentFiles'): self.vf.recentFiles.add(file, self.name) # Source Command GUI SourceGUI = CommandGUI() SourceGUI.addMenuCommand('menuRoot', 'File', 'Python Scripts', cascadeName='Import', cascadeIndex=1) ## SaveSessionCommand Command GUI #SaveSessionCommandGUI = CommandGUI() #SaveSessionCommandGUI.addMenuCommand('menuRoot', 'File', #'Current Session', cascadeName='Save', index=1) # SetUserPreference Command GUI SetUserPreferenceGUI = CommandGUI() SetUserPreferenceGUI.addMenuCommand('menuRoot', 'File', 'Set...', cascadeName='Preferences' ) ## # SetCmdParam Command GUI ## SetCmdParamGUI = CommandGUI() ## SetCmdParamGUI.addMenuCommand('menuRoot', 'File', 'Set command parameters', ## cascadeName='Preferences' ## ) # SetOnAddObjectCmds Command GUI setOnAddObjectCmdsGUI= CommandGUI() setOnAddObjectCmdsGUI.addMenuCommand('menuRoot', 'File', "Set Commands to be Applied on Objects", cascadeName="Preferences") commandList = [ ## {'name':'setDefaultParam', 'cmd':SetCmdParam(), ## 'gui': SetCmdParamGUI}, {'name':'setUserPreference', 'cmd':SetUserPreference(), 'gui': SetUserPreferenceGUI}, {'name':'setOnAddObjectCommands', 'cmd':SetOnAddObjectCmds(), 'gui':setOnAddObjectCmdsGUI}, ## {'name':'saveSession','cmd': SaveSessionCommand(), ## 'gui':SaveSessionCommandGUI}, {'name':'source', 'cmd':SourceCommand(), 'gui':SourceGUI} ] def initModule(viewer): for dict in commandList: #print 'dict',dict viewer.addCommand(dict['cmd'], dict['name'], dict['gui']) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/customizeVFGUICommands.py0000644000175000017500000005546311641447756027047 0ustar moellermoeller############################################################################# # # Author: Ruth HUEY, Michel F. SANNER # # Copyright: M. Sanner TSRI 2000 # ############################################################################# # # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/customizeVFGUICommands.py,v 1.33 2011/09/30 23:25:34 annao Exp $ # # $Id: customizeVFGUICommands.py,v 1.33 2011/09/30 23:25:34 annao Exp $ # """ This Module implements commands to change the appearance of the ViewerFrameworkGUI """ from ViewerFramework.VFCommand import CommandGUI, Command ## from ViewerFramework.gui import InputFormDescr from mglutil.gui.InputForm.Tk.gui import InputFormDescr from mglutil.util.callback import CallBackFunction from mglutil.util.misc import ensureFontCase import types, string, Tkinter, Pmw, sys, os class HideGUICommand(Command): """Allow to Hide the ViewerFrameworkGUI at any time \nPackage : Pmv \nModule : customizeVFGUICommands \nClass : HideGUICommand \nCommand : ShowHideGUI \nSynopsis:\n None <- ShowHideGUI( **kw) """ def __call__(self, **kw): """ None <- ShowHideGUI( **kw) """ if not kw.has_key('redraw'): kw['redraw']=0 apply(self.doitWrapper, (), kw) def doit(self): # don't do anything if the GUI is already not visible. if self.vf.hasGui and self.vf.guiVisible == 1: # widthdraw the ViewerFramework GUI self.vf.GUI.ROOT.withdraw() # set the guiVisile flag to 0 self.vf.guiVisible=0 if self.vf.withShell: self.vf.GUI.pyshell.top.deiconify() ## # Save the pyShell stdout and redirect it to the main Python ## # interpreter only works if the main interpreter has been ## # started in a interactive mode. ## self.vf.pyShellstdout = sys.stdout ## sys.stdout = sys.__stdout__ ## # Save the pyShell stdin and redirect it to the main Python ## # interpreter only works if the main interpreter has been ## # started in a interactive mode. ## self.vf.pyShellstdin = sys.stdin ## sys.stdin = sys.__stdin__ ## # Save the pyShell stderr and redirect it to the main Python ## # interpreter only works if the main interpreter has been ## # started in a interactive mode. ## self.vf.pyShellstderr = sys.stderr ## sys.stderr = sys.__stderr__ # HideGUI command GUI. HideGUI = CommandGUI() HideGUI.addMenuCommand('menuRoot', 'File', 'Hide VF GUI...', cascadeName='Preferences') class ShowGUICommand(Command): """Allow to show the ViewerFrameworkGUI at any time \nPackage : Pmv \nModule : customizeVFGUICommands \nClass : ShowGUICommand \nCommand : ShowGUI \nSynopsis:\n None <- ShowGUI(**kw) """ def __call__(self,**kw): """ None <- ShowGUI(**kw) """ if not kw.has_key('redraw'): kw['redraw']=1 apply(self.doitWrapper, (), kw) def doit(self): if self.vf.hasGui and self.vf.guiVisible == 0 : if self.vf.withShell: # Hide the Pyshell self.vf.GUI.pyshell.top.withdraw() # Make the ViewerFramework GUI visible self.vf.GUI.ROOT.deiconify() # Set the guiVisible flag to 1 self.vf.guiVisible=1 ## # redirect the stdout, stdin and stderr to the pyShell ## sys.stdout = self.vf.pyShellstdout ## sys.stdin = self.vf.pyShellstdin ## sys.stderr = self.vf.pyShellstderr ## #self.vf.GUI.ROOT.mainloop() class BindActionToMouse(Command): def __init__(self, func=None): Command.__init__(self, func) self.forwhat = 'Object' def negateCmdBefore(self, action, buttonNum, modifier='None', actionDict='Object'): cam = self.vf.GUI.VIEWER.currentCamera # bind action back to its current button and modifier value = cam.findButton(action, actionDict) if value[0]: #self.addUndoCall((action, value[0], value[1], actionDict), # {}, self.name) self.undoCmds = ([(self, (action, value[0], value[1], actionDict), {})], self.name) # restore action that will be overwritten oldaction = cam.mouseButtonActions[actionDict][buttonNum][modifier] #self.addUndoCall((oldaction, buttonNum, modifier, actionDict), # {}, self.name) return ([(self, (oldaction, buttonNum, modifier, actionDict), {})], self.name) def doit(self, action, buttonNum, modifier='None', actionDict='Object'): c = self.vf.GUI.VIEWER.currentCamera c.bindActionToMouseButton(action, buttonNum, modifier=modifier, actionDict=actionDict) def __call__(self, action, buttonNum, modifier='None', actionDict='Object', **kw): """None <- bindAction(action, buttonNum, modifier='None', actionDict='Object') bind an action to a given mouse button for the current camera action can be any of ['None', 'picking', 'rotation', 'scale', 'XYtranslation', 'Ztranslation'] modifier can be any of ['None', 'Shift', 'Control', 'Alt', 'Meta'] actionDict can be anu of ['Object', 'Camera', 'Clip', 'Light', 'Texture', 'Scissor'] 'picking' action is always assigned for all modifiers""" assert buttonNum in (1,2,3) cam = self.vf.GUI.VIEWER.currentCamera assert modifier in cam.mouseButtonModifiers assert action in cam.actions[actionDict].keys() kw['modifier'] = modifier kw['actionDict'] = actionDict apply( self.doitWrapper, (action, buttonNum,), kw ) self.forwhat = actionDict def guiCallback(self, event=None): self.ifd = InputFormDescr("Bind Actions to Mouse Buttons!") # create modifier dropDown combo box cam = self.vf.GUI.VIEWER.currentCamera self.ifd.append({ 'name':'forwhat', 'widgetType': Pmw.ComboBox, 'defaultValue': 'Object', 'wcfg':{ 'labelpos':'nw', 'label_text':'bindings for:', 'selectioncommand': self.binding_cb, 'scrolledlist_items':['Object', 'Insert2d', 'Camera', 'Clip', 'Light', 'Texture', 'Scissor']}, 'gridcfg':{'sticky':'ew', 'padx':2, 'pady':1} }) self.ifd.append({ 'name':'buttonNum', 'widgetType': Pmw.ComboBox, 'defaultValue': '1', 'wcfg':{ 'labelpos':'nw', 'label_text':'mouse Button Number:', 'scrolledlist_items':['1','2','3']}, 'gridcfg':{'sticky':'ew', 'padx':2, 'pady':1} }) self.ifd.append({ 'name':'action', 'widgetType': Pmw.ComboBox, 'defaultValue': 'None', 'wcfg':{ 'labelpos':'nw', 'label_text':'Action:', 'selectioncommand': self.actionSet_cb, 'scrolledlist_items':cam.actions[self.forwhat].keys()}, 'gridcfg':{'sticky':'ew', 'padx':2, 'pady':1} }) self.ifd.append({ 'name':'modifier', 'widgetType': Pmw.ComboBox, 'defaultValue': 'None', 'wcfg':{ 'labelpos':'nw', 'label_text':'keyboard modifier:', 'scrolledlist_items':cam.mouseButtonModifiers}, 'gridcfg':{'sticky':'ew', 'padx':2, 'pady':1} }) self.ifd.append({ 'name':'set', 'widgetType': Tkinter.Button, 'wcfg':{'text':'Set', 'command':self.set_cb, }, 'gridcfg':{'sticky':'ew', 'padx':2, 'pady':1} }) self.ifd.append({'widgetType':Tkinter.Button, 'name':'dismiss', 'wcfg':{'text':'dismiss', 'command':self.dismiss_cb}, 'gridcfg':{'sticky':'sew'} }) self.vf.getUserInput(self.ifd, modal=0, blocking=0) def binding_cb(self, event=None): self.forwhat = self.ifd.entryByName['forwhat']['widget'].get() c = self.vf.GUI.VIEWER.currentCamera w = self.ifd.entryByName['action']['widget'] w.setlist(c.actions[self.forwhat].keys()) def actionSet_cb(self, event=None): action = self.ifd.entryByName['action']['widget'].get() c = self.vf.GUI.VIEWER.currentCamera val = c.findButton(action, self.forwhat) if val[0]: w=self.ifd.entryByName['buttonNum']['widget'] w.selectitem(str(val[0]), setentry=1) if val[1]: w=self.ifd.entryByName['modifier']['widget'] w.selectitem(val[1], setentry=1) def set_cb(self, event=None): action = self.ifd.entryByName['action']['widget'].get() buttonNum = int(self.ifd.entryByName['buttonNum']['widget'].get()) modifier = self.ifd.entryByName['modifier']['widget'].get() apply( self.doitWrapper, (action, buttonNum,), {'modifier':modifier, 'actionDict':self.forwhat} ) def dismiss_cb(self, event=None): self.ifd.form.destroy() BindActionToMouseGUI = CommandGUI() BindActionToMouseGUI.addMenuCommand('menuRoot', 'File', 'Bind Action to Mouse Button ...', cascadeName='Preferences') class ChangeFont(Command): """ Command to change font of the VFGUI""" def getCurrentFont(self): currentfont = self.vf.GUI.ROOT.option_get('font', '*') # current font is '{family yyyy} size opt' if fontname contains # a spaces, else 'family size opt' if currentfont[0]=='{': family, rest = string.split(currentfont[1:], '}') rest = string.split(rest) else: split = string.split(currentfont) family = split[0] rest = split[1:] if len(rest)==0: size = 12 opt = 'normal' elif len(rest)==1: size = int(rest[0]) opt = 'normal' else: size = int(rest[0]) opt = rest[1] return family, size, opt def callbackFunc(self, name, old, new): self.doit(new) def negateCmdBefore(self, newfont): font = self.getCurrentFont() #self.addUndoCall( (font,), {}, self.name ) return ([(self, (font,), {})], self.name ) def onAddCmdToViewer(self): if self.vf.hasGui: self.familyVar=Tkinter.StringVar() self.sizeVar=Tkinter.IntVar() self.styleVar=Tkinter.StringVar() self.fontVar=Tkinter.StringVar() self.vf.userpref.add( 'Fonts', self.getCurrentFont(), callbackFunc = [self.callbackFunc], validateFunc = self.validateFunc, category="Viewer", doc="""Fonts used for Graphical User Interface. Use File -> Preferences -> "Change Font" to select a new font.""") def validateFunc(self, font): root=self.vf.GUI.ROOT.tk familyNames=list(root.splitlist(root.call('font','families'))) if not type(font) == tuple: font = font.split() if len(font) < 3: return False font0 = ensureFontCase(font[0]) if font0 in familyNames and font[2] in['normal','bold','bold italic','italic']: return True else: return False def makeChange(self,wid,newfont): try: wid.config(font=newfont) except : pass if len(wid.children)==0: return for item in wid.children.values(): self.makeChange(item, newfont) def doit(self, newfont): """Allow User to Change GUI's font""" self.makeChange(self.vf.GUI.ROOT, newfont) self.vf.GUI.ROOT.option_add('*font', newfont) #self.lastCmdLog.append(self.logString(newfont,log=0)) #self.vf.GUI.naturalSize() def __call__(self, font, **kw): """None <- changeFont(font, **kw) font has to be a 3-tuple ('arial', 14, 'normal') """ apply( self.doitWrapper, (font,), kw ) def guiCallback(self): #familyNames=[ensureFontCase('times'),ensureFontCase('helvetica'),ensureFontCase('Courier'),'Symbol','Verdana'] root=self.vf.GUI.ROOT.tk familyNames=list(root.splitlist(root.call('font','families'))) familyNames.sort() familyNames.append('from entry') sizeNames=[6,8,10,12,14,16,18,20] styleNames=['normal','bold','bold italic','italic'] if self.familyVar.get() not in familyNames: self.familyVar.set(ensureFontCase('helvetica')) if int(self.sizeVar.get()) not in sizeNames: self.sizeVar.set('10') if self.styleVar.get() not in styleNames: self.styleVar.set(styleNames[0]) ifd=InputFormDescr(title='Select New Font') ifd.append({'widgetType':Pmw.ComboBox, 'name':'family', 'defaultValue':self.familyVar.get(), 'wcfg':{'label_text':'Font Name', 'labelpos':'n', 'scrolledlist_items': familyNames, 'selectioncommand': self.changeSampleFont, }, 'gridcfg':{'sticky':'w'}}) ifd.append({'widgetType':Tkinter.Radiobutton, 'name':'size', 'listtext':sizeNames, 'defaultValue':self.sizeVar.get(), 'command': self.changeSampleOpt, 'wcfg':{'variable':self.sizeVar}, 'gridcfg':{'sticky':Tkinter.W,'row':0,'column':5}}) ifd.append({'widgetType':Tkinter.Radiobutton, 'name':'style', 'listtext':styleNames, 'command': self.changeSampleOpt, 'defaultValue':self.styleVar.get(), 'wcfg':{'variable':self.styleVar}, 'gridcfg':{'sticky':Tkinter.W,'row':0,'column':6}}) ifd.append({'widgetType':Tkinter.Entry, 'wcfg':{ 'textvariable':self.fontVar, 'width':60}, 'defaultValue':self.getCurrentFont(), 'name':'ent', 'gridcfg':{'sticky':Tkinter.W,'row':11,'column':0,'columnspan':16}}) ifd.append({'widgetType':Tkinter.Label, 'name':'sample', 'wcfg':{ 'text':"""This is a sample of this font 0123456789_!@#$%^&*()\nABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz""", 'width':60, 'relief':'ridge', 'borderwidth': 3}, 'gridcfg':{'sticky':Tkinter.W,'row':11,'column':0, 'columnspan':16}}) self.ifd = ifd val=self.vf.getUserInput(ifd) if not val: return self.val=val font = self.fontVar.get() if val['family'][0]=='from entry': newfont=val['ent'] newfont=eval('%s'%val['ent']) # turn tuple repr into objs self.fontVar.set(newfont) else: newfont=(val['family'][0],int(val['size']),val['style']) self.doitWrapper(newfont, log=1, redraw=0) #self.vf.userpref.saveSingleSetting('Fonts', newfont) def changeSampleFont(self, font): if font=='from entry': return self.fontVar.set(font) self.changeSampleOpt() def changeSampleOpt(self, event=None): font = self.fontVar.get() newfont=(font ,int(self.sizeVar.get()), self.styleVar.get()) lab = self.ifd.entryByName['sample']['widget'] lab.configure(font=newfont) ChangeFontGUI = CommandGUI() ChangeFontGUI.addMenuCommand('menuRoot', 'File', 'Change Font', cascadeName='Preferences',separatorAbove=1) class showHideGUI(Command): """ Command to change which parts of the VFGUI are visible""" def __init__(self, func=None): Command.__init__(self, func=func) self.tkvarDict = {} self.ifd = None def negateCmdBefore(self, name, onOff): # #self.addUndoCall( (name, not onOff), {}, self.name ) return ([( self, (name, not onOff), {})], self.name ) def getWidget(self, name): if hasattr(self.vf.GUI, name): return eval('self.vf.GUI.'+name) elif self.vf.GUI.menuBars.has_key(name): return self.vf.GUI.menuBars[name] else: return None def doit(self, name, onOff): w = self.getWidget(name) if w is None: return value = w.winfo_ismapped() if value==onOff: return # Need to repack the menubars properly if onOff==1: if name=='mBarFrame': w.pack(before=self.vf.GUI.vwrCanvasDocked, fill='x') elif name == 'menuRoot': m2= self.getWidget("icomBar") if m2.winfo_ismapped(): w.pack(before=m2,fill='x') else: m3 = self.getWidget("Toolbar") if m3.winfo_ismapped(): w.pack(before=m3,fill='x') else: w.pack(fill='x') elif name == 'Toolbar': m2 = self.getWidget("icomBar") if m2.winfo_ismapped() : w.pack(after=m2, fill='x') else: m3 = self.getWidget("menuRoot") if m3.winfo_ismapped(): w.pack(after=m3, fill='x') else: w.pack(fill='x') elif name == 'icomBar': m2 = self.getWidget("menuRoot") m3 = self.getWidget("Toolbar") if m2.winfo_ismapped(): if m3.winfo_ismapped(): w.pack(after=m2, before=m3, fill='x') else: w.pack(after=m2, fill='x') else: if m3.winfo_ismapped(): w.pack(before=m3, fill='x') else: w.pack(fill='x') elif name=='infoBar': w1 = self.getWidget('MESSAGE_BOX') if w1.winfo_ismapped(): w.pack(before=w1,fill='x') else: if self.vf.GUI.vwrCanvasDocked.winfo_ismapped(): w1.clear() w.pack(after=self.vf.GUI.vwrCanvasDocked, fill='x') else: w.pack(fill='x') elif name=='MESSAGE_BOX': w1 = self.getWidget('infoBar') #print 'show MESSAGE_BOX' text = self.vf.getLog() w.clear() [w.append(line) for line in text] if self.vf.GUI.vwrCanvasDocked.winfo_ismapped(): # show MESSAGE BOX when camera is docked w.pack(after=self.vf.GUI.vwrCanvasDocked,fill='x') elif w1.winfo_ismapped(): w.pack(after=w1,fill='x') self.vf.GUI.naturalSize() else: w.pack(fill='x') self.vf.GUI.toolbarCheckbuttons['MESSAGE_BOX']['Variable'].set(1) else: w.pack(fill='x') else: w.forget() if name=='MESSAGE_BOX': self.vf.GUI.toolbarCheckbuttons['MESSAGE_BOX']['Variable'].set(0) self.vf.GUI.VIEWER.currentCamera.update_idletasks() if self.ifd: self.tkvarDict[name].set(onOff) def __call__(self, name, onOff, **kw): """None <- showHideGUI(name, onOff, **kw) name: 'menuRoot', 'Toolbar', 'infoBar' 'MESSAGE_BOX', 'all', 'allAbove', 'allBelow' or bars that appear in self.GUI.menuBars""" if name=='all' or name=='allAbove': apply( self.doitWrapper, ('mBarFrame', onOff), kw ) if name=='all' or name=='allBelow': apply( self.doitWrapper, ('MESSAGE_BOX', onOff), kw ) apply( self.doitWrapper, ('infoBar', onOff), kw ) else: apply( self.doitWrapper, (name, onOff), kw ) def guiCallback(self): ifd=InputFormDescr(title='Show/Hide VFGUI components ') for name in ['infoBar', 'MESSAGE_BOX']: w = self.getWidget(name) var = Tkinter.IntVar() self.tkvarDict[name] = var cb = CallBackFunction( self.callback, name, var) ifd.append({'widgetType':Tkinter.Checkbutton, 'name':name, 'wcfg':{'text':name, 'command': cb, 'variable':var,}, 'defaultValue': w.winfo_ismapped(), 'gridcfg':{'sticky':Tkinter.W}}) posy = 0 for name in self.vf.GUI.menuBars.keys(): w = self.getWidget(name) var = Tkinter.IntVar() self.tkvarDict[name] = var cb = CallBackFunction( self.callback, name, var) ifd.append({'widgetType':Tkinter.Checkbutton, 'name':name, 'wcfg':{'text':name, 'command': cb, 'variable':var,}, 'defaultValue':w.winfo_ismapped(), 'gridcfg':{'sticky':Tkinter.W,'column':1,'row':posy}}) posy=posy+1 ifd.append({'widgetType':Tkinter.Button, 'name':'dismiss', 'wcfg':{'text':'dismiss', 'command':self.dismiss_cb}, 'gridcfg':{'columnspan':2}, }) self.ifd = ifd val=self.vf.getUserInput(ifd, modal=0) def dismiss_cb(self, event=None): self.ifd.form.destroy() self.ifd = None def callback(self, name, var): self.doitWrapper(name, var.get()) ChangeVFGUIvisGUI = CommandGUI() ChangeVFGUIvisGUI.addMenuCommand('menuRoot','File', 'Show/Hide GUI Sections', cascadeName='Preferences') commandList = [ {'name':'changeFont','cmd':ChangeFont(),'gui':ChangeFontGUI}, {'name':'showHideGUI','cmd':showHideGUI(),'gui':ChangeVFGUIvisGUI}, {'name':'bindAction', 'cmd':BindActionToMouse(), 'gui':BindActionToMouseGUI}, {'name':'hideGUI', 'cmd':HideGUICommand(), 'gui':HideGUI}, {'name':'showGUI', 'cmd':ShowGUICommand(), 'gui':None} ] def initModule(vf): for dict in commandList: vf.addCommand(dict['cmd'],dict['name'],dict['gui']) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/dejaVuCommands.py0000644000175000017500000025735112011267103025414 0ustar moellermoeller## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by ############################################################################# # # Author: Michel F. SANNER # # Copyright: M. Sanner TSRI 2000 # ############################################################################# """ This module implements classes relative to DejaVu. """ # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/dejaVuCommands.py,v 1.145 2012/08/10 20:25:39 sanner Exp $ # # $Id: dejaVuCommands.py,v 1.145 2012/08/10 20:25:39 sanner Exp $ # import numpy.oldnumeric as Numeric import types import os import string import Tkinter, Pmw from math import pi, pow from time import time, sleep import tkMessageBox from mglutil.util.callback import CallbackManager, CallBackFunction from mglutil.math.rotax import rotax from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ListChooser, SaveButton from mglutil.gui.InputForm.Tk.gui import InputFormDescr from mglutil.gui.BasicWidgets.Tk.thumbwheel import ThumbWheel from mglutil.util.misc import ensureFontCase from DejaVu.colorMap import ColorMap from DejaVu.ColormapGui import ColorMapGUI from DejaVu.colorTool import RGBRamp, RedWhiteBlueRamp,RedWhiteRamp, \ WhiteBlueRamp,GreyscaleRamp from DejaVu.colorTool import RGBARamp, RedWhiteBlueARamp,RedWhiteARamp, \ WhiteBlueARamp from DejaVu.Geom import Geom from DejaVu.Spheres import Spheres from ViewerFramework.VFCommand import Command, ICOM, CommandGUI from ViewerFramework.VF import ViewerFramework from mglutil.gui.BasicWidgets.Tk.colorWidgets import ColorChooser, BackgroundColorChooser from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ListChooser, \ kbScrolledListBox from opengltk.OpenGL import GL from mglutil.util.packageFilePath import getResourceFolder class ResetView(Command): def doit(self): vi = self.vf.GUI.VIEWER vi.Reset_cb() vi.Normalize_cb() vi.Center_cb() def guiCallback(self, event=None): self.doitWrapper() def __call__(self, **kw): """None <- ResetView( self, **kw) resets transformation on root object, translates and scales the scene to fit in viewport and sets the center of rotation to be the center of the scene """ apply( self.doitWrapper, (), kw ) ResetViewGUI = CommandGUI() ResetViewGUI.addToolBar('Reset View', icon1='icon-focus.gif', balloonhelp='Reset view, normalize and center', type='ToolBarButton', index=9) class ToggleNpr(Command): def doit(self, npr=1): if npr == 1: self.vf.GUI.VIEWER.GUI.contourTk.set(True) self.vf.GUI.VIEWER.cameras[0].Set(contours=True, tagModified=False) GL.glFinish() self.vf.GUI.VIEWER.GUI.showCurveTool() self.vf.GUI.VIEWER.GUI.continuousRamp() else: self.vf.GUI.VIEWER.GUI.contourTk.set(False) self.vf.GUI.VIEWER.cameras[0].Set(contours=False, tagModified=False) self.vf.GUI.VIEWER.GUI.GraphToolpanel.withdraw() def guiCallback(self): val = self.GUI.menuCheckbuttonVar.get() self.doitWrapper( *(val,), **{'redraw':1}) def __call__(self, npr=1, **kw): """None <- toggleNpr( self, npr=1, **kw) npr : flag when set to 1 toggle npr mode on when set to 0 turns npr mode off """ self.GUI.menuCheckbuttonVar.set(npr) self.doitWrapper( *(npr,), **kw ) toggleNprGuiDescr = {'widgetType':'Button', 'barName':'Toolbar', 'buttonName':'photo/cartoon'} ToggleNprGUI = CommandGUI() ToggleNprGUI.addToolBar('photo_cartoon', icon1 = 'npr.png', balloonhelp = 'Toggle photo/cartoon modes', index = 9) ToggleNprMenuGUI = CommandGUI() ToggleNprMenuGUI.addMenuCommand('menuRoot', 'Display', 'Cartoon', menuEntryType='checkbutton') class ToggleStereo(Command): def doit(self, stereo='MONO'): if self.vf.GUI.VIEWER.currentCamera.stereoMode == stereo: return if self.vf.GUI.VIEWER.activeStereoSupport is True: if stereo == 'STEREO_BUFFERS': self.vf.GUI.rebuildCamera(stereo='native') self.vf.GUI.VIEWER.currentCamera.Set( stereoMode=stereo, tagModified=False ) elif self.vf.GUI.VIEWER.currentCamera.stereoMode == 'STEREO_BUFFERS': self.vf.GUI.VIEWER.currentCamera.Set( stereoMode=stereo, tagModified=False ) self.vf.GUI.rebuildCamera(stereo='none') else: self.vf.GUI.VIEWER.currentCamera.Set( stereoMode=stereo, tagModified=False ) else: if stereo == 'STEREO_BUFFERS': # that way when we select STEREO_BUFFERS the camera is always rebuilt # it is a way to obtain a screen refresh self.vf.GUI.rebuildCamera(stereo='none') msg = """Stereo buffers are not present or not enabled on this system. enableStereo must be set to True in: ~/.mgltools/(ver_number)/DejaVu/_dejavurc """ #self.warningMsg(msg) tkMessageBox.showerror('Stereo Buffers Error', msg) stereo = 'MONO' self.vf.GUI.toolbarCheckbuttons['mono_stereo']['Variable'].set(stereo) self.vf.GUI.VIEWER.currentCamera.Set( stereoMode=stereo, tagModified=False ) def guiCallback(self): val = {} val['stereo'] = self.vf.GUI.toolbarCheckbuttons['mono_stereo']['Variable'].get() val['redraw'] = 1 apply( self.doitWrapper, (), val ) def __call__(self, stereo=1, **kw): """None <- toggleStereo( self, stereo=1, **kw) stereo : flag when set to 1 toggle stereo mode on when set to 0 turns mono mode on """ self.vf.GUI.toolbarCheckbuttons['mono_stereo']['Variable'].set(stereo) if stereo: kw['stereo'] = 'STEREO_BUFFERS' # was 'native' else: kw['stereo'] = 'MONO' # was 'none' apply( self.doitWrapper, (), kw ) stereoRadioLabels = [ 'mono (disabled)', 'SHUTTER GLASSES (on enabled systems)', '3DTV straight side by side', 'side by side cross', 'side by side straight', 'RED ****** CYAN', 'red green', 'red blue', 'yellow blue', 'cyan red', 'green red', 'blue red', 'blue yellow', ] stereoRadioValues = [ 'MONO', 'STEREO_BUFFERS', '3DTV', 'SIDE_BY_SIDE_CROSS', 'SIDE_BY_SIDE_STRAIGHT', 'COLOR_SEPARATION_RED_GREENBLUE', 'COLOR_SEPARATION_RED_GREEN', 'COLOR_SEPARATION_RED_BLUE', 'COLOR_SEPARATION_REDGREEN_BLUE', 'COLOR_SEPARATION_GREENBLUE_RED', 'COLOR_SEPARATION_GREEN_RED', 'COLOR_SEPARATION_BLUE_RED', 'COLOR_SEPARATION_BLUE_REDGREEN', ] toggleStereoGuiDescr = {'widgetType':'Menu', 'barName':'Toolbar', 'buttonName':'mono/stereo'} ToggleStereoGUI = CommandGUI() ToggleStereoGUI.addToolBar('mono_stereo', icon1='stereo.gif', type ='MenuRadiobutton', radioLabels=stereoRadioLabels, radioValues=stereoRadioValues, radioInitialValue=stereoRadioValues[0], balloonhelp='Toggle mono/stereo', index = 6) class TransformObject(Command): def doit(self, transformation, geomName, matrix): # should be # geomName, rot = None, trans = None, scale = None, mat = None, set = 1 if not self.vf.hasGui: return vi = self.vf.GUI.VIEWER geometry = vi.FindObjectByName(geomName) if not geometry: print 'WARNING: geometry name %s not found'%geomName return # set the vi.currentObject to be the object to transform oldCurrent = vi.currentObject vi.SetCurrentObject(geometry) # transform only the given geometry. if vi.redirectTransformToRoot == 1: old = vi.redirectTransformToRoot vi.TransformRootOnly(0) else: old = 0 if transformation[:3]=='rot': mat = Numeric.reshape(Numeric.array(matrix, 'f'), (16,)) geometry.SetRotation(mat) elif transformation[:3]=='tra': mat = Numeric.reshape(Numeric.array(matrix, 'f'), (3,)) geometry.SetTranslation(mat) elif transformation[:3]=='sca': mat = Numeric.reshape(Numeric.array(matrix, 'f'), (3,)) geometry.SetScale(mat) elif transformation[:3]=='piv': mat = Numeric.reshape(Numeric.array(matrix, 'f'), (3,)) geometry.SetPivot(mat) # do not understand those two lines ????? if self != vi.rootObject: vi.deleteOpenglList() # Put everything back like it was before. if old == 1: vi.TransformRootOnly(1) vi.SetCurrentObject(oldCurrent) def __call__( self, transformation, object, matrix, **kw): """ None <- tranformObject( transformation, object, matrix, **kw) transformation : type of transformation rotation : 'rot' translation : 'tra' scaling : 'sca' pivot : 'piv' object : the geometry to be transformed matrix : transformation matrix to be applied to the object """ if not kw.has_key('redraw'): kw['redraw']=1 apply(self.doitWrapper, (transformation, object, matrix), kw) class TransformCamera(Command): def doit(self, transformation, matrix, camIndex): # should be # geomName, rot = None, trans = None, scale = None, mat = None, set = 1 if not self.vf.hasGui: return vi = self.vf.GUI.VIEWER cam = vi.cameras[camIndex] if transformation=='fov': cam.Set(fov=matrix) elif transformation[:3]=='rot': mat = Numeric.reshape(Numeric.array(matrix, 'f'), (16,)) cam.SetRotation(mat) elif transformation[:3]=='tra': mat = Numeric.reshape(Numeric.array(matrix, 'f'), (3,)) cam.SetTranslation(mat) elif transformation[:3]=='sca': mat = Numeric.reshape(Numeric.array(matrix, 'f'), (3,)) cam.SetScale(mat) elif transformation[:3]=='piv': mat = Numeric.reshape(Numeric.array(matrix, 'f'), (3,)) cam.SetPivot(mat) def __call__( self, transformation, matrix, camIndex=0, **kw): """ None <- tranformCamera( transformation, matrix, camIndex=0, **kw) transformation : type of transformation rotation : 'rot' translation : 'tra' scaling : 'sca' pivot : 'piv' field of view : 'fov' matrix : transformation matrix to be applied to the object camIndex : index of camera (defaults to 0) """ if not kw.has_key('redraw'): kw['redraw']=1 apply(self.doitWrapper, (transformation, matrix, camIndex), kw) class SetObject(Command): def doit(self, object, **kw): if not self.vf.hasGui: return vi = self.vf.GUI.VIEWER viewerObj = vi.FindObjectByName(object) if not viewerObj: print 'WARNING: object %s not found'%object return kw['tagModified']=False apply( viewerObj.Set, (), kw) class SetCamera(Command): def doit(self, camera, **kw): if not self.vf.hasGui: return vi = self.vf.GUI.VIEWER viewerCameras = filter(lambda x, name=camera: x.name==name, vi.cameras) if len(viewerCameras)==1: viewerCamera = viewerCameras[0] elif len(viewerCameras)>1: print 'WARNING: more than one camera found for the name: %s'%camera return else: print 'WARNING: camera %s not found'%camera return #print kw kw['tagModified']=False apply( viewerCamera.Set, (), kw) class SetLight(Command): def doit(self, light, **kw): if not self.vf.hasGui: return vi = self.vf.GUI.VIEWER viewerLights = filter(lambda x, name=light: x.name==name, vi.lights) if len(viewerLights)==1: viewerLight = viewerLights[0] elif len(viewerLights)>1: print 'WARNING: more than one light found for the num: %d'%lightnum return else: print 'WARNING: light nb: %d not found'%lightnum return kw['tagModified']=False apply( viewerLight.Set, (), kw) class AddClipPlane(Command): def doit(self, object, clip, side=-1, inh=0): if not self.vf.hasGui: return vi = self.vf.GUI.VIEWER viewerObj = vi.FindObjectByName(object) if not viewerObj: print 'WARNING: object %s not found'%object return viewerClips = filter(lambda x, name=clip: x.name==name, vi.clipP) if len(viewerClips)==1: viewerClip = viewerClips[0] elif len(viewerClips)>1: print 'WARNING: more than one clipping plane found for the name: %s'%clip return else: print 'WARNING: camera %s not found'%clip return viewerObj.AddClipPlane( viewerClip, side, inh ) class SetClip(Command): def doit(self, clip, **kw): if not self.vf.hasGui: return vi = self.vf.GUI.VIEWER viewerClips = filter(lambda x, name=clip: x.name==name, vi.clipP) if len(viewerClips)==1: viewerClip = viewerClips[0] elif len(viewerClips)>1: print 'WARNING: more than one clipping plane found for the name: %s'%clip return else: print 'WARNING: camera %s not found'%clip return kw['tagModified']=False apply( viewerClip.Set, (), kw) class ViewPoints(Command): """None <- view(name, mode='save' or 'restore') Command to save current transformation of root node """ def __init__(self): Command.__init__(self) self.views = [] self.names = [] self.current = -1 def doit(self, name=None, index=None, mode='add'): if not self.vf: return root = self.vf.GUI.VIEWER.rootObject if name is None: name = 'View'+str(len(self.views)) if mode=='set': self.names = [ name ] self.views = [ (root.translation, root.rotation, root.scale, root.pivot) ] self.current = 1 elif mode=='add': self.names.append( name ) self.views.append( (root.translation, root.rotation, root.scale, root.pivot) ) self.current = len(self.views) elif mode=='previous': self.names.append( name ) self.views.append( (root.translation, root.rotation, root.scale, root.pivot) ) index = max(self.current-1, 0) self.go(index) elif mode=='next': index = min(self.current+1, len(self.views)) self.go(index) elif mode=='go': if index>-1 and index 0.0: sleep(pause) step = step+1 if nbSteps > 0.0 and step >= nbSteps: break t2 = time() #print 'FrameRate = %4.1f'%(step/(t2-t1),), step def stop(self): self.stopFlag = 1 def __call__(self, axis=(0,1,0), stepSize=0.0, nbSteps=0, pause=0.0, object=None, **kw): """None <- rotateScene(axis=(0,1,0), stepSize=0.0, nbSteps=0, pause=0.0, object=None) """ self._redraw = kw.get('redraw', True) kw['redraw'] = False apply( self.doitWrapper, (axis, stepSize, nbSteps, pause), kw ) class CenterScene(Command): """None <- centerScene() Command to scale and translate the scene to make it fit in the view frustum """ def onAddCmdToViewer(self): self.vf.userpref.add('Center Scene','firstObjectOnly', validValues=['firstObjectOnly','always', 'never', 'ask'], callbackFunc=[self.doit_cb], category="DejaVu", doc="""the value of this preference defines whether\ the sceen is centered and tranformed to fit into the field\ of view when a new object is loaded""") def doit_cb(self, name, old_value, new_value): if self.vf.hasGui: pass def doit(self, mode=None): choices = self.vf.userpref['Center Scene']['validValues'] if mode is None: mode=self.vf.userpref['Center Scene']['value'] else: assert mode in choices if mode=='never': return if mode==choices[0] and len(self.vf.objects)>1: return if mode=='ask': from SimpleDialog import SimpleDialog t= 'Do you want to center scene?' d=SimpleDialog(self.vf.GUI.ROOT, text=t, buttons=['yes','no'], default=0, title='Center Scene?') ok=d.go() if ok==1: return if self.vf.hasGui: self.vf.GUI.VIEWER.NormalizeCurrentObject() self.vf.GUI.VIEWER.CenterCurrentObject() class CenterGeom(Command): def negateCmdBefore(self, object, point): piv = tuple(object.pivot) #self.addUndoCall( (object, piv), {}, self.vf.centerGeom.name ) return ([( self.vf.centerGeom, (object, piv), {})], self.vf.centerGeom.name ) def doit(self, object, point): object.SetPivot( point ) def __call__(self, object, point, **kw): """None <- centerGeom(geom, point3D) set the center of rotation Geom can be either a tring or an instance of a DejaVu.Geom.Geom The point3D is given in the global coodinates system. """ if type(object)==types.StringType: vi = self.vf.GUI.VIEWER object = vi.FindObjectByName(object) apply( self.doitWrapper, (object, point), kw) class CenterSceneOnPickedPixel(Command, ICOM): """This command allows a user to set the center of rotation of the entire scene to the picked pixel. """ ## def onAddCmdToViewer(self): ## if self.vf.hasGui: ## sph = Spheres('flashSphere', vertices=((0,0,0),), radii=(0.3,), ## visible=0, materials=((0,1,1),)) ## self.vf.GUI.VIEWER.AddObject(sph, parent=self.vf.GUI.miscGeom) ## self.flashSphere = sph def __init__(self, func=None): Command.__init__(self, func) ICOM.__init__(self) def getObjects(self, pick): # we override this else we get pick.hits but we need pick.even return pick def negateCmdBefore(self, obj): root = self.vf.GUI.VIEWER.rootObject piv = tuple(root.pivot) #self.addUndoCall( (root, piv), {}, self.vf.centerGeom.name ) return ([(self.vf.centerGeom, (root, piv), {})], self.vf.centerGeom.name ) def doit(self, object): g, background = self.vf.GUI.VIEWER.get3DPointFromPick(object) #print 'CenterSceneOnPickedVertices', g, background if not background: self.vf.centerGeom( 'root', g, topCommand=0, log=1) self.vf.flashSphere.Set(vertices=(g,)) self.vf.flashSphere.flashT() def __call__(self, pick, **kw): """This command allows a user to set the center of rotation of the entire scene to the a vertex specified by a picking operation. This command is an interactive picking command and is aware of instance matrices. """ # we do not want this command to log or undo itself kw['topCommand'] = 0 kw['busyIdle'] = 1 apply( self.doitWrapper, (pick,), kw ) class CenterSceneOnVertices(Command, ICOM): """This command allows a user to set the center of rotation of the entire scene to the a vertex specified by a picking operation. This command is an interactive picking command and is aware of instance matrices. """ def __init__(self, func=None): Command.__init__(self, func) ICOM.__init__(self) def negateCmdBefore(self, obj): root = self.vf.GUI.VIEWER.rootObject piv = tuple(root.pivot) #self.addUndoCall( (root, piv), {}, self.vf.centerGeom.name ) return ([(self.vf.centerGeom, (root, piv), {})], self.vf.centerGeom.name ) def doit(self, objects): # objects is pick.hist = {geom: [(vertexInd, intance),...]} vt = ViewerFramework.transformedCoordinatesWithInstances(self.vf, objects) g = [0,0,0] i = 0 for v in vt: g[0] += v[0] g[1] += v[1] g[2] += v[2] i+=1 g[0] = g[0]/i g[1] = g[1]/i g[2] = g[2]/i self.vf.centerGeom( 'root', g, topCommand=0, log=1) def __call__(self, nodes, **kw): """This command allows a user to set the center of rotation of the entire scene to the a vertex specified by a picking operation. This command is an interactive picking command and is aware of instance matrices. """ # we do not want this command to log or undo itself kw['topCommand']=0 kw['busyIdle']=1 apply( self.doitWrapper, (nodes,), kw ) class AlignGeoms(Command): # this is the non-interactive command (see AlignGeomsPCOM) which # does log itself # FIXME: A UNDO METHOD SHOULD BE IMPLEMENTED HERE ## def setupUndoBefore(self, object): ## geom1 = object[0] ## t = geom1.translation ## self.addUndoCall( (geom1.getName(),root, piv), {}, self.vf.centerGeom.name ) def doit(self, geom1, vertInd1, geom2, vertInd2): vi = self.vf.GUI.VIEWER # "compute" translation vector vert1 = self.getVertex(geom1, vertInd1) vert2 = self.getVertex(geom2, vertInd2) v = [] v.append(vert2[0] - vert1[0]) v.append(vert2[1] - vert1[1]) v.append(vert2[2] - vert1[2]) v = Numeric.array(v) # make sure geom1.Ri is up-to-date by calling FrameTransform() # oldCurrent = vi.currentObject geom1.FrameTransform() if vi.redirectTransformToRoot == 1: old = vi.redirectTransformToRoot vi.TransformRootOnly(0) else: old = 0 # Note: adding the new translation is the # same as matrixmultiply Ri & v and then ConcatTranslation geom1.translation = geom1.translation + v ## d = Numeric.array( v ) ## d = Numeric.concatenate( (d, [1.0]) ) # go to homogenous coords ## rot = Numeric.reshape( geom1.Ri, (4,4) ) ## trans = Numeric.dot( rot, d )[:3] ## # Note to self: if you use SetTranslation instead it only works ## # the first time! ## geom1.ConcatTranslation(trans) if old == 1: vi.TransformRootOnly(1) def getVertex(self, geom, index): verts = geom.TransformedCoords(geom.LastParentBeforeRoot() ) pickedVerts = Numeric.take(verts, index) vertex = Numeric.sum(pickedVerts)/len(pickedVerts) return list(vertex) def __call__(self, geom1, vertInd1, geom2, vertInd2, **kw): """describe this command for a programmer""" if type(geom1) is types.StringType : geom1 = self.vf.GUI.VIEWER.FindObjectByName(geom1) if type(geom2) is types.StringType : geom2 = self.vf.GUI.VIEWER.FindObjectByName(geom2) apply( self.doitWrapper, (geom1, vertInd1, geom2, vertInd2), kw ) class AlignGeomsPCOM(Command, ICOM): """Pick one or more vertices on geom1 and one or more vertices on geom2. If more than one vertex is selected, the middle point (point1 and 2) of these vertices is computed. A translation vector point2-point1 is computed and applied to geom1. Point1 and point2 are displayed as spheres during this operation and deleted when finished.""" # This is the interactive picking command, which does not log itself and # will call AlignGeoms, which logs def __init__(self, func=None): Command.__init__(self, func) ICOM.__init__(self) self.vertInd1 = None # vertex index list of picked geom1 self.vertInd2 = None # vertex index list of picked geom2 self.geom1 = None # picked geom1 self.geom2 = None # picked geom2 # def onAddCmdToViewer(self): # if self.vf.hasGui: # if not self.vf.commands.has_key('setICOM'): ## FIXME makes ViewerFrameworj depend on PMV ... BAD ! # self.vf.loadCommand('interactiveCommands', 'setICOM', 'Pmv', # topCommand=0) # miscGeom = self.vf.GUI.miscGeom # self.masterGeom = Geom('pickSpheresGeom',shape=(0,0), # pickable=0, protected=True) # self.masterGeom.isScalable = 0 # self.vf.GUI.VIEWER.AddObject(self.masterGeom, parent=miscGeom) # self.spheres = Spheres(name='pickSpheres', shape=(0,3), # inheritMaterial=0, radii=0.3, quality=15, # materials = ((0.,1.,0.),), protected=True) # # self.vf.GUI.VIEWER.AddObject(self.spheres, parent=self.masterGeom) def stopICOM(self): # Reset everything if ICOM is stopped self.vertInd1 = None self.vertInd2 = None self.geom1 = None self.geom2 = None # self.spheres.Set(vertices=[], tagModified=False) self.vf.GUI.VIEWER.Redraw() def doit(self, object): if len(object)==0: return 'ERROR' # prevent logging if nothing picked vi = self.vf.GUI.VIEWER # first pick event if self.vertInd1 is None: self.geom1 = object[0] self.vertInd1 = self.getVertexIndex() vertex = self.getSphereVertex(self.geom1, self.vertInd1) self.spheres.Add(vertices=[vertex,]) vi.Redraw() # second pick event elif self.vertInd1 is not None: self.vertInd2 = self.getVertexIndex() self.geom2 = object[0] vertex = self.getSphereVertex(self.geom1, self.vertInd1) self.spheres.Add(vertices=[vertex,]) vi.Redraw() # reset to first picked if vertices in same geom were picked if self.geom1 == self.geom2: self.geom2 = None self.vertInd2 = None oldspheres = self.spheres.vertexSet.vertices.array self.spheres.Set(vertices=oldspheres[:1], tagModified=False) vi.Redraw() return # call the non-interactive, logable command self.vf.alignGeomsnogui(self.geom1, self.vertInd1, self.geom2, self.vertInd2, topCommand=0, log=1) # now we are done and can reset everything self.spheres.Set(vertices=[], tagModified=False) vi.Redraw() self.vertInd1 = None self.vertInd2 = None self.geom1 = None self.geom2 = None def getSphereVertex(self, geom, index): verts = geom.TransformedCoords( geom.LastParentBeforeRoot() ) pickedVerts = Numeric.take(verts, index) vertex = Numeric.sum(pickedVerts)/len(pickedVerts) return list(vertex) def getVertexIndex(self): vi = self.vf.GUI.VIEWER pick = vi.lastPick geom, vertIndList = pick.hits.items()[0] return vertIndList[1] def __call__(self, nodes, **kw): """describe this command for a programmer""" # we do not want this command to log or undo itself kw['topCommand']=0 kw['busyIdle']=1 apply( self.doitWrapper, (nodes,), kw ) class PrintGeometryName(Command, ICOM): def __init__(self, func=None): Command.__init__(self, func) ICOM.__init__(self) def doit(self, objects): # object is a list of geometries for o in objects: self.vf.message(o.name) def __call__(self, objects, topCommand=0, **kw): # we do not want this command to log or undo itself if not kw.has_key('topCommand'): kw['topCommand'] = topCommand apply( self.doitWrapper, (objects,), kw ) class StopContinuousPicking(Command): def start(self): #self.vf.GUI.ehm.RemoveCallback("", 'motion_cb') self.vf.GUI.removeCameraCallback("", 'motion_cb') def __call__(self, *args): self.start() def guiCallback(self): self.start() class StartContinuousPicking(Command): """Start the contiguous selection mode""" def __init__(self, delay=100): Command.__init__(self) self.delay=delay self.alarmID = None self.cbManager = CallbackManager() def onAddCmdToViewer(self): self.cbManager.AddCallback(CallBackFunction( self.vf.unsolicitedPick)) def start(self): self.vf.GUI.addCameraCallback("", self.motion_cb) def __call__(self, *args): self.start() def guiCallback(self): self.start() def _pick(self, event): # has to be first transformed in a DejaVu Camera Pick object pick = self.vf.DoPick( event.x, event.y, event=event ) if pick: self.cbManager.CallCallbacks(pick) def motion_cb(self, event=None): if (self.alarmID): self.vf.GUI.ROOT.after_cancel(self.alarmID) self.alarmID = self.vf.GUI.ROOT.after(self.delay, self._pick, event) class LoadColorMap(Command): """ Command to Load a Color Map """ def onAddCmdToViewer(self): # load the rgb256_map by default import ViewerFramework vfpath = ViewerFramework.__path__[0] idir = os.path.join(vfpath, 'ColorMaps/') cmap = os.path.join(idir, "rgb256_map.py") self.vf.loadColorMap(cmap, log=0) def guiCallback(self): # Update the level if the form exists already. import ViewerFramework vfpath = ViewerFramework.__path__[0] idir = os.path.join(vfpath, 'ColorMaps/') filename = self.vf.askFileOpen(idir=idir, types=[('color map files:', '*_map.py'),\ ('all files:', '*')],\ title = 'Color Map File:') if not filename: return apply(self.doitWrapper, (filename,), {}) def doit(self, filename): #colormap can be built from a filename name = os.path.splitext(os.path.basename(filename))[0] l = {} g = {} execfile(filename, g, l) newColorMap = None for name, object in l.items(): if isinstance(object, ColorMap): newColorMap = object break #newColorMap = ColorMap(name, filename=filename) if newColorMap: #name should be uniq already for k in self.vf.colorMaps.keys(): if k==name: newColorMap.name = name + '_' + str(self.vf.colorMapCt) self.vf.colorMapCt = self.vf.colorMapCt + 1 self.vf.addColorMap(newColorMap) return newColorMap def __call__(self, filename, **kw): """ None <- loadColorMap(filename) filename: file containing colorMap *_map.py """ return apply( self.doitWrapper, (filename,), kw) LoadColorMapGUIDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 'menuButtonName':'File', 'menuEntryLabel':'ColorMap'} LoadColorMapGUI = CommandGUI() LoadColorMapGUI.addMenuCommand('menuRoot', 'File', 'Color Map', cascadeName='Import') class SaveColorMap(Command): """ Command to Save a Color Map """ def logString(self, *args, **kw): """return None as log string as we don't want to log this """ pass def buildFormDescr(self, formName): if formName == 'saveCM': ifd = InputFormDescr(title = 'Save Color Map') cmNames = map(lambda x: (x, None), self.vf.colorMaps.keys()) ifd.append({'name':'colorMapName', 'widgetType':ListChooser, 'wcfg':{'entries': cmNames, 'title':'Choose a color map to save:', 'lbwcfg':{'exportselection':0}, 'mode':'single','withComment':0, }, 'gridcfg':{'sticky':'we', 'rowspan':4, 'padx':5}}) return ifd def guiCallback(self): #force a redraw of form keys = self.vf.colorMaps.keys() if not len(keys): self.vf.warningMsg('currently no color maps in viewer') return if self.cmdForms.has_key('saveCM'): descr = self.cmdForms['saveCM'] val = self.showForm('saveCM', force=1) if val=={}: return if not val: return if not len(val['colorMapName']): return colorMapName = val['colorMapName'][0] import ViewerFramework vfpath = ViewerFramework.__path__[0] idir = os.path.join(vfpath, 'ColorMaps/') filename = self.vf.askFileSave(idir=idir, types=[('color map files:', '*_map.py'),\ ('all files:', '*')],\ title = 'Color Map File:') if not filename: return apply(self.doitWrapper, (colorMapName, filename,), {}) def doit(self, colorMapName, filename): assert colorMapName in self.vf.colorMaps.keys(), 'no colorMap of that name' colorMap = self.vf.colorMaps[colorMapName] colorMap.write(filename) def __call__(self, colorMapName, filename, **kw): """ None <- saveColorMap(filename) colorMapName: name of colorMap to be written filename: file containing colorMap """ apply( self.doitWrapper, (colorMapName, filename,), kw) SaveColorMapGUIDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 'menuButtonName':'File', 'menuEntryLabel':'Color map'} SaveColorMapGUI = CommandGUI() SaveColorMapGUI.addMenuCommand('menuRoot', 'File', 'Color Map', cascadeName='Save') class CreateColorMap(Command): """ Command to Create a Color Map NB: colormaps are created from files by LoadColorMap """ def guiCallback(self): apply(self.doitWrapper, (), {'viewer':self.vf.GUI.VIEWER, 'log':0}) def accept_cb(self, event=None): #print "accept_cb" self.cmg.apply_cb() if self.colorMaps.has_key('self.cmg.name') is False: self.vf.addColorMap(self.cmg) self.cmg.apply.configure(command=self.cmg.apply_cb) def doit(self, name='colormap', ramp=None, geoms={}, legend=None, mini='not passed', maxi='not passed', viewer=None, log=0): if not viewer: viewer = self.vf.GUI.VIEWER if ramp and type(ramp) is types.StringType: #ramp can only be a string ramp = eval(ramp + '()') if name != 'colormap' and self.vf.colorMaps.has_key(name): self.cmg = self.vf.colorMaps[name] self.cmg.showColormapSettings_cb() else: i = 1 while self.vf.colorMaps.has_key(name): name = 'colormap' + str(i) i += 1 self.cmg = ColorMapGUI(name=name, ramp=ramp, viewer=viewer, mini=mini, maxi=maxi, allowRename=True, modifyMinMax=True) self.cmg.apply.configure(command=self.accept_cb) #self.cmg.apply.configure(text='Accept', command=self.accept_cb) ##FIX THIS TO BUILD LOG STRING FROM GUI ...???... def __call__(self, name='colormap', ramp='RGBARamp', filename=None, **kw): """ None <- createColorMap(name, ramp='RGBARamp', filename=None, **kw) name: identifier ramp: color ramp string ('RGBARamp', 'RedWhiteARamp', 'WhiteBlueARamp' or 'RedWhiteBlueARamp' """ if not kw.has_key('redraw'): kw['redraw'] = 1 if not kw.has_key('viewer'): kw['viewer'] = self.vf.GUI.VIEWER kw['ramp'] = ramp kw['name'] = name kw['log'] = 0 apply( self.doitWrapper, (), kw) CreateColorMapGUIDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 'menuButtonName':'Color', 'menuEntryLabel':'ColorMap'} CreateColorMapGUI = CommandGUI() CreateColorMapGUI.addMenuCommand('menuRoot', 'Color', 'Create', cascadeName='Color Map') class ColorMapEditor(Command): """ Create a GUI to edit a color map object """ def buildFormDescr(self, formName): if formName == 'editCM': self.interpOn = Tkinter.IntVar() #self.id = Tkinter.StringVar() self.showLabels = Tkinter.IntVar() self.showLabels.set(1) ifd = InputFormDescr(title = 'Select Color Map To Edit') #cmNames = self.vf.colorMaps.keys() cmNames = map(lambda x: (x, None), self.vf.colorMaps.keys()) #could use this to build a new one #self.id.set(cmNames[0]) # ifd.append({'widgetType':Pmw.ComboBox, # 'name':'cmap', # 'wcfg':{'label_text':'Color Maps', # 'entryfield_value':self.id.get(), # 'labelpos':'w', # 'listheight':'80', # 'scrolledlist_items': cmNames, # #'selectioncommand': self.update, # }, # 'gridcfg':{'sticky':'w'}}) ifd.append({'name':'colorMapName', 'widgetType':ListChooser, 'wcfg':{'entries': cmNames, 'title':'Choose a color map to edit:', 'lbwcfg':{'exportselection':0}, 'mode':'single','withComment':0, }, 'gridcfg':{'sticky':'we', 'rowspan':4, 'padx':5}}) return ifd def guiCallback(self): # Update the level if the form exists already. if not len(self.vf.colorMaps.keys()): print 'no color maps in viewer' return if self.cmdForms.has_key('editCM'): descr = self.cmdForms['editCM'].descr val = self.showForm('editCM',force=1) if val=={}: return if not val: return cmap = val['colorMapName'][0] vi = self.vf.GUI.VIEWER apply(self.doitWrapper, (cmap,), {'viewer':vi, 'log':0}) def doit(self, cmap, viewer=None): if type(cmap) is types.StringType: if self.vf.colorMaps.has_key(cmap): cmap=self.vf.colorMaps[cmap] else: print 'no such color map' assert isinstance(cmap, ColorMap) if isinstance(cmap, ColorMapGUI): if not cmap.master.winfo_ismapped(): cmap.showColormapSettings_cb() self.cmg = cmap else: if viewer is None: viewer = self.vf.GUI.VIEWER self.cmg = ColorMapGUI(cmap, viewer=viewer, allowRename=False, modifyMinMax=True) self.vf.colorMaps[self.cmg.name] = self.cmg def __call__(self, cmap, viewer=None, **kw): """ None <- showCMGUI(cmap='cmap', **kw) cmap: ColorMap or its name """ if type(cmap) is types.StringType: if cmap not in self.vf.colorMaps.keys(): print 'unknown color map name: ', cmap return 'ERROR' else: cmap = self.vf.colorMaps[cmap] elif not isinstance(cmap, ColorMap): print 'specified colormap not a ColorMap instance' return 'ERROR' if not viewer: viewer = self.vf.GUI.VIEWER kw['log'] = 0 kw['viewer'] = viewer apply( self.doitWrapper, (cmap,), kw) ColorMapEditorGUIDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 'menuButtonName':'Edit', 'menuEntryLabel':'ColorMap'} ColorMapEditorGUI = CommandGUI() #EditColorMapGUI.addMenuCommand('menuRoot', 'Edit', 'ColorMap') ColorMapEditorGUI.addMenuCommand('menuRoot', 'Color', 'Edit', cascadeName='Color Map') class EditColorMap(Command): """ Command to modify a color map object """ def doit(self, cmap, ramp=None, mini=None, maxi=None): cfg = {} if ramp: cfg['ramp']=ramp if mini: cfg['mini']=mini if maxi: cfg['maxi']=maxi apply( cmap.configure, (), cfg) def __call__(self, cmap, ramp=None, mini=None, maxi=None, **kw): """ None <- editCM(cmap, ramp=None, mini=None, maxi=None, name=None, **kw) """ if type(cmap) is types.StringType: if cmap not in self.vf.colorMaps.keys(): print 'unknown color map name: ', cmap return 'ERROR' cmap = self.vf.colorMaps[cmap] elif not isinstance(cmap, ColorMap): print 'specified colormap not a ColorMap instance' return 'ERROR' kw['ramp']=ramp kw['mini']=mini kw['maxi']=maxi apply( self.doitWrapper, (cmap,), kw) class RenderLargeImageCommand(Command): """ Package : ViewerFramework Module : dejaVuCommands Class : RenderLargeImageCommand Command : renderLargeImage Description: This command allows the user to enable the rendering of images larger than the screen. Synopsis: None <- renderLargeImage(width=None, height=None, border=0, outputFile='test.jpg', backbuffer=True) width, height : to specify either the width or the height. border : (default 0) specify the size of a border can be any any small integer between 1 and 20. outputFile : path to a output file. Use .tif to avoid compression backBuffer : default True, Boolean flag turn to False to see the tiles render. checkeredBackground: (False) Keywords : large, image, tile rendering """ def logString(self, *args, **kw): """return None as log string as we don't want to log this """ pass def doit(self, width=None, height=None, border=0, outputFile='test.tif', backBuffer=True, checkeredBackground=False): #print "RenderLargeImageCommand.doit" if width is None and height is None: self.warningMsg( "Please either specify the width or the height of the camera." ) vfgui = self.vf.GUI # cam = vfgui.VIEWER.cameras[0] # camHeight = cam.height # camWidth = cam.width # camrootX = cam.master.master.master.winfo_rootx() # camrootY = cam.master.master.master.winfo_rooty() # # # We set the camera to the biggest possible size to avoid multiple drawing # lLargestWidth = vfgui.screenWidth # lLargestHeight = lLargestWidth * float(height)/width # if lLargestHeight > vfgui.screenHeight: # lLargestHeight = vfgui.screenHeight # lLargestWidth = lLargestHeight * float(width)/height # status = self.vf.setCameraSize(lLargestWidth, # lLargestHeight, # xoffset=0, # yoffset=0, # topCommand=0) # if status=='ERROR': # return 'ERROR' vi = vfgui.VIEWER vi.stopAutoRedraw() vi.update() vi.startTileRendering(width=width, height=height, border=border, outputFile=outputFile, backBuffer=backBuffer, checkeredBackground=checkeredBackground) vi.OneRedraw() # # set camera to its previous size and position # self.vf.setCameraSize(camWidth, # camHeight, # xoffset=camrootX, # yoffset=camrootY, # topCommand=0) def __call__(self, width=None, height=None, border=0, outputFile='test.jpg', backBuffer=True, checkeredBackground=False, **kw): #print "RenderLargeImageCommand.__call__" kw['width'] = width kw['height'] = height kw['border'] = border kw['outputFile'] = outputFile kw['backBuffer'] = backBuffer kw['checkeredBackground'] = checkeredBackground kw['redraw'] = True apply(self.doitWrapper, (), kw) def guiCallback(self): #print "RenderLargeImageCommand.guiCallback" # in case we arrive here after a cancel and a resizing if self.cmdForms.has_key('tileRendering'): self.fixHeight_cb() val = self.showForm('tileRendering', okCfg={'text':'Render Image'}, cancelCfg={'text':'Cancel', 'command':self.cancel_cb} ) if not val=={}: del val['constraint'] if val.has_key('filebrowse'): del val['filebrowse'] if val.has_key('outputFile') and not val['outputFile']: val['outputFile'] = './test.tif' val['redraw'] = False apply(self.doitWrapper, (), val) def getConstrainedWidth(self, mode, height, width): #print "RenderLargeImageCommand.getConstrainedWidth" # compute val2 as a function of val1 if mode == 'square': return height elif mode == 'keep aspect ratio': cam = self.vf.GUI.VIEWER.currentCamera return round( height * cam.width/float(cam.height) ) else: return width def getConstrainedHeight(self, mode, width, height): #print "RenderLargeImageCommand.getConstrainedHeight" # compute val2 as a function of val1 if mode == 'square': return width elif mode == 'keep aspect ratio': cam = self.vf.GUI.VIEWER.currentCamera return round( width * cam.height/float(cam.width) ) else: return height def fixHeight_cb (self, event=None): #print "RenderLargeImageCommand.fixHeight_cb" # called when width thumbwheel changes f = self.cmdForms['tileRendering'] mode = f.descr.entryByName['constraint']['widget'].get() width = f.descr.entryByName['width']['widget'].value height = f.descr.entryByName['height']['widget'].value cam = self.vf.GUI.VIEWER.currentCamera if mode != 'None': nheight = self.getConstrainedHeight(mode, width, height) f.descr.entryByName['height']['widget'].set(nheight, update=0) if (mode == 'square') and (cam.width != cam.height): if cam.width < cam.height: tileSize = cam.width else: tileSize = cam.height self.vf.setCameraSize(tileSize, tileSize, topCommand=0) else: camWidth = int( cam.height * width/float(height) ) self.vf.setCameraSize(width=camWidth, height=cam.height, topCommand=0) def fixWidth_cb (self, event=None): #print "RenderLargeImageCommand.fixWidth_cb" # called when height thumbwheel changes f = self.cmdForms['tileRendering'] mode = f.descr.entryByName['constraint']['widget'].get() width = f.descr.entryByName['width']['widget'].value height = f.descr.entryByName['height']['widget'].value cam = self.vf.GUI.VIEWER.currentCamera if mode != 'None': nwidth = self.getConstrainedWidth(mode, height, width) f.descr.entryByName['width']['widget'].set(nwidth, update=0) if (mode == 'square') and (cam.width != cam.height): if cam.width < cam.height: tileSize = cam.width else: tileSize = cam.height self.vf.setCameraSize(tileSize, tileSize, topCommand=0) else: camHeight = int( cam.width * height/float(width) ) self.vf.setCameraSize(width=cam.width, height=camHeight, topCommand=0) def buildFormDescr(self, formName): #print "RenderLargeImageCommand.buildFormDescr" if formName == 'tileRendering': idf = InputFormDescr(title="Tile Rendering parameters") cam = self.vf.GUI.VIEWER.cameras[0] idf.append({'name':'width', 'widgetType':ThumbWheel, 'wcfg':{ 'labCfg':{'text':'Requested Width: ', 'font':(ensureFontCase('helvetica'),12,'bold')}, 'showLabel':1, 'width':100, 'min':0, 'callback':self.fixHeight_cb, 'type':int, 'precision':1, 'value':cam.width,'continuous':1, 'oneTurn':500, 'wheelPad':2, 'height':20}, 'gridcfg':{'sticky':'e'}}) idf.append({'name':'height', 'widgetType':ThumbWheel, 'wcfg':{ 'labCfg':{'text':'Requested Height: ', 'font':(ensureFontCase('helvetica'),12,'bold')}, 'showLabel':1, 'width':100, 'min':0, 'callback':self.fixWidth_cb, 'type':int, 'precision':1, 'value':cam.height,'continuous':1, 'oneTurn':500, 'wheelPad':2, 'height':20}, 'gridcfg':{'sticky':'e'}}) idf.append({'name':'constrLab', 'widgetType':Tkinter.Label, 'wcfg':{ 'text':'Constraints: '}, 'gridcfg':{'sticky':'wens', 'row':0, 'column':1}}) modes = ['None', 'square', 'keep aspect ratio'] idf.append({'name':'constraint', 'widgetType':Pmw.ComboBox, 'wcfg':{ 'scrolledlist_items':modes, 'dropdown':1, 'selectioncommand':self.fixHeight_cb, 'entryfield_entry_width':8}, 'defaultValue':'keep aspect ratio', 'gridcfg':{'sticky':'wens', 'row':1, 'column':1}, }) idf.append({'name':'border', 'widgetType':ThumbWheel, 'wcfg':{ 'labCfg':{'text':'Border: ', 'font':(ensureFontCase('helvetica'),12,'bold')}, 'showLabel':1, 'width':100, 'min':0, 'max':20, 'type':int, 'precision':1, 'value':0,'continuous':1, 'oneTurn':2, 'wheelPad':2, 'height':20}, 'gridcfg':{'sticky':'e'}}) idf.append({'name':'backBuffer', 'widgetType':Tkinter.Checkbutton, 'defaultValue':1, 'wcfg':{'text':'Back Buffer', 'variable':Tkinter.IntVar()}, 'gridcfg':{'sticky':'w', 'columnspan':2} }) idf.append({'name':'checkeredBackground', 'widgetType':Tkinter.Checkbutton, 'defaultValue':0, 'wcfg':{'text':'Checkered Background', 'variable':Tkinter.IntVar()}, 'gridcfg':{'sticky':'w', 'columnspan':2} }) # File to create idf.append({'name':'outputFile', 'widgetType':Pmw.EntryField, 'tooltip':'Enter the outputFile', 'wcfg':{'label_text':'Output File:', 'labelpos':'w', 'value':'test.tif'}, 'gridcfg':{'sticky':'w'}, }) idf.append({'widgetType':SaveButton, 'name':'filebrowse', 'wcfg':{'buttonType':Tkinter.Button, 'title':'Save In File ...', 'types':[('TIFF', '*.tif'), ('JPEG','*.jpg'), ('All','*.*')], 'callback':self.setEntry_cb, 'widgetwcfg':{'text':'BROWSE'}}, 'gridcfg':{'row':-1, 'sticky':'we'}}) return idf ### ################################################################## ### CALLBACK FUNCTIONS ### ################################################################## def setEntry_cb(self, filename): #print "RenderLargeImageCommand.setEntry_cb" ebn = self.cmdForms['tileRendering'].descr.entryByName entry = ebn['outputFile']['widget'] entry.setentry(filename) def cancel_cb(self): #print "RenderLargeImageCommand.cancel_cb" pass #cam = self.vf.GUI.VIEWER.cameras[0] #self.camHeight = cam.height #self.camWidth = cam.width #self.camrootX = cam.rootx #self.camrootY = cam.rooty ##self.vf.showHideGUI('all', 1, topCommand=0) #self.vf.setCameraSize(self.camWidth, self.camHeight, # xoffset=self.camrootX, yoffset=self.camrootY, # topCommand=0) RenderLargeImageGUI = CommandGUI() RenderLargeImageGUI.addMenuCommand('menuRoot', '3D Graphics', 'Render Large Image') class SpinCommand(Command): """ Package : ViewerFramework Module : dejaVuCommands Class : SpinCommand Command : spin Description: Open the spin gui Synopsis: Keywords : """ def logString(self, *args, **kw): """return None as log string as we don't want to log this """ pass def doit(self): self.vf.GUI.VIEWER.currentCamera.trackball.showSpinGui() spinGUI = CommandGUI() spinGUI.addMenuCommand('menuRoot', '3D Graphics', 'Spin - Bounce - Oscillate') class SetCameraSizeCommand(Command): """ Package : ViewerFramework Module : dejaVuCommands Class : SetCameraSizeCommand Command : setCameraSize Description Command allowing the user to resize the camera to the given width, height, xoffset and yoffset Synopsis: width, height <- setCameraSize(width, height, xoffset=None, yoffset=None) width : int to specify camera width in pixels height : int to specify camera height in pixels xoffset : int to specify the x position of the left corner of the camera relative to the left corner of the camera yoffset : int to specify the y position of the left corner of the camera relative to the left corner of the camera """ def doit(self, width, height, xoffset=0, yoffset=0): """ width : int to specify camera width in pixels height : int to specify camera height in pixels xoffset : int to specify the x position of the left corner of the camera relative to the left corner of the camera yoffset : int to specify the y position of the left corner of the camera relative to the left corner of the camera """ vfgui =self.vf.GUI vi = vfgui.VIEWER if not vfgui.isCameraFloating(): # Camera is docked # I was unable to find out how to resize the master such that # the camera ends up with the right size, because the message_box # expands along with the camera. So I disable expansion of the # message box when the camera size is set for a docked camera # disable message box expansion mb = vfgui.MESSAGE_BOX try: opts = mb.pack_info() mb.pack_forget() opts['expand'] = 0 apply( mb.pack, (), opts) MESSAGE_BOX_reqheight = vfgui.MESSAGE_BOX.winfo_reqheight() except: #mb.pack_info() hrows exception MESSAGE_BOX_reqheight = 0 # first set the width as this might add scroll bars under menus and # hence add the thir height c = vi.cameras[0] off = 2*c.frameBorderWidth vfgui.setGeom(xoffset, yoffset, width+off, c.height) #vi.update() # now compute height needed #print 'MENU', vfgui.mBarFrame.winfo_reqheight() #print 'Info', vfgui.infoBar.winfo_reqheight() #print 'MESSAGE', vfgui.MESSAGE_BOX.winfo_reqheight() #print 'camera', height+off h = vfgui.mBarFrame.winfo_reqheight() + \ height + off +\ vfgui.infoBar.winfo_reqheight() + \ MESSAGE_BOX_reqheight #print 'TOTAL', h, width+off, h+off # resize the top widget. At this point only thw camera should # expand, and reach the desired size vfgui.setGeom(xoffset, yoffset, width+off, h) vi.update() # now restore the message_box's packing options so that it scales # again when the user resizes the app else: # Camera is floating toplevel = self.vf.GUI.vwrCanvasFloating #geom = '%dx%d+%d+%d' % (width, height, xoffset, yoffset) #toplevel.geometry(geom) # Need to reposition the camera and the menu vi.currentCamera.Set(rootx=xoffset, rooty=yoffset, width=width, height=height) #menux, menuy, menuw, menuh = self.vf.GUI.getGeom() # give Tk a chance to handle the event self.vf.GUI.VIEWER.update() #nwidth = toplevel.cget('width') #nheight = toplevel.cget('height') # FIXME not sure why she sets the geometry of the menu window here #self.vf.GUI.setGeom(xoffset, yoffset+height+30, width, menuh) #return nwidth, nheight if self.vf.GUI.VIEWER.suspendRedraw is False: self.vf.GUI.VIEWER.OneRedraw() def buildFormDescr(self, formName): if formName == 'setCameraSize': idf = InputFormDescr(title="Set Camera Size:") cam = self.vf.GUI.VIEWER.cameras[0] idf.append({'name':'width', 'widgetType':ThumbWheel, 'wcfg':{ 'labCfg':{'text':'Camera Width: ', 'font':(ensureFontCase('helvetica'),12,'bold')}, 'showLabel':1, 'width':100, 'min':0, 'max':self.vf.GUI.screenWidth, 'type':int, 'precision':1, 'value':cam.width,'continuous':1, 'oneTurn':200, 'wheelPad':2, 'height':20}, 'gridcfg':{'sticky':'e'}}) idf.append({'name':'height', 'widgetType':ThumbWheel, 'wcfg':{ 'labCfg':{'text':'Camera Height: ', 'font':(ensureFontCase('helvetica'),12,'bold')}, 'showLabel':1, 'width':100, 'min':0, 'max':self.vf.GUI.screenHeight, 'type':int, 'precision':1, 'value':cam.height,'continuous':1, 'oneTurn':200, 'wheelPad':2, 'height':20}, 'gridcfg':{'sticky':'e'}}) if self.vf.GUI.floatCamVariable.get(): defRootx = self.vf.GUI.VIEWER.currentCamera.rootx defRooty = self.vf.GUI.VIEWER.currentCamera.rooty else: defRootx = self.vf.GUI.ROOT.winfo_rootx() defRooty = self.vf.GUI.ROOT.winfo_rooty() idf.append({'name':'xoffset', 'widgetType':ThumbWheel, 'wcfg':{ 'labCfg':{'text':'Camera X Offset: ', 'font':(ensureFontCase('helvetica'),12,'bold')}, 'showLabel':1, 'width':100, 'min':0, 'type':int, 'precision':1, 'value':defRootx,'continuous':1, 'oneTurn':50, 'wheelPad':2, 'height':20}, 'gridcfg':{'sticky':'e'}}) idf.append({'name':'yoffset', 'widgetType':ThumbWheel, 'wcfg':{ 'labCfg':{'text':'Camera Y Offset: ', 'font':(ensureFontCase('helvetica'),12,'bold')}, 'showLabel':1, 'width':100, 'min':0, 'max':self.vf.GUI.screenHeight, 'type':int, 'precision':1, 'value':defRooty,'continuous':1, 'oneTurn':50, 'wheelPad':2, 'height':20}, 'gridcfg':{'sticky':'e'}}) return idf def guiCallback(self): val = self.showForm('setCameraSize') if val: width = val['width'] del val['width'] height = val['height'] del val['height'] apply(self.doitWrapper, (width, height), val) def __call__(self, width, height, xoffset=0, yoffset=0, **kw): """ width, height <-self.setCameraSize(width, height, xoffset=None, yoffset=None, **kw) width : int to specify camera width in pixels height : int to specify camera height in pixels xoffset : int to specify the x position of the left corner of the camera relative to the left corner of the camera yoffset : int to specify the y position of the left corner of the camera relative to the left corner of the camera """ kw['xoffset']=xoffset kw['yoffset']=yoffset kw['redraw']=True return apply(self.doitWrapper, (width, height), kw) SetCamSizeGUI = CommandGUI() SetCamSizeGUI.addMenuCommand('menuRoot', '3D Graphics', 'Set Camera Size') class SaveImage(Command): """This command allows to save the content of the current frambuffer as an image into a file. The file format will be defined by the extension used in the filename. Currently de follwoing foramt are supported: BMP, EPS, GIF, IM, JPEG, PNG, PPM, TIFF or TIF, PDF. \nPackage : ViewerFramework \nModule : dejaVuCommands \nClass : SaveImage \nCommand : saveImage \nSynopsis:\n None <- saveImage(self,filename, **kw) \nfilename --- name of the file \nDependencies: require the Python Imaging Library \nregression test: testdir/testSaveImage.py """ # def logString(self, *args, **kw): # """return None as log string as we don't want to log this #""" # pass def checkDependencies(self, vf): import Image def doit(self, filename, transparentbg): # lift self.vf.GUI.ROOT.lift() vi = self.vf.GUI.VIEWER vi.OneRedraw() cam = self.vf.GUI.VIEWER.currentCamera if transparentbg: cam.SaveImage(filename, transparentBackground=True) else: cam.SaveImage(filename) def buildFormDescr(self, formName): idf = InputFormDescr(title="SaveImage") idf.append({'name':"TB", 'widgetType':Tkinter.Checkbutton, 'wcfg':{'text':'Transparent Background', 'variable':Tkinter.IntVar()}, 'command':self.switch_type_cb, 'gridcfg':{'sticky':'nw'}}) idf.append({'name':'File', 'widgetType':Pmw.EntryField, 'tooltip':'Enter the outputFile', 'wcfg':{'label_text':'Output File:', 'labelpos':'wnse', }, 'gridcfg':{'sticky':'wnse'}, }) idf.append({'widgetType':SaveButton, 'name':'filesave', 'wcfg':{'buttonType':Tkinter.Button, 'title':'Save as File', 'types':[('PNG files', '*.png'), ('TIFF files', '*.tif'), ('JPEG files', '*.jpg'), ('GIF files', '*.gif'), ('PPM files', '*.ppm'), ('EPS files', '*.eps'), ('IM files', '*.im'), ('PDF files', '*.pdf'), ('all files', '*.*')], 'callback':self.setEntry_cb, 'widgetwcfg':{'text':'Choose'}}, 'gridcfg':{'sticky':'we','row':-1}}) idf.append({'name':'cite', 'widgetType':Tkinter.Button, 'wcfg':{'text':'Cite', 'command':self.cite_cb, }, 'gridcfg':{'sticky':'wnse','column':1}}) idf.append({'name':'Citelab', 'widgetType':Tkinter.Label, 'wcfg':{ 'text':'If you are going to publish this image'}, 'gridcfg':{'sticky':'wnse','row':-1,'column':0}}) idf.append({'name':'ok', 'widgetType':Tkinter.Button, 'wcfg':{'text':'OK', 'command':self.ok_cb, }, 'gridcfg':{'sticky':'wnse'}}) idf.append({'name':'dismiss', 'widgetType':Tkinter.Button, 'wcfg':{'text':'DISMISS', 'command':self.dismiss_cb, }, 'gridcfg':{'sticky':'wnse','row':-1,'column':1}}) return idf def cite_cb(self): urlcite = "http://www.scripps.edu/~sanner/software/documentation/citationsinfo.html" import webbrowser webbrowser.open_new(urlcite) def switch_type_cb(self): # callback function for transparent background checkbutton # when checked configure file browser to show *.png file only ebn = self.cmdForms['SaveImage'].descr.entryByName if ebn['TB']['wcfg']['variable'].get()==0: saveb = ebn['filesave']['widget'] wcfg = ebn['filesave']['wcfg'] from mglutil.util.callback import CallBackFunction ftypes = [('PNG files', '*.png'), ('TIFF files', '*.tif'), ('JPEG files', '*.jpg'), ('GIF files', '*.gif'), ('PPM files', '*.ppm'), ('EPS files', '*.eps'), ('IM files', '*.im'), ('PDF files', '*.pdf'), ('all files', '*.*')] saveb.configure(title=wcfg['title'], idir=None, ifile=None, types=ftypes, callback=wcfg['callback']) else: saveb = self.cmdForms['SaveImage'].descr.entryByName['filesave']['widget'] wcfg = self.cmdForms['SaveImage'].descr.entryByName['filesave']['wcfg'] ftypes = [('PNG files', '*.png')] saveb.configure(idir=None, ifile=None, types=ftypes, title=wcfg['title'], callback=wcfg['callback']) def setEntry_cb(self, filename): ebn = self.cmdForms['SaveImage'].descr.entryByName entry = ebn['File']['widget'] entry.setentry(filename) def ok_cb(self): ebn = self.cmdForms['SaveImage'].descr.entryByName file = ebn['File']['widget'].get() if file == None or file =='': return transparentbg = ebn['TB']['wcfg']['variable'].get() if not self.cmdForms.has_key('SaveImage'): return f = self.cmdForms['SaveImage'] if f.root.winfo_ismapped(): f.root.withdraw() f.releaseFocus() apply(self.doitWrapper, (file,transparentbg), {}) def dismiss_cb(self): if not self.cmdForms.has_key('SaveImage'): return f = self.cmdForms['SaveImage'] if f.root.winfo_ismapped(): f.root.withdraw() f.releaseFocus() def guiCallback(self): f = self.vf.GUI.VIEWER.currentCamera.frame if f.winfo_height() + f.winfo_rooty() < f.winfo_screenheight() - 100: posy = f.winfo_height() + f.winfo_rooty() posx = int(f.winfo_width()/2) + f.winfo_rootx() -100 else: posx = None posy = None val = self.showForm('SaveImage', force=1, blocking=0, modal=0, master=self.vf.GUI.VIEWER.currentCamera.frame, posx=posx, posy=posy) def __call__(self, filename, transparentbg=False, **kw): """ None <- saveImage(self,filename, **kw) \nfilename : name of the file transparentbg: true to get a transparent background, works only with .png files""" if filename==None: return kw['transparentbg'] = transparentbg apply(self.doitWrapper, (filename,), kw) SaveImageGUI = CommandGUI() SaveImageGUI.addMenuCommand('menuRoot', 'File', 'Save Image As', cascadeName='Save') class ColorGeomsByName(Command): """ Command to choose color for geometries selected by name """ def onAddCmdToViewer(self): if self.vf.hasGui: self.patVar = Tkinter.StringVar() self.patVar.set("") def hidePalette_cb(self, event=None): self.palette.hide() def color_cb(self, colors, event=None): self.doitWrapper(pat = self.patVar.get(), material = colors) def doit(self, pat, material): print 'in doit with pat=', pat print 'and material=', material geomsToColor = self.vf.GUI.VIEWER.findGeomsByName(pat) print "geomsToColor=", for g in geomsToColor: print g.name if len(geomsToColor)==0: return for geom in geomsToColor: geom.Set(inheritMaterial=False, materials = [material,]) if geom.children!=[]: for childGeom in geom.children: childGeom.Set(inheritMaterial=False, materials = [material,]) self.vf.GUI.VIEWER.Redraw() def dismiss_cb(self, event=None): if hasattr(self, 'form'): self.form.withdraw() def buildForm(self): if hasattr(self, 'ifd'): return from mglutil.gui.BasicWidgets.Tk.colorWidgets import ColorChooser self.palette = ColorChooser(commands=self.color_cb, exitFunction = self.hidePalette_cb) top = self.palette.ccFrame menuBar = self.palette.ccFrame ifd = self.ifd = InputFormDescr(title="Color Geometries by Name") ifd.append({'name':'patternLab', 'widgetType':Tkinter.Label, 'parent':top, 'text':"pattern:", 'gridcfg':{'sticky':'w'}}) ifd.append({'name':'patternEnt', 'widgetType':Tkinter.Entry, 'parent':top, 'wcfg':{ 'textvariable': self.patVar, }, 'gridcfg':{'sticky':'wens', 'row':-1, 'column':1}}) self.form = self.vf.getUserInput(self.ifd, modal=0, blocking=0) self.label = self.ifd.entryByName['patternLab']['widget'] self.entry = self.ifd.entryByName['patternEnt']['widget'] top = self.label.master.master.master self.palette.pack(fill='both', expand=True) self.form.root.portocol("WM_DELETE_WINDOW", self.dismiss_cb) def guiCallback(self): if hasattr(self, 'ifd'): self.form.deiconify() else: self.buildForm() def __call__(self, pat, material, **kw): """ None <- colorGeomsByName(filename) pat: string to match to geometry names material: new color """ apply( self.doitWrapper, (pat, material,), kw) ColorGeomsByNameGUI = CommandGUI() ColorGeomsByNameGUI.addMenuCommand('menuRoot', 'Color', 'ColorGeomsByName') class setAntialiasingCommand(Command): """ Package : ViewerFramework \nModule : dejaVuCommands \nClass : setbackgroundcolorCommand \nCommand : SetBackGroundColor \nDescription \nCommand allowing the user to set color of the camera \nSynopsis: \ncolor : Required color of background """ def doit(self,value): vfgui = self.vf.GUI vi = vfgui.VIEWER vi.GUI.nbJitter.set(value) camera = vi.currentCamera camera.Set(antialiased = value) vi.Redraw() def buildFormDescr(self, formName): if formName == 'setAntialiasing': idf = InputFormDescr(title="SetAntialiasing") self.vallist = [0,2,3,4,8,15,24,66] idf.append({'name':'value', 'widgetType':kbScrolledListBox, 'wcfg':{'items':self.vallist, #'defaultValue': 0, 'listbox_exportselection':0, 'labelpos':'nw', 'label_text':'Antialiasing Values', 'selectioncommand':self.setJitter_cb, }, 'gridcfg':{'sticky':'wesn','columnspan':1}}) idf.append({'widgetType':Tkinter.Button, 'name':'dismiss', 'wcfg':{'text':'DISMISS', 'command':self.dismiss_cb}, 'gridcfg':{'sticky':'we', 'columnspan':3}}) return idf def dismiss_cb(self): if self.cmdForms.has_key('setAntialiasing'): self.cmdForms['setAntialiasing'].withdraw() def guiCallback(self): form = self.showForm('setAntialiasing', modal=0, blocking=0) def setJitter_cb(self): self.curselval = self.cmdForms['setAntialiasing'].descr.entryByName['value']['widget'].getcurselection() if self.curselval == (): self.curselv = 0 else: self.curselv = self.curselval[0] apply( self.doitWrapper, (self.curselv,),{}) def __call__(self,value, **kw): """None <-----setAntialiasing(value) \ncolor : background color """ if isinstance(value, types.IntType) is False: return apply( self.doitWrapper, (value,), kw) setAntialiasingGUI = CommandGUI() setAntialiasingGUI.addMenuCommand('menuRoot', '3D Graphics','SetAntialiasing') class setbackgroundcolorCommand(Command): """ Package : ViewerFramework \nModule : dejaVuCommands \nClass : setbackgroundcolorCommand \nCommand : SetBackGroundColor \nDescription \nCommand allowing the user to set color of the camera \nSynopsis: \ncolor : Required color of background """ def hidePalette_cb(self, event=None): self.palette.hide() def color_cb(self, colors, event=None): self.doitWrapper(colors) def onAddCmdToViewer(self): if self.vf.hasGui: self.patVar = Tkinter.StringVar() self.patVar.set("") path = os.path.join(getResourceFolder(),'backgroundColor') if os.path.exists(path): hcol = open(path).read() else: return rgb = int(hcol[1:3], 16), int(hcol[3:5], 16), int(hcol[5:7], 16) col = [x/255. for x in rgb] self.vf.GUI.VIEWER.CurrentCameraBackgroundColor(col) def doit(self,color, **kw): vfgui = self.vf.GUI vi = vfgui.VIEWER vi.CurrentCameraBackgroundColor(color) #vi.GUI.CameraColorButton_cb() #cam = vi.currentCamera #cc = vi.GUI.colorChooser #cc.Set( cam.backgroundColor[:3], 'RGB' ) def buildFormDescr(self, formName): if formName == 'setbackgroundcolor': idf = InputFormDescr(title="SetBackGroundColor") cam = self.vf.GUI.VIEWER.cameras[0] idf.append({'widgetType':ColorChooser, 'name':'colors', 'wcfg':{'title':'SetBackGroundColor', 'commands':self.color_cb, 'immediate':0, 'exitFunction':self.dismiss_cb}, 'gridcfg':{'sticky':'wens', 'columnspan':3} }) idf.append({'widgetType':Tkinter.Button, 'name':'dismiss', 'wcfg':{'text':'DISMISS', 'command':self.dismiss_cb}, 'gridcfg':{'sticky':'we', 'columnspan':3}}) return idf def dismiss_cb(self, **kw): if self.cmdForms.has_key('setbackgroundcolor'): self.cmdForms['setbackgroundcolor'].withdraw() def guiCallback(self): form = self.showForm('setbackgroundcolor', modal=0, blocking=0) def __call__(self, color, **kw): """ None <-----setbackgroundcolorCommand(color) \ncolor : background color """ if type(color) == types.StringType: return "Error: color type can't be string" elif hasattr(color, '__len__') is False: return "Error: color should have length" elif len(color) != 3: return "Error: color length should be 3" apply( self.doitWrapper, (color,), kw) setbackgroundcolorGUI = CommandGUI() setbackgroundcolorGUI.addMenuCommand('menuRoot', '3D Graphics','SetBackGroundColor') class setNPROutlinesCommand(ToggleNpr,Command): """ Package : ViewerFramework \nModule : dejaVuCommands \nClass : setNPROutlinesCommand \nCommand : SetNPROutlines \nDescription \nCommand allowing the user to set NPR outlines \nSynopsis: \ncolor : Required color of background """ def doit(self,control_points,sensitivity): self.vf.toggleNpr(npr=1) vi.GUI.curvetool.setControlPoints(control_points) vi.GUI.curvetool.d1scalewheel.set(sensitivity) #vi.GUI.CameraColorButton_cb() #cam = vi.currentCamera #cc = vi.GUI.colorChooser #cc.Set( cam.backgroundColor[:3], 'RGB' ) def onAddCmdToViewer(self): if self.vf.hasGui: self.sensitivityVar = Tkinter.StringVar() self.sensitivityVar.set("") self.cpVar = Tkinter.StringVar() self.cpVar.set("") def buildFormDescr(self, formName): if formName=="setNprparams": ifd = InputFormDescr(title="Set NPR Params") ifd.append({'name':'cpLab', 'widgetType':Tkinter.Label, 'wcfg':{'text':"Control Points"}, 'gridcfg':{"row":0,'column':0,'sticky':'w'}}) ifd.append({'name':'cpEnt', 'widgetType':Tkinter.Entry, 'tooltip':'controlpoints must be a list of tuples with x value ranging from [50,305] and y from [20,275].', 'wcfg':{'textvariable':self.cpVar}, 'gridcfg':{'sticky':'wens', 'row':0, 'column':1}}) ifd.append({'name':'sensitivityLab', 'widgetType':Tkinter.Label, 'wcfg':{'text':"Sensitivity"}, 'gridcfg':{"row":1,"column":0,'sticky':'w'}}) ifd.append({'name':'sensitivityEnt', 'widgetType':Tkinter.Entry, 'tooltip':'sensitivity should be in range of 0.0 to 1.0', 'wcfg':{'textvariable':self.sensitivityVar}, 'gridcfg':{'sticky':'wens', 'row':1, 'column':1}}) ifd.append({'widgetType':Tkinter.Button, 'name':'OK', 'wcfg':{'text':'OK', 'command':self.ok_cb}, 'gridcfg':{'sticky':'we', 'row':2,'column':0}}) ifd.append({'widgetType':Tkinter.Button, 'name':'dismiss', 'wcfg':{'text':'DISMISS', 'command':self.dismiss_cb}, 'gridcfg':{'sticky':'we', 'row':2,'column':1}}) return ifd def dismiss_cb(self): if self.cmdForms.has_key('setNprparams'): self.cmdForms['setNprparams'].withdraw() def guiCallback(self): form = self.showForm('setNprparams', modal=0, blocking=0) def ok_cb(self): vfgui = self.vf.GUI vi = vfgui.VIEWER self.vf.toggleNpr(npr=1) if self.cpVar.get() != '': vi.GUI.curvetool.setControlPoints(eval(self.cpVar.get())) if self.sensitivityVar.get() != '': vi.GUI.curvetool.d1scalewheel.set(eval(self.sensitivityVar.get())) self.dismiss_cb() def __call__(self,control_points,sensitivity): """None <-----setNPROutlines(points,sensitivity) points:list of points snesitivity:floatvalue(ranging from 0.0 to 1.0) \ncolor : background color """ if type(control_points) != types.ListType: print "Illegal type for points" return if type(sensitivity)!=types.FloatType: print "Illegal type for sensitivity" return apply( self.doitWrapper, (control_points,sensitivity),{}) setNPROutlinesGUI = CommandGUI() setNPROutlinesGUI.addMenuCommand('menuRoot', '3D Graphics','SetCartoonOutlines') commandList = [ {'name':'setNPROutlines', 'cmd':setNPROutlinesCommand(), 'gui':setNPROutlinesGUI}, {'name':'setAntialiasing', 'cmd':setAntialiasingCommand(), 'gui':setAntialiasingGUI}, {'name':'setbackgroundcolor', 'cmd':setbackgroundcolorCommand(), 'gui':setbackgroundcolorGUI}, {'name':'setCameraSize', 'cmd':SetCameraSizeCommand(), 'gui':SetCamSizeGUI}, {'name':'renderLargeImage', 'cmd':RenderLargeImageCommand(), 'gui':RenderLargeImageGUI}, {'name':'spin', 'cmd':SpinCommand(), 'gui':spinGUI}, {'name':'transformObject', 'cmd':TransformObject(), 'gui':None}, {'name':'transformCamera', 'cmd':TransformCamera(), 'gui':None}, {'name':'setObject', 'cmd': SetObject(), 'gui':None}, {'name':'setCamera', 'cmd':SetCamera(), 'gui': None}, {'name':'setLight', 'cmd':SetLight(), 'gui':None}, {'name':'setClip', 'cmd':SetClip(),'gui':None}, {'name':'addClipPlane', 'cmd':AddClipPlane(),'gui':None}, {'name':'centerGeom','cmd':CenterGeom(),'gui':None}, {'name':'viewPoints', 'cmd': ViewPoints(),'gui':None}, {'name': 'centerScene', 'cmd':CenterScene(), 'gui':None}, {'name': 'centerSceneOnVertices', 'cmd':CenterSceneOnVertices(), 'gui':None}, {'name':'centerSceneOnPickedPixel','cmd':CenterSceneOnPickedPixel(), 'gui':None}, {'name': 'alignGeomsnogui', 'cmd':AlignGeoms(), 'gui':None}, {'name': 'alignGeoms', 'cmd':AlignGeomsPCOM(), 'gui':None}, {'name': 'rotateScene', 'cmd':RotateScene(), 'gui':None}, {'name':'printGeometryName', 'cmd':PrintGeometryName(), 'gui':None}, {'name':'startContinuousPicking', 'cmd':StartContinuousPicking(), 'gui':None}, {'name':'stopContinuousPicking', 'cmd':StopContinuousPicking(), 'gui':None}, # {'name':'toggleStereo', 'cmd':ToggleStereo(), 'gui':ToggleStereoGUI}, # {'name':'toggleNpr', 'cmd':ToggleNpr(), 'gui':ToggleNprGUI}, {'name':'toggleStereo', 'cmd':ToggleStereo(), 'gui':ToggleStereoGUI}, {'name':'toggleNpr', 'cmd':ToggleNpr(), 'gui':ToggleNprMenuGUI}, {'name':'ResetView', 'cmd':ResetView(), 'gui':ResetViewGUI}, {'name':'loadColorMap', 'cmd':LoadColorMap(), 'gui':LoadColorMapGUI}, {'name':'saveColorMap', 'cmd':SaveColorMap(), 'gui':SaveColorMapGUI}, {'name':'createColorMap', 'cmd':CreateColorMap(), 'gui':CreateColorMapGUI}, {'name':'showCMGUI', 'cmd':ColorMapEditor(), 'gui':ColorMapEditorGUI}, {'name':'editColorMap', 'cmd':EditColorMap(), 'gui':None}, {'name':'saveImage', 'cmd':SaveImage(), 'gui':SaveImageGUI }, #{'name':'colorGeomsByName', 'cmd':ColorGeomsByName(), 'gui':ColorGeomsByNameGUI}, ] def initModule(viewer): for dict in commandList: viewer.addCommand(dict['cmd'], dict['name'], dict['gui']) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/drawShape.py0000644000175000017500000001672010651433475024442 0ustar moellermoeller## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by ############################################################################# # # Author: Sophie Coon, Michel F. SANNER, Kevin CHAN # # Copyright: M. Sanner TSRI 2000 # ############################################################################# # # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/drawShape.py,v 1.2 2007/07/24 17:30:37 vareille Exp $ # # $Id: drawShape.py,v 1.2 2007/07/24 17:30:37 vareille Exp $ # import Tkinter, numpy.oldnumeric as Numeric from DejaVu.IndexedPolygons import IndexedPolygons class DrawShape: """ gui to allow user to draw an arbitrary shape and get points and normals for the shape. """ def __init__(self, master, grid=10): self.root = Tkinter.Toplevel(master) # add a title self.title = Tkinter.Label(self.root,text='Draw a Shape') description = 'click left mouse button to set a point\n click right mouse button to stop drawing\n draw points clockwise' self.details = Tkinter.Label(self.root, text=description) self.title.pack(side='top', anchor='n') self.details.pack(side='bottom') self.f = Tkinter.Frame(self.root) self.c = Tkinter.Canvas(self.f, borderwidth = 3, relief='ridge') self.c.grid(column=4, rowspan=5) Tkinter.Widget.bind(self.c, "", self.mouseDown) Tkinter.Widget.bind(self.c, "", self.endShape) Tkinter.Widget.bind(self.c, "", self.mouseMotion) self.hasFirstPoint = 0 self.but=Tkinter.Button(self.f, text='clear',command=self.clear) self.but.grid(row=4, column=2) self.dup = Tkinter.IntVar() smooth = Tkinter.Radiobutton(self.f, text = 'smooth edges', var = self.dup, value = 0) sharp = Tkinter.Radiobutton(self.f, text = 'sharp edges', var = self.dup, value = 1) smooth.grid(row=0, columnspan=3) sharp.grid(row=1, columnspan=3) self.cap1 = Tkinter.IntVar() self.cap2 = Tkinter.IntVar() cap1 = Tkinter.Checkbutton(self.f, text = 'front cap', var = self.cap1) cap2 = Tkinter.Checkbutton(self.f, text = 'end cap', var = self.cap2) cap1.grid(row=2, columnspan=3) cap2.grid(row=3, columnspan=3) # list of points in contour self.shape = [] self.end = 0 # this is a "tagOrId" for the line we draw on the canvas self.rubberbandLine = None # this is the size of the gridding squares self.griddingSize = grid # how much 1 grid space is in real world self.gridToWorld = 0.1 # build the OK Cancel buttons ok = Tkinter.Button(self.f, text='OK', command=self.OK_cb) cancel = Tkinter.Button(self.f, text='Cancel', command=self.Cancel_cb) cancel.grid(row=4, column=1) ok.grid(row=4, column=0) self.f.pack(side='bottom', anchor='s') def mouseDown(self, event): # canvas x and y take the screen coords from the event and translate # them into the coordinate system of the canvas object x = self.c.canvasx(event.x, self.griddingSize) y = self.c.canvasy(event.y, self.griddingSize) if len(self.shape)>0: # after first point self.newline=self.c.create_line(self.shape[-1][0], self.shape[-1][1], x, y, tags='segment') self.shape.append((x,y)) if self.rubberbandLine: self.c.delete(self.rubberbandLine) self.rubberbandLine = self.c.create_line(x, y, x, y, tags='rubber') def endShape(self, event): self.end = 1 if self.rubberbandLine: self.c.delete(self.rubberbandLine) def mouseMotion(self, event): # canvas x and y take the screen coords from the event and translate # them into the coordinate system of the canvas object if len(self.shape)==0: return if self.end: return x = self.c.canvasx(event.x, self.griddingSize) y = self.c.canvasy(event.y, self.griddingSize) if (self.shape[-1][0] != event.x) and (self.shape[-1][1] != event.y): self.c.delete(self.rubberbandLine) self.rubberbandLine = self.c.create_line( self.shape[-1][0], self.shape[-1][1], x, y) # this flushes the output, making sure that # the rectangle makes it to the screen # before the next event is handled self.f.update_idletasks() def End(self): import math # center the points around the origin sca = (1.0/self.griddingSize)*self.gridToWorld points = Numeric.array(self.shape, 'f')* sca xsum, ysum = 0, 0 if points: repeat = 0 comp = points[-1]-points[0] if abs(comp[0])<.01 and abs(comp[1])<.01: repeat = -1 for i in range(len(points)+repeat): xsum = xsum + points[i][0] ysum = ysum + points[i][1] xcenter = xsum/(len(points)+repeat) ycenter = ysum/(len(points)+repeat) origin = (xcenter, ycenter) points = points - origin points[:,1:] = points[:,1:]*-1 # 3D o = Numeric.ones((len(points), 1)) points = Numeric.concatenate((points, o), 1) # calculate normals to each side normals = Numeric.zeros((len(points)-1, 3), 'f') for i in range(len(points)-1): diff = points[i+1] - points[i] if diff[1]==0: normals[i][0] = 0.0 normals[i][1] = diff[0]/abs(diff[0]) else: slope = -diff[0]/diff[1] size = -math.sqrt(1+slope**2)*(diff[1]/abs(diff[1])) normals[i][0] = 1.0/size normals[i][1] = slope/size # duplicate vertices if self.dup.get(): pts = Numeric.concatenate((points, points), 1) self.points = Numeric.reshape(pts, (2*len(points), 3)) norms1 = Numeric.concatenate((Numeric.reshape(normals[-1], (1,3)), normals)) norms2 = Numeric.concatenate((normals, Numeric.reshape(normals[0], (1,3)))) norms = Numeric.concatenate((norms1, norms2), 1) self.normals = Numeric.reshape(norms, (2*len(points), 3)) # single vertices: average normals else: self.points = points self.normals = Numeric.zeros((len(points), 3)).astype('f') for i in range(len(points)-1): n = (normals[i-1]+normals[i])/2 self.normals[i] = n.astype('f') self.normals[len(points)-1] = self.normals[0] print self.points else: self.points, self.normals = [], [] #now use points to make a polyline or polygon or whatever def OK_cb(self, event=None): """call back for OK button""" if not hasattr(self, 'points'): self.End() if self.points: self.root.quit() def Cancel_cb(self): """call back for Cancel button""" self.points = [] self.normals = [] self.root.quit() def clear(self): self.shape=[] self.end = 0 self.pointindex=0 self.c.delete(self.c.gettags('segment')) def go(self): """start chooser in modal mode""" self.root.grab_set() self.root.mainloop() self.root.destroy() return self.points, self.normals, self.dup.get(), self.cap1.get(),\ self.cap2.get() if __name__ =='__main__': import pdb root=Tkinter.Tk() myDraw=DrawShape(root) val = myDraw.go() ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/grid3DCommands.py0000644000175000017500000040572511453162222025317 0ustar moellermoeller######################################################################## # # Authors: Sargis Dallakyan, Michel Sanner # # sargis@scripps.edu # sanner@scripps.edu # # The Scripps Research Institute (TSRI) # Molecular Graphics Lab # La Jolla, CA 92037, USA # # Copyright: Sargis Dallakyan, Michel Sanner and TSRI # ######################################################################### # # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/grid3DCommands.py,v 1.21 2010/10/06 21:05:22 autin Exp $ # $Id: grid3DCommands.py,v 1.21 2010/10/06 21:05:22 autin Exp $ """This module integrates Volume.Grid3D with ViewerFramework for rendering 3D Grids. It includes Add/Remove, Isocontour, OrthoSlice and VolRender commands, and a table widget for navigating between grids. See http://mgltools.scripps.edu/documentation/tutorial/volume-rendering for more info. """ import sys import re, types, os, math, pickle import Tkinter, Pmw, tkFileDialog, tkMessageBox from PIL import Image, ImageTk from tkColorChooser import askcolor from DejaVu.Geom import Geom from ViewerFramework.VFCommand import Command, CommandGUI from mglutil.gui import widgetsOnBackWindowsCanGrabFocus from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ListChooser from mglutil.gui.InputForm.Tk.gui import InputFormDescr, InputForm from mglutil.gui.BasicWidgets.Tk.multiListbox import MultiListbox from mglutil.util.misc import ensureFontCase from Volume.IO.volReaders import ReadMRC, ReadCCP4, ReadCNS, ReadGRD, ReadBRIX,\ ReadSPIDER, ReadRawiv, ReadEM, ReadFLDBinary from Volume.IO.volWriters import WriteCCP4 from Volume.IO.UHBDGridReader import UHBDReaderASCII from Volume.IO.DelphiReader import DelphiReaderBin from Volume.IO.dxReader import ReadDX from Volume.IO.AutoGridReader import ReadAutoGrid from Volume.IO.gamessOrbitalsReader import ReadGamessOrbitals from Volume.Grid3D import Grid3D, Grid3DD, Grid3DF, Grid3DI, \ Grid3DSI, Grid3DUI, Grid3DUSI, Grid3DUC, ArrayTypeToGrid, GridTypeToArray from Volume.Renderers.UTVolumeLibrary.DejaVu.UTVolRenGeom import UTVolRenGeom from mglutil.util.packageFilePath import findFilePath from DejaVu.extendedSlider import ExtendedSlider try: from UTpackages.UTisocontour import isocontour isocontour.setVerboseLevel(0) except ImportError: isocontour = None from DejaVu.IndexedPolygons import IndexedPolygons from DejaVu.Box import Box from DejaVu.Textured2DArray import textured2DArray import numpy.oldnumeric as Numeric import numpy from DejaVu.colorMap import ColorMap from DejaVu.ColormapGui import ColorMapGUI from opengltk.OpenGL import GL ICONPATH = findFilePath('Icons', 'ViewerFramework') Grid_ICONPATH = os.path.join(ICONPATH, 'Grid3D') if sys.platform == 'darwin': rightClick = "Apple-Click" else: rightClick = "Right-Click" def get_icon(icon, master): iconfile = os.path.join(Grid_ICONPATH, icon) head, ext = os.path.splitext(iconfile) if ext == '.gif': if master is None: Icon = Tkinter.PhotoImage(file=iconfile) else: Icon = Tkinter.PhotoImage(file=iconfile, master=master) else: image = Image.open(iconfile) if master is None: Icon = ImageTk.PhotoImage(image=image) else: Icon = ImageTk.PhotoImage(image=image, master=master) return Icon class addGridCommand(Command): """ \nPackage : ViewerFramework \nModule : grid3DCommands \nClass : addGridCommand \nCommand : addGrid \ndoit(self, grid3D, name=None):\n """ def doit(self, grid3D, name=None): grid3D.origin_copy = grid3D.origin grid3D.stepSize_copy = grid3D.stepSize mini, maxi, mean, std = grid3D.stats() grid3D.mini = mini grid3D.maxi = maxi grid3D.mean = mean grid3D.std = std if name == None: name = str(grid3D) if self.vf.grids3D.has_key(name): name += "_" def returnStringRepr(): return None, "\"" + name + "\"" grid3D.returnStringRepr = returnStringRepr if not hasattr(grid3D,'geomContainer'): grid3D.geomContainer = {} g = Geom(name) grid3D.master_geom = g self.vf.GUI.VIEWER.AddObject(g) grid3D.geomContainer['IsoSurf'] = {} grid3D.geomContainer['OrthoSlice'] = {} IsoSurf = Geom('IsoSurf') OrthoSlice = Geom('OrthoSlice') box = Box('BoundingBox') pt1 = grid3D.origin dims = grid3D.data.shape pt2 = [pt1[0]+(grid3D.stepSize[0]*(dims[0]-1)), pt1[1]+(grid3D.stepSize[1]*(dims[1]-1)), pt1[2]+(grid3D.stepSize[2]*(dims[2]-1))] if grid3D.crystal: ptList=((pt2[0],pt2[1],pt1[2]), (pt1[0],pt2[1],pt1[2]), (pt1[0],pt1[1],pt1[2]), (pt2[0],pt1[1],pt1[2]), (pt2[0],pt2[1],pt2[2]), (pt1[0],pt2[1],pt2[2]), (pt1[0],pt1[1],pt2[2]), (pt2[0],pt1[1],pt2[2])) coords = grid3D.crystal.toCartesian(ptList) box.Set(vertices=coords) else: coords = (pt1, pt2) box.Set(cornerPoints=coords) grid3D.geomContainer['Box'] = box self.vf.GUI.VIEWER.AddObject(box,parent=g) self.vf.GUI.VIEWER.AddObject(IsoSurf,parent=g) self.vf.GUI.VIEWER.AddObject(OrthoSlice,parent=g) grid3D.IsoSurf = IsoSurf grid3D.OrthoSlice = OrthoSlice self.vf.grids3D[name] = grid3D if self.vf.Grid3DCommands.root: grid_name = name grid_type = grid3D.data.dtype self.vf.Grid3DCommands.mlb.insert(Tkinter.END, (grid_name, grid3D.dimensions, grid_type )) #self.vf.Grid3DCommands.mlb.selection_clear(0, Tkinter.END) #self.vf.Grid3DCommands.mlb.selection_set(Tkinter.END) #self.vf.Grid3DAddRemove.select() class readAnyGrid(Command): """ The readAnyGrid reads any of the grids supported by Volume.IO and saves Grid3D object in self.vf.grids3D[gridFile] where gridFile can be provided by Grid3D-->Read GUI \nPackage : ViewerFramework \nModule : grid3DCommands \nClass : readAnyGrid \nCommand : readAnyGrid \nSynopsis:\n grid3D<-readAnyGrid(gridFile)\n \nRequired Arguments:\n gridFile : location of the grid file\n """ def __init__(self, func=None): Command.__init__(self) self.ifd=InputFormDescr(title='Map Types') mapItems = [('AutoGrid',None), ('BRIX/DSN6',None), ('CCP4',None), ('CNS/XPLOR',None), ('Data Explorer(DX)',None), ('Delphi',None), ('GRD',None), ('MRC',None), ('Rawiv',None), ('SPIDER',None), ('UHBD/GRID',None), ('AVS/FLD Binary',None), ] self.ifd.append({'name':'listchooser', 'widgetType':ListChooser, 'wcfg':{'title':'Select a Map Type:', 'entries':mapItems, 'lbwcfg':{'width':20,'height':12}, 'mode':'single', }, 'gridcfg':{'sticky':'w','row':-1} }) def onAddCmdToViewer(self): if not hasattr(self.vf, 'grids3D'): self.vf.grids3D={} def __call__(self, gridFile, **kw): """Grid3D object<-readAnyGrid(gridFile)\n \nRequired Arguments:\n gridFile : location of the grid file\n """ return apply(self.doitWrapper, (gridFile,), kw) def doit(self, gridFile, name=None, show=True, normalize=True): """Reads gridFile and adds it to Control Panel Optoinal Arguments: name : name of the grid file used as a key in self.vf.grid3d if None os.path.basename(gridFile) is used show : if True show Control panel normalize : if true calls Normalize the Viewer """ if not gridFile: return if not os.path.exists(gridFile): print gridFile, " not exists" else: if(re.search('\.mrc$',gridFile,re.I)): reader = ReadMRC() elif(re.search('\.ccp4*$',gridFile,re.I)): reader = ReadCCP4() elif(re.search('\.cns$|\.xplo*r*$',gridFile,re.I)): reader = ReadCNS() elif(re.search('\.grd$',gridFile,re.I)): reader = ReadGRD() elif(re.search('\.fld$',gridFile,re.I)): reader = ReadFLDBinary() elif(re.search('\.map$',gridFile,re.I)): reader = ReadAutoGrid() elif(re.search('\.omap$|\.brix$|\.dsn6$|\.dn6$',gridFile,re.I)): reader = ReadBRIX() elif(re.search('\.rawiv$',gridFile,re.I)): reader = ReadRawiv() elif(re.search('\.d*e*l*phi$',gridFile,re.I)): reader = DelphiReaderBin() elif(re.search('\.uhbd$',gridFile,re.I)): reader = UHBDReaderASCII() elif(re.search('\.dx$',gridFile,re.I)): reader = ReadDX() elif(re.search('\.spi$',gridFile,re.I)): reader = ReadSPIDER() else: if not show: return reader = self.askMapType() if not reader: return try: grid3D = reader.read(gridFile, normalize=True) except Exception, inst: print inst if not show: return reader = self.askMapType() if not reader: return try: grid3D = reader.read(gridFile, normalize=True) except Exception, inst: print inst tkMessageBox.showerror("Error: in choosing a map", "Could not parse %s. Please open Python shell for Traceback"%gridFile) return if not grid3D: if not show: return reader = self.askMapType() if not reader: return try: grid3D = reader.read(gridFile, normalize=True) except Exception, inst: print inst tkMessageBox.showerror("Error: in choosing a map", "Could not parse %s. Please open Python shell for Traceback"%gridFile) return if name: grid_basename = name else: grid_basename = os.path.basename(gridFile) if grid3D: grid3D.path = gridFile self.vf.addGrid(grid3D, grid_basename, log=0) if normalize: self.vf.GUI.VIEWER.Normalize_cb() if show: self.vf.Grid3DCommands.show() return grid3D def askMapType(self): """Opens Select Map Type widget""" f = InputForm(master=Tkinter._default_root, root=Tkinter.Toplevel(), descr=self.ifd, blocking=1, modal=1) maptype=f.go() if not maptype: return False choice=maptype['listchooser'][0] if choice=='AutoGrid': reader=ReadAutoGrid() elif choice=='BRIX/DSN6': reader=ReadBRIX() elif choice=='CCP4': reader=ReadCCP4() elif choice=='CNS/XPLOR': reader=ReadCNS() elif choice=='Data Explorer(DX)': reader=ReadDX() elif choice=='Delphi': reader=DelphiReaderBin() elif choice=='GRD':reader=ReadGRD() elif choice=='MRC':reader=ReadMRC() elif choice=='Rawiv':reader=ReadRawiv() elif choice=='SPIDER':reader=ReadSPIDER() elif choice=='UHBD/GRID':reader=UHBDReaderASCII() elif choice=='AVS/FLD Binary':self.reader=ReadFLDBinary() else: tkMessageBox.showerror("Error: in choosing a map", "Error: in choosing" + choice) return False return reader def guiCallback(self, parent = None): """called each time the 'Grid3D -> Import...' sequence is pressed""" fileTypes = [('All supported files', '*.map *.ccp4 *.dx *.grd '+ '*.omap *.brix* *.dsn6* *.cns *.xplo*r* *.d*e*l*phi *.mrc *.rawiv *.spi *.uhbd'), ('AutoGrid', '*.map'), ('AVS/FLD Binary', '*.fld'), ('BRIX/DSN6', '*.omap *.brix* *.dsn6*'), ('CCP4', '*.ccp4'), ('CNS/XPLOR', '*.cns *.xplo*r*'), ('Data Explorer(DX)', '*.dx'), ('Delphi', '*.d*e*l*phi'), ('GRD', '*.grd'), ('MRC', '*.mrc'), ('Rawiv', '*.rawiv'), ('SPIDER', '*.spi'), ('UHBD/GRID', '*.uhbd'), ('all', '*')] gridFile = tkFileDialog.askopenfilename(parent = parent, filetypes=fileTypes, title = 'Grid File:') if gridFile is not None and len(gridFile): self.doitWrapper(gridFile, redraw=0) readAnyGridGUI = CommandGUI() readAnyGridGUI.addMenuCommand('menuRoot', 'Grid3D', 'Read...') class GridMultiListbox(MultiListbox): """Extends MultiListbox from mglutil.gui.BasicWidgets.Tk.multiListbox""" def __init__(self, master, lists, **kw): MultiListbox.__init__(self, master, lists, **kw) self.girdName = '' def _select(self, y): self.Grid3DCommands.root.config(cursor='watch') self.Grid3DCommands.root.update() row = self.lists[0].nearest(y) self.selection_clear(0, Tkinter.END) self.selection_set(row) if row != -1: girdName = self.Grid3DCommands.get_grid_name() if girdName != self.girdName: self.Grid3DCommands.current_cmd.select() self.girdName = girdName self.Grid3DCommands.root.config(cursor='') return 'break' width = 440 #width of the GUI height = 200 #height of the GUI class Grid3DCommands(Command): """This is the main class that adds GridMultiListbox widget with Add/Remove, Isocontour and OrthoSlice icons and widgets """ def __init__(self, func=None): Command.__init__(self) self.root = None self.Icons = [] self.Checkbuttons = {} def onAddCmdToViewer(self): if not hasattr(self.vf, 'grids3D'): self.vf.grids3D={} def get_grid_name(self): select = self.mlb.curselection() if not select: return None grid_name = self.mlb.get(select[0]) return grid_name[0] def select(self, name): "Selects Listbox by Grid Name" grids = self.mlb.lists[0].get(0,Tkinter.END) grids = list(grids) index = grids.index(name) self.mlb.selection_clear(0,Tkinter.END) self.mlb.selection_set(index) def doit(self, show = True, **kw): if show: self.show() else: self.hide() def guiCallback(self, **kw): if not self.root: self.root = Tkinter.Toplevel() self.root.title('3D Grid Rendering Control Panel') self.root.protocol("WM_DELETE_WINDOW", self.hide) menu = Tkinter.Menu(self.root) self.root.config(menu=menu) self.root.minsize(width+5,width-5) file = Tkinter.Menu(menu) file.add_command(label='Open Grid...', command=self.vf.Grid3DAddRemove.add) file.add_command(label='Load Settings...', command=self.open) file.add_command(label='Save Settings...', command=self.save) menu.add_cascade(label='File', menu=file) self.PanedWindow = Tkinter.PanedWindow(self.root, handlepad=0, handlesize=0, orient=Tkinter.VERTICAL, bd=1, width=width,height=2*height) self.PanedWindow.pack(fill=Tkinter.BOTH, expand=1) self.mlb = GridMultiListbox(self.PanedWindow, ((' Grid Name', 33), ('Dimensions ', 15), ('Type', 6)), hull_height = 100, usehullsize = 1, hull_width = width) self.mlb.pack(expand=Tkinter.NO, fill=Tkinter.X) self.mlb.Grid3DCommands = self for grid in self.vf.grids3D: grid_name = grid # if len(grid_name) > 40: # grid_name = grid_name[-37:] # grid_name = '...'+grid_name grid_type = self.vf.grids3D[grid].data.dtype.name self.vf.Grid3DCommands.mlb.insert(Tkinter.END, (grid_name, self.vf.grids3D[grid].dimensions, grid_type )) self.PanedWindow.add(self.mlb) main_frame = Tkinter.Frame(self.PanedWindow) main_frame.pack(expand=Tkinter.YES, fill=Tkinter.BOTH) self.PanedWindow.add(main_frame, height=height+90) self.main_frame = main_frame toolbar_frame = Tkinter.Frame(main_frame, bg='white', relief=Tkinter.RIDGE, bd=2) toolbar_frame.pack(expand=Tkinter.NO, fill=Tkinter.X) self.toolbar_frame = toolbar_frame widget_frame = Tkinter.Frame(main_frame) widget_frame.pack(expand=Tkinter.YES, fill=Tkinter.BOTH) self.widget_frame = widget_frame cmd_list = [ ('Add/Remove', 'add_rem.png', self.Add_Remove, 'Add/Remove 3D Gird')] if isocontour: cmd_list.append(('Isocontour', 'iso.png', self.Isocontour, 'Isocontouring Widget')) cmd_list.append(('OrthoSlice', 'ortho.png', self.OrthoSlice, 'Orthogonal Slices')) from Volume.Renderers.UTVolumeLibrary import UTVolumeLibrary test = UTVolumeLibrary.VolumeRenderer() flag = test.initRenderer() if flag: cmd_list.append(('VolRen', 'VolRen.png', self.VolRen, '3D Texture-Based Volume Renderer')) else: print "Volume Renderer is Disabled" #font LucidaTypewriter Marumoji, MiscFixed 14 for name, icon, func, txt in cmd_list: Icon = get_icon(icon, master=self.root) self.Icons.append(Icon) Checkbutton = Tkinter.Checkbutton(toolbar_frame, image=Icon, indicatoron=0, command=func, bg='white') Checkbutton.ballon = Pmw.Balloon() Checkbutton.ballon.bind(Checkbutton, txt) self.Checkbuttons[name] = Checkbutton Checkbutton.pack(side=Tkinter.LEFT) idf = self.vf.Grid3DAddRemove.ifd self.add_remove_form = InputForm(main_frame,self.widget_frame,idf, okcancel=0,closeWithWindow=0, width=width, height=height) self.add_remove_form.mf.config(bd =0) self.add_remove_form.mf.pack_forget() idf = self.vf.Grid3DIsocontour.ifd self.isocontour_form = InputForm(main_frame,self.widget_frame,idf, okcancel=0,closeWithWindow=0, width=width, height=height) self.isocontour_form.mf.config(bd =0) self.isocontour_form.mf.pack_forget() idf = self.vf.Grid3DOrthoSlice.ifd self.OrthoSlice_form = InputForm(main_frame,self.widget_frame,idf, okcancel=0,closeWithWindow=0, width=width, height=height) self.OrthoSlice_form.mf.config(bd =0) self.OrthoSlice_form.mf.pack_forget() idf = self.vf.Grid3DVolRen.ifd self.VolRen_form = InputForm(main_frame,self.widget_frame,idf, okcancel=0,closeWithWindow=0, width=width, height=height) self.VolRen_form.mf.config(bd =0) self.VolRen_form.mf.pack_forget() self.add_remove_form.mf.pack(expand=Tkinter.YES, fill=Tkinter.BOTH) self.current_obj = self.add_remove_form self.current_cmd = self.vf.Grid3DAddRemove bottom_frame = Tkinter.Frame(main_frame) bottom_frame.pack(fill=Tkinter.X) self.close_b = Tkinter.Button(bottom_frame, text=" Dismiss ", command=self.hide) self.close_b.pack(expand=Tkinter.NO) self.current_checkbutton = self.Checkbuttons['Add/Remove'] self.current_checkbutton.toggle() self.vf.GUI.toolbarCheckbuttons['Grid3D']['Variable'].set(1) self.GUI.menuButton.menu.entryconfig(3, label='Hide Control Panel', command=self.hide) h = self.root.winfo_reqheight() w = self.mlb.interior().winfo_reqwidth() if w > self.root.winfo_width(): self.root.geometry('%dx%d' % (w,h)) elif self.vf.GUI.toolbarCheckbuttons['Grid3D']['Variable'].get() == 0 \ and self.root: self.root.withdraw() self.GUI.menuButton.menu.entryconfig(3,label='Show Control Panel', command=self.show) elif self.vf.GUI.toolbarCheckbuttons['Grid3D']['Variable'].get() == 1 \ and self.root: self.root.deiconify() self.GUI.menuButton.menu.entryconfig(3,label='Hide Control Panel', command=self.hide) def show(self, event=None): if self.root is None: self.guiCallback() else: self.root.deiconify() self.vf.GUI.toolbarCheckbuttons['Grid3D']['Variable'].set(1) self.GUI.menuButton.menu.entryconfig(3, label='Hide Control Panel', command=self.hide) def hide(self, event=None): if self.root: self.root.withdraw() self.vf.GUI.toolbarCheckbuttons['Grid3D']['Variable'].set(0) self.GUI.menuButton.menu.entryconfig(3,label='Show Control Panel', command=self.show) def Add_Remove(self): if self.current_cmd == self.vf.Grid3DVolRen: self.current_cmd.ifd.entryByName['VolRen']['widget'].merge_function() self.current_cmd.saveLUT_Dict() self.current_checkbutton.config(state='normal') self.current_checkbutton.toggle() self.current_obj.mf.pack_forget() self.add_remove_form.mf.pack(expand=Tkinter.YES, fill=Tkinter.BOTH) self.current_obj = self.add_remove_form self.Checkbuttons['Add/Remove'].config(state='disabled') self.current_checkbutton = self.Checkbuttons['Add/Remove'] self.current_cmd = self.vf.Grid3DAddRemove self.current_cmd.select() def Isocontour(self): self.root.configure(cursor='watch') self.root.update() if self.current_cmd == self.vf.Grid3DVolRen: self.current_cmd.ifd.entryByName['VolRen']['widget'].merge_function() self.current_cmd.saveLUT_Dict() self.current_checkbutton.config(state='normal') self.current_checkbutton.toggle() self.current_obj.mf.pack_forget() self.isocontour_form.mf.pack(expand=Tkinter.YES, fill=Tkinter.BOTH) self.current_obj = self.isocontour_form self.Checkbuttons['Isocontour'].config(state='disabled') self.current_checkbutton = self.Checkbuttons['Isocontour'] self.current_cmd = self.vf.Grid3DIsocontour self.current_cmd.select() def OrthoSlice(self): self.root.configure(cursor='watch') self.root.update() #This in needed to save the VolRen if self.current_cmd == self.vf.Grid3DVolRen: self.current_cmd.ifd.entryByName['VolRen']['widget'].merge_function() self.current_cmd.saveLUT_Dict() self.current_checkbutton.config(state='normal') self.current_checkbutton.toggle() self.current_obj.mf.pack_forget() self.OrthoSlice_form.mf.pack(expand=Tkinter.YES, fill=Tkinter.BOTH) self.current_obj = self.OrthoSlice_form self.Checkbuttons['OrthoSlice'].config(state='disabled') self.current_checkbutton = self.Checkbuttons['OrthoSlice'] self.current_cmd = self.vf.Grid3DOrthoSlice self.current_cmd.select() def VolRen(self): self.root.configure(cursor='watch') self.root.update() self.current_checkbutton.config(state='normal') self.current_checkbutton.toggle() self.current_obj.mf.pack_forget() self.VolRen_form.mf.pack(expand=Tkinter.YES, fill=Tkinter.BOTH) self.current_obj = self.VolRen_form self.Checkbuttons['VolRen'].config(state='disabled') self.current_checkbutton = self.Checkbuttons['VolRen'] self.current_cmd = self.vf.Grid3DVolRen self.current_cmd.select() def save(self): outFile = tkFileDialog.asksaveasfile(parent=self.root, filetypes=[('Grid settings', '*.pkl')], title='Save Grid Control Panel File As:') if not outFile: return self.vf.Grid3DCommands.root.config(cursor='watch') settings = [] for gridName in self.vf.grids3D: gridSettings = {} gridSettings['name'] = gridName grid = self.vf.grids3D[gridName] gridSettings['path'] = grid.path gridSettings['origin'] = grid.origin gridSettings['stepSize'] = grid.stepSize gridSettings['boxVisible'] = grid.geomContainer['Box'].visible gridSettings['masterVisible'] = grid.master_geom.visible if hasattr(grid,'isoBarNumber'): #saves Isocontour attributes gridSettings['isoBarNumber'] = grid.isoBarNumber gridSettings['isoBarTags'] = grid.isoBarTags gridSettings['isoLastColor'] = grid.isoLastColor gridSettings['isoLastX'] = grid.isoLastX if hasattr(grid,'_X_Slice'): #saves OrthSlice attributes gridSettings['_X_Slice'] = grid._X_Slice gridSettings['_X_Vis'] = grid._X_Vis if hasattr(grid,'_Y_Slice'): gridSettings['_Y_Slice'] = grid._Y_Slice gridSettings['_Y_Vis'] = grid._Y_Vis if hasattr(grid,'_Z_Slice'): gridSettings['_Z_Slice'] = grid._Z_Slice gridSettings['_Z_Vis'] = grid._Z_Vis if hasattr(grid,'volRenGrid'): #saves volRenGrid attributes gridSettings['LUTintervals_list'] = grid.LUT_data.intervals_list gridSettings['LUTshapes'] = grid.LUT_data.shapes gridSettings['LUTvalues'] = grid.LUT_data.values gridSettings['LUTcolor_arr'] = grid.LUT_data.color_arr gridSettings['LUTalpha_arr'] = grid.LUT_data.alpha_arr settings.append(gridSettings) pickle.dump(settings, outFile) outFile.close() self.vf.Grid3DCommands.root.config(cursor='') self.vf.Grid3DCommands.PanedWindow.config(cursor='') def open(self,inFile=None): if inFile is None: inFile = tkFileDialog.askopenfile(parent=self.root, filetypes=[('Grid settings', '*.pkl'), ('all', '*') ], title='Open Grid Control Panel File:') if not inFile: return self.vf.Grid3DCommands.root.config(cursor='watch') else : inFile=open(inFile,'r') settings = pickle.load(inFile) for gridSettings in settings: self.vf.Grid3DReadAny.doit(gridSettings['path'], name=gridSettings['name']) grid = self.vf.grids3D[gridSettings['name']] grid.origin = gridSettings['origin'] grid.stepSize = gridSettings['stepSize'] grid.geomContainer['Box'].visible = gridSettings['boxVisible'] grid.master_geom.visible = gridSettings['masterVisible'] if gridSettings.has_key('isoBarNumber'): grid.isoBarNumber = gridSettings['isoBarNumber'] grid.isoBarTags = gridSettings['isoBarTags'] grid.isoLastColor = gridSettings['isoLastColor'] grid.isoLastX = gridSettings['isoLastX'] origin = Numeric.array(grid.origin).astype('f') stepsize = Numeric.array(grid.stepSize).astype('f') data = grid.data if data.dtype.char!=Numeric.Float32: data = data.astype('f') self.vf.Grid3DIsocontour.newgrid3D = Numeric.reshape( Numeric.transpose(data), (1, 1)+tuple(data.shape) ) if self.vf.Grid3DIsocontour.iso_data: isocontour.delDatasetReg(self.vf.Grid3DIsocontour.iso_data) self.vf.Grid3DIsocontour.iso_data = isocontour.\ newDatasetRegFloat3D(self.vf.Grid3DIsocontour.newgrid3D, origin, stepsize) for i in range(1, grid.isoBarNumber+1): tag = grid.isoBarTags[i-1] if grid.isoLastX[tag]<0: invertNormals = True else: invertNormals = False color = grid.isoLastColor[tag] r = int(color[1:3], 16) g = int(color[3:5], 16) b = int(color[5:7], 16) self.vf.Grid3DIsocontour.doit(grid, name=tag, isovalue=grid.isoLastX[tag], invertNormals=invertNormals, material=(r/255., g/255., b/255, 0.5)) if gridSettings.has_key('_X_Slice'): grid._X_Slice = gridSettings['_X_Slice'] grid._X_Vis = gridSettings['_X_Vis'] geom = textured2DArray('OrthoSlice_X', inheritLighting=False, lighting=False) self.vf.GUI.VIEWER.AddObject(geom, parent=grid.OrthoSlice) grid.geomContainer['OrthoSlice']['X'] = geom data, vertices = grid.get2DOrthoSlice('x', grid._X_Slice) geom.Set(vertices=vertices, array=data, visible=grid._X_Vis) if gridSettings.has_key('_Y_Slice'): grid._Y_Slice = gridSettings['_Y_Slice'] grid._Y_Vis = gridSettings['_Y_Vis'] geom = textured2DArray('OrthoSlice_Y', inheritLighting=False, lighting=False) self.vf.GUI.VIEWER.AddObject(geom, parent=grid.OrthoSlice) grid.geomContainer['OrthoSlice']['Y'] = geom data, vertices = grid.get2DOrthoSlice('y', grid._Y_Slice) geom.Set(vertices=vertices, array=data, visible=grid._Y_Vis) if gridSettings.has_key('_Z_Slice'): grid._Z_Slice = gridSettings['_Z_Slice'] grid._Z_Vis = gridSettings['_Z_Vis'] geom = textured2DArray('OrthoSlice_Z', inheritLighting=False, lighting=False) self.vf.GUI.VIEWER.AddObject(geom, parent=grid.OrthoSlice) grid.geomContainer['OrthoSlice']['Z'] = geom data, vertices = grid.get2DOrthoSlice('z', grid._Z_Slice) geom.Set(vertices=vertices, array=data, visible=grid._Z_Vis) if gridSettings.has_key('LUTintervals_list'): from Volume.Operators.MapData import MapGridData datamap = {} datamap['src_min'] = grid.mini datamap['src_max'] = grid.maxi datamap['dst_min'] = 0 datamap['dst_max'] = 255 datamap['map_type'] = 'linear' mapper = MapGridData() result = mapper(grid.data, datatype=Numeric.UInt8, datamap=datamap, powerOf2=True) gtype = ArrayTypeToGrid[result.dtype.char] if grid.crystal: from mglutil.math.crystal import Crystal crystal = Crystal( grid.crystal.length, grid.crystal.angles) else: crystal = None newgrid = gtype(result, grid.origin, grid.stepSize, grid.header.copy(), crystal) newgrid.dataDims = grid.data.shape[:] grid.volRenGrid = newgrid geom = UTVolRenGeom('VolRender') grid.geomContainer['VolRender'] = geom self.vf.GUI.VIEWER.AddObject(geom, parent=grid.master_geom) geom.AddGrid3D(newgrid) self.vf.GUI.VIEWER.OneRedraw() grid.LUT_data = LUT_data() grid.LUT_data.intervals_list = gridSettings['LUTintervals_list'] grid.LUT_data.shapes = gridSettings['LUTshapes'] grid.LUT_data.values = gridSettings['LUTvalues'] grid.LUT_data.color_arr = gridSettings['LUTcolor_arr'] grid.LUT_data.alpha_arr = gridSettings['LUTalpha_arr'] geom.setVolRenAlpha([0,grid.LUT_data.alpha_arr]) geom.setVolRenColors([0,grid.LUT_data.color_arr]) inFile.close() self.vf.Grid3DCommands.root.config(cursor='') self.vf.Grid3DCommands.PanedWindow.config(cursor='') Grid3DGUI = CommandGUI() msg = '3D Grid/Volume Rendering' Grid3DGUI.addToolBar('Grid3D', icon1='vol.png', balloonhelp=msg, index=13., icon_dir=ICONPATH) Grid3DGUI.addMenuCommand('menuRoot', 'Grid3D', 'Show Control Panel') class AddRemove(Command): def __init__(self, func=None): if hasattr(self, 'root') is True: master = self.root else: master = None Command.__init__(self) self.boundingBoxVisible = Tkinter.BooleanVar() self.boundingBoxVisible.set(1) self.childGeomVisible = Tkinter.BooleanVar() self.childGeomVisible.set(1) self.Icons = [] self.ifd = InputFormDescr(title = "Add Ion") self.ifd.append({'name':'step_size_label', 'widgetType':Tkinter.Label, 'wcfg':{'text':''}, 'gridcfg':{'row':0, 'column':1, 'sticky':'w'} }) Icon = get_icon('add.png', master=master) self.Icons.append(Icon) self.ifd.append({'name':'Add', 'widgetType':Tkinter.Button, 'wcfg':{'text':'Add', 'image':Icon, 'command':self.add}, 'gridcfg':{'row':1, 'column':0, 'sticky':'we'} }) self.ifd.append({'name':'Name', 'widgetType':Pmw.EntryField, 'wcfg':{'labelpos':'w', 'label_text':'Grid Name:', 'command':self.apply}, 'gridcfg':{'row':1, 'column':1, 'columnspan':4,'sticky':'we'} }) self.ifd.append({'name':'l_add', 'widgetType':Tkinter.Label, 'wcfg':{'text':'Add'}, 'gridcfg':{'row':2, 'column':0, 'sticky':'we'} }) self.ifd.append({'name':'origin_label', 'widgetType':Tkinter.Label, 'wcfg':{'text':' Origin:'}, 'gridcfg':{'row':3, 'column':1, 'sticky':'w'} }) self.ifd.append({'name':'X_origin', 'widgetType':Pmw.EntryField, 'wcfg':{'labelpos':'e', 'label_text':'X', 'entry_width':8, 'validate':{'validator' : 'real'},'sticky':'w', 'command':self.apply}, 'gridcfg':{'row':3, 'column':2, 'sticky':'w'} }) self.ifd.append({'name':'Y_origin', 'widgetType':Pmw.EntryField, 'wcfg':{'labelpos':'e', 'label_text':'Y', 'entry_width':8, 'validate':{'validator' : 'real'},'sticky':'w', 'command':self.apply}, 'gridcfg':{'row':3, 'column':3, 'sticky':'w'} }) self.ifd.append({'name':'Z_origin', 'widgetType':Pmw.EntryField, 'wcfg':{'labelpos':'e', 'label_text':'Z', 'entry_width':8, 'validate':{'validator' : 'real'},'sticky':'w', 'command':self.apply}, 'gridcfg':{'row':3, 'column':4, 'sticky':'w'} }) Icon = get_icon('rem.png', master=master) self.Icons.append(Icon) self.ifd.append({'name':'Remove', 'widgetType':Tkinter.Button, 'wcfg':{'text':'Remove','image':Icon,'command':self.remove}, 'gridcfg':{'row':3, 'column':0, 'sticky':'we'} }) self.ifd.append({'name':'l_remove', 'widgetType':Tkinter.Label, 'wcfg':{'text':'Remove'}, 'gridcfg':{'row':4, 'column':0, 'sticky':'we'} }) self.ifd.append({'name':'step_size_label', 'widgetType':Tkinter.Label, 'wcfg':{'text':' Step Size:'}, 'gridcfg':{'row':4, 'column':1, 'sticky':'w'} }) self.ifd.append({'name':'dX', 'widgetType':Pmw.EntryField, 'wcfg':{'labelpos':'e', 'label_text':'dX', 'entry_width':8, 'validate':{'validator' : 'real'},'sticky':'w', 'command':self.apply}, 'gridcfg':{'row':4, 'column':2, 'sticky':'w'} }) self.ifd.append({'name':'dY', 'widgetType':Pmw.EntryField, 'wcfg':{'labelpos':'e', 'label_text':'dY', 'entry_width':8, 'validate':{'validator' : 'real'},'sticky':'w', 'command':self.apply}, 'gridcfg':{'row':4, 'column':3, 'sticky':'w'} }) self.ifd.append({'name':'dZ', 'widgetType':Pmw.EntryField, 'wcfg':{'labelpos':'e', 'label_text':'dZ', 'entry_width':8, 'validate':{'validator' : 'real'},'sticky':'w', 'command':self.apply}, 'gridcfg':{'row':4, 'column':4, 'sticky':'w'} }) self.ifd.append({'name':'Apply', 'widgetType':Tkinter.Button, 'wcfg':{'text':'Apply', 'command':self.apply}, 'gridcfg':{'row':5, 'column':3,'sticky':'we'} }) self.ifd.append({'name':'Reset', 'widgetType':Tkinter.Button, 'wcfg':{'text':'Reset', 'command':self.reset}, 'gridcfg':{'row':5, 'column':4, 'sticky':'we'} }) self.ifd.append({'name':'childGeomVisible', 'widgetType':Tkinter.Checkbutton, 'wcfg':{'text':'Show/Hide Volume', 'command':self.changeChildrenVisible, 'variable':self.childGeomVisible}, 'gridcfg':{'row':6, 'column':0,'columnspan':3, 'sticky':'w'} }) self.ifd.append({'name':'boundingBoxVisible', 'widgetType':Tkinter.Checkbutton, 'wcfg':{'text':'Show Bounding Box','command':self.changeBox, 'variable':self.boundingBoxVisible}, 'gridcfg':{'row':6, 'column':3,'columnspan':3} }) def onAddCmdToViewer(self): if not hasattr(self.vf, 'grids3D'): self.vf.grids3D={} def __call__(self, grid3D, **kw): apply(self.doitWrapper, (grid3D,), kw) def doit(self, grid3D, remove = True): grid3D = self.vf.grids3D[grid3D] self.vf.GUI.VIEWER.Redraw() def guiCallback(self): self.vf.Grid3DCommands.show() if self.vf.Grid3DCommands.current_cmd != self.vf.Grid3DAddRemove: self.vf.Grid3DCommands.Checkbuttons["Add/Remove"].toggle() self.vf.Grid3DCommands.Add_Remove() def changeBox(self,event=None): grid_name = self.vf.Grid3DCommands.get_grid_name() if not grid_name: return if self.boundingBoxVisible.get(): self.vf.grids3D[grid_name].geomContainer['Box'].Set(visible=1) else: self.vf.grids3D[grid_name].geomContainer['Box'].Set(visible=0) self.vf.GUI.VIEWER.Redraw() def changeChildrenVisible(self, event=None): grid_name = self.vf.Grid3DCommands.get_grid_name() if not grid_name: return if self.childGeomVisible.get(): self.vf.grids3D[grid_name].master_geom.Set(visible=1) self.ifd.entryByName['boundingBoxVisible']['widget'].configure(state='normal') else: self.vf.grids3D[grid_name].master_geom.Set(visible=0) self.ifd.entryByName['boundingBoxVisible']['widget'].configure(state='disabled') self.vf.GUI.VIEWER.Redraw() def add(self): self.vf.Grid3DCommands.root.config(cursor='watch') self.vf.Grid3DReadAny.guiCallback(parent = self.vf.Grid3DCommands.root) self.vf.Grid3DCommands.mlb.selection_clear(0, Tkinter.END) self.vf.Grid3DCommands.mlb.selection_set(Tkinter.END) self.select() self.vf.Grid3DCommands.root.config(cursor='') self.vf.Grid3DCommands.PanedWindow.config(cursor='') def remove(self): grid_name = self.vf.Grid3DCommands.get_grid_name() if not grid_name: if self.vf.Grid3DCommands.mlb.size() != 0: self.ifd.entryByName['Name']['widget'].\ setvalue('Please select grid from the list') else: self.ifd.entryByName['Name']['widget'].\ setvalue('There are no grids in the list') return grid3D = self.vf.grids3D[grid_name] for geoms in grid3D.geomContainer: if hasattr(grid3D.geomContainer[geoms],'__iter__'): for geom in grid3D.geomContainer[geoms]: self.vf.GUI.VIEWER.RemoveObject(grid3D.geomContainer[geoms][geom]) else: self.vf.GUI.VIEWER.RemoveObject(grid3D.geomContainer[geoms]) for children in grid3D.master_geom.children: children.protected = False grid3D.master_geom.protected = False self.vf.GUI.VIEWER.RemoveObject(grid3D.master_geom) self.vf.grids3D.pop(grid_name) select = self.vf.Grid3DCommands.mlb.curselection()[0] self.vf.Grid3DCommands.mlb.delete(select) self.ifd.entryByName['Name']['widget'].setvalue('') self.ifd.entryByName['X_origin']['widget'].setvalue('') self.ifd.entryByName['Y_origin']['widget'].setvalue('') self.ifd.entryByName['Z_origin']['widget'].setvalue('') self.ifd.entryByName['dX']['widget'].setvalue('') self.ifd.entryByName['dY']['widget'].setvalue('') self.ifd.entryByName['dZ']['widget'].setvalue('') self.vf.GUI.VIEWER.Redraw() self.vf.Grid3DCommands.mlb.girdName = None def select(self): grid_name = self.vf.Grid3DCommands.get_grid_name() if not grid_name: return self.vf.Grid3DCommands.mlb.girdName = grid_name self.ifd.entryByName['Name']['widget'].setvalue(grid_name) grid = self.vf.grids3D[grid_name] origin = grid.origin self.ifd.entryByName['X_origin']['widget'].setvalue(origin[0]) self.ifd.entryByName['Y_origin']['widget'].setvalue(origin[1]) self.ifd.entryByName['Z_origin']['widget'].setvalue(origin[2]) stepSize = grid.stepSize self.ifd.entryByName['dX']['widget'].setvalue(stepSize[0]) self.ifd.entryByName['dY']['widget'].setvalue(stepSize[1]) self.ifd.entryByName['dZ']['widget'].setvalue(stepSize[2]) visible = grid.geomContainer['Box'].visible self.boundingBoxVisible.set(visible) visible = grid.master_geom.visible self.childGeomVisible.set(visible) if visible: self.ifd.entryByName['boundingBoxVisible']['widget'].configure(state='normal') else: self.ifd.entryByName['boundingBoxVisible']['widget'].configure(state='disabled') def apply(self): grid_name = self.vf.Grid3DCommands.get_grid_name() if not grid_name: if self.vf.Grid3DCommands.mlb.size() != 0: self.ifd.entryByName['Name']['widget'].\ setvalue('Please select grid from the list') else: self.ifd.entryByName['Name']['widget'].\ setvalue('There a no grids added') return tmp_grid = self.vf.grids3D[grid_name] self.vf.grids3D.pop(grid_name) new_name = self.ifd.entryByName['Name']['widget'].getvalue() tmp_grid.master_geom.Set(name=new_name) self.vf.grids3D[new_name] = tmp_grid row = self.vf.Grid3DCommands.mlb.curselection()[0] l = self.vf.Grid3DCommands.mlb.lists[0] l.delete(row) l.insert(row,new_name) self.vf.Grid3DCommands.mlb.selection_set(row) X = self.ifd.entryByName['X_origin']['widget'].getvalue() Y = self.ifd.entryByName['Y_origin']['widget'].getvalue() Z = self.ifd.entryByName['Z_origin']['widget'].getvalue() tmp_grid.origin = (float(X),float(Y),float(Z)) dX = self.ifd.entryByName['dX']['widget'].getvalue() dY = self.ifd.entryByName['dY']['widget'].getvalue() dZ = self.ifd.entryByName['dZ']['widget'].getvalue() tmp_grid.stepSize = [float(dX),float(dY),float(dZ)] def reset(self): grid_name = self.vf.Grid3DCommands.get_grid_name() if not grid_name: return tmp_grid = self.vf.grids3D[grid_name] self.vf.grids3D.pop(grid_name) if hasattr(tmp_grid, 'path'): grid_basename = os.path.basename(tmp_grid.path) else: grid_basename = grid_name self.vf.grids3D[grid_basename] = tmp_grid tmp_grid.master_geom.Set(name=grid_basename) tmp_grid.origin = tmp_grid.origin_copy tmp_grid.stepSize = tmp_grid.stepSize_copy row = self.vf.Grid3DCommands.mlb.curselection()[0] l = self.vf.Grid3DCommands.mlb.lists[0] l.delete(row) l.insert(row,grid_basename) self.vf.Grid3DCommands.mlb.selection_clear(0, Tkinter.END) self.vf.Grid3DCommands.mlb.selection_set(row) self.select() AddRemoveGUI = CommandGUI() AddRemoveGUI.addMenuCommand('menuRoot', 'Grid3D', 'Add/Remove...') class IGraph(Tkinter.Frame): """Extends Tkinter.Frame by adding a canvas with histogram and bars for isocontouring. """ def __init__(self, master, width = width, height = height, labelsBarFormat = '%4.2f'): self.width = width - 10 self.height = height self.offset_y1 = 6 self.offset_y2 = 20 self.a_x = 1 self.b_x = 0 self.a_y = -1 self.b_y = height self.sig_tags = ['area', 'min_vol', 'max_vol', 'gradient'] self.colors = ['red', 'green', 'blue', 'orange']#used in Plot Signature self.labelsBarFormat = labelsBarFormat Tkinter.Frame.__init__(self, master) #Tkinter.Grid.config(self) self.upperLabel = Tkinter.Label(self, text = "(0, 0)",width=20) self.upperLabel.grid(row=0, column=0,sticky='we') self.log_var = Tkinter.IntVar() self.log_var.set(1) self.sig_var = Tkinter.IntVar() self.log_cb = Tkinter.Checkbutton(self, text='Logarithmic',anchor="w", command = self.plot_histogram, variable=self.log_var) self.log_cb.grid(row=0, column=1,sticky='e') self.sig_cb = Tkinter.Checkbutton(self, text='Plot Signature',anchor="e", command = self.plot_signature, variable=self.sig_var) self.sig_cb.grid(row=0, column=2,sticky='e') #self.canvasFrame = Tkinter.Frame(self) #self.canvasFrame.grid(row=1, column=0,columnspan=4, sticky='wens') self.canvas = Tkinter.Canvas(self, width=self.width,cursor = 'cross', highlightbackground = 'blue', height=height, background='white') self.canvas.grid(row=1, column=0,columnspan=3) self.minEntry = Pmw.ComboBox(self,label_text = 'min',labelpos = 'e', dropdown=1, selectioncommand=self.setMin) self.minEntry.grid(row=2, column=0, sticky='w') self.minEntry._entryWidget.configure(width=8) self.balloon = Pmw.Balloon(self) self.balloon.bind(self, "Press Shift and mouse click inside the canvas to add Isocontour") self.maxEntry = Pmw.ComboBox(self,label_text = 'max',labelpos = 'w', dropdown=1, selectioncommand=self.setMax) self.maxEntry.grid(row=2, column=2, sticky='e') self.maxEntry._entryWidget.configure(width=8) Tkinter.Widget.bind(self.canvas, "<1>", self.selectMoveBar) Tkinter.Widget.bind(self.canvas, "", self.moveBar) Tkinter.Widget.bind(self.canvas, "", self.onMouseOver) Tkinter.Widget.bind(self.canvas,'', self.button3) Tkinter.Widget.bind(self.canvas,'', self.addBar) #Tkinter.Widget.bind(self.canvas, '', self.showDejaVu) #Tkinter.Widget.bind(self, '', self.changeSize) self.valueLabel = {} self.bar_text = 'IsoSurf_' self.isoBarNumber = 0 self.last_tag = None self.canvas.create_rectangle(0,self.offset_y1,self.width, self.offset_y1+1,fill='gray68', tag='h_bar') self.canvas.create_rectangle(0,self.height - self.offset_y2,self.width, self.height - self.offset_y2+1,fill='gray68', tag='h_bar') self.menu = Tkinter.Menu(self.master, title='Isocontour - Menu') self.menu.add_command(label='Set IsoValue...',command=self.isoValueGUI) self.menu.add_command(label='Color...',command=self.setColor) self.menu.add_command(label='Set 3D Surface Properties...', command=self.showDejaVu) self.menu.add_command(label='Hide', command=self.hideShowIso) # self.menu.add_command(label='Transparency',command=self.setTransparency) self.menu.add_command(label='Delete',command=self.deleteCB) self.menu.add_command(label='Cancel',command=self.cancelManu) self.menu.bind('', self.cancelManu) def cancelManu(self, event=None): self.menu.unpost() def changeSize(self, event): self.canvas.scale('all',0,0,float(event.width)/float(self.width), float(event.height)/float(self.height) ) self.width = event.width self.height = event.height def plot_signature(self): if not self.cmd.grid: return for s in range(4): self.canvas.delete(self.sig_tags[s]) if not self.sig_var.get(): return self.cmd.vf.Grid3DCommands.root.configure(cursor='watch') self.cmd.vf.Grid3DCommands.PanedWindow.config(cursor='watch') self.cmd.vf.Grid3DCommands.root.update() for s in range(4): if hasattr(self.cmd.grid,'signature'): sig = self.cmd.grid.signature[s] else: self.cmd.grid.signature = [] for si in range(4): self.cmd.grid.signature.append( self.cmd.iso_data.getSignature(0, 0, si)) sig =self.cmd.grid.signature[s] x = Numeric.zeros( (sig.nval,), 'f') sig.getFx(x) y = Numeric.zeros( (sig.nval,), 'f') sig.getFy(y) max_y = max(y) min_y = min(y) a_y = (self.offset_y1 - self.height + self.offset_y2)/(max_y - min_y) b_y = self.height - self.offset_y2 - a_y*min_y coords = [] for i in range(len(x)): screen_x = self.a_x*x[i] + self.b_x screen_y = a_y*y[i] + b_y coords.append(screen_x) coords.append(screen_y) self.canvas.create_line( coords,fill=self.colors[s], tag=self.sig_tags[s] ) self.canvas.create_text( self.width-40 , 15*s + self.offset_y2, fill=self.colors[s], text=sig.name, tag=self.sig_tags[s]) self.cmd.vf.Grid3DCommands.root.configure(cursor='') self.cmd.vf.Grid3DCommands.PanedWindow.config(cursor='') def plot_histogram(self, event = None, data = None): if data is not None: self.data = data elif not hasattr(self, 'data'): return self.canvas.delete("rect") x = self.data[1].tolist() y = self.data[0].tolist() self.min_x = self.cmd.grid.hist[1][0] self.max_x = self.cmd.grid.hist[1][-1] self.maxEntry.setentry((self.labelsBarFormat)%self.max_x) self.minEntry.setentry((self.labelsBarFormat)%self.min_x) self.min_y = min(y) self.max_y = max(y) if self.log_var.get(): for i in range(len(y)): if y[i] != 0: y[i] = math.log10(float(y[i])) self.min_y = min(y) self.max_y = max(y) self.update_a_b() for i in range(len(y)): screen_x = self.a_x*x[i] + self.b_x screen_y = self.a_y*y[i] + self.b_y self.canvas.create_rectangle(screen_x, screen_y, screen_x+2, self.height - self.offset_y2, outline="gray70", fill="gray70", tag = 'rect') for tag in self.cmd.grid.isoBarTags: newX = self.a_x*self.cmd.grid.isoLastX[tag] + self.b_x if newX < -1 or newX > self.width+1: self.canvas.itemconfig(self.valueLabel[tag], state='hidden') self.canvas.itemconfig(tag, state='hidden') else: coords = self.canvas.coords(self.valueLabel[tag]) self.canvas.coords(self.valueLabel[tag],newX,coords[1]) items = self.canvas.find_withtag(tag) for item in items[0:-2]: coords = self.canvas.coords(item) coords[0] = newX-5 coords[2] = newX+5 self.canvas.coords(item,coords[0],coords[1],coords[2],coords[3]) coords = self.canvas.coords(items[2]) coords[0] = newX-1 coords[2] = newX+1 self.canvas.coords(items[2],coords[0],coords[1],coords[2],coords[3]) self.canvas.itemconfig(self.valueLabel[tag], state='normal') self.canvas.itemconfig(tag, state='normal') self.canvas.lift(tag) def setMin(self, text): try: hMin = float(text) except ValueError: self.minEntry.setentry(str(self.min_x)) return bound = [hMin,self.cmd.grid.hist[1][-1]] hist = numpy.histogram(self.cmd.grid.data.copy().flat,bins=self.width+100, range=bound) self.cmd.grid.hist = hist self.data = hist self.plot_histogram() self.plot_signature() def setMax(self, text): try: hMax = float(text) except ValueError: self.maxEntry.setentry(str(self.max_x)) return bound = [self.cmd.grid.hist[1][0],hMax] hist = numpy.histogram(self.cmd.grid.data.copy().flat,bins=self.width+100, range=bound) self.cmd.grid.hist = hist self.data = hist self.plot_histogram() self.plot_signature() def onMouseOver(self, event): x = (event.x - self.b_x)/self.a_x x = (self.labelsBarFormat)%x y = (event.y - self.b_y)/self.a_y y = (self.labelsBarFormat)%y self.upperLabel.configure(text = "( " + x + " , " + y + " )") def update_a_b(self): if self.max_x == self.min_x: print 'Error: min and max for the X axis are equal ', self.max_x self.a_x = 10000000000000000000000000000000000000000 else: self.a_x = self.width/float((self.max_x - self.min_x)) self.b_x = -self.a_x*self.min_x if self.max_y == self.min_y: print 'Error: min and max for the Y axis are equal ', self.max_y self.a_y = 10000000000000000000000000000000000000000 else: self.a_y = (self.offset_y1 - self.height + self.offset_y2)/\ float((self.max_y - self.min_y)) self.b_y = self.height - self.offset_y2 - self.a_y*self.min_y def drawBar(self, x, isoBarNumber=0, doit=True, color="#ff00ff", alpha=0.5, tag = None): bbox = x - 5, self.offset_y1 - 5, x + 5, self.offset_y1 + 5 if tag is not None: tag = tag else: tag = self.bar_text + str(isoBarNumber) self.canvas.create_arc(bbox, extent=180, tags=(tag,tag+"cap")) bbox = x - 5, self.height - self.offset_y2 -4, x + 5, \ self.height - self.offset_y2 + 7 self.canvas.create_arc(bbox, start=180, extent=180, tags=(tag,tag+"cap")) self.canvas.create_rectangle(x - 1, self.offset_y1, x + 1, self.height - self.offset_y2 + 2, tag=tag, fill='red', activefill='gray68') val = (x - self.b_x)/self.a_x lv = (self.labelsBarFormat)%val self.valueLabel[tag] = self.canvas.create_text(x, self.height - self.offset_y2+15, text=lv, tag=tag) self.cmd.grid.isoLastX[tag] = val invertNormals = False if val<0: invertNormals = True r = int(color[1:3], 16) g = int(color[3:5], 16) b = int(color[5:7], 16) if doit: self.cmd.doit(self.cmd.grid, name=tag, isovalue=val, invertNormals=invertNormals, material=(r/255., g/255., b/255, alpha)) self.canvas.itemconfig(tag, fill=color) def addBar(self, event): if not self.cmd.grid: tkMessageBox.showerror("Error: No grid selected", "Please select grid first.", parent=self) return self.isoBarNumber += 1 self.cmd.grid.isoBarNumber = self.isoBarNumber tag = self.bar_text + str(self.isoBarNumber) # this part was taken from ASPN/Cookbook/Python/Recipe/52273 x = float(event.x)/float(self.width) yellow = min((max((4*(0.75-x), 0.)), 1.)) red = min((max((4*(x-0.25), 0.)), 1.)) green= min((max((4*math.fabs(x-0.5)-1., 0.)), 1.)) color = (int(red*255), int(green*255), int(yellow*255)) hexcolor = '#%02x%02x%02x' % color self.cmd.grid.isoLastColor[tag] = hexcolor self.drawBar(event.x, self.isoBarNumber, color=hexcolor) self.canvas.lift(tag) if self.last_tag in self.cmd.grid.isoLastColor.keys(): self.canvas.itemconfig(self.last_tag + "cap", fill=self.cmd.grid.isoLastColor[self.last_tag]) self.last_tag = tag self.canvas.itemconfig(tag + "cap", fill='gray68') self.cmd.grid.isoBarTags.append(tag) self.balloon.bind(self, rightClick +" on the bar for Options") def deleteCB(self): self.canvas.delete(self.selected_tag) name = '|' + self.cmd.grid.master_geom.name self.cmd.grid.geomContainer['IsoSurf'].pop(self.selected_tag) name = name + '|' + 'IsoSurf' + '|' + self.selected_tag g = self.cmd.vf.GUI.VIEWER.FindObjectByName(name) self.cmd.vf.GUI.VIEWER.RemoveObject(g) self.isoBarNumber -= 1 self.cmd.grid.isoBarNumber = self.isoBarNumber if self.last_tag == self.selected_tag: self.last_tag = self.cmd.grid.isoBarTags[0] self.cmd.grid.isoBarTags.remove(self.selected_tag) self.cmd.grid.isoLastColor.pop(self.selected_tag) self.cmd.grid.isoLastX.pop(self.selected_tag) self.cmd.vf.GUI.VIEWER.Redraw() self.balloon.unbind(self.canvas) def showDejaVu(self): tag = self.selected_tag if not self.cmd.vf.GUI.VIEWER.GUI.shown: self.cmd.vf.GUI.showHideDejaVuGUI() name = '|' + self.cmd.grid.master_geom.name name = name + '|' + 'IsoSurf' + '|' + tag g = self.cmd.vf.GUI.VIEWER.FindObjectByName(name) self.cmd.vf.GUI.VIEWER.SetCurrentObject(g) def selectMoveBar(self, event): self.menu.unpost() if not self.isoBarNumber: self.onMouseOver(event) return x = event.x if x < 0: x = 0 if x > self.width: x = self.width tag = self.canvas.find_closest(event.x,event.y, halo=2) tag = self.canvas.gettags(tag) if tag: if tag[0] in self.cmd.grid.isoBarTags: tag = tag[0] if self.last_tag: self.canvas.itemconfig(self.last_tag+"cap", fill=self.cmd.grid.isoLastColor[self.last_tag]) self.last_tag = tag self.canvas.itemconfig(tag+"cap", fill='gray68') elif self.isoBarNumber > 0: tag = self.last_tag else: self.onMouseOver(event) return else: self.onMouseOver(event) return val = (x - self.b_x)/self.a_x invertNormals = False if val<0: invertNormals = True #move with delta worked here until we let user change the min and max self.canvas.delete(tag) self.drawBar(x, doit=False, color=self.cmd.grid.isoLastColor[tag], tag=tag) self.cmd.grid.isoLastX[tag] = val self.cmd.doit(self.cmd.grid, name=tag, isovalue=val, invertNormals=invertNormals) self.onMouseOver(event) def moveBar(self, event): self.menu.unpost() if not self.isoBarNumber: self.onMouseOver(event) return x = event.x if x < 0: x = 0 if x > self.width: x = self.width tag = self.last_tag delta_x = x - self.a_x*self.cmd.grid.isoLastX[tag] - self.b_x val = (x - self.b_x)/self.a_x invertNormals = False if val<0: invertNormals = True self.canvas.itemconfig(self.valueLabel[tag], text = (self.labelsBarFormat)%val ) self.canvas.move(tag, delta_x, 0 ) self.cmd.grid.isoLastX[tag] = val self.cmd.doit(self.cmd.grid, name=tag, isovalue=val, invertNormals=invertNormals) self.onMouseOver(event) def button3(self, event): if not self.cmd.grid: return tag = self.canvas.find_closest(event.x,event.y) tag = self.canvas.gettags(tag) if tag: if tag[0] in self.cmd.grid.isoBarTags: tag = tag[0] self.selected_color = self.canvas.itemcget(tag,'fill') if self.cmd.grid.geomContainer['IsoSurf'][tag].visible: self.menu.entryconfig(4,label="Hide") else: self.menu.entryconfig(4,label="Show") self.menu.post(event.x_root, event.y_root) self.selected_tag = tag if widgetsOnBackWindowsCanGrabFocus is False: lActiveWindow = self.menu.focus_get() if lActiveWindow is not None \ and ( lActiveWindow.winfo_toplevel() != self.menu.winfo_toplevel() ): return self.menu.focus_set() def setColor(self): tag = self.selected_tag rgb, hex = askcolor(self.selected_color,title='Choose Color') if rgb: self.cmd.grid.geomContainer['IsoSurf'][tag].Set(materials=\ [(rgb[0]/255.,rgb[1]/255.,rgb[2]/255.,0.5),],) #I'm not sure why this is needed but without this Set doen't work self.cmd.grid.geomContainer['IsoSurf'][tag].redoNow(1,1,4) self.canvas.itemconfig(tag,fill=hex) self.cmd.grid.isoLastColor[tag] = str(hex) def isoValueGUI(self): self.isoValueDialog = Pmw.PromptDialog(self, title = 'Set isoValue', label_text = 'Please enter isoValue', entryfield_labelpos = 'n', defaultbutton = 0, buttons = ('OK', 'Cancel'), command = self.setIsoValue) self.isoValueDialog.insertentry(0, self.cmd.grid.isoLastX[self.selected_tag]) self.isoValueDialog.activate() def setIsoValue(self, result): if result is None or result == 'Cancel': self.isoValueDialog.deactivate() return try: val = float(self.isoValueDialog.get()) except Exception, inst: print inst self.isoValueDialog.deactivate() return if val > self.max_x: val = self.max_x if val < self.min_x: val = self.min_x tag = self.selected_tag delta_x = self.a_x*(val-self.cmd.grid.isoLastX[tag]) delta_x = int(delta_x) invertNormals = False if val<0: invertNormals = True self.canvas.itemconfig(self.valueLabel[tag], text=(self.labelsBarFormat)%val ) self.canvas.move(tag, delta_x, 0 ) self.cmd.grid.isoLastX[tag] = val self.cmd.doit(self.cmd.grid, name=tag, isovalue=val, invertNormals=invertNormals) self.isoValueDialog.deactivate() def hideShowIso(self): tag = self.selected_tag surfaceGeom = self.cmd.grid.geomContainer['IsoSurf'][tag] if surfaceGeom.visible: surfaceGeom.Set(visible=False) self.menu.entryconfig('Hide',label="Show") else: surfaceGeom.Set(visible=True) self.menu.entryconfig('Show',label="Hide") def setTransparency(self): tag = self.selected_tag root = Tkinter.Toplevel() root.title("Set Transparency - %s"%self.cmd.grid.master_geom.name) surfaceGeom = self.cmd.grid.geomContainer['IsoSurf'][tag] transparencySl = ExtendedSlider(root, label=' Transparency', minval=0.0, maxval=1.0, init=1 - surfaceGeom.materials[GL.GL_FRONT].prop[5][0], sd='left', withValue=0, immediate=1) transparencySl.AddCallback(self.opacity_cb) transparencySl.frame.pack(side='top', expand=1, fill='y') def opacity_cb(self, val): tag = self.selected_tag surfaceGeom = self.cmd.grid.geomContainer['IsoSurf'][tag] surfaceGeom.Set(opacity=1-val) self.cmd.vf.GUI.VIEWER.Redraw() class IsocontourCommand(Command): """IsocontourCommand calculates and displays isocontours for any given gridname gridname, material = (0.,0.,1.0,0.5), isovalue = None , name = None, invertNormals = False \nPackage : ViewerFramework \nModule : grid3DCommands \nClass : IsocontourCommand \nCommand : isocontour \nSynopsis:\nfF None<-isocontour(gridname)\n \nRequired Arguments:\n grid3D : grids3D object\n \nOptional Arguments:\n isovalue : if None given, uses the first element in the Grid3D \n material : defaults to (0.,0.,1.0,0.5) - yellow half transparent\n name : the name given to IndexedPolygons that represents isocontour.\n invertNormals : defaults to False """ def __init__(self, func=None): Command.__init__(self) self.ifd = InputFormDescr(title = "Isocontour") self.ifd.append({'name':'iso', 'widgetType':IGraph, 'wcfg':{'width':width, 'height':height-50}, 'gridcfg':{'row':0, 'column':0, 'sticky':'wens'} }) self.grid = None self.iso_data = None def onAddCmdToViewer(self): if not hasattr(self.vf, 'grids3D'): self.vf.grids3D={} self.ifd[0]['widgetType'].cmd = self def __call__(self, grid3D, **kw): """None<-isocontour(gridname)\n \nRequired Arguments:\n grid3D : key for self.vf.grids3D object\n \nOptional Arguments:\n isovalue : if None given, uses the first element in the Grid3D \n material : defaults to (0.,0.,1.0,0.5) - yellow half transparent\n name : the name given to IndexedPolygons that represents isocontour.\n invertNormals : defaults to False """ return apply(self.doitWrapper, (grid3D,), kw) def doit(self, grid3D, material = None, isovalue = None , name = None, invertNormals = False): if type(grid3D) in types.StringTypes: if self.vf.grids3D.has_key(grid3D): grid3D = self.vf.grids3D[grid3D] else: print "ERROR!!! "+ grid3D + "is not in the self.vf.grids3D" if isovalue == None: isovalue = float(grid3D.data[0][0][0]) isoc = isocontour.getContour3d(self.iso_data, 0, 0, isovalue, isocontour.NO_COLOR_VARIABLE) vert = Numeric.zeros((isoc.nvert,3)).astype('f') norm = Numeric.zeros((isoc.nvert,3)).astype('f') col = Numeric.zeros((isoc.nvert)).astype('f') tri = Numeric.zeros((isoc.ntri,3)).astype('i') if invertNormals: isocontour.getContour3dData(isoc, vert, norm, col, tri, 1) else: isocontour.getContour3dData(isoc, vert, norm, col, tri, 0) if grid3D.crystal: vert = grid3D.crystal.toCartesian(vert) if not name: name = "Grid3D_Iso_%4.4f"%isovalue if name in grid3D.geomContainer['IsoSurf']: g = grid3D.geomContainer['IsoSurf'][name] else: g = IndexedPolygons(name) if self.vf.userpref['Sharp Color Boundaries for MSMS']['value'] == 'blur': g.Set(inheritSharpColorBoundaries=False, sharpColorBoundaries=False,) g.Set(culling='none') g.Set(vertices=vert,vnormals=norm,faces=tri) self.vf.GUI.VIEWER.AddObject(g, parent = grid3D.IsoSurf) grid3D.geomContainer['IsoSurf'][name] = g if material: g.inheritMaterial = False g.Set(materials=[material,],) g.Set(vertices=vert,vnormals=norm,faces=tri) if vert is not None: g.sortPoly() self.vf.GUI.VIEWER.Redraw() return g def select(self): entry = self.ifd.entryByName['iso'] grid_name = self.vf.Grid3DCommands.get_grid_name() isoBarNumber = entry['widget'].isoBarNumber if not grid_name: self.vf.Grid3DCommands.root.configure(cursor='') self.vf.Grid3DCommands.PanedWindow.config(cursor='') for i in range(1, isoBarNumber + 1): tag = entry['widget'].bar_text + str(i) entry['widget'].canvas.delete(tag) entry['widget'].canvas.delete("rect") self.grid = None return grid = self.vf.grids3D[grid_name] if not hasattr(grid,'hist'): bound = None #this is used to set the limits on the histogram if grid_name.endswith('.map'): if grid.mini < 0: bound = [grid.mini,-grid.mini] hist = numpy.histogram(grid.data.copy().flat,bins=entry['widget'].width+100) grid.hist = hist if not hasattr(grid,'isoBarNumber'): grid.isoLastX = {} grid.isoLastColor = {} grid.isoBarNumber = 0 grid.isoBarTags = [] for i in range(1, isoBarNumber + 1): tag = entry['widget'].bar_text + str(i) entry['widget'].canvas.delete(tag) self.vf.Grid3DCommands.root.config(cursor='watch') self.vf.Grid3DCommands.PanedWindow.config(cursor='watch') self.vf.Grid3DCommands.root.update() self.grid = grid entry['widget'].isoBarNumber = self.grid.isoBarNumber origin = Numeric.array(grid.origin).astype('f') stepsize = Numeric.array(grid.stepSize).astype('f') data = grid.data if data.dtype != Numeric.Float32: print 'converting %s from %s to float'%(grid_name,data.dtype) data = data.astype('f') self.newgrid3D = Numeric.ascontiguousarray(Numeric.reshape( Numeric.transpose(data), (1, 1)+tuple(data.shape) ) , data.dtype.char) if self.iso_data: isocontour.delDatasetReg(self.iso_data) self.iso_data = isocontour.newDatasetRegFloat3D(self.newgrid3D, origin, stepsize) for i in range(1, grid.isoBarNumber+1): tag = grid.isoBarTags[i-1] x = entry['widget'].a_x*grid.isoLastX[tag] + entry['widget'].b_x entry['widget'].drawBar(x, i, doit=False, color=grid.isoLastColor[tag]) #entry['widget'].canvas.lift(tag) entry['widget'].plot_signature() entry['widget'].plot_histogram(data=self.grid.hist) entry['widget'].canvas.tag_raise('h_bar') self.vf.Grid3DCommands.root.configure(cursor='') self.vf.Grid3DCommands.PanedWindow.config(cursor='') displayIsocontourGUI = CommandGUI() displayIsocontourGUI.addMenuCommand('menuRoot', 'Grid3D', 'Isocontour...') class OrthoSliceCommand(Command): def __init__(self, func=None): Command.__init__(self) self.ifd = InputFormDescr(title="OrthoSlice") self.X_vis = Tkinter.BooleanVar() self.X_vis.set(1) self.Y_vis = Tkinter.BooleanVar() self.Z_vis = Tkinter.BooleanVar() self.grid = None self.ifd.append({'widgetType':Pmw.Group, 'name':'XGroup', 'container':{'XGroup':'w.interior()'}, 'wcfg':{'tag_pyclass':Tkinter.Checkbutton, 'tag_text':'X Direction', 'tag_command':self.createX, 'tag_variable': self.X_vis, }, 'gridcfg':{'sticky':'we','columnspan':2} }) self.ifd.append({'name':'X_Slice', 'widgetType':Tkinter.Scale, 'parent':'XGroup', 'wcfg':{'orient':'horizontal','sliderrelief':'sunken', 'sliderlength':10,'width':12, 'troughcolor':'red', 'command':self.X_Slice}, 'gridcfg':{'row':0, 'column':0,'sticky':'ew', 'weight':10}}) self.ifd.append({'name':'X_ColorMap', 'widgetType':Tkinter.Button, 'parent':'XGroup', 'wcfg':{'text':'Colormap', 'command':self.X_ColorMap}, 'gridcfg':{'row':0, 'column':1,'sticky':'se'} }) self.ifd.append({'widgetType':Pmw.Group, 'name':'YGroup', 'container':{'YGroup':'w.interior()'}, 'wcfg':{'tag_pyclass':Tkinter.Checkbutton, 'tag_text':'Y Direction', 'tag_command':self.createY, 'tag_variable': self.Y_vis, }, 'gridcfg':{'sticky':'we','columnspan':2} }) self.ifd.append({'name':'Y_Slice', 'widgetType':Tkinter.Scale, 'parent':'YGroup', 'wcfg':{'orient':'horizontal','sliderrelief':'sunken', 'sliderlength':10,'width':12, 'troughcolor':'red', 'command':self.Y_Slice}, 'gridcfg':{'row':0, 'column':0,'sticky':'ew', 'weight':10} }) self.ifd.append({'name':'Y_ColorMap', 'widgetType':Tkinter.Button, 'parent':'YGroup', 'wcfg':{'text':'Colormap', 'command':self.Y_ColorMap}, 'gridcfg':{'row':0, 'column':1,'sticky':'se'} }) self.ifd.append({'widgetType':Pmw.Group, 'name':'ZGroup', 'container':{'ZGroup':'w.interior()'}, 'wcfg':{'tag_pyclass':Tkinter.Checkbutton, 'tag_text':'Z Direction', 'tag_command':self.createZ, 'tag_variable': self.Z_vis, }, 'gridcfg':{'sticky':'we','columnspan':2} }) self.ifd.append({'name':'Z_Slice', 'widgetType':Tkinter.Scale, 'parent':'ZGroup', 'wcfg':{'orient':'horizontal','sliderrelief':'sunken', 'sliderlength':10,'width':12, 'troughcolor':'red', 'command':self.Z_Slice}, 'gridcfg':{'row':0, 'column':0,'sticky':'ew', 'weight':10} }) self.ifd.append({'name':'Z_ColorMap', 'widgetType':Tkinter.Button, 'parent':'ZGroup', 'wcfg':{'text':'Colormap', 'command':self.Z_ColorMap}, 'gridcfg':{'row':0, 'column':1,'sticky':'se'} }) def X_ColorMap(self): if not self.X_vis.get(): return elif self.grid: colormap = self.grid.geomContainer['OrthoSlice']['X'].colormap name = "X Slice - " name += self.vf.Grid3DCommands.get_grid_name() colormap.name = name self.X_ColorMapGUI = ColorMapGUI(cmap=colormap,modifyMinMax=True) self.X_ColorMapGUI.addCallback( self.X_ColorMap_cb ) self.ifd.entryByName['X_ColorMap']['widget'].configure(state='disabled') def dismissXCmap(): self.ifd.entryByName['X_ColorMap']['widget'].configure(state='normal') if self.X_ColorMapGUI.master.winfo_ismapped(): self.X_ColorMapGUI.master.withdraw() self.X_ColorMapGUI.dismiss.configure(command = dismissXCmap) self.X_ColorMapGUI.master.protocol('WM_DELETE_WINDOW', dismissXCmap) else: parent = self.vf.Grid3DCommands.root tkMessageBox.showerror("Error: No grid selected", "Please add and select grid first.", parent=parent) def X_ColorMap_cb(self, colorMap): self.grid.geomContainer['OrthoSlice']['X'].Set(colormap=colorMap) def X_Slice(self, event): if not self.X_vis.get(): return elif self.grid: data, vertices = self.grid.get2DOrthoSlice('x', int(event)) geom = self.grid.geomContainer['OrthoSlice']['X'] geom.Set(vertices=vertices, array=data) self.grid._X_Slice = int(event) self.grid._X_Vis = True self.vf.GUI.VIEWER.Redraw() # else: # parent = self.vf.Grid3DCommands.root # tkMessageBox.showerror("Error: No grid selected", # "Please add and select grid first.", parent=parent) def createX(self): if not self.grid: return if self.X_vis.get(): geom = textured2DArray('OrthoSlice_X', inheritLighting=False, lighting=False) self.vf.GUI.VIEWER.AddObject(geom, parent=self.grid.OrthoSlice) self.grid.geomContainer['OrthoSlice']['X'] = geom slice_number = self.ifd.entryByName['X_Slice']['widget'].get() data, vertices = self.grid.get2DOrthoSlice('x', slice_number) self.grid._X_Slice = slice_number self.grid._X_Vis = True geom.Set(vertices=vertices, array=data) if hasattr(self.grid, 'path') and self.grid.path.endswith('.map'): if self.grid.mini < 0: geom.Set(max=-self.grid.mini, min=self.grid.mini) else: geom.Set(max=self.grid.maxi, min=self.grid.mini) else: geom.Set(max=self.grid.maxi, min=self.grid.mini) self.ifd.entryByName['XGroup']['widget'].expand() else: name = '|' + self.grid.master_geom.name + '|' + 'OrthoSlice' + \ '|' + 'OrthoSlice_X' geom = self.vf.GUI.VIEWER.FindObjectByName(name) self.vf.GUI.VIEWER.RemoveObject(geom) self.grid.geomContainer['OrthoSlice'].pop('X') self.ifd.entryByName['XGroup']['widget'].collapse() self.grid._X_Vis = False self.vf.GUI.VIEWER.Redraw() def Y_Slice(self, event): if not self.Y_vis.get(): return elif self.grid: data, vertices = self.grid.get2DOrthoSlice('y', int(event)) geom = self.grid.geomContainer['OrthoSlice']['Y'] geom.Set(vertices=vertices, array=data) self.grid._Y_Slice = int(event) self.grid._Y_Vis = True self.vf.GUI.VIEWER.Redraw() # else: # parent = self.vf.Grid3DCommands.root # tkMessageBox.showerror("Error: No grid selected", # "Please add and select grid first.", parent=parent) def createY(self): if not self.grid: return if self.Y_vis.get(): geom = textured2DArray('OrthoSlice_Y', inheritLighting=False, lighting=False) self.vf.GUI.VIEWER.AddObject(geom, parent=self.grid.OrthoSlice) self.grid.geomContainer['OrthoSlice']['Y'] = geom slice_number = self.ifd.entryByName['Y_Slice']['widget'].get() data, vertices = self.grid.get2DOrthoSlice('y', slice_number) geom.Set(vertices=vertices, array=data) if hasattr(self.grid, 'path') and self.grid.path.endswith('.map'): if self.grid.mini < 0: geom.Set(max=-self.grid.mini, min=self.grid.mini) else: geom.Set(max=self.grid.maxi, min=self.grid.mini) else: geom.Set(max=self.grid.maxi, min=self.grid.mini) self.ifd.entryByName['YGroup']['widget'].expand() self.grid._Y_Slice = slice_number self.grid._Y_Vis = True else: name = '|' + self.grid.master_geom.name + '|' + 'OrthoSlice' + \ '|' + 'OrthoSlice_Y' geom = self.vf.GUI.VIEWER.FindObjectByName(name) self.vf.GUI.VIEWER.RemoveObject(geom) self.grid.geomContainer['OrthoSlice'].pop('Y') self.ifd.entryByName['YGroup']['widget'].collapse() self.grid._Y_Vis = False self.vf.GUI.VIEWER.Redraw() def Y_ColorMap(self): if not self.Y_vis.get(): return elif self.grid: colormap = self.grid.geomContainer['OrthoSlice']['Y'].colormap name = "Y Slice - " name += self.vf.Grid3DCommands.get_grid_name() colormap.name = name self.Y_ColorMapGUI = ColorMapGUI(cmap=colormap, modifyMinMax=True) self.Y_ColorMapGUI.addCallback( self.Y_ColorMap_cb ) self.ifd.entryByName['Y_ColorMap']['widget'].configure(state='disabled') def dismissYCmap(): self.ifd.entryByName['Y_ColorMap']['widget'].configure(state='normal') if self.Y_ColorMapGUI.master.winfo_ismapped(): self.Y_ColorMapGUI.master.withdraw() self.Y_ColorMapGUI.dismiss.configure(command = dismissYCmap) self.Y_ColorMapGUI.master.protocol('WM_DELETE_WINDOW', dismissYCmap) else: parent = self.vf.Grid3DCommands.root tkMessageBox.showerror("Error: No grid selected", "Please add and select grid first.", parent=parent) def Y_ColorMap_cb(self, colorMap): self.grid.geomContainer['OrthoSlice']['Y'].Set(colormap=colorMap) def Z_Slice(self, event): if not self.Z_vis.get(): return elif self.grid: data, vertices = self.grid.get2DOrthoSlice('z', int(event)) geom = self.grid.geomContainer['OrthoSlice']['Z'] geom.Set(vertices=vertices, array=data) self.grid._Z_Slice = int(event) self.grid._Z_Vis = True self.vf.GUI.VIEWER.Redraw() # else: # parent = self.vf.Grid3DCommands.root # tkMessageBox.showerror("Error: No grid selected", # "Please add and select grid first.", parent=parent) def createZ(self): if not self.grid: return if self.Z_vis.get(): geom = textured2DArray('OrthoSlice_Z', inheritLighting=False, lighting=False) self.vf.GUI.VIEWER.AddObject(geom, parent=self.grid.OrthoSlice) self.grid.geomContainer['OrthoSlice']['Z'] = geom slice_number = self.ifd.entryByName['Z_Slice']['widget'].get() data, vertices = self.grid.get2DOrthoSlice('z', slice_number) geom.Set(vertices=vertices, array=data) if hasattr(self.grid, 'path') and self.grid.path.endswith('.map'): if self.grid.mini < 0: geom.Set(max=-self.grid.mini, min=self.grid.mini) else: geom.Set(max=self.grid.maxi, min=self.grid.mini) else: geom.Set(max=self.grid.maxi, min=self.grid.mini) self.ifd.entryByName['ZGroup']['widget'].expand() self.grid._Z_Slice = slice_number self.grid._Z_Vis = True else: name = '|' + self.grid.master_geom.name + '|' + 'OrthoSlice' + \ '|' + 'OrthoSlice_Z' geom = self.vf.GUI.VIEWER.FindObjectByName(name) self.vf.GUI.VIEWER.RemoveObject(geom) self.grid.geomContainer['OrthoSlice'].pop('Z') self.ifd.entryByName['ZGroup']['widget'].collapse() self.grid._Z_Vis = False self.vf.GUI.VIEWER.Redraw() def Z_ColorMap(self): if not self.Z_vis.get(): return elif self.grid: colormap = self.grid.geomContainer['OrthoSlice']['Z'].colormap name = "Z Slice - " name += self.vf.Grid3DCommands.get_grid_name() colormap.name = name self.Z_ColorMapGUI = ColorMapGUI(cmap=colormap, modifyMinMax=True) self.Z_ColorMapGUI.addCallback( self.Z_ColorMap_cb ) self.ifd.entryByName['Z_ColorMap']['widget'].configure(state='disabled') def dismissZCmap(): self.ifd.entryByName['Z_ColorMap']['widget'].configure(state='normal') if self.Z_ColorMapGUI.master.winfo_ismapped(): self.Z_ColorMapGUI.master.withdraw() self.Z_ColorMapGUI.dismiss.configure(command = dismissZCmap) self.Z_ColorMapGUI.master.protocol('WM_DELETE_WINDOW', dismissZCmap) else: parent = self.vf.Grid3DCommands.root tkMessageBox.showerror("Error: No grid selected", "Please add and select grid first.", parent=parent) def Z_ColorMap_cb(self, colorMap): self.grid.geomContainer['OrthoSlice']['Z'].Set(colormap=colorMap) def onAddCmdToViewer(self): if not hasattr(self.vf, 'grids3D'): self.vf.grids3D={} def __call__(self, grid3D, **kw): return apply(self.doitWrapper, (grid3D,), kw) def doit(self, grid3D, name = None, axis = 'x', sliceNumber = 0): if type(grid3D) in types.StringTypes: if self.vf.grids3D.has_key(grid3D): grid3D = self.vf.grids3D[grid3D] else: print "ERROR!!! "+ grid3D + "is not in the self.vf.grids3D" if not name: name = "Grid3D_Ortho_%s_%d"%(axis,sliceNumber) if name in grid3D.geomContainer['OrthoSlice']: g = grid3D.geomContainer['OrthoSlice'][name] else: g = textured2DArray(name) self.vf.GUI.VIEWER.AddObject(g, parent = grid3D.OrthoSlice) grid3D.geomContainer['OrthoSlice'][name] = g data, vertices = grid.get2DOrthoSlice(axis, sliceNumber) g.Set(vertices=vertices, array=data) self.vf.GUI.VIEWER.OneRedraw() return g def select(self): grid_name = self.vf.Grid3DCommands.get_grid_name() if not grid_name: self.vf.Grid3DCommands.root.configure(cursor='') self.vf.Grid3DCommands.PanedWindow.config(cursor='') self.grid = None return self.grid = self.vf.grids3D[grid_name] self.ifd.entryByName['X_Slice']['widget'].config(to=self.grid.dimensions[0]-1) self.ifd.entryByName['Y_Slice']['widget'].config(to=self.grid.dimensions[1]-1) self.ifd.entryByName['Z_Slice']['widget'].config(to=self.grid.dimensions[2]-1) if hasattr(self.grid,'_X_Slice'): self.ifd.entryByName['X_Slice']['widget'].set(self.grid._X_Slice) self.X_vis.set(self.grid._X_Vis) if self.grid._X_Vis: self.ifd.entryByName['XGroup']['widget'].expand() else: self.ifd.entryByName['XGroup']['widget'].collapse() else: self.ifd.entryByName['X_Slice']['widget'].set(0) self.X_vis.set(1) self.createX() self.ifd.entryByName['XGroup']['widget'].expand() if hasattr(self.grid,'_Y_Slice'): self.ifd.entryByName['Y_Slice']['widget'].set(self.grid._Y_Slice) self.Y_vis.set(self.grid._Y_Vis) if self.grid._Y_Vis: self.ifd.entryByName['YGroup']['widget'].expand() else: self.ifd.entryByName['YGroup']['widget'].collapse() else: self.ifd.entryByName['Y_Slice']['widget'].set(0) self.Y_vis.set(0) self.ifd.entryByName['YGroup']['widget'].collapse() if hasattr(self.grid,'_Z_Slice'): self.ifd.entryByName['Z_Slice']['widget'].set(self.grid._Z_Slice) self.Z_vis.set(self.grid._Z_Vis) if self.grid._Z_Vis: self.ifd.entryByName['ZGroup']['widget'].expand() else: self.ifd.entryByName['ZGroup']['widget'].collapse() else: self.ifd.entryByName['Z_Slice']['widget'].set(0) self.Z_vis.set(0) self.ifd.entryByName['ZGroup']['widget'].collapse() self.vf.Grid3DCommands.root.configure(cursor='') self.vf.Grid3DCommands.PanedWindow.config(cursor='') OrthoSliceGUI = CommandGUI() OrthoSliceGUI.addMenuCommand('menuRoot', 'Grid3D', 'OrthoSlice...') from mglutil.gui.BasicWidgets.Tk.tablemaker import Colormap, TableManager, LUT from Volume.Operators.MapData import MapGridData globalFont = (ensureFontCase('helvetica'), 10) from math import log10 class myLUT(LUT): """Extend mglutil.gui.BasicWidgets.Tk.tablemaker.LUT; removes label to top """ def __init__(self, master=None, xminval=0,xmaxval=255, ymaxval=4095, width = width-20, height = height-50, grid_row=0, num_of_entries = 256, initdraw = 1): self.callbacks = {'entries':None, 'rgbmap':None, 'setalpha':None, 'setcolor':None} self.master = master self.xmaxval = xmaxval self.xminval = xminval self.ymaxval = ymaxval self.num_of_entries = num_of_entries assert self.num_of_entries > 0 self.font = globalFont self.canvas = Tkinter.Canvas(master,width = width, height=height, relief = Tkinter.FLAT, highlightbackground='blue', borderwidth = 2) self.width = width self.height = height c = self.canvas c.grid(row=grid_row, sticky=Tkinter.W) width = float(c.cget('width')) # 461.0 height = float(c.cget('height'))#106.0 diff = 15 self.right = width-4 self.top = diff self.left = 8 self.bott = height-12 # c.create_rectangle(3,3, width+3,height+3, # outline ='', width=4, # fill='', tags='outline') c.create_rectangle(self.left,self.top, self.right,self.bott, outline ='black', width=1, fill='white', tags='box') #c.create_text(self.right-15, self.bott+10, text=str(xmaxval), # anchor=Tkinter.W, font=self.font) #c.create_text(self.left, self.bott+11, text=str(xminval), anchor=Tkinter.W, # font=self.font) #c.create_text(self.left-3, self.top-7, text=str(ymaxval), anchor=Tkinter.W, # font=self.font, tags = 'ytext') # scale x and y axes self.sclx = (self.right-self.left)/(xmaxval-xminval) self.scly = (self.bott-self.top)/ymaxval self.delta = self.sclx+1e-6 ## c.create_line(self.left,self.bott,self.right, ## self.bott, width = 2, fill='black', tags=('line','line0')) ## self.line_count = 1 ## self.dot_count = 0 c.tag_bind('dot', '', self.mouse1Down) c.tag_bind('dot', '', self.mouse1Up) c.tag_bind('isodot', '', self.pickIsoVal) c.tag_bind('isodot', '', self.moveIsoVal) #c.tag_bind('line', '', self.pick) self.bind_tags() arr_len = xmaxval-xminval+1 self.color_arr = Numeric.zeros((arr_len,3),'f') self.alpha_arr = Numeric.zeros(arr_len).astype(Numeric.Int16) self.points = [] self.values = [] self.shapes = [] self.isoVals = [] self.dotrad = 5 self.isodotrad = 5 self.isoval_inrange = [] if initdraw: self.draw_initshape() self.last_event = '' self.curr_ind = 1 #self.continuous = 1 def plot_histogram(self, event = None, data = None): if data is not None: self.data = data elif not hasattr(self, 'data'): return self.canvas.delete("rect") x = data[1].tolist() y = data[0].tolist() for i in range(len(y)): if y[i] != 0: y[i] = math.log10(y[i]) self.min_y = min(y) self.max_y = max(y) self.update_a_b() for i in range(len(y)): screen_x = self.a_x*x[i] + self.b_x screen_y = self.a_y*y[i] + self.b_y self.canvas.create_rectangle(screen_x, screen_y, screen_x+2, self.bott , outline="gray70", fill="gray70", tag = 'rect') tags = self.canvas.find_all() tags = list(tags) rect = self.canvas.find_withtag('rect') rect = list(rect) box = self.canvas.find_withtag('box') box = list(box) for i in rect: tags.remove(i) for i in box: tags.remove(i) for i in tags: self.canvas.tag_raise(i) def update_a_b(self): if self.max_x == self.min_x: print 'Error: min and max for the X axis are equal ', self.max_x self.a_x = 10000000000000000000000000000000000000000 else: self.a_x = (self.right - self.left -1 )/(self.max_x - self.min_x) self.b_x = -self.a_x*self.min_x + self.left + 1 bottom = self.bott if self.max_y == self.min_y: print 'Error: min and max for the Y axis are equal ', self.max_y self.a_y = 10000000000000000000000000000000000000000 else: self.a_y = (-bottom + self.top)/(self.max_y - self.min_y) self.b_y = bottom - self.a_y*self.min_y from DejaVu.colorTool import RGBARamp class myTF(TableManager): """Extends mglutil.gui.BasicWidgets.Tk.tablemaker.TableManager and removes iso widget """ def __init__(self, master, xminval=0, xmaxval=255, ymaxval=255, alphaCallback = None, colorCallback = None): self.viewer = self.cmd.vf.GUI.VIEWER self.xminval = int(xminval) self.xmaxval = int(xmaxval) self.ymaxval = int(ymaxval) self.ymaxval_limit = int(ymaxval) self.master = master self.lutcallbacks = {} self.labelsBarFormat = '%4.2f' self.heightAdded = 0 #this keeps track the height added when splitting self.balloon = Pmw.Balloon(self.master) #place menu buttons #mbutton = Tkinter.Menubutton(self.master, text='VolRender - Menu') #mbutton.pack(side=Tkinter.LEFT) self.menu = Tkinter.Menu(self.master, title='VolRender - Menu') self.menu.add_command(label="Set Color", command=self.showColormap) self.menu.add_command(label="Reset", command=self.reset) self.menu.add_command(label="Hide", command=self.hideShow) self.menu.drawchoices= Tkinter.Menu(self.menu) self.menu.add_cascade(label="Draw Function...", menu=self.menu.drawchoices) self.menu.drawchoices.add_command(label ="Ramp", command=(lambda self=self, num=0: self.draw_ramp(num))) self.menu.drawchoices.add_command(label ="Reversed Ramp", command=(lambda self=self, num=1: self.draw_ramp(num))) self.menu.add_command(label="Flip Function", command = self.flip_function_cb) self.menu.sizechoices= Tkinter.Menu(self.menu) self.menu.add_command(label="Set Dots Size", command=(lambda self=self, st="dot": self.set_dotsize_cb(st))) self.menu.add_command(label="Delete Selected Dot", command=self.del_selected_dot) self.menu.add_separator() #self.editBtn = self # needed since split_cb calls self.editBtn.menu.... # self.menu.add_command(label="Split Function", # command=self.show_splitDialog) # self.menu.add_command(label="Merge Function", # command=self.merge_function, # state="disabled") # # self.menu.add_separator() self.menu.add_command(label="Load LUT (.lut)", command=self.ask_open_file_cb) self.menu.add_command(label="Save LUT (.lut)", command=self.saveLUT) self.menu.add_command(label='Save TF (.clu)', command=self.saveTF) self.continVar = Tkinter.IntVar() self.continVar.set(1) font = self.font = globalFont self.set_font(self.menu, font) self.intervals_list = [(self.xminval, self.xmaxval),] self.parent_interval = (self.xminval, self.xmaxval) self.create_splitDialog() self.colormapWin = Tkinter.Toplevel() self.colormapWin.title('Color - VolRender') self.colormapWin.protocol('WM_DELETE_WINDOW', self.closeRGB) iconpath = 'mglutil.gui.BasicWidgets.Tk' file = findFilePath('icons', iconpath) file = os.path.join(file,'colors.gif') self.colormap = Colormap(self.colormapWin, file=file) Tkinter.Button(self.colormapWin,text="Dismiss", command=self.closeRGB).grid(columnspan=2) self.colormapWin.withdraw() self.colormap.callbacks = [self.set_hsv] #self.Label = Tkinter.Label(self.master, # text="(0,0)") #self.Label.pack(anchor='w') self.intervals_list = [(self.xminval, self.xmaxval),] self.parent_interval = (self.xminval, self.xmaxval) self.create_splitDialog() #place Lookup Table editor on the form self.f1 = Tkinter.Frame(self.master) self.f1.pack() self.log_var = Tkinter.IntVar() self.log_var.set(1) lut = myLUT(self.f1, xmaxval=self.xmaxval, xminval=xminval, grid_row=1, num_of_entries = self.xmaxval+1, ymaxval=ymaxval) lut.canvas.bind('', self.selected) lut.canvas.bind('', self.button3) self.canvas_list = [lut.canvas,] #lut.canvas.itemconfigure('outline', outline='blue') self.with_focus = lut self.lut_list = [lut,] #place entries for ISO value info #place color editor on the form self.lutcallbacks['entries'] = self.entries_update self.lutcallbacks['rgbmap'] = self.colormap.show_color if alphaCallback: self.lutcallbacks['setalpha'] = alphaCallback else: self.lutcallbacks['setalpha'] = self.lut_alpha_cb if colorCallback : self.lutcallbacks['setcolor'] = colorCallback else : self.lutcallbacks['setcolor'] = self.lut_color_cb lut.setCallbacks(self.lutcallbacks) self.data = [] #data saved to Undo splitting intervals lut.master.bind('', self.cancelManu) #lut.canvas.bind("", self.onMouseOver) self.minEntry = Pmw.ComboBox(self.master,label_text = 'min',labelpos = 'e', dropdown=1, selectioncommand=self.setMin) self.minEntry.pack(side='left') self.minEntry._entryWidget.configure(width=8) self.maxEntry = Pmw.ComboBox(self.master,label_text = 'max',labelpos = 'w', dropdown=1, selectioncommand=self.setMax) self.maxEntry.pack(side='right') self.maxEntry._entryWidget.configure(width=8) self.cVar = Tkinter.IntVar() radioS = Pmw.RadioSelect(self.master, command=self.colorGUI) radioS.pack(side="top", fill = 'x',) radioS.add(' Use This Widget ') radioS.add(' Use Colormap GUI ') radioS.setvalue(' Use This Widget ') self.radioS = radioS self.balloon.bind(self.lut_list[0].canvas, "Move the dots to change the transfer "+ "function. " + rightClick+" for options.") def dismissCmap(self, toggle=True): if hasattr(self, 'ColorMapGUI') and self.ColorMapGUI.master.winfo_ismapped(): self.ColorMapGUI.master.withdraw() self.radioS.setvalue(' Use This Widget ') self.balloon.bind(self.lut_list[0].canvas, "Move the dots to change the transfer "+ "function. " + rightClick+" for options.") self.lut_list[0].canvas.configure(state='normal') def colorGUI(self, tag=None): name = self.cmd.vf.Grid3DCommands.get_grid_name() if not name: parent = self.cmd.vf.Grid3DCommands.root tkMessageBox.showerror("Error: No grid selected", "Please add and select grid first.", parent=parent) return if tag == ' Use This Widget ': self.dismissCmap(toggle=False) return else: self.lut_list[0].canvas.configure(state='disabled') self.balloon.bind(self.lut_list[0].canvas, "Click on 'Use This Widget' to enable this widget") self.radioS.setvalue(' Use Colormap GUI ') if hasattr(self,'ColorMapGUI'): self.ColorMapGUI.master.deiconify() name += "-VolRender Colormap" self.ColorMapGUI.master.title(name) else: ramp = RGBARamp() ramp[:,3] = Numeric.arange(0,0.25,1./(4*256.),'f') name += "-VolRender Colormap" self.ColorMapGUI = ColorMapGUI(ramp=ramp,name=name ) self.ColorMapGUI.numOfRampValues.pack_forget() self.ColorMapGUI.addCallback( self.ColorMap_cb ) #self.colorMapB.configure(state='active') #for value in self.ColorMapGUI.buttonFrame.children.values(): # if not isinstance(value,Tkinter.Radiobutton): # value.grid_forget() self.ColorMapGUI.dismiss.configure(command = self.dismissCmap) self.ColorMapGUI.master.protocol('WM_DELETE_WINDOW', self.dismissCmap) def ColorMap_cb(self, colorMap): ramp = Numeric.array(colorMap.ramp) self.cmd.alpha_cb([0,(240.*ramp[:,3]).astype('string')]) self.cmd.vf.GUI.VIEWER.ReallyRedraw() self.cmd.color_cb([0,ramp[:,:3].astype(numpy.float)]) def setMin(self, text): try: hMin = float(text) except ValueError: self.minEntry.setentry(str(self.min_x)) return grid = self.cmd.grid bound = [hMin,self.cmd.grid.Vhist[1][-1]] datamap = {} datamap['src_min'] = hMin datamap['src_max'] = self.cmd.grid.Vhist[1][-1] datamap['dst_min'] = 0 datamap['dst_max'] = 255 datamap['map_type'] = 'linear' mapper = MapGridData() result = mapper(grid.data, datatype=Numeric.UInt8, datamap=datamap, powerOf2=True) gtype = ArrayTypeToGrid[result.dtype.char] if grid.crystal: from mglutil.math.crystal import Crystal crystal = Crystal( grid.crystal.length, grid.crystal.angles) else: crystal = None newgrid = gtype(result, grid.origin, grid.stepSize, grid.header.copy(), crystal) newgrid.dataDims = grid.data.shape[:] grid.volRenGrid = newgrid geom = UTVolRenGeom('VolRender') grid.geomContainer['VolRender'] = geom self.cmd.vf.GUI.VIEWER.AddObject(geom, parent=grid.master_geom) geom.AddGrid3D(newgrid) hist = numpy.histogram(self.cmd.grid.data.copy().flat, bins=self.lut_list[0].width+100, range=bound) self.cmd.grid.Vhist = hist self.data = hist self.plot_histogram() self.reset() self.cmd.vf.GUI.VIEWER.OneRedraw() def setMax(self, text): try: hMax = float(text) except ValueError: self.maxEntry.setentry(str(self.max_x)) return grid = self.cmd.grid bound = [self.cmd.grid.Vhist[1][0],hMax] datamap = {} datamap['src_min'] = self.cmd.grid.Vhist[1][0] datamap['src_max'] = hMax datamap['dst_min'] = 0 datamap['dst_max'] = 255 datamap['map_type'] = 'linear' mapper = MapGridData() result = mapper(grid.data.copy(), datatype=Numeric.UInt8, datamap=datamap, powerOf2=True) gtype = ArrayTypeToGrid[result.dtype.char] if grid.crystal: from mglutil.math.crystal import Crystal crystal = Crystal( grid.crystal.length, grid.crystal.angles) else: crystal = None newgrid = gtype(result, grid.origin, grid.stepSize, grid.header.copy(), crystal) newgrid.dataDims = grid.data.shape[:] grid.volRenGrid = newgrid geom = UTVolRenGeom('VolRender') grid.geomContainer['VolRender'] = geom self.cmd.vf.GUI.VIEWER.AddObject(geom, parent=grid.master_geom) geom.AddGrid3D(newgrid) hist = numpy.histogram(self.cmd.grid.data.copy().flat, bins=self.lut_list[0].width+100, range=bound) self.cmd.grid.Vhist = hist self.plot_histogram() self.reset() self.cmd.vf.GUI.VIEWER.OneRedraw() def plot_histogram(self, event=None): grid = self.cmd.grid if not hasattr(grid,'Vhist'): hist = numpy.histogram(grid.data.copy().flat, bins=self.lut_list[0].width+100) grid.Vhist = hist self.lut_list[0].min_x = grid.Vhist[1][0] self.lut_list[0].max_x = grid.Vhist[1][-1] self.maxEntry.setentry((self.labelsBarFormat)%grid.Vhist[1][-1]) self.minEntry.setentry((self.labelsBarFormat)%grid.Vhist[1][0]) self.lut_list[0].plot_histogram(data=grid.Vhist) def hideShow(self): geom = self.cmd.grid.master_geom.children[-1] if geom.visible: geom.Set(visible=False) self.cmd.vf.GUI.VIEWER.OneRedraw() self.menu.entryconfig("Hide",label="Show") else: geom.Set(visible=True) self.cmd.vf.GUI.VIEWER.OneRedraw() self.menu.entryconfig("Show",label="Hide") def onMouseOver(self, event): x = str(event.x) y = str(event.y) self.Label.configure(text = "( " + x + " , " + y + " )") def showColormap(self): self.colormapWin.deiconify() self.colormapWin.tkraise() #self.menu.entryconfigure(self.menu.index('Set color'), state='disabled') def closeRGB(self): self.colormapWin.withdraw() #self.menu.entryconfigure(self.menu.index('Set color'), state='normal') def entries_update(self, **values): pass def entry_color_set(self): pass def entry_value_set(self): pass def selected(self, event): """Activates selected canvas widget.""" curr_widget = event.widget if not isinstance(curr_widget,Tkinter.Frame): self.make_selected(curr_widget) self.menu.unpost() self.balloon.unbind(self.master) def button3(self, event): #the following 2 lines simulate right-click even which is needed for "Set Color" menu self.lut_list[0].canvas.event_generate('', x=event.x_root, y=event.y_root) self.lut_list[0].last_event = 'ButtonRelease-1' self.menu.post(event.x_root, event.y_root) if widgetsOnBackWindowsCanGrabFocus is False: lActiveWindow = self.menu.focus_get() if lActiveWindow is not None \ and ( lActiveWindow.winfo_toplevel() != self.menu.winfo_toplevel() ): return self.balloon.bind(self.lut_list[0].canvas,"Double-click on the line connecting dots to add a dot") self.menu.focus_set() def cancelManu(self, event=None): self.menu.unpost() def split_cb(self, entry_minval, entry_maxval, split=1): """Executing command of the 'Split Interval Dialog'. Determines new intervals of values. Destroys canvas widget representing the original interval. Calls a function creating canvas widgets for the new intervals.""" parent_interval = self.parent_interval try: ind = self.intervals_list.index(parent_interval) except ValueError: print 'ValueError: interval',parent_interval,'is not in self.intervals_list' return if entry_minval == parent_interval[0]: intervals = [(entry_minval, entry_maxval), (entry_maxval+1, parent_interval[1])] curr_interval = ind elif entry_maxval == parent_interval[1]: intervals = [(parent_interval[0], entry_minval-1), (entry_minval, entry_maxval)] curr_interval = ind+1 else: intervals = [(parent_interval[0], entry_minval-1), (entry_minval, entry_maxval), (entry_maxval+1, parent_interval[1])] curr_interval = ind+1 self.intervals_list.pop(ind) self.with_focus.canvas.configure(highlightbackground='gray') self.canvas_list[ind].destroy() self.canvas_list.pop(ind) old_lut = self.lut_list.pop(ind) #print "ind :", ind i = ind for interval in intervals: self.intervals_list.insert(i, interval) lut = myLUT(self.f1, xminval=interval[0], xmaxval=interval[1], ymaxval=self.ymaxval, grid_row=i+1, num_of_entries=self.xmaxval+1, initdraw = 0) lut.canvas.bind('', self.selected) lut.canvas.bind('', self.button3) self.lut_list.insert(i, lut) self.canvas_list.insert(i, lut.canvas) i = i + 1 lut.setCallbacks(self.lutcallbacks) lut.canvas.configure(highlightbackground='gray') no_intervals = len(self.intervals_list) if i < no_intervals: for n in range(i, no_intervals): self.canvas_list[n].grid(row=n, sticky=W) self.canvas_list[curr_interval].configure(highlightbackground='blue') self.with_focus = self.lut_list[curr_interval] i = 0 for interval in intervals: self.split_function(old_lut, interval, ind+i) i = i + 1 old_lut = None self.menu.entryconfigure("Merge Function", state='normal') self.master.update() reqHeight = self.master.winfo_reqheight() realHeight = self.master.winfo_height() if reqHeight > realHeight: root = self.master.winfo_toplevel() h = root.winfo_height() h += reqHeight - realHeight self.heightAdded += reqHeight - realHeight w = root.winfo_width() root.geometry('%dx%d' % (w,h)) def make_selected(self, curr_widget): if curr_widget == self.with_focus.canvas: return curr_widget.configure(highlightbackground='blue') self.with_focus.canvas.configure(highlightbackground='gray') ind = self.canvas_list.index(curr_widget) i = 0 for lut in self.lut_list: if i == ind: lut.bind_tags() else: lut.unbind_tags() i=i+1 self.with_focus = self.lut_list[ind] def merge_function(self): if len(self.intervals_list)<2: return interval = (self.xminval, self.xmaxval) #data ={'intervals':[interval,]} points = self.lut_list[0].points[1:-1] values = self.lut_list[0].values[1:-1] shapes = self.lut_list[0].shapes[1:-1] color_arr = self.lut_list[0].color_arr alpha_arr = self.lut_list[0].alpha_arr for lut in self.lut_list[1:]: points.extend(lut.points[1:-1]) alpha_arr = Numeric.concatenate((alpha_arr, lut.alpha_arr)) color_arr = Numeric.concatenate((color_arr, lut.color_arr)) old_shapes =lut.shapes[1:-1] old_vals = lut.values[1:-1] val1 = values[-1] val2 = old_vals[0] if alpha_arr[val1] == 0 and alpha_arr[val2] == 0: d = shapes[-1] for s in old_shapes: shapes.append(s+d) else: d = shapes[-1] shapes[-1] = d+old_shapes[1] if len(old_shapes) > 2: for s in old_shapes[2:]: shapes.append(s+d) values.extend(old_vals) shapes.insert(0,0) shapes.append(shapes[-1]+1) ######## for canvas in self.canvas_list: canvas.destroy() self.canvas_list = [] self.lut_list = [] self.intervals_list = [interval,] i=0 lut = myLUT(self.f1, xminval=interval[0], ymaxval=self.ymaxval, xmaxval=interval[1], grid_row=i, num_of_entries=self.xmaxval+1, initdraw = 0) lut.canvas.bind('', self.selected) lut.canvas.bind('', self.button3) self.lut_list.append(lut) self.canvas_list.append(lut.canvas) right = lut.right left = lut.left bott = lut.bott sclx = lut.sclx new_points = [(left, bott),] for i in range(len(points)): new_points.append(((values[i]-self.xminval)*sclx+left, points[i][1])) new_points.append((right, bott)) lut.points = new_points lut.shapes = shapes lut.color_arr = color_arr lut.alpha_arr = alpha_arr values.insert(0, self.xminval) values.append(self.xmaxval) lut.values = values lut.redraw() lut.setCallbacks(self.lutcallbacks) self.lut_list[0].canvas.configure(highlightbackground='blue') self.with_focus = self.lut_list[0] ####### self.menu.entryconfigure("Merge Function", state='disabled') root = self.master.winfo_toplevel() h = root.winfo_height() h -= self.heightAdded self.heightAdded = 0 w = root.winfo_width() root.geometry('%dx%d' % (w,h)) def load_file(self, file): from string import split, atoi of = open(file, 'r') line = split(of.readline()) warning = "Warning: wrong file format. Could not read file %s" %(file,) if len(line): if line[0] != "Transfer": of.close() if self.load_file_old(file): return else: print warning return else: of.close() print warning return ymaxval = 0 while(1): line = of.readline() line = split(line) if len(line): if line[0] == "End": break else: if line[0] == "NumIntervals": nintervals = atoi(line[1]) elif line[0] == "Intervals": intervals_str= line[1:] elif line[0] == "DataSizes": sizes_str = line[1:] elif line[0] == "Maxalpha": ymaxval = atoi(line[1]) intervals = [] sizes = [] for n in range(nintervals): intervals.append( (atoi(intervals_str[n*2]), atoi(intervals_str[n*2+1]) )) sizes.append( (atoi(sizes_str[n*3]), atoi(sizes_str[n*3+1]), atoi(sizes_str[n*3+2])) ) #print "nintervals: ", nintervals #print "intervals: ", intervals #print "sizes: ", sizes data = [] xmaxval = intervals[nintervals-1][1] if xmaxval != self.xmaxval: if self.viewer.hasGui: text = "WARNING: number of LUT entries in\n%s\n is %d,\n current number of LUT entries is %d.\nLoad new LUT?" %(file,xmaxval+1,self.xmaxval+1) dialog = Pmw.MessageDialog(self.master, buttons=('OK','Cancel'), defaultbutton='OK', title='Load New LUT', message_text=text) result=dialog.activate() if result=='Cancel': of.close() return else: self.xmaxval = xmaxval else: print "WARNING: number of LUT entries in %s is %d, current number of LUT entries is %d." % (file, xmaxval+1, self.xmaxval+1) shapes = [] values = [] alphas = [] colors = [] from struct import unpack, calcsize for n in range(nintervals): fmt_shapes = ">%di"%sizes[n][0] fmt_values = ">%di"%sizes[n][1] fmt_colors = ">%df"%sizes[n][2] l_shapes = of.read(calcsize(fmt_shapes)) #values and alphas have the same format l_values= of.read(calcsize(fmt_values)) l_alphas = of.read(calcsize(fmt_values)) l_colors = of.read(calcsize(fmt_colors)) shapes.append(list(unpack(fmt_shapes, l_shapes))) values.append(unpack(fmt_values, l_values)) alphas.append(unpack(fmt_values, l_alphas)) colors.append(unpack(fmt_colors, l_colors)) #print 'shapes:', shapes #print 'values: ', values #print 'alphas: ', alphas of.close() d = 1 if ymaxval: ## d = (ymaxval*1.0)/self.ymaxval self.ymaxval = ymaxval #print "ymaxval: ", ymaxval, "self.ymaxval: ", self.ymaxval self.xmaxval = xmaxval for canvas in self.canvas_list: canvas.destroy() self.canvas_list = [] self.lut_list = [] self.intervals_list = intervals i = 0 for interval in intervals: ## print 'in load_file: interval =', interval lut = myLUT(self.f1, xminval=interval[0], xmaxval=interval[1], ymaxval = self.ymaxval, grid_row=i, num_of_entries=xmaxval+1, initdraw = 0) lut.canvas.bind('', self.selected) lut.canvas.bind('', self.button3) self.lut_list.append(lut) self.canvas_list.append(lut.canvas) if d != 1 : lut.calculate_points(values[i], map(lambda x: x/d, alphas[i])) else: lut.calculate_points(values[i], alphas[i]) lut.shapes = shapes[i] colors_size = (len(colors[i])/3, 3) #print "colors_size: ", len(colors[i]), colors_size lut.color_arr = Numeric.reshape(Numeric.array(colors[i], 'f'), colors_size) lut.calculate_alphas() lut.redraw() lut.setCallbacks(self.lutcallbacks) lut.callbacks['setalpha']([interval[0], lut.alpha_arr]) lut.callbacks['setcolor']([interval[0], lut.color_arr]) i = i + 1 #self.lut_list[0].canvas.configure(highlightbackground='blue') self.with_focus = self.lut_list[0] if len(intervals)>1: self.menu.entryconfigure("Merge Function", state='normal') root = self.master.winfo_toplevel() h = len(intervals)*(height-50) + height + 50 w = root.winfo_width() root.geometry('%dx%d' % (w,h)) class LUT_data: "This class stores LUT data" intervals_list = None shapes = None values = None color_arr = None alpha_arr = None class VolRenCommand(Command): "Volume Rendering command with Trasnfer Function editor GUI" def __init__(self, func=None): Command.__init__(self) self.grid = None self.ifd = InputFormDescr(title="VolRen") self.ifd.append({'name':'VolRen', 'widgetType':myTF, 'wcfg':{'alphaCallback':self.alpha_cb, 'colorCallback':self.color_cb, }, 'gridcfg':{'row':0, 'column':0, 'sticky':'wens'} }) def color_cb(self, values): if self.grid: #print "col",values[0],values[1] self.grid.geomContainer['VolRender'].setVolRenColors(values) def alpha_cb(self, values): if self.grid: #print "alpha",values self.grid.geomContainer['VolRender'].setVolRenAlpha(values) def saveLUT_Dict(self): if not self.grid: return widget = self.ifd.entryByName['VolRen']['widget'] self.grid.LUT_data.intervals_list = widget.intervals_list lut = widget.lut_list[0] self.grid.LUT_data.shapes = lut.shapes self.grid.LUT_data.values = lut.values self.grid.LUT_data.color_arr = lut.color_arr.copy() self.grid.LUT_data.alpha_arr = lut.alpha_arr.copy() def onAddCmdToViewer(self): if not hasattr(self.vf, 'grids3D'): self.vf.grids3D={} self.ifd[0]['widgetType'].cmd = self def __call__(self, grid3D, **kw): return apply(self.doitWrapper, (grid3D,), kw) def doit(self, grid3D, name = None): if type(grid3D) in types.StringTypes: if self.vf.grids3D.has_key(grid3D): grid3D = self.vf.grids3D[grid3D] else: print "ERROR!!! "+ grid3D + "is not in the self.vf.grids3D" self.vf.GUI.VIEWER.OneRedraw() def select(self): grid_name = self.vf.Grid3DCommands.get_grid_name() if not grid_name: self.vf.Grid3DCommands.root.configure(cursor='') self.vf.Grid3DCommands.PanedWindow.config(cursor='') self.grid = None return grid = self.vf.grids3D[grid_name] widget = self.ifd.entryByName['VolRen']['widget'] widget.merge_function() if not hasattr(grid,'volRenGrid'): datamap = {} datamap['src_min'] = grid.mini datamap['src_max'] = grid.maxi datamap['dst_min'] = 0 datamap['dst_max'] = 255 datamap['map_type'] = 'linear' mapper = MapGridData() result = mapper(grid.data, datatype=Numeric.UInt8, datamap=datamap, powerOf2=True) gtype = ArrayTypeToGrid[result.dtype.char] if grid.crystal: from mglutil.math.crystal import Crystal crystal = Crystal(grid.crystal.length, grid.crystal.angles) else: crystal = None newgrid = gtype(result, grid.origin, grid.stepSize, grid.header.copy(), crystal) newgrid.dataDims = grid.data.shape[:] grid.volRenGrid = newgrid geom = UTVolRenGeom('VolRender') grid.geomContainer['VolRender'] = geom self.vf.GUI.VIEWER.AddObject(geom, parent=grid.master_geom) geom.AddGrid3D(newgrid) self.vf.GUI.VIEWER.OneRedraw() grid.LUT_data = LUT_data() self.grid = grid widget.lut_list[0].draw_initshape() widget.applylut_cb() else: self.saveLUT_Dict() widget.intervals_list = grid.LUT_data.intervals_list widget.lut_list[0].shapes = grid.LUT_data.shapes widget.lut_list[0].values = values = grid.LUT_data.values widget.lut_list[0].color_arr = grid.LUT_data.color_arr widget.lut_list[0].alpha_arr = grid.LUT_data.alpha_arr self.grid = grid alphas = Numeric.take(grid.LUT_data.alpha_arr,values) widget.lut_list[0].calculate_points(values,alphas) #widget.lut_list[0].calculate_alphas() widget.lut_list[0].redraw(redrawIsoVals=False) if not hasattr(grid,'Vhist'): bound = None #this is used to set the limits on the histogram if grid_name.endswith('.map'): if grid.mini < 0: bound = [grid.mini,-grid.mini] Vhist = numpy.histogram(grid.data.copy().flat, bins=widget.lut_list[0].width+100) grid.Vhist = Vhist #widget.lut_list[0].min_x = grid.hist.min #widget.lut_list[0].max_x = grid.hist.max widget.plot_histogram() self.vf.Grid3DCommands.root.configure(cursor='') self.vf.Grid3DCommands.PanedWindow.config(cursor='') commandList = [ {'name':'Grid3DReadAny','cmd':readAnyGrid(),'gui':readAnyGridGUI}, {'name':'Grid3DAddRemove','cmd':AddRemove(),'gui':AddRemoveGUI}, {'name':'Grid3DCommands','cmd':Grid3DCommands(),'gui':Grid3DGUI}, {'name':'addGrid','cmd':addGridCommand(),'gui':None}, {'name':'Grid3DIsocontour','cmd':IsocontourCommand(),'gui':None}, {'name':'Grid3DOrthoSlice','cmd':OrthoSliceCommand(),'gui':None}, {'name':'Grid3DVolRen','cmd':VolRenCommand(),'gui':None}, ] def initModule(viewer): for dict in commandList: viewer.addCommand(dict['cmd'],dict['name'],dict['gui']) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/handlerCommand.py0000644000175000017500000001706611432565443025443 0ustar moellermoellerfrom ViewerFramework.VFCommand import Command, CommandGUI from DejaVu.Spheres import Spheres from DejaVu.Arrows import Arrows from MolKit.molecule import Atom import numpy.oldnumeric as Numeric import math #from Pmv.moleculeViewer import EditAtomsEvent #from DejaVu.Transformable import translateEvent class Handler(Command): def create(self,target,geom=None,imd=None,forceType="steered"): self.target = target.findType(Atom) #should be an atom selection self.imd = imd if self.imd is not None : self.slot = self.imd.slot else : self.slot = 0 self.initial_position = self.getTargetCenter() self.previousForce = [0.,0.,0.] self.scale_force = 0.5 #scale before display and send to MD self.sphere_radius = 4. if geom is None : #by default the handler is a sphere self.geom = Spheres('handler', inheritMaterial=False, centers=[[0.,0.,0.],],radii=[2.], visible=1) if self.vf.hasGui : self.vf.GUI.VIEWER.AddObject(self.geom) else : self.geom = geom #if self.vf.hasGui : self.geom.SetTranslation(Numeric.array(self.initial_position)) #else : self.geom.setLocation(self.initial_position[0],self.initial_position[1],self.initial_position[2]) if self.vf.hasGui : self.prepareQuickKeys() self.N_forces = len(self.target) self.atoms_list = self.target.number #need to check this self.forces_list = Numeric.zeros((self.N_forces,3),'f') self.arrow = None self.isinited = True self.handler_pattern = None self.mol_pattern = None #preaper the arrow that will represent the force if self.vf.hasGui : self.prepareArrow() self.forceType = forceType #self.vf.registerListener(translateEvent, self.getForces) #self.vf.GUI.VIEWER.registerListener(translateEvent, self.getForces) def getTargetCenter(self): self.target.setConformation(self.slot) coords = Numeric.array(self.target.coords)#self.allAtoms.coords center = sum(coords)/(len(coords)*1.0) center = list(center) for i in range(3): center[i] = round(center[i], 4) self.target.setConformation(0) self.N_forces = len(coords) return center def prepareArrow(self): force = Numeric.array(self.forces_list) self.target.setConformation(1) point = Numeric.array(self.target.coords) self.target.setConformation(0) vertices=[] faces =[] indice=0 for i in range(self.N_forces): vertices.append(point[i]) vertices.append(point[i]+force[i]) faces.append([indice,indice+1]) indice = indice+2 vertices = Numeric.array(vertices,'f').tolist() self.arrow = Arrows('pyarrow', vertices = vertices,faces=faces) self.vf.GUI.VIEWER.AddObject(self.arrow) def updateArrow(self): if self.forceType != "move": force = Numeric.array(self.forces_list) self.target.setConformation(1) point = Numeric.array(self.target.coords) self.target.setConformation(0) vertices=[] faces =[] indice=0 for i in range(self.N_forces): vertices.append(point[i]) vertices.append(point[i]+force[i]) faces.append([indice,indice+1]) indice = indice+2 vertices = Numeric.array(vertices,'f').tolist() self.arrow.Set(vertices = vertices,faces=faces) def prepareQuickKeys(self): import Tkinter from mglutil.util.callback import CallBackFunction #prepare the QuickKeys one for the root, one for the handler self.vf.GUI.VIEWER.GUI.showHideQuickKeysVar.set(1) xform = 'Object' root=self.vf.GUI.VIEWER.rootObject cbroot = CallBackFunction( self.vf.GUI.VIEWER.GUI.quickKey_cb, xform, root, 1 ) cbhandler = CallBackFunction( self.vf.GUI.VIEWER.GUI.quickKey_cb, xform, self.geom, 0 ) label = "Xform Scene" labelHandler = "Xform Handler" # create a button and add it to the Quick Keys panel button = Tkinter.Button(self.vf.GUI.VIEWER.GUI.QuickKeysFrame, text=label, command=cbroot) button.pack(side='top', expand=1, fill='y') # create a button and add it to the Quick Keys panel button = Tkinter.Button(self.vf.GUI.VIEWER.GUI.QuickKeysFrame, text=labelHandler, command=cbhandler) button.pack(side='top', expand=1, fill='y') def getHandlerPos(self): if self.vf.hasGui : if hasattr(self.vf,"art"): from numpy import matrix #the inverse matrix for molecule pattern m1 = self.mol_pattern.mat_transfo M1 = matrix(m1.reshape(4,4)) #get the pattern transfor m2 = self.handler_pattern.mat_transfo M2 = matrix(m2.reshape(4,4)) transfo = M2*M1.I pos = Numeric.array(transfo[3,:3]) else : pos = self.geom.translation else : pos = self.geom.getLocation() return pos def findNeighbor(self,pos): #loop or pmvcommands self.vf.selectInSphere(pos, self.sphere_radius, [self.imd.mol.name], log=0) node=self.vf.selection if node != None : self.target = node.findType(Atom) self.N_forces = len(self.target) self.atoms_list = self.target.number #need to check this self.forces_list = Numeric.zeros((self.N_forces,3),'f') return Numeric.array(self.getTargetCenter()) else : return None def getPush(self,target=True): pos = self.getHandlerPos() if target : targetpos = Numeric.array(self.getTargetCenter()) else : targetpos = self.findNeighbor(pos[0].tolist()) if targetpos == None : return Numeric.array([0.,0.,0.]) force = - Numeric.array(pos[0]) + targetpos d=math.sqrt(Numeric.sum(force*force)) return force*1/(d*d) #else : return Numeric.array([0.,0.,0.]) def getSteered(self): pos = self.getHandlerPos() force = Numeric.array(pos) - Numeric.array(self.getTargetCenter()) #d=math.sqrt(Numeric.sum(force[0]*force[0])) #if d > 30. : return Numeric.zeros(3) #else : return force def getCoord(self): pos = self.getHandlerPos() mol = self.target.top mol.allAtoms.setConformation(self.slot) coords = mol.allAtoms.coords[:] mol.allAtoms.setConformation(0) force = Numeric.array(coords) + (Numeric.array(pos) - Numeric.array(self.getTargetCenter()))#Numeric.array([1.0,0.,0.]) self.N_forces = len(coords) return force def getForces(self,event): if event == None : obj=self.geom else : obj = event.objects if obj != self.geom : return 0 if self.forceType == "steered": force = self.getSteered() elif self.forceType == "pushtarget": force = self.getPush(target=True) elif self.forceType == "push": force = self.getPush(target=False) elif self.forceType == "move": force = self.getCoord() if self.forceType != "move": for i in range(self.N_forces): self.forces_list[i] = force*self.scale_force else : self.forces_list = force self.previousForce = force commandList = [ {'name':'handler', 'cmd':Handler(), 'gui': None}, ] def initModule(viewer): for dict in commandList: # print 'dict',dict viewer.addCommand(dict['cmd'], dict['name'], dict['gui']) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/helpCommands.py0000644000175000017500000013764511451152074025140 0ustar moellermoeller############################################################################# # # Author: Michel F. SANNER # # Copyright: M. Sanner TSRI 2000 # ############################################################################# """ Module implementing classes to provide documentation on the application """ # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/helpCommands.py,v 1.19 2010/09/30 18:17:32 sargis Exp $ # # $Id: helpCommands.py,v 1.19 2010/09/30 18:17:32 sargis Exp $ # from ViewerFramework.basicCommand import loadCommandCommand import Tkinter, Pmw, tkFileDialog ## from ViewerFramework.gui import InputFormDescr from mglutil.gui.InputForm.Tk.gui import InputFormDescr from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ListChooser, \ kbScrolledListBox from ViewerFramework.VFCommand import Command,CommandGUI from mglutil.util.packageFilePath import findFilePath, findAllPackages, \ findModulesInPackage import os from string import join global commandslist import webbrowser # This should open a particular web page. class CitationCommand(Command): """Command that shows citation information \nPackage : Pmv \nModule : helpCommands \nClass : CitationCommand """ def onAddCmdToViewer(self): self.citations = {'Pmv':""" Please acknowledge the use of the PMV software that results in any published work, including scientific papers, films and videotapes, by citing the following reference: Michel F. Sanner. Python: A Programming Language for Software Integration and Development. J. Mol. Graphics Mod., 1999, Vol 17, February. pp57-61 """, 'ADT':""" Please acknowledge the use of the ADT software that results in any published work, including scientific papers, films and videotapes, by citing the following reference: Michel F. Sanner. Python: A Programming Language for Software Integration and Development. J. Mol. Graphics Mod., 1999, Vol 17, February. pp57-61 """, 'msms':""" The MSMS library is used by the Pmv module msmsCommands. Please acknowledge the use of the MSMS library that results in any published work, including scientific papers, films and videotapes, by citing the following reference: Sanner, M.F., Spehner, J.-C., and Olson, A.J. (1996) Reduced surface: an efficient way to compute molecular surfaces. Biopolymers, Vol. 38, (3),305-320. """, 'isocontour':""" The isocontour library is used by the Pmv module .... Please acknowledge the use of the isocontour library that results in any published work, including scientific papers, films and videotapes, by citing the following reference: Bajaj, C, Pascucci, V., Schikore, D., (1996), Fast IsoContouring for Improved Interactivity, Proceedings of ACM Siggraph/IEEE Symposium on Volume Visualization, ACM Press, 1996, pages 39 - 46, San Francisco, CA """, 'Vision':""" Please acknowledge the use of the Vision software that results in any published work, including scientific papers, films and videotapes, by citing the following reference: Michel F. Sanner, Daniel Stoffler and Arthur J. Olson. ViPEr a Visual Programming Environment for Python. 10th International Python Conference, February 2002. """, 'PCVolRen':""" The PCVolRen library is used in the PMV module .... Please acknowledge the use of the FAST VOLUME RENDERING library that results in any published work, including scientific papers, films and videotapes, by citing the following reference: Bajaj, C, Park, S., Thane, A., (2002), A Parallel Multi-PC Volume Rendering System, ICES and CS Technical Report, University of Texas, 2002. """, 'APBS':""" APBS is used in the Pmv Module.... Please acknowledge the use of APBS that results in any published work, including scientific papers,films and videotapes, by citing the following reference: Baker NA, Sept D, Joseph S, Holst MJ, McCammon JA. Electrostatics of nanosystems: application to microtubules and the ribosome. /Proc. Natl. Acad. Sci. USA/ *98*, 10037-10041 2001 """, 'stride':""" stride is used in Pmv Module...... Please acknowledge the use of stride that results in any published work, including scientific papers,films and videotapes, by citing the following reference: Frishman,D & Argos,P. (1995) Knowledge-based secondary structure assignment. Proteins: structure, function and genetics, 23, 566-579.""", 'PROSS':""" PROSS is used in Pmv for Secondary Structure prediction. Please acknowledge the use of PROSS that results in any published work, including scientific papers,films and videotapes, by citing the following reference: Srinivasan R, Rose GD. (1999) A physical basis for protein secondary structure. Proc. Natl. Acad. Sci. USA 96, 14258-63. """ } def buildFormDescr(self, formName): if formName=='chooseCitation': idf = InputFormDescr(title="Choose Package") pname = self.citations.keys() #pname.sort() idf.append({'name':'packList', 'widgetType':Pmw.ScrolledListBox, 'wcfg':{'items':pname, 'listbox_exportselection':0, 'labelpos':'nw','usehullsize': 1, 'hull_width':100,'hull_height':150, 'listbox_height':5, 'listbox_width':150, 'label_text':'Select a package:', 'selectioncommand':self.displayCitation_cb, }, 'gridcfg':{'sticky':'wesn'}}) idf.append({'name':'citation', 'widgetType':Pmw.ScrolledText, 'wcfg':{'labelpos':'nw', 'text_width':60, 'text_height':10}, 'gridcfg':{'sticky':'wens'} }) idf.append({'name':'dismiss', 'widgetType':Tkinter.Button, 'wcfg':{'text':'DISMISS','command':self.dismiss_cb, }, 'gridcfg':{'sticky':'wens'}}) return idf def dismiss_cb(self): if self.cmdForms.has_key('chooseCitation'): self.cmdForms['chooseCitation'].withdraw() def displayCitation_cb(self, event=None): ebn = self.cmdForms['chooseCitation'].descr.entryByName packW = ebn['packList']['widget'] packs = packW.getcurselection() # Nothing selected if len(packs) == 0: return packName = packs[0] if not self.citations.has_key(packName): return citation = self.citations[packName] citWidget = ebn['citation']['widget'] citWidget.setvalue(citation) def guiCallback(self): form = self.showForm('chooseCitation', modal=0,blocking=0) citationCommandGUI = CommandGUI() citationCommandGUI.addMenuCommand('menuRoot', 'Help', 'Citation Information') class CiteThisSceneCommand(Command): """Command that helps to cite references used in a given scene \nPackage : Pmv \nModule : helpCommands \nClass : CiteThisSceneCommand """ def buildFormDescr(self, formName): if formName=='citationHelp': idf = InputFormDescr(title="Choose Package") citeKeys = self.vf.showCitation.citations.keys() txt = """ This widget helps you cite the use of appropriate packages in your publication. Based on the information we collected, please cite the following publications: """ idf.append({'name':'help', 'widgetType':Tkinter.Label, 'wcfg':{'text':txt, 'justify':Tkinter.LEFT }, 'gridcfg':{'sticky':'wens', 'columnspan':2}}) txt = """ADT/PMV/ViewerFramework: Michel F. Sanner. Python: A Programming Language for Software Integration and Development. J. Mol. Graphics Mod., 1999, Vol 17, February. pp57-61 """ #this is the part where we find out which packages are used MSMS = False isocontour = False volRen = False APBS = False PROSS = False if hasattr(self.vf, 'Mols'): for mol in self.vf.Mols: if 'secondarystructure' in mol.geomContainer.geoms.keys(): PROSS = True if 'MSMS-MOL' in mol.geomContainer.geoms.keys(): MSMS = True for gridName in self.vf.grids3D: if '.potential.dx' in gridName: APBS = True grid = self.vf.grids3D[gridName] if hasattr(grid, 'isoBarNumber') and grid.isoBarNumber > 0: isocontour = True if hasattr(grid, 'volRenGrid'): volRen = True if MSMS: txt += """ MSMS: Sanner, M.F., Spehner, J.-C., and Olson, A.J. (1996) Reduced surface: an efficient way to compute molecular surfaces. Biopolymers, Vol. 38, (3),305-320. """ if APBS: txt += """ APBS: Baker NA, Sept D, Joseph S, Holst MJ, McCammon JA. Electrostatics of nanosystems: application to microtubules and the ribosome. /Proc. Natl. Acad. Sci. USA/ *98*, 10037-10041 2001 """ if isocontour: txt += """ IsoContour: Bajaj, C, Pascucci, V., Schikore, D., (1996), Fast IsoContouring for Improved Interactivity, Proceedings of ACM Siggraph/IEEE Symposium on Volume Visualization, ACM Press, 1996, pages 39 - 46, San Francisco, CA """ if volRen: txt += """ Volume Rendering: Bajaj, C, Park, S., Thane, A., (2002), A Parallel Multi-PC Volume Rendering System, ICES and CS Technical Report, University of Texas, 2002. """ if PROSS: txt += """ Secondary Structure: Srinivasan R, Rose GD. (1999) A physical basis for protein secondary structure. Proc. Natl. Acad. Sci. USA 96, 14258-63. """ idf.append({'name':'citation', 'widgetType':Pmw.ScrolledText, 'defaultValue':txt, 'gridcfg':{'sticky':'wens', 'columnspan':2} }) idf.append({'name':'save', 'widgetType':Tkinter.Button, 'wcfg':{'text':'Save As','command':self.save, }, 'gridcfg':{'sticky':'we', 'row':2, 'column':0}}) idf.append({'name':'dismiss', 'widgetType':Tkinter.Button, 'wcfg':{'text':'DISMISS','command':self.dismiss_cb, }, 'gridcfg':{'sticky':'we', 'row':2, 'column':1}}) return idf def save(self): file = tkFileDialog.asksaveasfilename(parent=self.cmdForms['citationHelp'].f, filetypes=[('Text files', '.txt'), ('BibTeX files', '.bib'), ], initialfile="cite.txt", title="Save file") if file: if file.endswith('.bib'): MSMS = False isocontour = False volRen = False APBS = False PROSS = False if hasattr(self.vf, 'Mols'): for mol in self.vf.Mols: if 'secondarystructure' in mol.geomContainer.geoms.keys(): PROSS = True if 'MSMS-MOL' in mol.geomContainer.geoms.keys(): MSMS = True if 'CoarseMolSurface' in mol.geomContainer.geoms.keys(): isocontour = True for gridName in self.vf.grids3D: if '.potential.dx' in gridName: APBS = True grid = self.vf.grids3D[gridName] if hasattr(grid, 'isoBarNumber') and grid.isoBarNumber > 0: isocontour = True if hasattr(grid, 'volRenGrid'): volRen = True txt = """ @article{mgltools, author = {Sanner MF}, title = {Python: A Programming Language for Software Integration and Development}, journal = {J. Mol. Graphics Mod.}, year = {1999}, volume = {17}, pages = {57-61} } """ if MSMS: txt += """ @article{msms, author = {Sanner MF, Olson AJ, Spehner JC}, title = {Reduced surface: an efficient way to compute molecular surfaces}, journal = {Biopolymers}, year = {1996}, volume = {38}, pages = {305-320} """ if APBS: txt += """ @article{apbs, author = {Baker NA, Sept D, Joseph S, Holst MJ, McCammon JA}, title = {Electrostatics of nanosystems: application to microtubules and the ribosome}, journal = {Proc. Natl. Acad. Sci. USA}, year = {2001}, volume = {98}, pages = {10037-10041} """ if isocontour: txt += """ @proceedings{isocontour, author = {Bajaj C, Pascucci V, Schikore D}, title = {Fast IsoContouring for Improved Interactivity}, booktitle = {Proceedings of ACM Siggraph/IEEE Symposium on Volume Visualization}, publisher = {ACM Press}, year = {1996}, pages = {39-46} """ if volRen: txt += """ @techreport{volren, author = {Bajaj C, Park S, Thane A}, title = {A Parallel Multi-PC Volume Rendering System}, institution = {CS & ICES Technical Report, University of Texas}, year = {2002} """ if PROSS: txt += """ @article{pross, author = {Srinivasan R, Rose GD}, title = {A physical basis for protein secondary structure}, journal = {Proc. Natl. Acad. Sci. USA}, year = {1999}, volume = {96}, pages = {14258-14263} """ open(file,'w').write(txt) else: txt = self.cmdForms['citationHelp'].descr.entryByName['citation']['widget'].getvalue() open(file,'w').write(txt) def dismiss_cb(self): if self.cmdForms.has_key('citationHelp'): self.cmdForms['citationHelp'].destroy() def guiCallback(self): form = self.showForm('citationHelp', okcancel=False, help=False, force=1) CiteThisSceneCommandGUI = CommandGUI() CiteThisSceneCommandGUI.addMenuCommand('menuRoot', 'Help', 'Cite This Scene') class mailingListsCommand(Command): """Command to show mailing lists of Pmv and Vision. \nPackage : Pmv \nModule : helpCommands \nClass : mailingListsCommand \nCommand : mailingListsCommand \nSynopsis:\n None <--- mailingListsCommand(module, commands=None, package=None, **kw) \nRequired Arguements\n: module --- name of the module (filename) \nOptional Arguements:\n commands --- list of cammnds in that module \nPackage --- package name to which module belongs """ def __init__(self, func=None): Command.__init__(self, func) def doit(self, pack, page): if page == None or pack == None: return if pack == "Pmv": if page == "Login Page": webbrowser.open_new('http://mgldev.scripps.edu/mailman/listinfo/pmv') if page == "Archive Page": webbrowser.open_new('http://mgldev.scripps.edu/pipermail/pmv') if pack == "Vision": if page == "Login Page": webbrowser.open_new('http://mgldev.scripps.edu/mailman/listinfo/vision') if page == "Archive Page": webbrowser.open_new('http://mgldev.scripps.edu/pipermail/vision') def __call__(self,pack,page): """None <--- mailingListsCommand(pack,page) \nRequired Arguements\n: pack --- name of the package(Pmv, or Vision) \npage ---name of the page(Login or Archive) """ if page == None: return if type(page) or type(pack) is not StringType: return "ERROR: pack or page are string type" if page not in ["Login Page", "Archive Page"]: return "ERROR: Invalid page name" if pack not in ["Pmv","Vision"]: return "ERROR: Invalid pack name" apply(self.doitWrapper,(pack,page,),{}) def buildFormDescr(self, formName): if not formName == 'Show MailingLists': return idf = InputFormDescr(title='Show MailingLists') self.mailinglists_pages=["Login Page","Archive Page"] idf.append({'name':'pmvlist', 'widgetType':kbScrolledListBox, 'wcfg':{'items':self.mailinglists_pages, 'listbox_exportselection':0, 'labelpos':'nw', 'label_text':'Pmv Mailing List', 'selectioncommand':self.mailCmds_cb, 'listbox_height':3 , #'hscrollmode':'dynamic', }, 'gridcfg':{'sticky':'wesn','columnspan':1}}) idf.append({'name':'visionlist', 'widgetType':kbScrolledListBox, 'wcfg':{'items':self.mailinglists_pages, 'listbox_exportselection':0, 'labelpos':'nw', 'label_text':'Vision Mailing List', 'selectioncommand':self.mailCmds_cb, 'listbox_height':3, #'hscrollmode':'dynamic', }, 'gridcfg':{'sticky':'wesn','columnspan':1}}) idf.append({'name':'dismiss', 'widgetType':Tkinter.Button, 'wcfg':{'text':'DISMISS', 'command':self.dismiss_cb, }, 'gridcfg':{'sticky':'ew','columnspan':3}}) return idf def guiCallback(self): val = self.showForm('Show MailingLists',force = 1,modal =0,blocking = 0) ebn = val.descr.entryByName def dismiss_cb(self, event=None): self.cmdForms['Show MailingLists'].withdraw() def mailCmds_cb(self): ebn = self.cmdForms['Show MailingLists'].descr.entryByName c = self.cmdForms['Show MailingLists'].mf.cget('cursor') cmdW1 = ebn['pmvlist']['widget'] cmdW2 = ebn['visionlist']['widget'] CmdName1 = cmdW1.getcurselection() cmdW1.select_clear(0,last=1) CmdName2 = cmdW2.getcurselection() cmdW2.select_clear(0,last=1) if len(CmdName1) != 0: if CmdName1[0] == 'Login Page': page = "Login Page" pack ="Pmv" apply( self.doitWrapper,(pack, page,),{}) if CmdName1[0] == 'Archive Page': page = "Archive Page" pack ="Pmv" apply( self.doitWrapper,(pack, page,),{}) CmdName1 =() if len(CmdName2) != 0: if CmdName2[0] == 'Login Page': page = "Login Page" pack = "Vision" apply( self.doitWrapper,(pack, page,),{}) if CmdName2[0] == 'Archive Page': page = "Archive Page" pack = "Vision" apply( self.doitWrapper,(pack, page,),{}) CmdName2 =() mailingListsCommandGUI = CommandGUI() mailingListsCommandGUI.addMenuCommand('menuRoot', 'Help', 'MailingList') class helpCommand(Command): """Command to show dynamically either modules or individual commands in the viewer. \nPackage : Pmv \nModule : helpCommands \nClass : helpCommand \nCommand : helpCommand \nSynopsis:\n None <--- helpCommand(module, commands=None, package=None, **kw) \nRequired Arguements\n: module --- name of the module (filename) \nOptional Arguements:\n commands --- list of cammnds in that module \nPackage --- package name to which module belongs """ def __init__(self, func=None): Command.__init__(self, func) self.var=0 self.allPack = {} self.packMod = {} self.allPackFlag = False def doit(self, module, commands=None, package=None): # If the package is not specified the default is the first library if package is None: package = self.vf.libraries[0] d=[] importName = package + '.' + module try: mod = __import__(importName, globals(), locals(), [module]) except: self.vf.warningMsg("ERROR: Could not show module %s"%module) #traceback.print_exc() return 'ERROR' if commands is None: if hasattr(mod,"initModule"): mod.initModule(self.vf) else: self.vf.warningMsg("ERROR: Could not show module %s"%module) return "ERROR" else: if not type(commands) in [types.ListType, types.TupleType]: commands = [commands,] if not hasattr(mod, 'commandList'): return for cmd in commands: d = filter(lambda x: x['name'] == cmd, mod.commandList) if len(d) == 0: self.vf.warningMsg("Command %s not found in module %s.%s"% (cmd, package, module)) continue d = d[0] self.vf.addCommand(d['cmd'], d['name'], d['gui']) def __call__(self, module, commands=None, package=None, **kw): """None <--- helpCommand(module, commands=None, package=None, **kw) \nRequired Arguements\n: module --- name of the module (filename) \nOptional Arguements:\n commands --- list of cammnds in that module \nPackage --- package name to which module belongs """ kw['commands'] = commands kw['package'] = package apply(self.doitWrapper, (module,), kw ) def buildFormDescr(self, formName): if not formName == 'showCmds': return idf = InputFormDescr(title='Show Commands and Documentation') from ViewerFramework.basicCommand import commandslist cname = commandslist cname.sort() idf.append({'name':'cmdList', 'widgetType':kbScrolledListBox, 'wcfg':{'items':cname, 'listbox_exportselection':0, 'labelpos':'nw', 'label_text':'Loaded commands:', 'selectioncommand':self.displayCmds_cb, }, 'gridcfg':{'sticky':'wesn','columnspan':1, 'weight':20}}) idf.append({'name':'doclist', 'widgetType':kbScrolledListBox, 'wcfg':{'items':[], 'listbox_exportselection':0, #'listbox_selectmode':'extended', 'labelpos':'nw', 'labelmargin':0, 'label_text':'DOCUMENTATION', 'listbox_width':30 }, 'gridcfg':{'sticky':'wesn','row':-1,'columnspan':1, 'weight':20}}) idf.append({'name':'dismiss', 'widgetType':Tkinter.Button, 'wcfg':{'text':'DISMISS', 'command':self.dismiss_cb, }, 'gridcfg':{'sticky':'ew','columnspan':3}}) return idf def guiCallback(self): if self.allPack == {}: self.allPack = findAllPackages() val = self.showForm('showCmds', force=1,modal=0,blocking=0) def dismiss_cb(self, event=None): self.cmdForms['showCmds'].withdraw() def displayCmds_cb(self, event=None): """This function """ packname=0 cmdnames=[] c = self.cmdForms['showCmds'].mf.cget('cursor') self.cmdForms['showCmds'].mf.update_idletasks() ebn = self.cmdForms['showCmds'].descr.entryByName cmdW = ebn['cmdList']['widget'] from ViewerFramework.basicCommand import cmd_docslist CmdName=cmdW.getcurselection() if len(CmdName)!=0: name= CmdName[0] #finding documentation for command from cmd_docslist imported from #basicCommand if name in cmd_docslist.keys(): docstring = cmd_docslist[name] cmdW.selection_clear() d =[] import string if docstring!=None: if '\n' in docstring: x = string.split(docstring,"\n") for i in x: if i !='': d.append(i) else: d.append(docstring) docw = ebn['doclist']['widget'] docw.clear() docw.setlist(d) helpCommandGUI = CommandGUI() helpCommandGUI.addMenuCommand('menuRoot', 'Help', 'Commands Documentation') class SearchCommand(Command): """Command to allow the user to search for commands using a given 'search string'. This search string can be matched against either the modules name, the commands name and or the command's documentation string.This will be done to either the default packages or all the packages found on the disk.The user will then be able to show the documentation on the command and load the commands in the application. \nPackage : Pmv \nModule : helpCommands \nClass : SearchCommand \nCommand : searchFor \nSynopsis:\n cmdsFound <- self.searchFor(self, searchString, matchCmdName=True, matchModName=True, matchDocString=True, caseSensitive=True, allPack=False, **kw) \ncmdsFound --- list of string describing the command matching the search string. The format is either Package.module.command or package.module \nRequired Arguements:\n searchString --- string that will be used to search for the commands. \nOptional Arguements:\n matchCmdName --- Boolean to specify whether or not to match the search string agains the command name. \nmatchModName --- Boolean to specify whether or not to match the search string agains the name of the modules. \nmatchDocString --- Boolean to specify whether or not to match the search string agains the documentation string of the command. \ncaseSensitive --- Boolean to specify whether or not the search should be case sensitive. \nallPack --- Boolean to specify whether or not the search should be done in the default packages contained in self.vf.libraries or in all packages on the disk. """ def __init__(self, func=None): Command.__init__(self, func) self.allPack = findAllPackages() self.packModCmd = {} def buildInformation(self, packName, package ): if not self.packModCmd.has_key(packName): modules = findModulesInPackage(package,"def initModule") if modules.values(): modNames = map(lambda x: os.path.splitext(x)[0], modules.values()[0]) else: modNames = {} self.packModCmd[packName]={} packDict = self.packModCmd[packName] for modName in modNames: importName = packName + '.' + modName try: m = __import__(importName, globals(), locals(), ['commandList']) if not hasattr(m, 'commandList'): packDict[modName]={} else: packDict[modName]={} keys = map(lambda x: x['name'], m.commandList) values = map(lambda x: x['cmd'].__doc__, m.commandList) for k, v in map(None, keys, values): packDict[modName][k] = v except: continue def guiCallback(self): form = self.showForm('searchForm', modal=0, blocking=0) def __call__(self, searchString, matchCmdName=True, matchModName=True, matchDocString=True, caseSensitive=True, allPack=False, **kw ): """cmdsFound <- self.searchFor(self, searchString, matchCmdName=True, matchModName=True, matchDocString=True, caseSensitive=True, allPack=False, **kw) \ncmdsFound --- list of string describing the command matching the search string. The format is either Package.module.command or package.module \nsearchString --- string that will be used to search for the commands. \nmatchCmdName --- Boolean to specify whether or not to match the search string agains the command name. \nmatchModName --- Boolean to specify whether or not to match the search string agains the name of the modules. \nmatchDocString --- Boolean to specify whether or not to match the search string agains the documentation string of the command. \ncaseSensitive --- Boolean to specify whether or not the search should be case sensitive. \nallPack --- Boolean to specify whether or not the search should be done in the default packages contained in self.vf.libraries or in all packages on the disk. """ kw['matchCmdName']=matchCmdName kw['matchDocString']=matchDocString kw['caseSensitive']=caseSensitive kw['allPack']=allPack results = apply(self.doitWrapper, (searchString,), kw) return results def doit(self, searchString, matchCmdName=True, matchModName=True, matchDocString=True, caseSensitive=True, allPack=False): if not caseSensitive: searchString = searchString.lower() import re pat = re.compile(searchString) if not allPack: # only look in the default package packages = self.vf.libraries else: packages = self.allPack # populate the packModCmd cmdsFound = [] for pName in packages: if not self.packModCmd.has_key(pName): self.buildInformation(pName, self.allPack[pName]) # look for the search string at the right place. modCmd = self.packModCmd[pName] for modName, cmds in modCmd.items(): # match command Name foundMod = False if matchModName: if not caseSensitive: mName = modName.lower() else: mName = modName res = pat.search(mName) if res: cmdsFound.append("%s.%s"%(pName, modName)) foundMod = True if foundMod or \ (not matchCmdName and not matchDocString): continue for cmd, descr in cmds.items(): if matchCmdName: if not caseSensitive: cmdName = cmd.lower() else: cmdName=cmd res = pat.search(cmdName) if res: cmdsFound.append('%s.%s.%s'%(pName,modName,cmd)) continue if matchDocString and descr: if not caseSensitive: cmdDescr = descr.lower() else: cmdDescr = descr res = pat.search(cmdDescr) if res: cmdsFound.append('%s.%s.%s'%(pName,modName,cmd)) if cmdsFound: ebn = self.cmdForms['searchForm'].descr.entryByName ebn['cmdFound']['widget'].setlist(cmdsFound) return cmdsFound def buildFormDescr(self, formName): if formName == 'infoForm': idf = InputFormDescr(title='Command Description') idf = InputFormDescr('Documentation') idf.append({'name':'cmdDoc', 'widgetType':Pmw.ScrolledText, 'wcfg':{ 'labelpos':'nw', 'label_text':'command documentation:', 'text_width':50, 'text_height':5}, 'gridcfg':{'sticky':'we'}}) idf.append({'widgetType':Tkinter.Button, 'wcfg':{'text':'Dismiss', 'command':self.dismissDoc_cb}, 'gridcfg':{'sticky':'we'}}) return idf elif formName == 'searchForm': idf = InputFormDescr(title='Search For Commands') idf.append({'name':'searchGroup', 'widgetType':Pmw.Group, 'container':{'searchGroup':"w.interior()"}, 'wcfg':{'tag_text':'Search Options'}, 'gridcfg':{'sticky':'wnse', 'columnspan':2}}) idf.append({'name':'searchString', 'widgetType':Pmw.EntryField, 'parent':'searchGroup', 'wcfg':{'label_text':'Search String', 'labelpos':'w', }, 'gridcfg':{'sticky':'wnse', 'columnspan':2}}) idf.append({'name':'caseSensitive', 'widgetType':Tkinter.Checkbutton, 'parent':'searchGroup', 'wcfg':{'text':'Case sensitive', 'variable':Tkinter.IntVar(),}, 'gridcfg':{'sticky':'w'}, }) idf.append({'name':'matchGroup', 'widgetType':Pmw.Group, 'parent':'searchGroup', 'container':{'matchGroup':"w.interior()"}, 'wcfg':{'tag_text':'Match search string to'}, 'gridcfg':{'sticky':'wnse', 'columnspan':2}}) idf.append({'name':'matchModName', 'widgetType':Tkinter.Checkbutton, 'parent':'matchGroup', 'defaultValue':1, 'tooltip':"The Search String will be matched against the modules name", 'wcfg':{'text':'Module Name', 'variable':Tkinter.IntVar()}, 'gridcfg':{'sticky':'w'}, }) idf.append({'name':'matchCmdName', 'widgetType':Tkinter.Checkbutton, 'parent':'matchGroup', 'defaultValue':1, 'tooltip':"The Search String will be matched against the commands name", 'wcfg':{'text':'Command Name', 'variable':Tkinter.IntVar()}, 'gridcfg':{'sticky':'w'}, }) idf.append({'name':'matchDocString', 'widgetType':Tkinter.Checkbutton, 'parent':'matchGroup', 'defaultValue':1, 'tooltip':"The Search String will be matched against the content of the documentation string", 'wcfg':{'text':'Documentation String', 'variable':Tkinter.IntVar()}, 'gridcfg':{'sticky':'w'}, }) idf.append({'name':'choices', 'widgetType':Pmw.RadioSelect, 'parent':'searchGroup', 'defaultValue':'Default Packages', 'listtext':['Default Packages', 'All Packages'], 'tooltip':"Choose where to look for a command: \n- Default packages \n-All packages on disk which is slower", 'wcfg':{'labelpos':'nw', 'label_text':'Search in:', 'buttontype':'radiobutton'}, 'gridcfg':{'sticky':'w'}}) idf.append({'name':'search', 'widgetType':Tkinter.Button, 'wcfg':{'text':'SEARCH', 'command':self.searchCmd_cb}, 'gridcfg':{'columnspan':2}}) idf.append({'name':'resultGroup', 'widgetType':Pmw.Group, 'container':{'resultGroup':"w.interior()"}, 'wcfg':{'tag_text':'Search Result'}, 'gridcfg':{'sticky':'wnse', 'columnspan':2}}) idf.append({'name':'cmdFound', 'widgetType':kbScrolledListBox, 'parent':'resultGroup', 'tooltip':"This widget will list all the commands found with the search string.", 'wcfg':{'items':[], 'listbox_exportselection':0, 'labelpos':'nw', 'label_text':'Found Commands:', 'dblclickcommand':self.loadCmd_cb }, 'gridcfg':{'sticky':'wesn','columnspan':2 }}) idf.append({'name':'info', 'widgetType':Tkinter.Button, 'parent':'resultGroup', 'tooltip':"Display the documentation string of the selected command.", 'wcfg':{'text':'INFO','height':1, 'command':self.info_cb}, 'gridcfg':{'sticky':'wesn' }}) idf.append({'name':'load', 'widgetType':Tkinter.Button, 'parent':'resultGroup', 'tooltip':"Show the selected commands in the application", 'wcfg':{'text':'LOAD','height':1, 'command':self.loadCmd_cb}, 'gridcfg':{'sticky':'wesn','row':-1}}) ## idf.append({'name':'cmdLoaded', ## 'widgetType':kbScrolledListBox, ## 'parent':'resultGroup', ## 'tooltip':"This widget will list all the commands found with the search \nstring that have already been loaded in the application", ## 'wcfg':{'items':[], ## 'listbox_exportselection':0, ## 'labelpos':'nw', ## 'label_text':'Loaded Commands:', ## }, ## 'gridcfg':{'sticky':'wesn', 'rowspan':2, ## 'column':2, 'row':0}}) idf.append({'name':'search', 'widgetType':Tkinter.Button, 'wcfg':{'text':'DISMISS', 'command':self.dismiss_cb}, 'gridcfg':{'columnspan':2}}) return idf def info_cb(self): ebn = self.cmdForms['searchForm'].descr.entryByName sel = ebn['cmdFound']['widget'].getvalue() # get teh description: if not len(sel): return entry = sel[0].split('.') if len(entry) == 3: cmdDescr = self.packModCmd[entry[0]][entry[1]][entry[2]] elif len(entry) == 2: # need to get the module descr. importName = sel[0] m = __import__(importName, globals(), locals()) cmdDescr = eval('m.%s.__doc__'%entry[1]) if cmdDescr is None: cmdDescr="" val = self.showForm('infoForm', modal=0, blocking=0) ebn = self.cmdForms['infoForm'].descr.entryByName ebn['cmdDoc']['widget'].setvalue(cmdDescr) def searchCmd_cb(self): val = self.cmdForms['searchForm'].checkValues() if not val: self.vf.warningMsg("Please Enter a search string") searchString = val['searchString'] self.cmdForms['searchForm'].descr.entryByName['cmdFound']['widget'].clear() del val['searchString'] kw = {} if val.has_key('choice'): choice = val['choice'] if choice == 'All Packages': kw['allPack'] = True elif choice == 'Default Packages': kw['allPack'] = False if val.has_key('matchCmdName'): kw['matchCmdName'] = val['matchCmdName'] if val.has_key('matchDocString'): kw['matchDocString'] = val['matchDocString'] if val.has_key('caseSensitive'): kw['caseSensitive'] = val['caseSensitive'] if val.has_key('matchModName'): kw['matchModName'] = val['matchModName'] results = apply(self.doitWrapper, (searchString,), kw) def dismiss_cb(self): self.cmdForms['searchForm'].withdraw() if self.cmdForms.has_key('infoForm') and \ self.cmdForms['infoForm'].root.winfo_ismapped(): self.dismissDoc_cb def dismissDoc_cb(self): self.cmdForms['infoForm'].withdraw() def loadCmd_cb(self): # need to call the split the name and call the # browse commands ebn = self.cmdForms['searchForm'].descr.entryByName rlb = ebn['cmdFound']['widget'] sel = rlb.getvalue() entry = sel[0].split('.') if len(entry) == 3: self.vf.browseCommands(entry[1], commands=[entry[2]], package=entry[0]) elif len(entry)==2: self.vf.browseCommands(entry[1], package=entry[0]) SearchCommandGUI = CommandGUI() SearchCommandGUI.addMenuCommand('menuRoot', 'Help', 'Search For Commands') class ReportBugCommand(Command): """This command will open a browser allowing the user to enter a bug in MGL Bugzilla. """ pass ## class Helpwin: ## def __init__(self, master, contents, title='Help'): ## self.__root = root = Tkinter.Toplevel(master, class_='Pynche') ## root.protocol('WM_DELETE_WINDOW', self.__withdraw) ## root.title(title) ## root.iconname(title) ## self.text = Tkinter.Text(root, relief=Tkinter.SUNKEN, ## width=80, height=24) ## self.text.insert(0.0, contents) ## scrollbar = Tkinter.Scrollbar(root) ## scrollbar.pack(fill=Tkinter.Y, side=Tkinter.RIGHT) ## self.text.pack(fill=Tkinter.BOTH, expand=Tkinter.YES) ## self.text.configure(yscrollcommand=(scrollbar, 'set')) ## scrollbar.configure(command=(self.text, 'yview')) ## okay = Tkinter.Button(root, text='Ok', command=self.__withdraw) ## okay.pack(side=Tkinter.BOTTOM, expand=1) ## okay.focus_set() ## def __withdraw(self, event=None): ## self.__root.withdraw() ## def deiconify(self): ## self.__root.deiconify() ## class helpModuleCommand(Command): ## """Command to acces documentation of modules""" ## def buildMenus(self, button, menuName): ## # remove first entry which is an empty line ## mmenu = button.menu.children[menuName] ## mmenu.delete(1) ## mmenu.bind("", self.guiCallback) ## if len(self.vf.libraries)==0: return ## # here we would have to loop over all libraries ## ## modu = __import__(self.vf.package+'.modlib', globals(), ## ## locals(), ['modlib']) ## ## mod = '' ## ## # dictionary of files keys=widget, values = filename ## ## self.entries = modu.modlist ## ## for entry in modu.modlist: ## ## # add command as last entry cascade entry ## ## mmenu.add_command(label=entry[1]) ## def doit(self, package, filename): ## if package is None: _package = filename ## else: _package = "%s.%s"%(package, filename) ## self.log(_package, filename) ## module = __import__( _package, globals(), locals(), [filename]) ## if module.__doc__: ## Helpwin(self.vf.GUI.ROOT, doc = module.__doc__, ## title = '%s.%s help'% (package, filename) ) ## else: ## msg = 'Sorry no documentation available for module %s.%s !' % (package, filename) ## tkMessageBox.showwarning('No documentation', msg) ## ## self.vf.message(module.__doc__) ## def customizeGUI(self): ## """create the cascade menu for selecting modules to be loaded""" ## # ugly hack ! when menu is torn off guiCallback get's called twice ## self.isFirstTearOffCallback = 1 ## barName = self.GUI.menuDict['menuBarName'] ## bar = self.vf.GUI.menuBars[barName] ## buttonName = self.GUI.menuDict['menuButtonName'] ## button = bar.menubuttons[buttonName] ## self.buildMenus(button, 'Module documentation') ## def __call__(self, filename, package=None): ## if package==None: package=self.vf.package ## self.doit(filename, package) ## def guiCallback(self, event=None): ## if type(event.widget) is types.StringType: #when menu is torn off ## if not self.isFirstTearOffCallback: ## self.isFirstTearOffCallback = 1 ## return ## self.isFirstTearOffCallback = 0 ## index = int(self.vf.GUI.ROOT.tk.call(event.widget, 'index', ## 'active'))-1 ## else: ## index = event.widget.index("active")-1 ## if index==-1: # when tear-off bar is used we come here ## return ## entry = self.entries[index] ## self.doit(entry[0], entry[1]) commandList = [ {'name':'mailingListsCommand','cmd':mailingListsCommand(),'gui':mailingListsCommandGUI}, {'name': 'helpCommand', 'cmd':helpCommand(), 'gui':helpCommandGUI}, {'name': 'showCitation', 'cmd':CitationCommand(), 'gui':citationCommandGUI}, {'name': 'citeThisScene', 'cmd':CiteThisSceneCommand(), 'gui':CiteThisSceneCommandGUI}, {'name':'searchForCmd','cmd':SearchCommand(),'gui':SearchCommandGUI}, ] def initModule(viewer): for dict in commandList: viewer.addCommand(dict['cmd'], dict['name'], dict['gui']) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/hostApp.py0000644000175000017500000000773511355033061024135 0ustar moellermoellerfrom ViewerFramework.VFCommand import Command from ViewerFramework.VF import LogEvent import traceback,sys class HostApp: """ support a host application in which ViewerFramework is embedded handle log event and execute interpreted command in the host app """ def __init__(self, vf, hostApp, debug=0): self.vf = vf # ViewerFramework which is embedded self.driver = None # is set by self._setDriver self.debug=debug # redirect stderr to file # open file for logging commands executed by self.vf if self.debug == 1 : self.vf.pmvstderr=open('/tmp/pmvstderr','w') sys.stderr=self.vf.pmvstderr self.vf.abclogfiles=open('/tmp/logEvent','w') print 'logEvent',self.vf.abclogfiles else: self.vf.pmvstderr=None self.vf.abclogfiles = None # create host application driver # this driver creates the connection between VF and the host application self.hostname = hostApp self._setDriver(hostApp) # register the function to be called when a log string is generated by VF # this function will create an equivalent cmd for the hot application # and have the host app run this command self.vf.registerListener(LogEvent, self.handleLogEvent) #Variable for the server-client mode self.servers = [] # list of (host, portNum) used to connect PMV server applications self._stop = False # set to True to stop executing commands sent by servers self.thread=None # the thread used to apply the command from the server def _setDriver(self,hostApp): """ Define the host application and call the approriate command interpreter setDriver(hostApp) hostApp is case in-sensitive string which can be 'Blender' or 'c4d' raises ValueError if the hostApp is invalid """ #from mglutil.hostappInterface import appliDriver from Pmv.hostappInterface import appliDriver #currently hostApp have to be c4d,blender or maya self.driver=appliDriver.HostPmvCommand(soft=hostApp.lower()) def handleLogEvent(self, event): """ Function call everytime the embeded pmv create a log event, cf a command is execute with the keyword log=1 """ import sys mesgcmd='' #the message command string lines=event.logstr.split('\n') #the last log event ie the last command string for line in lines : #parse and interprete the pmv command to generate the appropriate host appli command func,arg=self.driver.parseMessageToFunc(line) temp=self.driver.createMessageCommand(func,arg,line) mesgcmd+=temp if self.debug ==1 : self.vf.abclogfiles.write("################\n"+self.hostname+"_CMD\n"+mesgcmd+'\n') self.vf.abclogfiles.flush() self.vf.pmvstderr.flush() #try to exec the command generated, using keywords dictionary try: exec(mesgcmd, {'self':self.vf,'mv':self.vf,'pmv':self.vf}) except : import sys,traceback tb=traceback.format_exc() raise ValueError(tb) if self.debug ==1: # tb = traceback.extract_tb(sys.exc_traceback) self.vf.abclogfiles.write("exeption\n"+str(tb)+"\n") self.vf.abclogfiles.flush() ######Dedicated function for the client-server mode################# def runServerCommandLoop(self): """ Infinite loop which call the viewerframework runservercommand """ while not self._stop: self.vf.runServerCommands() def setServer(self,address,port): """ Define the server,portnumeber of the server """ self.servers=[address,port] def start(self): """ Connect to the server and start the thread which permit the execution of the server command """ self.vf.socketComm.connectToServer(self.servers[0],self.servers[1],self.vf.server_cb) from Queue import Queue self.vf.cmdQueue = Queue(-1) import thread self._stop=False if self.thread==None : self.thread=thread.start_new(self.runServerCommandLoop, ()) if self.debug ==1: sys.stderr.write('ok thread\n') self.vf.pmvstderr.flush() def stop(self): #stop the infinite loop and diconect from the server self._stop=True self.vf.socketComm.disconnectFromServer(self.servers[0],self.servers[1]) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/imdCommands.py0000644000175000017500000006035511432565443024761 0ustar moellermoeller############################################################################# # # Author: Ludovic Autin # # Copyright: L. Autin TSRI 2010 # ############################################################################# # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/imdCommands.py,v 1.6 2010/08/17 20:03:47 autin Exp $ # # $Id: imdCommands.py,v 1.6 2010/08/17 20:03:47 autin Exp $ # """ This module implements classes to start a server and to connect to a server. """ #import psyco #psyco.full() from ViewerFramework.VFCommand import Command from Pmv.moleculeViewer import EditAtomsEvent import struct import numpy from numpy import matrix import sys, os from socket import * if os.name == 'nt': #sys.platform=='win32': mswin = True else: mswin = False HEADERSIZE=8 IMDVERSION=2 IMD_DISCONNECT=0 #//!< close IMD connection, leaving sim running 0 IMD_ENERGIES=1 #//!< energy data block 1 IMD_FCOORDS=2 #//!< atom coordinates 2 IMD_GO=3 #//!< start the simulation 3 IMD_HANDSHAKE=4 #//!< endianism and version check message 4 IMD_KILL=5 #//!< kill the simulation job, shutdown IMD 5 IMD_MDCOMM=6 #//!< MDComm style force data 6 IMD_PAUSE=7 #//!< pause the running simulation 7 IMD_TRATE=8 #//!< set IMD update transmission rate 8 IMD_IOERROR=9 #//!< indicate an I/O error 9 class vmdsocket: def __init__(self): self.addr=None #!< address of socket provided by bind() self.port=None self.addrlen=None #!< size of the addr struct self.sd=None #< socket descriptor class File2Send: def __init__(self): self.data=None self.length=None self.buffer=None #Convert a 32-bit integer from host to network byte order. def imd_htonl(self,h) : return htonl(h) #Convert a 32-bit integer from network to host byte order. def imd_ntohl(self,n) : return ntohl(n) def fill(self, data): self.data = data self.length = len(data)#self.imd_htonl(len(data)) def swap_header(self) : #pass #self.imdtype = self.imd_ntohl(self.imdtype) self.length = self.imd_ntohl(self.length ) def getBinary(self): """Returns the binary message (so far) with typetags.""" length = struct.pack(">i", int(self.length)) if len(self.data) == 0 : return length for l in self.data: length += struct.pack(">i", len(l)) for i in l : length += struct.pack(">c", i) self.buffer = length return length class Bonds2Send(File2Send): def getBinary(self): """Returns the binary message (so far) with typetags.""" length = struct.pack(">i", int(self.length)) if len(self.data) == 0 : return length for l in self.data: print l for j in range(len(l)): length += struct.pack(">i", int(l[j])) self.buffer = length return length class IMDheader: def __init__(self): self.imdtype=None self.length=None self.buffer=None #Convert a 32-bit integer from host to network byte order. def imd_htonl(self,h) : return htonl(h) #Convert a 32-bit integer from network to host byte order. def imd_ntohl(self,n) : return ntohl(n) def fill_header(self, IMDType, length): self.imdtype = IMDType#self.imd_htonl(IMDType) self.length = length# self.imd_htonl(length) def swap_header(self) : self.imdtype = self.imd_ntohl(self.imdtype) self.length = self.imd_ntohl(self.length ) def getBinary(self): """Returns the binary message (so far) with typetags.""" types = struct.pack(">i", int(self.imdtype)) length = struct.pack(">i", int(self.length)) return types + length class IMDEnergies: def __init__(self): self.buffer = None self.tstep = None #//!< integer timestep index self.T = None #//!< Temperature in degrees Kelvin self.Etot = None #//!< Total energy, in Kcal/mol self.Epot = None #//!< Potential energy, in Kcal/mol self.Evdw = None #//!< Van der Waals energy, in Kcal/mol self.Eelec = None #//!< Electrostatic energy, in Kcal/mol self.Ebond = None #//!< Bond energy, Kcal/mol self.Eangle = None #//!< Angle energy, Kcal/mol self.Edihe = None #//!< Dihedral energy, Kcal/mol self.Eimpr = None #//!< Improper energy, Kcal/mol self.len = 9*12+1*4 #number of element->9 float (12bit) 1 int (4bit) class IMD(Command): """ This class implements method to connect to a server.""" def checkDependencies(self, vf): import thread def init(self,hostname, mode, IMDwait_, IMDport_, IMDmsg_, IMDlogname_, length ): self.current_buffer = None self.current_send_buffer = None self.mol = None self.slot = None self.imd_coords = numpy.zeros((length,3),'f') self.pause = False self.gui = False self.ffreq = 30 self.rates = 1 blen = 1024 hname="" str="" IMDport=IMDport_ if ( IMDlogname_ == 0 ) : IMDlog = sys.stderr else : IMDlog = open ( IMDlogname_, "w") if ( IMDlog == 0 ) : IMDlog.write("MDDriver > Bad filename, using stderr\n") IMDmsg = IMDmsg_ #IMDmsg < 0 force to display to stderr (IMDlog=stderr) if( IMDmsg < 0) : IMDmsg = -IMDmsg IMDlog = sys.stderr IMDlog.write("MDDriver > Negative IMDmsg - Setting IMDlog=stderr \n") if (IMDmsg > 1) : IMDlog.write("MDDriver > ---- Entering in %s\n"%sys._getframe().f_code.co_name) IMDwait = IMDwait_ # IMDwait = 1 -> blocking IMDignore = 0 #if ( self.vmdsock_init() ): # IMDlog.write("MDDriver > Unable to initialize socket interface for IMD.\n") IMDignore = 1; self.sock = self.vmdsock_create(); self.vmdsock_connect(self.sock , hostname, IMDport) #before handshacking do we need to send the files if self.mindy: self.sendFiles() print "fileSend" IMDswap = self.imd_recv_handshake(self.sock); print "IMDswap",IMDswap """ if ( IMDswap == 0 ){ fprintf(IMDlog, "MDDriver > Same endian machines\n"); } else if ( IMDswap == 1 ) { fprintf(IMDlog, "MDDriver > Different endian machines\n"); } else { fprintf(IMDlog, "MDDriver > Unknown endian machine - disconnecting\n"); if (sock) { imd_disconnect(sock); vmdsock_shutdown(sock); vmdsock_destroy(sock); sock = 0; if (IMDmsg > 1) fprintf( IMDlog, "MDDriver > ---- Leaving %s\n", __FUNCTION__); """ imd_event = -1; #return ( IMDlog ) def vmdsock_create(self) : s=vmdsocket() #open socket using TCP/IP protocol family, using a streaming type and the #default protocol. This is connection-oriented, sequenced, error-controlled #and full-duplex #ref Wall p.380 s.sd = socket(AF_INET, SOCK_STREAM) #no PF_INET in python if s.sd is None : print "Failed to open socket." # TODO: provide error detail using errno return None return s def vmdsock_connect(self, vmdsocket, host, port) : #vmdsock_connect(sock, hostname, IMDport) s = vmdsocket host = gethostbyname(host) s.port = port s.addr = host s.sd.connect( ( host, port)) def vmdsock_write(self,s, header, size) :#s, header, HEADERSIZE header.swap_header() buf = header.getBinary() s.sd.send(buf) #return len(buf) def vmdsock_read(self,s, ptr, size) :#socket, header, HEADERSIZE=8 buf = s.sd.recv(size) if isinstance(ptr,IMDheader): ptr.buffer=buf ptr.imdtype=struct.unpack(">i", buf[0:4])[0] ptr.length =struct.unpack(">i", buf[4:])[0] elif isinstance(ptr,IMDEnergies): ptr.buffer= buf ptr.tstep = ntohl(struct.unpack(">i", buf[0:4])[0]) #//!< integer timestep index rest=buf[4:] ptr.T = struct.unpack("f", rest[0:4])[0] #//!< Temperature in degrees Kelvin rest=rest[4:] ptr.Etot = struct.unpack("f", rest[0:4])[0] #//!< Total energy, in Kcal/mol rest=rest[4:] ptr.Epot = struct.unpack("f", rest[0:4])[0] #//!< Potential energy, in Kcal/mol rest=rest[4:] ptr.Evdw = struct.unpack("f",rest[0:4])[0] #//!< Van der Waals energy, in Kcal/mol rest=rest[4:] ptr.Eelec = struct.unpack("f", rest[0:4])[0] #//!< Electrostatic energy, in Kcal/mol rest=rest[4:] ptr.Ebond = struct.unpack("f", rest[0:4])[0] #//!< Bond energy, Kcal/mol rest=rest[4:] ptr.Eangle = struct.unpack("f", rest[0:4])[0] #//!< Angle energy, Kcal/mol rest=rest[4:] ptr.Edihe = struct.unpack("f", rest[0:4])[0] #//!< Dihedral energy, Kcal/mol rest=rest[4:] ptr.Eimpr = struct.unpack("f", rest[0:4])[0] #//!< Improper energy, Kcal/mol elif isinstance(ptr,numpy.ndarray): self.current_buffer = buf[:] rest=buf[:] #print "len",int(ptr.shape[0]) for i in range(int(ptr.shape[0])): for j in range(3): #print i,j,struct.unpack("f", rest[0:4]) try : ptr[i][j]=float(struct.unpack("f", rest[0:4])[0]) rest=rest[4:] except : pass#print i,j, rest[0:4] #print "ok" #return len(buf) def vmdsock_selread(self,vmdsocket, sec): pass #s = vmdsocket #fd_set rfd; #struct timeval tv; #int rc; # #FD_ZERO(&rfd); #FD_SET(s->sd, &rfd); #memset((void *)&tv, 0, sizeof(struct timeval)); #tv.tv_sec = sec; #do { # rc = select(s->sd+1, &rfd, NULL, NULL, &tv); #while (rc < 0 && errno == EINTR); #return rc; def sendOne(self,data,sender): sender.fill(data) buf=sender.getBinary() res=self.sock.sd.send(buf) print "res",res def sendFiles(self): #first get the pdb/psf try : from MDTools.md_AtomGroup import Molecule except : print "no MDTools package, cancel action" return m = self.m =Molecule(self.pdbFile,self.psfFile) s2Send = File2Send() b2Send = Bonds2Send() #need to send pdb print "pdb" self.sendOne(m.pdbLines,s2Send) #need to send the parmaFile o = open(self.paraFile,'r') data = o.readlines() o.close() print "param" self.sendOne(data,s2Send) #need to send psf file print "psf" self.sendOne(m.psfAtomsLines,s2Send) self.sendOne(m._bonds,b2Send) self.sendOne(m._angles,b2Send) self.sendOne(m._dihedrals,b2Send) self.sendOne(m._impropers,b2Send) self.sendOne([],s2Send) #need then to send fixed atoms print "atomsF" self.sendOne([],s2Send) def imd_pause(self): header=IMDheader() header.fill_header(IMD_PAUSE, 0) self.pause = not self.pause return (self.imd_writen(self.sock, header, HEADERSIZE) != HEADERSIZE) def imd_go(self): #swap ? header=IMDheader() header.fill_header(IMD_GO, 0) #print "type", header.imdtype header.swap_header() print "type", header.imdtype return (self.imd_writen(self.sock, header, HEADERSIZE) != HEADERSIZE) def imd_send_fcoords(self,n,coords): size = HEADERSIZE+12*n header=IMDheader() header.fill_header(IMD_FCOORDS, n) #header.swap_header() buf = header.getBinary() #need to pack coords (float*3) self.current_send_buffer = buf + self.packFloatVectorList(coords) self.sock.sd.send(self.current_send_buffer) def imd_send_mdcomm(self,n,indices,forces): """ send n forces to apply to n atoms of indices indices """ #rc=0 size = HEADERSIZE+16*n header=IMDheader() header.fill_header(IMD_MDCOMM, n) header.swap_header() buf = header.getBinary() #need to pack indices (int) and forces (float*3) indiceBuff = self.packIntegerList(indices) forcesBuff = self.packFloatVectorList(forces) buffer = buf + indiceBuff + forcesBuff self.current_send_buffer = buffer self.sock.sd.send(buffer) #return rc def imd_readn(self,s,ptr,n) : #socket, header, HEADERSIZE=8 #print "readN"#nread=None nleft = n self.vmdsock_read(s, ptr, nleft) return n """ while (nleft > 0) : if ((nread = self.vmdsock_read(s, ptr, nleft)) < 0) { if (errno == EINTR) nread = 0; # and call read() again */ else return -1; else if (nread == 0) break; /* EOF */ nleft -= nread; ptr += nread; return n-nleft """ def imd_writen(self,s,ptr,n) : nleft = n nwritten=None self.vmdsock_write(s, ptr, nleft) del ptr return 0 """ while (nleft > 0): if ((nwritten = self.vmdsock_write(s, ptr, nleft)) <= 0) : if (errno == EINTR): nwritten = 0; else return -1 nleft -= nwritten; ptr += nwritten; return n """ def imd_recv_handshake(self,s) : buf=None IMDType=None #print "handscheck" # Wait up to 5 seconds for the handshake to come #if (self.vmdsock_selread(s, 5) != 1) return -1; #import time #time.sleep(5.) # Check to see that a valid handshake was received */ header = self.imd_recv_header_nolengthswap(s); #print "handscheck rcv" #print header.imdtype, IMD_HANDSHAKE if (header.imdtype != IMD_HANDSHAKE) : return -1 #ok send imd_go #print "imd_go" self.imd_go() #if header.length == IMDVERSION : # if (not self.imd_go(s)) : return 0 #header.swap_header() #if header.length == IMDVERSION : # if (not self.imd_go(s)) : return 0 return -1; """ # Check its endianness, as well as the IMD version. */ if (buf == IMDVERSION) { if (!imd_go(s)) return 0; return -1; } imd_swap4((char *)&buf, 4); if (buf == IMDVERSION) { if (!imd_go(s)) return 1; } #/* We failed to determine endianness. */ return -1; """ #/* The IMD receive functions */ def imd_recv_header_nolengthswap(self,socket) : header=IMDheader() if (self.imd_readn(socket, header, HEADERSIZE) != HEADERSIZE): return IMD_IOERROR; #header.swap_header() return header; def imd_recv_header(self,socket) : header=IMDheader() if (self.imd_readn(socket, header, HEADERSIZE) != HEADERSIZE): return IMD_IOERROR; #header.swap_header() return header; def imd_recv_mdcomm(self, n, indices, forces) : if (self.imd_readn(self.sock, indices, 4*n) != 4*n) : return 1 if (self.imd_readn(self.sock, forces, 12*n) != 12*n) : return 1 return 0; def imd_recv_energies(self, imdEnergies) : return (self.imd_readn(self.sock, imdEnergies, 1024) != imdEnergies.len); def imd_recv_fcoords(self, n, coords) : return (self.imd_readn(self.sock, coords, 12*n) != 12*n); def getType(self,bytes): types="" for i in range(len(bytes)): types=types+str(ord(bytes[i])) return types def readInt(self,data): if(len(data)<4): print "Error: too few bytes for int", data, len(data) rest = data integer = 0 else: integer = struct.unpack(">i", data[0:4])[0] rest = data[4:] return (integer, rest) def packIntegerList(self,listeI): buffer = '' for i in listeI: buffer += struct.pack("i", i) return buffer def packFloatVectorList(self,listeV): buffer = '' for vector in listeV: for j in vector : buffer += struct.pack("f", j) return buffer def start(self,func=None): import thread self.lock = thread.allocate_lock() if self.pause : self.imd_pause() thread.start_new(self.listenToImdServer, (func,)) def mindySend(self): from ARViewer import util import numpy.oldnumeric as Numeric coords=[] for m in self.mol: if hasattr(self.vf,'art'): M = m.pat.mat_transfo vt = [] vt=util.ApplyMatrix(Numeric.array(m.allAtoms.coords),M,transpose=False) else : vt = m.allAtoms.coords[:] coords.extend(vt) self.imd_send_fcoords(len(coords),coords) def mindyGet(self): from ARViewer import util import numpy.oldnumeric as Numeric imdheader = self.imd_recv_header(self.sock) vmd_length = imdheader.length imdtype = imdheader.imdtype if imdtype == IMD_FCOORDS: #print "recv fcoords ",vmd_length test=self.imd_recv_fcoords(vmd_length,self.imd_coords) #print self.imd_coords[0] b=0 n1 = 0 for i,m in enumerate(self.mol) : n1 += len(m.allAtoms.coords) try : #should apply the inverse matrix? to get back to the origin #before going on the marker.. #but problem of scaleFactor if hasattr(self.vf,'art'): M = matrix(m.pat.mat_transfo.reshape(4,4)) vt=util.ApplyMatrix(Numeric.array(self.imd_coords[b:n1]), Numeric.array(M.I),transpose=False) #print "update coords but back in CS" #print vt[0] if True in numpy.isnan(vt[0]): vt = map(lambda x: x[0], m.allAtoms._coords) m.allAtoms.updateCoords(vt, self.slot[i]) #print m.allAtoms.coords[0] else : m.allAtoms.updateCoords(self.imd_coords[b:n1], self.slot[i]) except: print "coord update failed" b=n1 from Pmv.moleculeViewer import EditAtomsEvent for i,m in enumerate(self.mol) : event = EditAtomsEvent('coords', m.allAtoms) try : self.vf.dispatchEvent(event) except: print "event failed" def updateMindy(self): from ARViewer import util import numpy.oldnumeric as Numeric imdheader = self.imd_recv_header(self.sock) vmd_length = imdheader.length imdtype = imdheader.imdtype if imdtype == IMD_FCOORDS: print "recv fcoords ",vmd_length test=self.imd_recv_fcoords(vmd_length,self.imd_coords) print self.imd_coords[0] b=0 n1 = 0 for i,m in enumerate(self.mol) : n1 += len(m.allAtoms.coords) try : #should apply the inverse matrix? to get back to the origin before going on the marker.. if hasattr(self.vf,'art'): M = matrix(m.pat.mat_transfo.reshape(4,4)) vt=util.ApplyMatrix(Numeric.array(self.imd_coords[b:n1]),numpy.array(M.I)) print "update coords but back in CS" print vt[0] m.allAtoms.updateCoords(vt, self.slot[i]) print m.allAtoms.coords[0] else : m.allAtoms.updateCoords(self.imd_coords[b:n1], self.slot[i]) except: print "coord update failed" b=n1 #print m.allAtoms._coords[0] #print "ipdate coords events" from Pmv.moleculeViewer import EditAtomsEvent for i,m in enumerate(self.mol) : event = EditAtomsEvent('coords', m.allAtoms) try : self.vf.dispatchEvent(event) except: print "event failed" #here we should update from AR....which is apply the marker transformation #one marker per mol...should have some mol.mat_transfo attributes #get the maker position transfo coords=[] for m in self.mol: if hasattr(self.vf,'art'): M = m.pat.mat_transfo vt = [] vt=util.ApplyMatrix(Numeric.array(m.allAtoms.coords),M) else : vt = m.allAtoms.coords[:] coords.extend(vt) self.imd_send_fcoords(self.N,coords) def treatProtocol(self,i): #import Pmv.hostappInterface.pdb_blender as epmv if not self.pause: imdheader = self.imd_recv_header(self.sock) vmd_length = imdheader.length imdtype = imdheader.imdtype #print "TYPE ",imdtype if imdtype == IMD_ENERGIES: #print "energie" ene=IMDEnergies() test=self.imd_recv_energies(ene) #print ene.tstep,ene.Etot,ene.Epot,ene.Evdw,ene.Epot,ene.Eelec,ene.Eangle if imdtype == IMD_MDCOMM: #receive Force and Atom listes #print "mdcom",vmd_length vmd_atoms=numpy.zeros(vmd_length,'i') vmd_forces=numpy.zeros(vmd_length*3,'f') test=self.imd_recv_mdcomm(vmd_length,vmd_atoms,vmd_forces) if imdtype == IMD_FCOORDS: #get the coord #vmd_coords=numpy.zeros((vmd_length,3),'f') self.lock.acquire() test=self.imd_recv_fcoords(vmd_length,self.imd_coords) #self.imd_coords[:]=vmd_coords[:]#.copy() self.lock.release() #self.vf.updateIMD #epmv.updateCloudObject("1hvr_cloud",self.imd_coords) #epmv.insertKeys(self.mol.geomContainer.geoms['cpk'],1) if self.vf.handler.isinited: if (i % self.ffreq) == 0 : if self.vf.handler.forceType == "move" : self.imd_send_fcoords(self.vf.handler.N_forces,self.vf.handler.forces_list) print "ok",self.vf.handler.N_forces else : self.imd_send_mdcomm(self.vf.handler.N_forces, self.vf.handler.atoms_list, self.vf.handler.forces_list) if self.mindy: coords=[] for m in self.mol: coords.extend(m.allAtoms.coords) self.imd_send_fcoords(self.N,coords) def listenToImdServer(self,func): i=0 while (1): self.treatProtocol(i) i = i + 1 commandList = [ {'name':'imd', 'cmd':IMD(), 'gui': None}, ] def initModule(viewer): for dict in commandList: # print 'dict',dict viewer.addCommand(dict['cmd'], dict['name'], dict['gui']) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/modlib.py0000644000175000017500000000125007262435735023767 0ustar moellermoellermodlist = [ ("ViewerFramework","customizationCommands",""" This module implements a set of class to customize a ViewerFramework application: SetUserPreference SetOnAddObjectCmds """), ("ViewerFramework","customizeVFGUICommands",""" This Module implements commands to change the appearance of the ViewerFrameworkGUI """), ("ViewerFramework","dejaVuCommands",""" This module implements classes relative to DejaVu. """), ("ViewerFramework","documentationCommands",""" Module implementing classes to provide documentation on the application """), ("ViewerFramework","serverCommands",""" This module implements classes to start a server and to connect to a server. """), ] ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/picker.py0000644000175000017500000001717710057176512024004 0ustar moellermoeller############################################################################# # # Author: Michel F. SANNER # # Copyright: M. Sanner TSRI 2000 # ############################################################################# # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/picker.py,v 1.5 2004/06/01 22:03:54 sanner Exp $ # # $Id: picker.py,v 1.5 2004/06/01 22:03:54 sanner Exp $ # # """ implement classes for object pickers in viewer. Pickers support, GUI and non-GUI versions. Picking can be done in the viewer's camera. A picker can terminate automatically when a given number of objects has been picked. Exact number of objects can be enforced. Callback functions can be invoked after each picking operation or after the picker finishes. The picking level can be set to 'vertices' or 'parts'. Duplicate checks is performed by default. The base class Picker has to be sub-classed by speciliazed classes implementing methods such as: getObjects(self, pick) def allChoices(self) def buildInputFormDescr(self) def updateGUI(self) When a gui is present, each sub-class has to implement the updateGUI method that will reflect the action of picking an object. if the method "allChoices" returns a non-empty list, a list chooser from which objects can be picked is added. """ ## from ViewerFramework.gui import InputFormDescr from mglutil.gui.InputForm.Tk.gui import InputFormDescr import Tkinter, time, types class Picker: """Base class for picker objects""" def __init__(self, vf, numberOfObjects=None, gui=1, immediate=0, callbacks=[], mode='exact', checkDuplicates=1, disableOtherPickingFunctions=0): """picker constructor, numberOfObjects: None or positive integer. if None call stop() to end gui: 0/1 for display GUI immediate: 1/0. If 1 call callback function after each pick else call after picker's termination callbacks: list of functions to be called with a list of objects as arg mode: 'exact' or 'atLeast'. If exact only pick operation that do not exceed the numberOfObject are considered checkDuplicates: 0/1. Remove duplicate entries form list of objects """ self.vf = vf # viewer application self.numberOfObjects = numberOfObjects # required number of objects self.immediate = immediate self.gui = gui # show GUI self.mode = mode self.checkDuplicates = checkDuplicates l = len(callbacks) self.callbacks = callbacks self.disableOtherPickingFunctions = disableOtherPickingFunctions self.clear() #this set-up self.objects to be the right thing self.saveCallBackList = None if self.gui and self.vf.hasGui: self.ifd=self.buildInputFormDescr() self.form = self.vf.getUserInput(self.ifd, modal=0, blocking=0) def go(self, modal=0, level='vertices'): """return only after the specified number of objects have been picked level: 'vertices' or 'parts', Picking level to be used """ assert level in ['vertices', 'parts'] self.pickLevel = level vi = self.vf.GUI.VIEWER vi.pickLevel = self.pickLevel self.modal = modal if self.disableOtherPickingFunctions: self.saveCallBackList = vi.SetPickingCallback(self.pickObject_cb) else: vi.AddPickingCallback(self.pickObject_cb) if modal: while len(self.objects) < self.numberOfObjects: self.vf.GUI.VIEWER.master.update() time.sleep(0.001) if self.disableOtherPickingFunctions: vi.SetPickingCallback(self.saveCallBackList) elif self.pickObject_cb in vi.pickingFunctions: vi.RemovePickingCallback(self.pickObject_cb) # FIXME # hack to go back to default mode. This raise the problem that we # cannot have a vertices picker and a part picker at the same time vi.pickLevel = 'vertices' return self.objects def stop(self, event=None): if not self.immediate: self.callCallback(self.objects) vi = self.vf.GUI.VIEWER if self.disableOtherPickingFunctions: vi.SetPickingCallback(self.saveCallBackList) self.saveCallBackList = None else: vi.RemovePickingCallback(self.pickObject_cb) if hasattr(self, 'form'): self.form.destroy() # FIXME see remark in go() vi.pickLevel = 'vertices' def clear(self): """clear list of selected objects""" self.objects = [] def removeAlreadySelected(self, objects): """remove for objects the ones already in self.objects""" l = [] for o in objects: if not o in self.objects: l.append(o) return l def pickObject_cb(self, pick): """handle a picking operation""" #print 'in Picker pickObject_cb' objects = self.getObjects(pick) #print objects if objects: if self.gui: self.updateGUI(objects) # remove objects that are aleady in self.objects if self.checkDuplicates: objects = self.removeAlreadySelected(objects) # make sure we do not select too many objects if self.mode=='exact': l = len(objects)+len(self.objects) if self.numberOfObjects is not None and \ l > self.numberOfObjects: print "WARNING: this operation would select %d objects while %d are needed\n" % (l,self.numberOfObjects) return # add te new objects to already selected ones self.objects = self.objects + objects # call callbacks with new objects (only in immediate mode) if self.immediate: self.callCallback(objects) # check whether obect count has been reached if self.numberOfObjects is not None: if len(self.objects)>=self.numberOfObjects: self.stop() def buildInputFormDescr(self): ifd = InputFormDescr() all = self.allChoices() if len(all)>0: ifd.append({'widgetType':'ListChooser', 'name':'AllObjects', 'entries':all, 'title':'All objects', 'wcfg':{'mode':'multiple'}, }) if self.numberOfObjects==None: ifd.append({'widgetType':Tkinter.Button, 'wcfg':{'text':'Done'}, 'command': self.stop}) return ifd def getSelectedObjects(self): return self.objects def callCallback(self, objects): for f in self.callbacks: apply(f, ( (objects), ) ) def addCallback(self, callback): """Add a callback function""" assert callable(callback) # Here we should also check that callback has exactly 1 argument self.callbacks.append(callback) def removeCallback(self, func): """Delete function func from the list of callbacks for eventType""" self.callbacks.remove(callback) def getObjects(self, pick): """to be implemented by sub-class""" # has to return a list (or equivalent) of unique objects pass def updateGUI(self): """to be implemented by sub-class""" pass def allChoices(self): return [] class GeomPicker(Picker): def getObjects(self, pick): return pick.hits.keys() ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/serverCommands.py0000644000175000017500000004420111440315426025477 0ustar moellermoeller############################################################################# # # Author: Michel F. SANNER # # Copyright: M. Sanner TSRI 2000 # ############################################################################# # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/serverCommands.py,v 1.19 2010/09/04 01:04:22 sanner Exp $ # # $Id: serverCommands.py,v 1.19 2010/09/04 01:04:22 sanner Exp $ # """ This module implements classes to start a server and to connect to a server. """ from ViewerFramework.VFCommand import Command, CommandGUI try: import ViewerFramework.imdCommands as imd imdFound = True except ImportError: imdFound = False from mglutil.popen2Threads import SysCmdInThread from mglutil.gui.InputForm.Tk.gui import InputForm, InputFormDescr import Tkinter import sys, os if os.name == 'nt': #sys.platform=='win32': mswin = True else: mswin = False class StartServer(Command): """ This class implements methods to start a server""" def checkDependencies(self, vf): import thread def doit(self): import thread com = self.vf.socketComm if com.port: print 'WARNING: server already running on port', com.port return self.vf.socketComm.startServer() thread.start_new(com.acceptClients, (self.vf.clients_cb,)) self.vf.GUI.ROOT.after(300, self.vf.sendViewerState) # create a threadsafe command queue from Queue import Queue self.vf.cmdQueue = Queue(-1) # infinite size self.vf.GUI.ROOT.after(10, self.vf.runClientCommands) class WebDrivenTutorial(Command): """start a web browser that can send commands over a socket to Viewerframework We use Karrigell-2.0.3 as a light webserver. The source of Karrigell need to be install in the python path. When a server is started a webbrowser is started and display a url which should point to a file in the web server root dir. The commands take 2 keywords argument which specify the path to Karrigell package, and the file to open in the webbrowser. If not specify, we search the python path to find karrigell package, and give the top level of the karigell folder as the file to open as a url. """ def onExitFromViewer(self): """ method which will be call when the Viewer is closed""" # we need to stop the Karigell webserver if hasattr(self,'cmd'): if not mswin: import os,signal print 'killing process Karrigell' pid = self.cmd.com.pid os.kill(pid,signal.SIGKILL) #self.cmd.com.kill(signal.SIGKILL) else: pass def doit(self,**kw): import webbrowser karrigell_path = kw['karrigell_path'] file = kw['file'] if karrigell_path is None: server_root = self.findKarrigell() if server_root is None: self.warningMsg("Karrigell package not install, Webserver not started.") else: karrigell_path = server_root # Karrigell folder should be in python path, we expect version-2.0.3 import os # we create a absolute path as windows need it to under path karrigell_start = os.path.realpath(os.path.join(karrigell_path,'Karrigell.py')) karrigell_init = os.path.realpath(os.path.join(karrigell_path,'Karrigell.ini')) status = False port = 8080 status,port = self.startKarrigell(port,karrigell_start,karrigell_init) if status: print 'Karrigell started, listenning on port %d'%port else: print 'Karrigell could not be started' return # web page have to be in the server_root directory which # is by default karrigell_path if file is None: file = '' url2open = 'http://localhost:%d/'%port+file webbrowser.open_new(url2open) def startKarrigell(self,port,karrigell_start,karrigell_init): """ start the webserver Karrigell on the port specify in input return False for failure , True for sucess """ if hasattr(self,'cmd'): del(self.cmd) print "Trying to start Karrigell on port %d"%port self.cmd = SysCmdInThread("python -u %s -P %d %s "%(karrigell_start, port,karrigell_init), hasGui=False) self.cmd.start() status = self.checkKarrigellStatus() if not status: # print try to start on another port port = port + 1 if port > 8180: self.warningMsg("Could not start Karrigell server, no port available") return False,0 else: status,port =self.startKarrigell(port,karrigell_start,karrigell_init) return status,port def checkKarrigellStatus(self): # check the status of Karrigell # did the webserver started, if so we get the port back #while not self.cmd.output.empty(): while(1): if not self.cmd.output.empty(): data = self.cmd.output.get(False) # server fail to start if 'Address already in use' in data: return False # server start success if 'running on port' in data: return True return False def findKarrigell(self): """ method which search the path to the Karrigel directory in the python path""" import sys,os karrigell_path =None for d in sys.path: dirname = os.path.join(d,'Karrigell-2.0.3') if os.path.exists(dirname): karrigell_path = dirname return karrigell_path def guiCallback(self): kw ={} server_root = self.findKarrigell() if server_root is None: return file = self.vf.askFileOpen(types=[('all', '*')], idir=server_root, title='Select a web page or folder') if file is not None: import string webpage = string.split(file,'Karrigell-2.0.3')[1] kw['karrigell_path']=server_root kw['file'] = webpage apply(self.doitWrapper,(),kw) def __call__(self,karrigell_path=None,file=None,**kw): """ None<-web_tutorial( karrigell_path=None,file=None,**kw) karrigell_path = path to server_root of Karrigell webserver file = file or folder to show as url, should be in the webserver_root """ kw['karrigell_path'] = karrigell_path kw['file'] = file apply(self.doitWrapper,(),kw) class StartWebControlServer(Command): """ This class implements methods to start a communication pipe to receive commands from a web browser""" def checkDependencies(self, vf): import thread def doit(self): import thread com = self.vf.webControl if com.port: print 'WARNING: server already running on port', com.port return com.startServer() thread.start_new(com.acceptClients, (self.clients_cb,)) # print port number to a file in file pmv_server.pid in the directory where the # python process was started, if the package Karigell does not exist, otherwise # save pmv_server.pid in Karrigell folder. import os,sys karrigell_path =None for d in sys.path: dirname = os.path.join(d,'Karrigell-2.0.3') if os.path.exists(dirname): karrigell_path = dirname if not karrigell_path: filename = 'pmv_server.pid' else: filename = os.path.join(karrigell_path,'pmv_server.pid') f = open(filename,'w') f.write('%d'%com.port) f.close() from Queue import Queue self.cmdQueue = Queue(-1) # infinite size # start checking for messages from the web controler self.vf.GUI.ROOT.after(10, self.checkForCommands) def checkForCommands(self, event=None): """periodically check for new commands cmd should be a string where the Viewerframework command is separate by || from a tuple representing the args separated by || from a dictonnary which represent the keyword arguments of commands example: 'colorByAtomType||'+ '(self.vf.getSelection(), ('lines',))|| {}' colorByAtmoType: cmd to run (self.vf.getSelection(), ('lines',)): arguments to pass to cmd {}: keyword argument to pass to cmd """ if not self.cmdQueue.empty(): cmd = self.cmdQueue.get(False) # do not block if queue empty if cmd: #print 'got', cmd w = cmd.split('||') if self.vf.commands.has_key(w[0]): # cmd should be a string where the Viewerframework command is separate by | # from a tuple representing the args separated by | from a dictonnary # which represent the keyword arguments of commands # example: # "colorByAtomType|"+ "(self.vf.getSelection(), ('lines',))| {}" # colorByAtmoType: cmd to run # (self.vf.getSelection(), ('lines',)): arguments to pass to cmd # {}: keyword argument to pass to cmd args = eval(w[1]) kw = eval(w[2]) apply( self.vf.commands[w[0]], args,kw ) self.vf.GUI.ROOT.after(10, self.checkForCommands) def clients_cb(self, client, data): """get called every time a web page sends a message The message is sent using Karrigell's Python in Html """ # put it in a thread safe queue self.cmdQueue.put(data) class ConnectToServer(Command): """ This class implements method to connect to a server.""" def checkDependencies(self, vf): import thread def doit(self): import thread idf = InputFormDescr("Viewerframework server connection!") idf.append({'widgetType':Tkinter.Entry, 'name': 'host','defaultValue':'localhost', 'wcfg':{'label':'Host name or IP'}, 'gridcfg':{'sticky':Tkinter.E} }) idf.append({'widgetType':Tkinter.Entry, 'name': 'port','defaultValue':'50000', 'wcfg':{'label':"Server's Port"}, 'gridcfg':{'sticky':Tkinter.E} }) self.idf = idf val = self.vf.getUserInput(idf) self.vf.socketComm.connectToServer(val['host'], int(val['port']), self.vf.server_cb) # create a threadsafe command queue from Queue import Queue self.vf.cmdQueue = Queue(-1) # infinite size self.vf.GUI.ROOT.after(10, self.vf.runServerCommands) if imdFound: class ConnectToImdServer(Command): """ This class implements method to connect to a imd server.""" def checkDependencies(self, vf): import thread def setup(self,hostname,port,molname,atmslist="",htype="steered"): self.host = hostname self.port = port self.molname = molname self.atmslist = atmslist self.htype = htype def doit(self,gui=True): import thread if self.vf.hasGui and gui: idf = InputFormDescr("Viewerframework imd server connection!") idf.append({'widgetType':Tkinter.Entry, 'name': 'host','defaultValue':'localhost', 'wcfg':{'label':'Host name or IP'}, 'gridcfg':{'sticky':Tkinter.E} }) idf.append({'widgetType':Tkinter.Entry, 'name': 'port','defaultValue':'2030', 'wcfg':{'label':"Server's Port"}, 'gridcfg':{'sticky':Tkinter.E} }) idf.append({'widgetType':Tkinter.Entry, 'name': 'molname','defaultValue':'', 'wcfg':{'label':"molecule name"}, 'gridcfg':{'sticky':Tkinter.E} }) idf.append({'widgetType':Tkinter.Entry, 'name': 'handler','defaultValue':'', 'wcfg':{'label':"handler atoms"}, 'gridcfg':{'sticky':Tkinter.E} }) idf.append({'widgetType':Tkinter.Entry, 'name': 'htype','defaultValue':'', 'wcfg':{'label':"handler type"}, 'gridcfg':{'sticky':Tkinter.E} }) self.idf = idf val = self.vf.getUserInput(idf) mol = self.vf.getMolFromName(val['molname']) host = val['host'] port = val['port'] atmslist = val['handler'] #exple htype = val["htype"] if len(htype) ==0 : htype = "steered" else : mol = self.vf.getMolFromName(self.molname) host = self.host port = self.port atmslist = self.atmslist htype = self.htype if type(mol) is list : slot =[] for m in mol : m.allAtoms.addConformation(m.allAtoms.coords[:]) slot.append( len(m.allAtoms[0]._coords) - 1) else : mol.allAtoms.addConformation(mol.allAtoms.coords[:]) slot = len(mol.allAtoms[0]._coords) - 1 self.vf.browseCommands('imdCommands',package='ViewerFramework', topCommand=0) #if two molecule if type(mol) is list : N=0 for m in mol : N+=len(m.allAtoms.coords) self.vf.imd.mindy = True #setup the file ? pdb, parameters, psf self.vf.imd.pdbFile = "/local/MGL/MGLTools-1.5.6/MGLToolsPckgs/ARDemo/mindy/two_alanin.pdb" self.vf.imd.psfFile = "/local/MGL/MGLTools-1.5.6/MGLToolsPckgs/ARDemo/mindy/two_alanin.psf" self.vf.imd.paraFile = "/local/MGL/MGLTools-1.5.6/MGLToolsPckgs/ARDemo/mindy/alanin.params" self.vf.imd.fixedAtoms = [] self.vf.imd.init(host, 0,0, int(port), 1 , 0,N ) else : self.vf.imd.init(host, 0,0, int(port), 1 , 0,len(mol.allAtoms) ) if not self.vf.imd.mindy : self.vf.imd.imd_pause() else : self.vf.imd.mol = mol self.vf.imd.slot = slot #self.vf.imd.gui = True #set coord at time 0 #get all coordinate, and the total count #i will first translate mol2 # m2 = self.vf.imd.mol[0] # vt = [] # M=[0.,0,0] # #vt=util.ApplyMatrix(Numeric.array(self.mol2.allAtoms.coords),M) # for pt in m2.allAtoms.coords: # ptx = pt[0]+M[0] # pty = pt[1]+M[1] # ptz = pt[2]+M[2] # vt.append( (ptx, pty, ptz) ) # # m2.allAtoms.updateCoords(vt,ind=0) coords=[] N=0 for m in self.vf.imd.mol: if hasattr(self.vf,'art'): self.vf.art.doimd = True from ARViewer import util import numpy.oldnumeric as Numeric M = m.pat.mat_transfo vt=util.ApplyMatrix(Numeric.array(m.allAtoms.coords),M,transpose=False) else : vt=m.allAtoms.coords[:] N+=len(m.allAtoms.coords) coords.extend(vt) self.vf.imd.N = N print "sendFcoords" self.vf.imd.imd_send_fcoords(self.vf.imd.N,coords) self.vf.browseCommands('handlerCommand',package='ViewerFramework', topCommand=0) self.vf.handler.isinited = False if len(atmslist) : atms = self.vf.select(atmslist) self.vf.handler.create(atms,forceType=htype) if self.vf.hasGui and self.vf.imd.gui : if not self.vf.imd.mindy : self.vf.imd.start() print "after" self.vf.GUI.ROOT.after(1, self.vf.updateIMD) # add StartServer Command StartServerGUI = CommandGUI() StartServerGUI.addMenuCommand('menuRoot', 'File', 'start server', cascadeName='server', cascadeBefore='Exit') # add StartWebControlServer Command StartWebControlServerGUI = CommandGUI() StartWebControlServerGUI.addMenuCommand( 'menuRoot', 'File', 'start web controller', cascadeName='server') # add ConnectToServer Command ConnectToServerGUI = CommandGUI() ConnectToServerGUI.addMenuCommand( 'menuRoot', 'File', 'connect to server', cascadeName='server') # add ConnectToImdServer Command if imdFound: ConnectToImdServerGUI = CommandGUI() ConnectToImdServerGUI.addMenuCommand( 'menuRoot', 'File', 'connect to imd server', cascadeName='server') # add WebDrivenTutorial Command WebDrivenTutorialGUI = CommandGUI() WebDrivenTutorialGUI.addMenuCommand( 'menuRoot', 'File', 'web tutorial') commandList = [ {'name':'startServer', 'cmd':StartServer(), 'gui': StartServerGUI}, {'name':'connectToServer', 'cmd':ConnectToServer(), 'gui': ConnectToServerGUI}, {'name':'StartWebControlServer', 'cmd':StartWebControlServer(), 'gui': StartWebControlServerGUI}, {'name':'web tutorial', 'cmd':WebDrivenTutorial(), 'gui': WebDrivenTutorialGUI}, ] if imdFound: commandList.append( {'name':'connectToImdServer', 'cmd':ConnectToImdServer(), 'gui': ConnectToImdServerGUI}) def initModule(viewer): for dict in commandList: # print 'dict',dict viewer.addCommand(dict['cmd'], dict['name'], dict['gui']) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/ColorMaps/0000755000175000017500000000000012326214505024033 5ustar moellermoellerViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/ColorMaps/bgr256_map.py0000644000175000017500000003700010651433475026261 0ustar moellermoeller## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by from DejaVu.colorMap import ColorMap from numpy.oldnumeric import array cm = ColorMap('bgr256') cfg = {'name': 'bgr256', 'ramp': array([[ 1. , 0. , 0. , 1. ], [ 1. , 0. , 0. , 1. ], [ 1. , 0.024 , 0. , 1. ], [ 1. , 0.048 , 0. , 1. ], [ 1. , 0.048 , 0. , 1. ], [ 1. , 0.066 , 0. , 1. ], [ 1. , 0.09 , 0. , 1. ], [ 1. , 0.09 , 0. , 1. ], [ 1. , 0.114 , 0. , 1. ], [ 1. , 0.138 , 0. , 1. ], [ 1. , 0.138 , 0. , 1. ], [ 1. , 0.162 , 0. , 1. ], [ 1. , 0.18000001, 0. , 1. ], [ 1. , 0.18000001, 0. , 1. ], [ 1. , 0.204 , 0. , 1. ], [ 1. , 0.228 , 0. , 1. ], [ 1. , 0.228 , 0. , 1. ], [ 1. , 0.252 , 0. , 1. ], [ 1. , 0.27599999, 0. , 1. ], [ 1. , 0.30000001, 0. , 1. ], [ 1. , 0.30000001, 0. , 1. ], [ 1. , 0.31799999, 0. , 1. ], [ 1. , 0.34200001, 0. , 1. ], [ 1. , 0.34200001, 0. , 1. ], [ 1. , 0.366 , 0. , 1. ], [ 1. , 0.38999999, 0. , 1. ], [ 1. , 0.38999999, 0. , 1. ], [ 1. , 0.414 , 0. , 1. ], [ 1. , 0.43200001, 0. , 1. ], [ 1. , 0.43200001, 0. , 1. ], [ 1. , 0.456 , 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.50400001, 0. , 1. ], [ 1. , 0.528 , 0. , 1. ], [ 1. , 0.546 , 0. , 1. ], [ 1. , 0.546 , 0. , 1. ], [ 1. , 0.56999999, 0. , 1. ], [ 1. , 0.59399998, 0. , 1. ], [ 1. , 0.59399998, 0. , 1. ], [ 1. , 0.61799997, 0. , 1. ], [ 1. , 0.64200002, 0. , 1. ], [ 1. , 0.64200002, 0. , 1. ], [ 1. , 0.66000003, 0. , 1. ], [ 1. , 0.68400002, 0. , 1. ], [ 1. , 0.68400002, 0. , 1. ], [ 1. , 0.708 , 0. , 1. ], [ 1. , 0.73199999, 0. , 1. ], [ 1. , 0.73199999, 0. , 1. ], [ 1. , 0.75599998, 0. , 1. ], [ 1. , 0.77999997, 0. , 1. ], [ 1. , 0.79799998, 0. , 1. ], [ 1. , 0.79799998, 0. , 1. ], [ 1. , 0.82200003, 0. , 1. ], [ 1. , 0.84600002, 0. , 1. ], [ 1. , 0.84600002, 0. , 1. ], [ 1. , 0.87 , 0. , 1. ], [ 1. , 0.89399999, 0. , 1. ], [ 1. , 0.89399999, 0. , 1. ], [ 1. , 0.912 , 0. , 1. ], [ 1. , 0.93599999, 0. , 1. ], [ 1. , 0.93599999, 0. , 1. ], [ 1. , 0.95999998, 0. , 1. ], [ 1. , 0.98400003, 0. , 1. ], [ 1. , 0.98400003, 0. , 1. ], [ 0.99199998, 1. , 0. , 1. ], [ 0.97399998, 1. , 0. , 1. ], [ 0.97399998, 1. , 0. , 1. ], [ 0.94999999, 1. , 0. , 1. ], [ 0.926 , 1. , 0. , 1. ], [ 0.90200001, 1. , 0. , 1. ], [ 0.90200001, 1. , 0. , 1. ], [ 0.87800002, 1. , 0. , 1. ], [ 0.86000001, 1. , 0. , 1. ], [ 0.86000001, 1. , 0. , 1. ], [ 0.83600003, 1. , 0. , 1. ], [ 0.81199998, 1. , 0. , 1. ], [ 0.81199998, 1. , 0. , 1. ], [ 0.78799999, 1. , 0. , 1. ], [ 0.764 , 1. , 0. , 1. ], [ 0.764 , 1. , 0. , 1. ], [ 0.74000001, 1. , 0. , 1. ], [ 0.722 , 1. , 0. , 1. ], [ 0.722 , 1. , 0. , 1. ], [ 0.69800001, 1. , 0. , 1. ], [ 0.67400002, 1. , 0. , 1. ], [ 0.64999998, 1. , 0. , 1. ], [ 0.64999998, 1. , 0. , 1. ], [ 0.62599999, 1. , 0. , 1. ], [ 0.60799998, 1. , 0. , 1. ], [ 0.60799998, 1. , 0. , 1. ], [ 0.58399999, 1. , 0. , 1. ], [ 0.56 , 1. , 0. , 1. ], [ 0.56 , 1. , 0. , 1. ], [ 0.53600001, 1. , 0. , 1. ], [ 0.51200002, 1. , 0. , 1. ], [ 0.51200002, 1. , 0. , 1. ], [ 0.49399999, 1. , 0. , 1. ], [ 0.47 , 1. , 0. , 1. ], [ 0.47 , 1. , 0. , 1. ], [ 0.44600001, 1. , 0. , 1. ], [ 0.42199999, 1. , 0. , 1. ], [ 0.398 , 1. , 0. , 1. ], [ 0.398 , 1. , 0. , 1. ], [ 0.38 , 1. , 0. , 1. ], [ 0.35600001, 1. , 0. , 1. ], [ 0.35600001, 1. , 0. , 1. ], [ 0.33199999, 1. , 0. , 1. ], [ 0.308 , 1. , 0. , 1. ], [ 0.308 , 1. , 0. , 1. ], [ 0.28400001, 1. , 0. , 1. ], [ 0.25999999, 1. , 0. , 1. ], [ 0.25999999, 1. , 0. , 1. ], [ 0.242 , 1. , 0. , 1. ], [ 0.21799999, 1. , 0. , 1. ], [ 0.21799999, 1. , 0. , 1. ], [ 0.19400001, 1. , 0. , 1. ], [ 0.17 , 1. , 0. , 1. ], [ 0.17 , 1. , 0. , 1. ], [ 0.146 , 1. , 0. , 1. ], [ 0.12800001, 1. , 0. , 1. ], [ 0.104 , 1. , 0. , 1. ], [ 0.104 , 1. , 0. , 1. ], [ 0.08 , 1. , 0. , 1. ], [ 0.056 , 1. , 0. , 1. ], [ 0.056 , 1. , 0. , 1. ], [ 0.032 , 1. , 0. , 1. ], [ 0.014 , 1. , 0. , 1. ], [ 0.014 , 1. , 0. , 1. ], [ 0. , 1. , 0.01 , 1. ], [ 0. , 1. , 0.034 , 1. ], [ 0. , 1. , 0.034 , 1. ], [ 0. , 1. , 0.058 , 1. ], [ 0. , 1. , 0.082 , 1. ], [ 0. , 1. , 0.082 , 1. ], [ 0. , 1. , 0.1 , 1. ], [ 0. , 1. , 0.124 , 1. ], [ 0. , 1. , 0.148 , 1. ], [ 0. , 1. , 0.148 , 1. ], [ 0. , 1. , 0.17200001, 1. ], [ 0. , 1. , 0.19599999, 1. ], [ 0. , 1. , 0.19599999, 1. ], [ 0. , 1. , 0.22 , 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.26199999, 1. ], [ 0. , 1. , 0.28600001, 1. ], [ 0. , 1. , 0.28600001, 1. ], [ 0. , 1. , 0.31 , 1. ], [ 0. , 1. , 0.33399999, 1. ], [ 0. , 1. , 0.33399999, 1. ], [ 0. , 1. , 0.352 , 1. ], [ 0. , 1. , 0.37599999, 1. ], [ 0. , 1. , 0.40000001, 1. ], [ 0. , 1. , 0.40000001, 1. ], [ 0. , 1. , 0.42399999, 1. ], [ 0. , 1. , 0.44800001, 1. ], [ 0. , 1. , 0.44800001, 1. ], [ 0. , 1. , 0.46599999, 1. ], [ 0. , 1. , 0.49000001, 1. ], [ 0. , 1. , 0.49000001, 1. ], [ 0. , 1. , 0.514 , 1. ], [ 0. , 1. , 0.53799999, 1. ], [ 0. , 1. , 0.53799999, 1. ], [ 0. , 1. , 0.56199998, 1. ], [ 0. , 1. , 0.57999998, 1. ], [ 0. , 1. , 0.57999998, 1. ], [ 0. , 1. , 0.60399997, 1. ], [ 0. , 1. , 0.62800002, 1. ], [ 0. , 1. , 0.62800002, 1. ], [ 0. , 1. , 0.65200001, 1. ], [ 0. , 1. , 0.676 , 1. ], [ 0. , 1. , 0.69999999, 1. ], [ 0. , 1. , 0.69999999, 1. ], [ 0. , 1. , 0.71799999, 1. ], [ 0. , 1. , 0.74199998, 1. ], [ 0. , 1. , 0.74199998, 1. ], [ 0. , 1. , 0.76599997, 1. ], [ 0. , 1. , 0.79000002, 1. ], [ 0. , 1. , 0.79000002, 1. ], [ 0. , 1. , 0.81400001, 1. ], [ 0. , 1. , 0.83200002, 1. ], [ 0. , 1. , 0.83200002, 1. ], [ 0. , 1. , 0.85600001, 1. ], [ 0. , 1. , 0.88 , 1. ], [ 0. , 1. , 0.88 , 1. ], [ 0. , 1. , 0.90399998, 1. ], [ 0. , 1. , 0.92799997, 1. ], [ 0. , 1. , 0.94599998, 1. ], [ 0. , 1. , 0.94599998, 1. ], [ 0. , 1. , 0.97000003, 1. ], [ 0. , 1. , 0.99400002, 1. ], [ 0. , 1. , 0.99400002, 1. ], [ 0. , 0.98199999, 1. , 1. ], [ 0. , 0.958 , 1. , 1. ], [ 0. , 0.958 , 1. , 1. ], [ 0. , 0.94 , 1. , 1. ], [ 0. , 0.91600001, 1. , 1. ], [ 0. , 0.91600001, 1. , 1. ], [ 0. , 0.89200002, 1. , 1. ], [ 0. , 0.86799997, 1. , 1. ], [ 0. , 0.86799997, 1. , 1. ], [ 0. , 0.84399998, 1. , 1. ], [ 0. , 0.81999999, 1. , 1. ], [ 0. , 0.80199999, 1. , 1. ], [ 0. , 0.80199999, 1. , 1. ], [ 0. , 0.778 , 1. , 1. ], [ 0. , 0.75400001, 1. , 1. ], [ 0. , 0.75400001, 1. , 1. ], [ 0. , 0.73000002, 1. , 1. ], [ 0. , 0.70599997, 1. , 1. ], [ 0. , 0.70599997, 1. , 1. ], [ 0. , 0.68800002, 1. , 1. ], [ 0. , 0.66399997, 1. , 1. ], [ 0. , 0.66399997, 1. , 1. ], [ 0. , 0.63999999, 1. , 1. ], [ 0. , 0.616 , 1. , 1. ], [ 0. , 0.616 , 1. , 1. ], [ 0. , 0.59200001, 1. , 1. ], [ 0. , 0.574 , 1. , 1. ], [ 0. , 0.574 , 1. , 1. ], [ 0. , 0.55000001, 1. , 1. ], [ 0. , 0.52600002, 1. , 1. ], [ 0. , 0.50199997, 1. , 1. ], [ 0. , 0.50199997, 1. , 1. ], [ 0. , 0.47799999, 1. , 1. ], [ 0. , 0.46000001, 1. , 1. ], [ 0. , 0.46000001, 1. , 1. ], [ 0. , 0.43599999, 1. , 1. ], [ 0. , 0.412 , 1. , 1. ], [ 0. , 0.412 , 1. , 1. ], [ 0. , 0.38800001, 1. , 1. ], [ 0. , 0.36399999, 1. , 1. ], [ 0. , 0.36399999, 1. , 1. ], [ 0. , 0.34 , 1. , 1. ], [ 0. , 0.322 , 1. , 1. ], [ 0. , 0.322 , 1. , 1. ], [ 0. , 0.29800001, 1. , 1. ], [ 0. , 0.27399999, 1. , 1. ], [ 0. , 0.25 , 1. , 1. ], [ 0. , 0.25 , 1. , 1. ], [ 0. , 0.226 , 1. , 1. ], [ 0. , 0.208 , 1. , 1. ], [ 0. , 0.208 , 1. , 1. ], [ 0. , 0.184 , 1. , 1. ], [ 0. , 0.16 , 1. , 1. ], [ 0. , 0.16 , 1. , 1. ], [ 0. , 0.13600001, 1. , 1. ], [ 0. , 0.112 , 1. , 1. ], [ 0. , 0.112 , 1. , 1. ], [ 0. , 0.094 , 1. , 1. ], [ 0. , 0.07 , 1. , 1. ], [ 0. , 0.07 , 1. , 1. ], [ 0. , 0.046 , 1. , 1. ], [ 0. , 0.022 , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ]],'f'), 'maxi': 10.0, 'mini': 0.0} apply( cm.configure, (), cfg) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/ColorMaps/rgb10_map.py0000644000175000017500000003677610651433475026210 0ustar moellermoeller## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by from DejaVu.colorMap import ColorMap from numpy.oldnumeric import array cm = ColorMap('rgb10') cfg = {'name': 'rgb10', 'ramp': array([[ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.442 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 0.88 , 1. , 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.68199998, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0. , 1. , 0.23800001, 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.2 , 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 0.63800001, 1. , 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.91799998, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.47999999, 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ], [ 1. , 0.042 , 0. , 1. ]],'f'), 'maxi': 10.0, 'mini': 0.0} apply( cm.configure, (), cfg) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/ColorMaps/rgb128_map.py0000644000175000017500000000660410651433475026265 0ustar moellermoeller## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by from DejaVu.colorMap import ColorMap from numpy.oldnumeric import array cm = ColorMap('rgb128') cfg = {'name': 'rgb128', 'ramp': [[0.0, 0.0, 1.0, 1.0], [0.0, 0.03125, 1.0, 1.0], [0.0, 0.0625, 1.0, 1.0], [0.0, 0.09375, 1.0, 1.0], [0.0, 0.125, 1.0, 1.0], [0.0, 0.15625, 1.0, 1.0], [0.0, 0.1875, 1.0, 1.0], [0.0, 0.21875, 1.0, 1.0], [0.0, 0.25, 1.0, 1.0], [0.0, 0.28125, 1.0, 1.0], [0.0, 0.3125, 1.0, 1.0], [0.0, 0.34375, 1.0, 1.0], [0.0, 0.375, 1.0, 1.0], [0.0, 0.40625, 1.0, 1.0], [0.0, 0.4375, 1.0, 1.0], [0.0, 0.46875, 1.0, 1.0], [0.0, 0.5, 1.0, 1.0], [0.0, 0.53125, 1.0, 1.0], [0.0, 0.5625, 1.0, 1.0], [0.0, 0.59375, 1.0, 1.0], [0.0, 0.625, 1.0, 1.0], [0.0, 0.65625, 1.0, 1.0], [0.0, 0.6875, 1.0, 1.0], [0.0, 0.71875, 1.0, 1.0], [0.0, 0.75, 1.0, 1.0], [0.0, 0.78125, 1.0, 1.0], [0.0, 0.8125, 1.0, 1.0], [0.0, 0.84375, 1.0, 1.0], [0.0, 0.875, 1.0, 1.0], [0.0, 0.90625, 1.0, 1.0], [0.0, 0.9375, 1.0, 1.0], [0.0, 0.96875, 1.0, 1.0], [0.0, 1.0, 1.0, 1.0], [0.0, 1.0, 0.96875, 1.0], [0.0, 1.0, 0.9375, 1.0], [0.0, 1.0, 0.90625, 1.0], [0.0, 1.0, 0.875, 1.0], [0.0, 1.0, 0.84375, 1.0], [0.0, 1.0, 0.8125, 1.0], [0.0, 1.0, 0.78125, 1.0], [0.0, 1.0, 0.75, 1.0], [0.0, 1.0, 0.71875, 1.0], [0.0, 1.0, 0.6875, 1.0], [0.0, 1.0, 0.65625, 1.0], [0.0, 1.0, 0.625, 1.0], [0.0, 1.0, 0.59375, 1.0], [0.0, 1.0, 0.5625, 1.0], [0.0, 1.0, 0.53125, 1.0], [0.0, 1.0, 0.5, 1.0], [0.0, 1.0, 0.46875, 1.0], [0.0, 1.0, 0.4375, 1.0], [0.0, 1.0, 0.40625, 1.0], [0.0, 1.0, 0.375, 1.0], [0.0, 1.0, 0.34375, 1.0], [0.0, 1.0, 0.3125, 1.0], [0.0, 1.0, 0.28125, 1.0], [0.0, 1.0, 0.25, 1.0], [0.0, 1.0, 0.21875, 1.0], [0.0, 1.0, 0.1875, 1.0], [0.0, 1.0, 0.15625, 1.0], [0.0, 1.0, 0.125, 1.0], [0.0, 1.0, 0.09375, 1.0], [0.0, 1.0, 0.0625, 1.0], [0.0, 1.0, 0.03125, 1.0], [0.0, 1.0, 0.0, 1.0], [0.03125, 1.0, 0.0, 1.0], [0.0625, 1.0, 0.0, 1.0], [0.09375, 1.0, 0.0, 1.0], [0.125, 1.0, 0.0, 1.0], [0.15625, 1.0, 0.0, 1.0], [0.1875, 1.0, 0.0, 1.0], [0.21875, 1.0, 0.0, 1.0], [0.25, 1.0, 0.0, 1.0], [0.28125, 1.0, 0.0, 1.0], [0.3125, 1.0, 0.0, 1.0], [0.34375, 1.0, 0.0, 1.0], [0.375, 1.0, 0.0, 1.0], [0.40625, 1.0, 0.0, 1.0], [0.4375, 1.0, 0.0, 1.0], [0.46875, 1.0, 0.0, 1.0], [0.5, 1.0, 0.0, 1.0], [0.53125, 1.0, 0.0, 1.0], [0.5625, 1.0, 0.0, 1.0], [0.59375, 1.0, 0.0, 1.0], [0.625, 1.0, 0.0, 1.0], [0.65625, 1.0, 0.0, 1.0], [0.6875, 1.0, 0.0, 1.0], [0.71875, 1.0, 0.0, 1.0], [0.75, 1.0, 0.0, 1.0], [0.78125, 1.0, 0.0, 1.0], [0.8125, 1.0, 0.0, 1.0], [0.84375, 1.0, 0.0, 1.0], [0.875, 1.0, 0.0, 1.0], [0.90625, 1.0, 0.0, 1.0], [0.9375, 1.0, 0.0, 1.0], [0.96875, 1.0, 0.0, 1.0], [1.0, 1.0, 0.0, 1.0], [1.0, 0.96875, 0.0, 1.0], [1.0, 0.9375, 0.0, 1.0], [1.0, 0.90625, 0.0, 1.0], [1.0, 0.875, 0.0, 1.0], [1.0, 0.84375, 0.0, 1.0], [1.0, 0.8125, 0.0, 1.0], [1.0, 0.78125, 0.0, 1.0], [1.0, 0.75, 0.0, 1.0], [1.0, 0.71875, 0.0, 1.0], [1.0, 0.6875, 0.0, 1.0], [1.0, 0.65625, 0.0, 1.0], [1.0, 0.625, 0.0, 1.0], [1.0, 0.59375, 0.0, 1.0], [1.0, 0.5625, 0.0, 1.0], [1.0, 0.53125, 0.0, 1.0], [1.0, 0.5, 0.0, 1.0], [1.0, 0.46875, 0.0, 1.0], [1.0, 0.4375, 0.0, 1.0], [1.0, 0.40625, 0.0, 1.0], [1.0, 0.375, 0.0, 1.0], [1.0, 0.34375, 0.0, 1.0], [1.0, 0.3125, 0.0, 1.0], [1.0, 0.28125, 0.0, 1.0], [1.0, 0.25, 0.0, 1.0], [1.0, 0.21875, 0.0, 1.0], [1.0, 0.1875, 0.0, 1.0], [1.0, 0.15625, 0.0, 1.0], [1.0, 0.125, 0.0, 1.0], [1.0, 0.09375, 0.0, 1.0], [1.0, 0.0625, 0.0, 1.0], [1.0, 0.03125, 0.0, 1.0]], 'maxi': 10.0, 'mini': 0.0} apply( cm.configure, (), cfg) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/ColorMaps/rgb256_map.py0000644000175000017500000003300010651433475026255 0ustar moellermoeller## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by from DejaVu.colorMap import ColorMap from numpy.oldnumeric import array cm = ColorMap('rgb256') cfg = {'name': 'rgb256', 'ramp': array([[ 0. , 0. , 1. , 1. ], [ 0. , 0.015625, 1. , 1. ], [ 0. , 0.03125 , 1. , 1. ], [ 0. , 0.046875, 1. , 1. ], [ 0. , 0.0625 , 1. , 1. ], [ 0. , 0.078125, 1. , 1. ], [ 0. , 0.09375 , 1. , 1. ], [ 0. , 0.109375, 1. , 1. ], [ 0. , 0.125 , 1. , 1. ], [ 0. , 0.140625, 1. , 1. ], [ 0. , 0.15625 , 1. , 1. ], [ 0. , 0.171875, 1. , 1. ], [ 0. , 0.1875 , 1. , 1. ], [ 0. , 0.203125, 1. , 1. ], [ 0. , 0.21875 , 1. , 1. ], [ 0. , 0.234375, 1. , 1. ], [ 0. , 0.25 , 1. , 1. ], [ 0. , 0.265625, 1. , 1. ], [ 0. , 0.28125 , 1. , 1. ], [ 0. , 0.296875, 1. , 1. ], [ 0. , 0.3125 , 1. , 1. ], [ 0. , 0.328125, 1. , 1. ], [ 0. , 0.34375 , 1. , 1. ], [ 0. , 0.359375, 1. , 1. ], [ 0. , 0.375 , 1. , 1. ], [ 0. , 0.390625, 1. , 1. ], [ 0. , 0.40625 , 1. , 1. ], [ 0. , 0.421875, 1. , 1. ], [ 0. , 0.4375 , 1. , 1. ], [ 0. , 0.453125, 1. , 1. ], [ 0. , 0.46875 , 1. , 1. ], [ 0. , 0.484375, 1. , 1. ], [ 0. , 0.5 , 1. , 1. ], [ 0. , 0.515625, 1. , 1. ], [ 0. , 0.53125 , 1. , 1. ], [ 0. , 0.546875, 1. , 1. ], [ 0. , 0.5625 , 1. , 1. ], [ 0. , 0.578125, 1. , 1. ], [ 0. , 0.59375 , 1. , 1. ], [ 0. , 0.609375, 1. , 1. ], [ 0. , 0.625 , 1. , 1. ], [ 0. , 0.640625, 1. , 1. ], [ 0. , 0.65625 , 1. , 1. ], [ 0. , 0.671875, 1. , 1. ], [ 0. , 0.6875 , 1. , 1. ], [ 0. , 0.703125, 1. , 1. ], [ 0. , 0.71875 , 1. , 1. ], [ 0. , 0.734375, 1. , 1. ], [ 0. , 0.75 , 1. , 1. ], [ 0. , 0.765625, 1. , 1. ], [ 0. , 0.78125 , 1. , 1. ], [ 0. , 0.796875, 1. , 1. ], [ 0. , 0.8125 , 1. , 1. ], [ 0. , 0.828125, 1. , 1. ], [ 0. , 0.84375 , 1. , 1. ], [ 0. , 0.859375, 1. , 1. ], [ 0. , 0.875 , 1. , 1. ], [ 0. , 0.890625, 1. , 1. ], [ 0. , 0.90625 , 1. , 1. ], [ 0. , 0.921875, 1. , 1. ], [ 0. , 0.9375 , 1. , 1. ], [ 0. , 0.953125, 1. , 1. ], [ 0. , 0.96875 , 1. , 1. ], [ 0. , 0.984375, 1. , 1. ], [ 0. , 1. , 1. , 1. ], [ 0. , 1. , 0.984375, 1. ], [ 0. , 1. , 0.96875 , 1. ], [ 0. , 1. , 0.953125, 1. ], [ 0. , 1. , 0.9375 , 1. ], [ 0. , 1. , 0.921875, 1. ], [ 0. , 1. , 0.90625 , 1. ], [ 0. , 1. , 0.890625, 1. ], [ 0. , 1. , 0.875 , 1. ], [ 0. , 1. , 0.859375, 1. ], [ 0. , 1. , 0.84375 , 1. ], [ 0. , 1. , 0.828125, 1. ], [ 0. , 1. , 0.8125 , 1. ], [ 0. , 1. , 0.796875, 1. ], [ 0. , 1. , 0.78125 , 1. ], [ 0. , 1. , 0.765625, 1. ], [ 0. , 1. , 0.75 , 1. ], [ 0. , 1. , 0.734375, 1. ], [ 0. , 1. , 0.71875 , 1. ], [ 0. , 1. , 0.703125, 1. ], [ 0. , 1. , 0.6875 , 1. ], [ 0. , 1. , 0.671875, 1. ], [ 0. , 1. , 0.65625 , 1. ], [ 0. , 1. , 0.640625, 1. ], [ 0. , 1. , 0.625 , 1. ], [ 0. , 1. , 0.609375, 1. ], [ 0. , 1. , 0.59375 , 1. ], [ 0. , 1. , 0.578125, 1. ], [ 0. , 1. , 0.5625 , 1. ], [ 0. , 1. , 0.546875, 1. ], [ 0. , 1. , 0.53125 , 1. ], [ 0. , 1. , 0.515625, 1. ], [ 0. , 1. , 0.5 , 1. ], [ 0. , 1. , 0.484375, 1. ], [ 0. , 1. , 0.46875 , 1. ], [ 0. , 1. , 0.453125, 1. ], [ 0. , 1. , 0.4375 , 1. ], [ 0. , 1. , 0.421875, 1. ], [ 0. , 1. , 0.40625 , 1. ], [ 0. , 1. , 0.390625, 1. ], [ 0. , 1. , 0.375 , 1. ], [ 0. , 1. , 0.359375, 1. ], [ 0. , 1. , 0.34375 , 1. ], [ 0. , 1. , 0.328125, 1. ], [ 0. , 1. , 0.3125 , 1. ], [ 0. , 1. , 0.296875, 1. ], [ 0. , 1. , 0.28125 , 1. ], [ 0. , 1. , 0.265625, 1. ], [ 0. , 1. , 0.25 , 1. ], [ 0. , 1. , 0.234375, 1. ], [ 0. , 1. , 0.21875 , 1. ], [ 0. , 1. , 0.203125, 1. ], [ 0. , 1. , 0.1875 , 1. ], [ 0. , 1. , 0.171875, 1. ], [ 0. , 1. , 0.15625 , 1. ], [ 0. , 1. , 0.140625, 1. ], [ 0. , 1. , 0.125 , 1. ], [ 0. , 1. , 0.109375, 1. ], [ 0. , 1. , 0.09375 , 1. ], [ 0. , 1. , 0.078125, 1. ], [ 0. , 1. , 0.0625 , 1. ], [ 0. , 1. , 0.046875, 1. ], [ 0. , 1. , 0.03125 , 1. ], [ 0. , 1. , 0.015625, 1. ], [ 0. , 1. , 0. , 1. ], [ 0.015625, 1. , 0. , 1. ], [ 0.03125 , 1. , 0. , 1. ], [ 0.046875, 1. , 0. , 1. ], [ 0.0625 , 1. , 0. , 1. ], [ 0.078125, 1. , 0. , 1. ], [ 0.09375 , 1. , 0. , 1. ], [ 0.109375, 1. , 0. , 1. ], [ 0.125 , 1. , 0. , 1. ], [ 0.140625, 1. , 0. , 1. ], [ 0.15625 , 1. , 0. , 1. ], [ 0.171875, 1. , 0. , 1. ], [ 0.1875 , 1. , 0. , 1. ], [ 0.203125, 1. , 0. , 1. ], [ 0.21875 , 1. , 0. , 1. ], [ 0.234375, 1. , 0. , 1. ], [ 0.25 , 1. , 0. , 1. ], [ 0.265625, 1. , 0. , 1. ], [ 0.28125 , 1. , 0. , 1. ], [ 0.296875, 1. , 0. , 1. ], [ 0.3125 , 1. , 0. , 1. ], [ 0.328125, 1. , 0. , 1. ], [ 0.34375 , 1. , 0. , 1. ], [ 0.359375, 1. , 0. , 1. ], [ 0.375 , 1. , 0. , 1. ], [ 0.390625, 1. , 0. , 1. ], [ 0.40625 , 1. , 0. , 1. ], [ 0.421875, 1. , 0. , 1. ], [ 0.4375 , 1. , 0. , 1. ], [ 0.453125, 1. , 0. , 1. ], [ 0.46875 , 1. , 0. , 1. ], [ 0.484375, 1. , 0. , 1. ], [ 0.5 , 1. , 0. , 1. ], [ 0.515625, 1. , 0. , 1. ], [ 0.53125 , 1. , 0. , 1. ], [ 0.546875, 1. , 0. , 1. ], [ 0.5625 , 1. , 0. , 1. ], [ 0.578125, 1. , 0. , 1. ], [ 0.59375 , 1. , 0. , 1. ], [ 0.609375, 1. , 0. , 1. ], [ 0.625 , 1. , 0. , 1. ], [ 0.640625, 1. , 0. , 1. ], [ 0.65625 , 1. , 0. , 1. ], [ 0.671875, 1. , 0. , 1. ], [ 0.6875 , 1. , 0. , 1. ], [ 0.703125, 1. , 0. , 1. ], [ 0.71875 , 1. , 0. , 1. ], [ 0.734375, 1. , 0. , 1. ], [ 0.75 , 1. , 0. , 1. ], [ 0.765625, 1. , 0. , 1. ], [ 0.78125 , 1. , 0. , 1. ], [ 0.796875, 1. , 0. , 1. ], [ 0.8125 , 1. , 0. , 1. ], [ 0.828125, 1. , 0. , 1. ], [ 0.84375 , 1. , 0. , 1. ], [ 0.859375, 1. , 0. , 1. ], [ 0.875 , 1. , 0. , 1. ], [ 0.890625, 1. , 0. , 1. ], [ 0.90625 , 1. , 0. , 1. ], [ 0.921875, 1. , 0. , 1. ], [ 0.9375 , 1. , 0. , 1. ], [ 0.953125, 1. , 0. , 1. ], [ 0.96875 , 1. , 0. , 1. ], [ 0.984375, 1. , 0. , 1. ], [ 1. , 1. , 0. , 1. ], [ 1. , 0.984375, 0. , 1. ], [ 1. , 0.96875 , 0. , 1. ], [ 1. , 0.953125, 0. , 1. ], [ 1. , 0.9375 , 0. , 1. ], [ 1. , 0.921875, 0. , 1. ], [ 1. , 0.90625 , 0. , 1. ], [ 1. , 0.890625, 0. , 1. ], [ 1. , 0.875 , 0. , 1. ], [ 1. , 0.859375, 0. , 1. ], [ 1. , 0.84375 , 0. , 1. ], [ 1. , 0.828125, 0. , 1. ], [ 1. , 0.8125 , 0. , 1. ], [ 1. , 0.796875, 0. , 1. ], [ 1. , 0.78125 , 0. , 1. ], [ 1. , 0.765625, 0. , 1. ], [ 1. , 0.75 , 0. , 1. ], [ 1. , 0.734375, 0. , 1. ], [ 1. , 0.71875 , 0. , 1. ], [ 1. , 0.703125, 0. , 1. ], [ 1. , 0.6875 , 0. , 1. ], [ 1. , 0.671875, 0. , 1. ], [ 1. , 0.65625 , 0. , 1. ], [ 1. , 0.640625, 0. , 1. ], [ 1. , 0.625 , 0. , 1. ], [ 1. , 0.609375, 0. , 1. ], [ 1. , 0.59375 , 0. , 1. ], [ 1. , 0.578125, 0. , 1. ], [ 1. , 0.5625 , 0. , 1. ], [ 1. , 0.546875, 0. , 1. ], [ 1. , 0.53125 , 0. , 1. ], [ 1. , 0.515625, 0. , 1. ], [ 1. , 0.5 , 0. , 1. ], [ 1. , 0.484375, 0. , 1. ], [ 1. , 0.46875 , 0. , 1. ], [ 1. , 0.453125, 0. , 1. ], [ 1. , 0.4375 , 0. , 1. ], [ 1. , 0.421875, 0. , 1. ], [ 1. , 0.40625 , 0. , 1. ], [ 1. , 0.390625, 0. , 1. ], [ 1. , 0.375 , 0. , 1. ], [ 1. , 0.359375, 0. , 1. ], [ 1. , 0.34375 , 0. , 1. ], [ 1. , 0.328125, 0. , 1. ], [ 1. , 0.3125 , 0. , 1. ], [ 1. , 0.296875, 0. , 1. ], [ 1. , 0.28125 , 0. , 1. ], [ 1. , 0.265625, 0. , 1. ], [ 1. , 0.25 , 0. , 1. ], [ 1. , 0.234375, 0. , 1. ], [ 1. , 0.21875 , 0. , 1. ], [ 1. , 0.203125, 0. , 1. ], [ 1. , 0.1875 , 0. , 1. ], [ 1. , 0.171875, 0. , 1. ], [ 1. , 0.15625 , 0. , 1. ], [ 1. , 0.140625, 0. , 1. ], [ 1. , 0.125 , 0. , 1. ], [ 1. , 0.109375, 0. , 1. ], [ 1. , 0.09375 , 0. , 1. ], [ 1. , 0.078125, 0. , 1. ], [ 1. , 0.0625 , 0. , 1. ], [ 1. , 0.046875, 0. , 1. ], [ 1. , 0.03125 , 0. , 1. ], [ 1. , 0.015625, 0. , 1. ]],'f'), 'maxi': 10.0, 'mini': 0.0} apply( cm.configure, (), cfg) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/ColorMaps/rw256_map.py0000644000175000017500000003677610651433475026162 0ustar moellermoeller## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by from DejaVu.colorMap import ColorMap from numpy.oldnumeric import array cm = ColorMap('rw256') cfg = {'name': 'rw256', 'ramp': array([[ 1. , 1. , 1. , 1. ], [ 1. , 1. , 1. , 1. ], [ 1. , 0.99400002, 0.99400002, 1. ], [ 1. , 0.98900002, 0.98900002, 1. ], [ 1. , 0.98900002, 0.98900002, 1. ], [ 1. , 0.98299998, 0.98299998, 1. ], [ 1. , 0.977 , 0.977 , 1. ], [ 1. , 0.977 , 0.977 , 1. ], [ 1. , 0.97100002, 0.97100002, 1. ], [ 1. , 0.96600002, 0.96600002, 1. ], [ 1. , 0.96600002, 0.96600002, 1. ], [ 1. , 0.95999998, 0.95999998, 1. ], [ 1. , 0.954 , 0.954 , 1. ], [ 1. , 0.954 , 0.954 , 1. ], [ 1. , 0.949 , 0.949 , 1. ], [ 1. , 0.94300002, 0.94300002, 1. ], [ 1. , 0.94300002, 0.94300002, 1. ], [ 1. , 0.93699998, 0.93699998, 1. ], [ 1. , 0.93099999, 0.93099999, 1. ], [ 1. , 0.926 , 0.926 , 1. ], [ 1. , 0.926 , 0.926 , 1. ], [ 1. , 0.92000002, 0.92000002, 1. ], [ 1. , 0.91399997, 0.91399997, 1. ], [ 1. , 0.91399997, 0.91399997, 1. ], [ 1. , 0.90899998, 0.90899998, 1. ], [ 1. , 0.903 , 0.903 , 1. ], [ 1. , 0.903 , 0.903 , 1. ], [ 1. , 0.89700001, 0.89700001, 1. ], [ 1. , 0.89099997, 0.89099997, 1. ], [ 1. , 0.89099997, 0.89099997, 1. ], [ 1. , 0.88599998, 0.88599998, 1. ], [ 1. , 0.88 , 0.88 , 1. ], [ 1. , 0.88 , 0.88 , 1. ], [ 1. , 0.87400001, 0.87400001, 1. ], [ 1. , 0.86900002, 0.86900002, 1. ], [ 1. , 0.86299998, 0.86299998, 1. ], [ 1. , 0.86299998, 0.86299998, 1. ], [ 1. , 0.85699999, 0.85699999, 1. ], [ 1. , 0.85100001, 0.85100001, 1. ], [ 1. , 0.85100001, 0.85100001, 1. ], [ 1. , 0.84600002, 0.84600002, 1. ], [ 1. , 0.83999997, 0.83999997, 1. ], [ 1. , 0.83999997, 0.83999997, 1. ], [ 1. , 0.83399999, 0.83399999, 1. ], [ 1. , 0.829 , 0.829 , 1. ], [ 1. , 0.829 , 0.829 , 1. ], [ 1. , 0.82300001, 0.82300001, 1. ], [ 1. , 0.81699997, 0.81699997, 1. ], [ 1. , 0.81699997, 0.81699997, 1. ], [ 1. , 0.81099999, 0.81099999, 1. ], [ 1. , 0.80599999, 0.80599999, 1. ], [ 1. , 0.80000001, 0.80000001, 1. ], [ 1. , 0.80000001, 0.80000001, 1. ], [ 1. , 0.79400003, 0.79400003, 1. ], [ 1. , 0.78899997, 0.78899997, 1. ], [ 1. , 0.78899997, 0.78899997, 1. ], [ 1. , 0.78299999, 0.78299999, 1. ], [ 1. , 0.77700001, 0.77700001, 1. ], [ 1. , 0.77700001, 0.77700001, 1. ], [ 1. , 0.77100003, 0.77100003, 1. ], [ 1. , 0.76599997, 0.76599997, 1. ], [ 1. , 0.76599997, 0.76599997, 1. ], [ 1. , 0.75999999, 0.75999999, 1. ], [ 1. , 0.75400001, 0.75400001, 1. ], [ 1. , 0.75400001, 0.75400001, 1. ], [ 1. , 0.74900001, 0.74900001, 1. ], [ 1. , 0.74299997, 0.74299997, 1. ], [ 1. , 0.74299997, 0.74299997, 1. ], [ 1. , 0.73699999, 0.73699999, 1. ], [ 1. , 0.73100001, 0.73100001, 1. ], [ 1. , 0.72600001, 0.72600001, 1. ], [ 1. , 0.72600001, 0.72600001, 1. ], [ 1. , 0.72000003, 0.72000003, 1. ], [ 1. , 0.71399999, 0.71399999, 1. ], [ 1. , 0.71399999, 0.71399999, 1. ], [ 1. , 0.70899999, 0.70899999, 1. ], [ 1. , 0.70300001, 0.70300001, 1. ], [ 1. , 0.70300001, 0.70300001, 1. ], [ 1. , 0.69700003, 0.69700003, 1. ], [ 1. , 0.69099998, 0.69099998, 1. ], [ 1. , 0.69099998, 0.69099998, 1. ], [ 1. , 0.68599999, 0.68599999, 1. ], [ 1. , 0.68000001, 0.68000001, 1. ], [ 1. , 0.68000001, 0.68000001, 1. ], [ 1. , 0.67400002, 0.67400002, 1. ], [ 1. , 0.66900003, 0.66900003, 1. ], [ 1. , 0.66299999, 0.66299999, 1. ], [ 1. , 0.66299999, 0.66299999, 1. ], [ 1. , 0.65700001, 0.65700001, 1. ], [ 1. , 0.65100002, 0.65100002, 1. ], [ 1. , 0.65100002, 0.65100002, 1. ], [ 1. , 0.64600003, 0.64600003, 1. ], [ 1. , 0.63999999, 0.63999999, 1. ], [ 1. , 0.63999999, 0.63999999, 1. ], [ 1. , 0.634 , 0.634 , 1. ], [ 1. , 0.62900001, 0.62900001, 1. ], [ 1. , 0.62900001, 0.62900001, 1. ], [ 1. , 0.62300003, 0.62300003, 1. ], [ 1. , 0.61699998, 0.61699998, 1. ], [ 1. , 0.61699998, 0.61699998, 1. ], [ 1. , 0.611 , 0.611 , 1. ], [ 1. , 0.60600001, 0.60600001, 1. ], [ 1. , 0.60000002, 0.60000002, 1. ], [ 1. , 0.60000002, 0.60000002, 1. ], [ 1. , 0.59399998, 0.59399998, 1. ], [ 1. , 0.58899999, 0.58899999, 1. ], [ 1. , 0.58899999, 0.58899999, 1. ], [ 1. , 0.583 , 0.583 , 1. ], [ 1. , 0.57700002, 0.57700002, 1. ], [ 1. , 0.57700002, 0.57700002, 1. ], [ 1. , 0.57099998, 0.57099998, 1. ], [ 1. , 0.56599998, 0.56599998, 1. ], [ 1. , 0.56599998, 0.56599998, 1. ], [ 1. , 0.56 , 0.56 , 1. ], [ 1. , 0.55400002, 0.55400002, 1. ], [ 1. , 0.55400002, 0.55400002, 1. ], [ 1. , 0.54900002, 0.54900002, 1. ], [ 1. , 0.54299998, 0.54299998, 1. ], [ 1. , 0.54299998, 0.54299998, 1. ], [ 1. , 0.537 , 0.537 , 1. ], [ 1. , 0.53100002, 0.53100002, 1. ], [ 1. , 0.52600002, 0.52600002, 1. ], [ 1. , 0.52600002, 0.52600002, 1. ], [ 1. , 0.51999998, 0.51999998, 1. ], [ 1. , 0.514 , 0.514 , 1. ], [ 1. , 0.514 , 0.514 , 1. ], [ 1. , 0.509 , 0.509 , 1. ], [ 1. , 0.50300002, 0.50300002, 1. ], [ 1. , 0.50300002, 0.50300002, 1. ], [ 1. , 0.49700001, 0.49700001, 1. ], [ 1. , 0.491 , 0.491 , 1. ], [ 1. , 0.491 , 0.491 , 1. ], [ 1. , 0.486 , 0.486 , 1. ], [ 1. , 0.47999999, 0.47999999, 1. ], [ 1. , 0.47999999, 0.47999999, 1. ], [ 1. , 0.47400001, 0.47400001, 1. ], [ 1. , 0.46900001, 0.46900001, 1. ], [ 1. , 0.463 , 0.463 , 1. ], [ 1. , 0.463 , 0.463 , 1. ], [ 1. , 0.45699999, 0.45699999, 1. ], [ 1. , 0.45100001, 0.45100001, 1. ], [ 1. , 0.45100001, 0.45100001, 1. ], [ 1. , 0.44600001, 0.44600001, 1. ], [ 1. , 0.44 , 0.44 , 1. ], [ 1. , 0.44 , 0.44 , 1. ], [ 1. , 0.43399999, 0.43399999, 1. ], [ 1. , 0.42899999, 0.42899999, 1. ], [ 1. , 0.42899999, 0.42899999, 1. ], [ 1. , 0.42300001, 0.42300001, 1. ], [ 1. , 0.417 , 0.417 , 1. ], [ 1. , 0.417 , 0.417 , 1. ], [ 1. , 0.41100001, 0.41100001, 1. ], [ 1. , 0.40599999, 0.40599999, 1. ], [ 1. , 0.40000001, 0.40000001, 1. ], [ 1. , 0.40000001, 0.40000001, 1. ], [ 1. , 0.39399999, 0.39399999, 1. ], [ 1. , 0.389 , 0.389 , 1. ], [ 1. , 0.389 , 0.389 , 1. ], [ 1. , 0.38299999, 0.38299999, 1. ], [ 1. , 0.377 , 0.377 , 1. ], [ 1. , 0.377 , 0.377 , 1. ], [ 1. , 0.37099999, 0.37099999, 1. ], [ 1. , 0.366 , 0.366 , 1. ], [ 1. , 0.366 , 0.366 , 1. ], [ 1. , 0.36000001, 0.36000001, 1. ], [ 1. , 0.354 , 0.354 , 1. ], [ 1. , 0.354 , 0.354 , 1. ], [ 1. , 0.34900001, 0.34900001, 1. ], [ 1. , 0.34299999, 0.34299999, 1. ], [ 1. , 0.34299999, 0.34299999, 1. ], [ 1. , 0.33700001, 0.33700001, 1. ], [ 1. , 0.331 , 0.331 , 1. ], [ 1. , 0.32600001, 0.32600001, 1. ], [ 1. , 0.32600001, 0.32600001, 1. ], [ 1. , 0.31999999, 0.31999999, 1. ], [ 1. , 0.31400001, 0.31400001, 1. ], [ 1. , 0.31400001, 0.31400001, 1. ], [ 1. , 0.30899999, 0.30899999, 1. ], [ 1. , 0.303 , 0.303 , 1. ], [ 1. , 0.303 , 0.303 , 1. ], [ 1. , 0.29699999, 0.29699999, 1. ], [ 1. , 0.29100001, 0.29100001, 1. ], [ 1. , 0.29100001, 0.29100001, 1. ], [ 1. , 0.28600001, 0.28600001, 1. ], [ 1. , 0.28 , 0.28 , 1. ], [ 1. , 0.28 , 0.28 , 1. ], [ 1. , 0.27399999, 0.27399999, 1. ], [ 1. , 0.26899999, 0.26899999, 1. ], [ 1. , 0.26300001, 0.26300001, 1. ], [ 1. , 0.26300001, 0.26300001, 1. ], [ 1. , 0.257 , 0.257 , 1. ], [ 1. , 0.25099999, 0.25099999, 1. ], [ 1. , 0.25099999, 0.25099999, 1. ], [ 1. , 0.24600001, 0.24600001, 1. ], [ 1. , 0.23999999, 0.23999999, 1. ], [ 1. , 0.23999999, 0.23999999, 1. ], [ 1. , 0.234 , 0.234 , 1. ], [ 1. , 0.229 , 0.229 , 1. ], [ 1. , 0.229 , 0.229 , 1. ], [ 1. , 0.223 , 0.223 , 1. ], [ 1. , 0.21699999, 0.21699999, 1. ], [ 1. , 0.21699999, 0.21699999, 1. ], [ 1. , 0.211 , 0.211 , 1. ], [ 1. , 0.206 , 0.206 , 1. ], [ 1. , 0.2 , 0.2 , 1. ], [ 1. , 0.2 , 0.2 , 1. ], [ 1. , 0.19400001, 0.19400001, 1. ], [ 1. , 0.189 , 0.189 , 1. ], [ 1. , 0.189 , 0.189 , 1. ], [ 1. , 0.183 , 0.183 , 1. ], [ 1. , 0.177 , 0.177 , 1. ], [ 1. , 0.177 , 0.177 , 1. ], [ 1. , 0.171 , 0.171 , 1. ], [ 1. , 0.16599999, 0.16599999, 1. ], [ 1. , 0.16599999, 0.16599999, 1. ], [ 1. , 0.16 , 0.16 , 1. ], [ 1. , 0.154 , 0.154 , 1. ], [ 1. , 0.154 , 0.154 , 1. ], [ 1. , 0.149 , 0.149 , 1. ], [ 1. , 0.14300001, 0.14300001, 1. ], [ 1. , 0.14300001, 0.14300001, 1. ], [ 1. , 0.13699999, 0.13699999, 1. ], [ 1. , 0.131 , 0.131 , 1. ], [ 1. , 0.126 , 0.126 , 1. ], [ 1. , 0.126 , 0.126 , 1. ], [ 1. , 0.12 , 0.12 , 1. ], [ 1. , 0.114 , 0.114 , 1. ], [ 1. , 0.114 , 0.114 , 1. ], [ 1. , 0.109 , 0.109 , 1. ], [ 1. , 0.103 , 0.103 , 1. ], [ 1. , 0.103 , 0.103 , 1. ], [ 1. , 0.097 , 0.097 , 1. ], [ 1. , 0.091 , 0.091 , 1. ], [ 1. , 0.091 , 0.091 , 1. ], [ 1. , 0.086 , 0.086 , 1. ], [ 1. , 0.08 , 0.08 , 1. ], [ 1. , 0.08 , 0.08 , 1. ], [ 1. , 0.074 , 0.074 , 1. ], [ 1. , 0.069 , 0.069 , 1. ], [ 1. , 0.063 , 0.063 , 1. ], [ 1. , 0.063 , 0.063 , 1. ], [ 1. , 0.057 , 0.057 , 1. ], [ 1. , 0.051 , 0.051 , 1. ], [ 1. , 0.051 , 0.051 , 1. ], [ 1. , 0.046 , 0.046 , 1. ], [ 1. , 0.04 , 0.04 , 1. ], [ 1. , 0.04 , 0.04 , 1. ], [ 1. , 0.034 , 0.034 , 1. ], [ 1. , 0.029 , 0.029 , 1. ], [ 1. , 0.029 , 0.029 , 1. ], [ 1. , 0.023 , 0.023 , 1. ], [ 1. , 0.017 , 0.017 , 1. ], [ 1. , 0.017 , 0.017 , 1. ], [ 1. , 0.011 , 0.011 , 1. ], [ 1. , 0.006 , 0.006 , 1. ], [ 1. , 0. , 0. , 1. ]],'f'), 'maxi': 10.0, 'mini': 0.0} apply( cm.configure, (), cfg) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/ColorMaps/rwb128_map.py0000644000175000017500000000720410651433475026302 0ustar moellermoeller## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by from DejaVu.colorMap import ColorMap from numpy.oldnumeric import array cm = ColorMap('rwb128') cfg = {'name': 'rwb128', 'ramp': [[0.002, 0.0, 1.0, 1.0], [0.012978, 0.011, 1.0, 1.0], [0.030942, 0.029, 1.0, 1.0], [0.047908, 0.046, 1.0, 1.0], [0.064874, 0.063, 1.0, 1.0], [0.075852, 0.074, 1.0, 1.0], [0.092818, 0.091, 1.0, 1.0], [0.110782, 0.109, 1.0, 1.0], [0.127748, 0.126, 1.0, 1.0], [0.144714, 0.143, 1.0, 1.0], [0.155692, 0.154, 1.0, 1.0], [0.172658, 0.171, 1.0, 1.0], [0.190622, 0.189, 1.0, 1.0], [0.207588, 0.206, 1.0, 1.0], [0.218566, 0.217, 1.0, 1.0], [0.235532, 0.234, 1.0, 1.0], [0.252498, 0.251, 1.0, 1.0], [0.270462, 0.269, 1.0, 1.0], [0.287428, 0.286, 1.0, 1.0], [0.298406, 0.297, 1.0, 1.0], [0.315372, 0.314, 1.0, 1.0], [0.332338, 0.331, 1.0, 1.0], [0.350302, 0.349, 1.0, 1.0], [0.36128, 0.36, 1.0, 1.0], [0.378246, 0.377, 1.0, 1.0], [0.395212, 0.394, 1.0, 1.0], [0.412178, 0.411, 1.0, 1.0], [0.430142, 0.429, 1.0, 1.0], [0.44112, 0.44, 1.0, 1.0], [0.458086, 0.457, 1.0, 1.0], [0.475052, 0.474, 1.0, 1.0], [0.492018, 0.491, 1.0, 1.0], [0.503994, 0.503, 1.0, 1.0], [0.52096, 0.52, 1.0, 1.0], [0.537926, 0.537, 1.0, 1.0], [0.554892, 0.554, 1.0, 1.0], [0.571858, 0.571, 1.0, 1.0], [0.583834, 0.583, 1.0, 1.0], [0.6008, 0.6, 1.0, 1.0], [0.617766, 0.617, 1.0, 1.0], [0.634732, 0.634, 1.0, 1.0], [0.646708, 0.646, 1.0, 1.0], [0.663674, 0.663, 1.0, 1.0], [0.68064, 0.68, 1.0, 1.0], [0.697606, 0.697, 1.0, 1.0], [0.714572, 0.714, 1.0, 1.0], [0.726548, 0.726, 1.0, 1.0], [0.743514, 0.743, 1.0, 1.0], [0.76048, 0.76, 1.0, 1.0], [0.777446, 0.777, 1.0, 1.0], [0.789422, 0.789, 1.0, 1.0], [0.806388, 0.806, 1.0, 1.0], [0.823354, 0.823, 1.0, 1.0], [0.84032, 0.84, 1.0, 1.0], [0.857286, 0.857, 1.0, 1.0], [0.869262, 0.869, 1.0, 1.0], [0.886228, 0.886, 1.0, 1.0], [0.903194, 0.903, 1.0, 1.0], [0.92016, 0.92, 1.0, 1.0], [0.931138, 0.931, 1.0, 1.0], [0.949102, 0.949, 1.0, 1.0], [0.966068, 0.966, 1.0, 1.0], [0.983034, 0.983, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0], [1.0, 0.989, 0.989, 1.0], [1.0, 0.971, 0.971, 1.0], [1.0, 0.954, 0.954, 1.0], [1.0, 0.937, 0.937, 1.0], [1.0, 0.926, 0.926, 1.0], [1.0, 0.909, 0.909, 1.0], [1.0, 0.891, 0.891, 1.0], [1.0, 0.874, 0.874, 1.0], [1.0, 0.857, 0.857, 1.0], [1.0, 0.846, 0.846, 1.0], [1.0, 0.829, 0.829, 1.0], [1.0, 0.811, 0.811, 1.0], [1.0, 0.794, 0.794, 1.0], [1.0, 0.783, 0.783, 1.0], [1.0, 0.766, 0.766, 1.0], [1.0, 0.749, 0.749, 1.0], [1.0, 0.731, 0.731, 1.0], [1.0, 0.714, 0.714, 1.0], [1.0, 0.703, 0.703, 1.0], [1.0, 0.686, 0.686, 1.0], [1.0, 0.669, 0.669, 1.0], [1.0, 0.651, 0.651, 1.0], [1.0, 0.64, 0.64, 1.0], [1.0, 0.623, 0.623, 1.0], [1.0, 0.606, 0.606, 1.0], [1.0, 0.589, 0.589, 1.0], [1.0, 0.571, 0.571, 1.0], [1.0, 0.56, 0.56, 1.0], [1.0, 0.543, 0.543, 1.0], [1.0, 0.526, 0.526, 1.0], [1.0, 0.509, 0.509, 1.0], [1.0, 0.497, 0.497, 1.0], [1.0, 0.48, 0.48, 1.0], [1.0, 0.463, 0.463, 1.0], [1.0, 0.446, 0.446, 1.0], [1.0, 0.429, 0.429, 1.0], [1.0, 0.417, 0.417, 1.0], [1.0, 0.4, 0.4, 1.0], [1.0, 0.383, 0.383, 1.0], [1.0, 0.366, 0.366, 1.0], [1.0, 0.354, 0.354, 1.0], [1.0, 0.337, 0.337, 1.0], [1.0, 0.32, 0.32, 1.0], [1.0, 0.303, 0.303, 1.0], [1.0, 0.286, 0.286, 1.0], [1.0, 0.274, 0.274, 1.0], [1.0, 0.257, 0.257, 1.0], [1.0, 0.24, 0.24, 1.0], [1.0, 0.223, 0.223, 1.0], [1.0, 0.211, 0.211, 1.0], [1.0, 0.194, 0.194, 1.0], [1.0, 0.177, 0.177, 1.0], [1.0, 0.16, 0.16, 1.0], [1.0, 0.143, 0.143, 1.0], [1.0, 0.131, 0.131, 1.0], [1.0, 0.114, 0.114, 1.0], [1.0, 0.097, 0.097, 1.0], [1.0, 0.08, 0.08, 1.0], [1.0, 0.069, 0.069, 1.0], [1.0, 0.051, 0.051, 1.0], [1.0, 0.034, 0.034, 1.0], [1.0, 0.017, 0.017, 1.0], [1.0, 0.0, 0.0, 1.0]], 'maxi': 10.0, 'mini': 0.0} apply( cm.configure, (), cfg) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/ColorMaps/rwb256_map.py0000644000175000017500000003700010651433475026301 0ustar moellermoeller## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by from DejaVu.colorMap import ColorMap from numpy.oldnumeric import array cm = ColorMap('rwb256') cfg = {'name': 'rwb256', 'ramp': array([[ 1. , 0. , 0. , 1. ], [ 0.00798478, 0.006 , 1. , 1. ], [ 0.01297748, 0.011 , 1. , 1. ], [ 0.02495463, 0.023 , 1. , 1. ], [ 0.03094184, 0.029 , 1. , 1. ], [ 0.03593225, 0.034 , 1. , 1. ], [ 0.04790861, 0.046 , 1. , 1. ], [ 0.0528977 , 0.051 , 1. , 1. ], [ 0.06487406, 0.063 , 1. , 1. ], [ 0.07086179, 0.069 , 1. , 1. ], [ 0.07585198, 0.074 , 1. , 1. ], [ 0.0878282 , 0.086 , 1. , 1. ], [ 0.09281833, 0.091 , 1. , 1. ], [ 0.09880612, 0.097 , 1. , 1. ], [ 0.11078227, 0.109 , 1. , 1. ], [ 0.11577237, 0.114 , 1. , 1. ], [ 0.12774806, 0.126 , 1. , 1. ], [ 0.13273776, 0.131 , 1. , 1. ], [ 0.13872601, 0.13699999, 1. , 1. ], [ 0.15070179, 0.149 , 1. , 1. ], [ 0.15569188, 0.154 , 1. , 1. ], [ 0.16168009, 0.16 , 1. , 1. ], [ 0.17265806, 0.171 , 1. , 1. ], [ 0.17864597, 0.177 , 1. , 1. ], [ 0.19062206, 0.189 , 1. , 1. ], [ 0.1956121 , 0.19400001, 1. , 1. ], [ 0.20160003, 0.2 , 1. , 1. ], [ 0.212578 , 0.211 , 1. , 1. ], [ 0.21856593, 0.21699999, 1. , 1. ], [ 0.22455387, 0.223 , 1. , 1. ], [ 0.23553205, 0.234 , 1. , 1. ], [ 0.24151999, 0.23999999, 1. , 1. ], [ 0.25249797, 0.25099999, 1. , 1. ], [ 0.25848609, 0.257 , 1. , 1. ], [ 0.26447403, 0.26300001, 1. , 1. ], [ 0.27545202, 0.27399999, 1. , 1. ], [ 0.28143996, 0.28 , 1. , 1. ], [ 0.28742805, 0.28600001, 1. , 1. ], [ 0.29840603, 0.29699999, 1. , 1. ], [ 0.30439401, 0.303 , 1. , 1. ], [ 0.31537199, 0.31400001, 1. , 1. ], [ 0.32135993, 0.31999999, 1. , 1. ], [ 0.3273479 , 0.32600001, 1. , 1. ], [ 0.33832601, 0.33700001, 1. , 1. ], [ 0.34431398, 0.34299999, 1. , 1. ], [ 0.35529196, 0.354 , 1. , 1. ], [ 0.36128005, 0.36000001, 1. , 1. ], [ 0.367268 , 0.366 , 1. , 1. ], [ 0.37824601, 0.377 , 1. , 1. ], [ 0.38423407, 0.38299999, 1. , 1. ], [ 0.39022204, 0.389 , 1. , 1. ], [ 0.40119994, 0.40000001, 1. , 1. ], [ 0.407188 , 0.40599999, 1. , 1. ], [ 0.41816598, 0.417 , 1. , 1. ], [ 0.42415395, 0.42300001, 1. , 1. ], [ 0.43014202, 0.42899999, 1. , 1. ], [ 0.44112 , 0.44 , 1. , 1. ], [ 0.44710797, 0.44600001, 1. , 1. ], [ 0.45209798, 0.45100001, 1. , 1. ], [ 0.46407402, 0.463 , 1. , 1. ], [ 0.47006199, 0.46900001, 1. , 1. ], [ 0.48104 , 0.47999999, 1. , 1. ], [ 0.48702797, 0.486 , 1. , 1. ], [ 0.49201798, 0.491 , 1. , 1. ], [ 0.50399399, 0.50300002, 1. , 1. ], [ 0.50998199, 0.509 , 1. , 1. ], [ 0.51497197, 0.514 , 1. , 1. ], [ 0.52694798, 0.52600002, 1. , 1. ], [ 0.53193796, 0.53100002, 1. , 1. ], [ 0.54391402, 0.54299998, 1. , 1. ], [ 0.54990202, 0.54900002, 1. , 1. ], [ 0.554892 , 0.55400002, 1. , 1. ], [ 0.56686801, 0.56599998, 1. , 1. ], [ 0.57185799, 0.57099998, 1. , 1. ], [ 0.57784599, 0.57700002, 1. , 1. ], [ 0.58982199, 0.58899999, 1. , 1. ], [ 0.59481204, 0.59399998, 1. , 1. ], [ 0.60678798, 0.60600001, 1. , 1. ], [ 0.61177802, 0.611 , 1. , 1. ], [ 0.61776602, 0.61699998, 1. , 1. ], [ 0.62974203, 0.62900001, 1. , 1. ], [ 0.63473201, 0.634 , 1. , 1. ], [ 0.64072001, 0.63999999, 1. , 1. ], [ 0.65169799, 0.65100002, 1. , 1. ], [ 0.657686 , 0.65700001, 1. , 1. ], [ 0.669662 , 0.66900003, 1. , 1. ], [ 0.67465198, 0.67400002, 1. , 1. ], [ 0.68063998, 0.68000001, 1. , 1. ], [ 0.69161803, 0.69099998, 1. , 1. ], [ 0.69760603, 0.69700003, 1. , 1. ], [ 0.70958197, 0.70899999, 1. , 1. ], [ 0.71457201, 0.71399999, 1. , 1. ], [ 0.72056001, 0.72000003, 1. , 1. ], [ 0.731538 , 0.73100001, 1. , 1. ], [ 0.737526 , 0.73699999, 1. , 1. ], [ 0.743514 , 0.74299997, 1. , 1. ], [ 0.75449198, 0.75400001, 1. , 1. ], [ 0.76047999, 0.75999999, 1. , 1. ], [ 0.77145803, 0.77100003, 1. , 1. ], [ 0.77744597, 0.77700001, 1. , 1. ], [ 0.78343397, 0.78299999, 1. , 1. ], [ 0.79441202, 0.79400003, 1. , 1. ], [ 0.80040002, 0.80000001, 1. , 1. ], [ 0.80638802, 0.80599999, 1. , 1. ], [ 0.817366 , 0.81699997, 1. , 1. ], [ 0.82335401, 0.82300001, 1. , 1. ], [ 0.83433199, 0.83399999, 1. , 1. ], [ 0.84031999, 0.83999997, 1. , 1. ], [ 0.84630799, 0.84600002, 1. , 1. ], [ 0.85728598, 0.85699999, 1. , 1. ], [ 0.86327398, 0.86299998, 1. , 1. ], [ 0.86926198, 0.86900002, 1. , 1. ], [ 0.88024002, 0.88 , 1. , 1. ], [ 0.88622802, 0.88599998, 1. , 1. ], [ 0.89720601, 0.89700001, 1. , 1. ], [ 0.90319401, 0.903 , 1. , 1. ], [ 0.90918201, 0.90899998, 1. , 1. ], [ 0.92016 , 0.92000002, 1. , 1. ], [ 0.926148 , 0.926 , 1. , 1. ], [ 0.93113798, 0.93099999, 1. , 1. ], [ 0.94311398, 0.94300002, 1. , 1. ], [ 0.94910198, 0.949 , 1. , 1. ], [ 0.96008003, 0.95999998, 1. , 1. ], [ 0.96606803, 0.96600002, 1. , 1. ], [ 0.97105801, 0.97100002, 1. , 1. ], [ 0.98303401, 0.98299998, 1. , 1. ], [ 0.98902202, 0.98900002, 1. , 1. ], [ 1. , 1. , 1. , 1. ], [ 1. , 1. , 1. , 1. ], [ 1. , 0.99400002, 0.99400002, 1. ], [ 1. , 0.98900002, 0.98900002, 1. ], [ 1. , 0.977 , 0.977 , 1. ], [ 1. , 0.97100002, 0.97100002, 1. ], [ 1. , 0.96600002, 0.96600002, 1. ], [ 1. , 0.954 , 0.954 , 1. ], [ 1. , 0.949 , 0.949 , 1. ], [ 1. , 0.93699998, 0.93699998, 1. ], [ 1. , 0.93099999, 0.93099999, 1. ], [ 1. , 0.926 , 0.926 , 1. ], [ 1. , 0.91399997, 0.91399997, 1. ], [ 1. , 0.90899998, 0.90899998, 1. ], [ 1. , 0.903 , 0.903 , 1. ], [ 1. , 0.89099997, 0.89099997, 1. ], [ 1. , 0.88599998, 0.88599998, 1. ], [ 1. , 0.87400001, 0.87400001, 1. ], [ 1. , 0.86900002, 0.86900002, 1. ], [ 1. , 0.86299998, 0.86299998, 1. ], [ 1. , 0.85100001, 0.85100001, 1. ], [ 1. , 0.84600002, 0.84600002, 1. ], [ 1. , 0.83999997, 0.83999997, 1. ], [ 1. , 0.829 , 0.829 , 1. ], [ 1. , 0.82300001, 0.82300001, 1. ], [ 1. , 0.81099999, 0.81099999, 1. ], [ 1. , 0.80599999, 0.80599999, 1. ], [ 1. , 0.80000001, 0.80000001, 1. ], [ 1. , 0.78899997, 0.78899997, 1. ], [ 1. , 0.78299999, 0.78299999, 1. ], [ 1. , 0.77700001, 0.77700001, 1. ], [ 1. , 0.76599997, 0.76599997, 1. ], [ 1. , 0.75999999, 0.75999999, 1. ], [ 1. , 0.74900001, 0.74900001, 1. ], [ 1. , 0.74299997, 0.74299997, 1. ], [ 1. , 0.73699999, 0.73699999, 1. ], [ 1. , 0.72600001, 0.72600001, 1. ], [ 1. , 0.72000003, 0.72000003, 1. ], [ 1. , 0.71399999, 0.71399999, 1. ], [ 1. , 0.70300001, 0.70300001, 1. ], [ 1. , 0.69700003, 0.69700003, 1. ], [ 1. , 0.68599999, 0.68599999, 1. ], [ 1. , 0.68000001, 0.68000001, 1. ], [ 1. , 0.67400002, 0.67400002, 1. ], [ 1. , 0.66299999, 0.66299999, 1. ], [ 1. , 0.65700001, 0.65700001, 1. ], [ 1. , 0.64600003, 0.64600003, 1. ], [ 1. , 0.63999999, 0.63999999, 1. ], [ 1. , 0.634 , 0.634 , 1. ], [ 1. , 0.62300003, 0.62300003, 1. ], [ 1. , 0.61699998, 0.61699998, 1. ], [ 1. , 0.611 , 0.611 , 1. ], [ 1. , 0.60000002, 0.60000002, 1. ], [ 1. , 0.59399998, 0.59399998, 1. ], [ 1. , 0.583 , 0.583 , 1. ], [ 1. , 0.57700002, 0.57700002, 1. ], [ 1. , 0.57099998, 0.57099998, 1. ], [ 1. , 0.56 , 0.56 , 1. ], [ 1. , 0.55400002, 0.55400002, 1. ], [ 1. , 0.54900002, 0.54900002, 1. ], [ 1. , 0.537 , 0.537 , 1. ], [ 1. , 0.53100002, 0.53100002, 1. ], [ 1. , 0.51999998, 0.51999998, 1. ], [ 1. , 0.514 , 0.514 , 1. ], [ 1. , 0.509 , 0.509 , 1. ], [ 1. , 0.49700001, 0.49700001, 1. ], [ 1. , 0.491 , 0.491 , 1. ], [ 1. , 0.486 , 0.486 , 1. ], [ 1. , 0.47400001, 0.47400001, 1. ], [ 1. , 0.46900001, 0.46900001, 1. ], [ 1. , 0.45699999, 0.45699999, 1. ], [ 1. , 0.45100001, 0.45100001, 1. ], [ 1. , 0.44600001, 0.44600001, 1. ], [ 1. , 0.43399999, 0.43399999, 1. ], [ 1. , 0.42899999, 0.42899999, 1. ], [ 1. , 0.42300001, 0.42300001, 1. ], [ 1. , 0.41100001, 0.41100001, 1. ], [ 1. , 0.40599999, 0.40599999, 1. ], [ 1. , 0.39399999, 0.39399999, 1. ], [ 1. , 0.389 , 0.389 , 1. ], [ 1. , 0.38299999, 0.38299999, 1. ], [ 1. , 0.37099999, 0.37099999, 1. ], [ 1. , 0.366 , 0.366 , 1. ], [ 1. , 0.36000001, 0.36000001, 1. ], [ 1. , 0.34900001, 0.34900001, 1. ], [ 1. , 0.34299999, 0.34299999, 1. ], [ 1. , 0.331 , 0.331 , 1. ], [ 1. , 0.32600001, 0.32600001, 1. ], [ 1. , 0.31999999, 0.31999999, 1. ], [ 1. , 0.30899999, 0.30899999, 1. ], [ 1. , 0.303 , 0.303 , 1. ], [ 1. , 0.29100001, 0.29100001, 1. ], [ 1. , 0.28600001, 0.28600001, 1. ], [ 1. , 0.28 , 0.28 , 1. ], [ 1. , 0.26899999, 0.26899999, 1. ], [ 1. , 0.26300001, 0.26300001, 1. ], [ 1. , 0.257 , 0.257 , 1. ], [ 1. , 0.24600001, 0.24600001, 1. ], [ 1. , 0.23999999, 0.23999999, 1. ], [ 1. , 0.229 , 0.229 , 1. ], [ 1. , 0.223 , 0.223 , 1. ], [ 1. , 0.21699999, 0.21699999, 1. ], [ 1. , 0.206 , 0.206 , 1. ], [ 1. , 0.2 , 0.2 , 1. ], [ 1. , 0.19400001, 0.19400001, 1. ], [ 1. , 0.183 , 0.183 , 1. ], [ 1. , 0.177 , 0.177 , 1. ], [ 1. , 0.16599999, 0.16599999, 1. ], [ 1. , 0.16 , 0.16 , 1. ], [ 1. , 0.154 , 0.154 , 1. ], [ 1. , 0.14300001, 0.14300001, 1. ], [ 1. , 0.13699999, 0.13699999, 1. ], [ 1. , 0.131 , 0.131 , 1. ], [ 1. , 0.12 , 0.12 , 1. ], [ 1. , 0.114 , 0.114 , 1. ], [ 1. , 0.103 , 0.103 , 1. ], [ 1. , 0.097 , 0.097 , 1. ], [ 1. , 0.091 , 0.091 , 1. ], [ 1. , 0.08 , 0.08 , 1. ], [ 1. , 0.074 , 0.074 , 1. ], [ 1. , 0.069 , 0.069 , 1. ], [ 1. , 0.057 , 0.057 , 1. ], [ 1. , 0.051 , 0.051 , 1. ], [ 1. , 0.04 , 0.04 , 1. ], [ 1. , 0.034 , 0.034 , 1. ], [ 1. , 0.029 , 0.029 , 1. ], [ 1. , 0.017 , 0.017 , 1. ], [ 1. , 0.011 , 0.011 , 1. ], [ 1. , 0. , 0. , 1. ]],'f'), 'maxi': 10.0, 'mini': 0.0} apply( cm.configure, (), cfg) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/ColorMaps/wb256_map.py0000644000175000017500000003677610651433475026142 0ustar moellermoeller## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by from DejaVu.colorMap import ColorMap from numpy.oldnumeric import array cm = ColorMap('wb256') cfg = {'name': 'wb256', 'ramp': array([[ 0.002 , 0. , 1. , 1. ], [ 0.002 , 0. , 1. , 1. ], [ 0.007988 , 0.006 , 1. , 1. ], [ 0.012978 , 0.011 , 1. , 1. ], [ 0.012978 , 0.011 , 1. , 1. ], [ 0.018966 , 0.017 , 1. , 1. ], [ 0.024954 , 0.023 , 1. , 1. ], [ 0.024954 , 0.023 , 1. , 1. ], [ 0.030942 , 0.029 , 1. , 1. ], [ 0.035932 , 0.034 , 1. , 1. ], [ 0.035932 , 0.034 , 1. , 1. ], [ 0.04192 , 0.04 , 1. , 1. ], [ 0.047908 , 0.046 , 1. , 1. ], [ 0.047908 , 0.046 , 1. , 1. ], [ 0.052898 , 0.051 , 1. , 1. ], [ 0.058886 , 0.057 , 1. , 1. ], [ 0.058886 , 0.057 , 1. , 1. ], [ 0.064874 , 0.063 , 1. , 1. ], [ 0.070862 , 0.069 , 1. , 1. ], [ 0.075852 , 0.074 , 1. , 1. ], [ 0.075852 , 0.074 , 1. , 1. ], [ 0.08184 , 0.08 , 1. , 1. ], [ 0.087828 , 0.086 , 1. , 1. ], [ 0.087828 , 0.086 , 1. , 1. ], [ 0.092818 , 0.091 , 1. , 1. ], [ 0.098806 , 0.097 , 1. , 1. ], [ 0.098806 , 0.097 , 1. , 1. ], [ 0.104794 , 0.103 , 1. , 1. ], [ 0.110782 , 0.109 , 1. , 1. ], [ 0.110782 , 0.109 , 1. , 1. ], [ 0.115772 , 0.114 , 1. , 1. ], [ 0.12176 , 0.12 , 1. , 1. ], [ 0.12176 , 0.12 , 1. , 1. ], [ 0.127748 , 0.126 , 1. , 1. ], [ 0.13273799, 0.131 , 1. , 1. ], [ 0.138726 , 0.13699999, 1. , 1. ], [ 0.138726 , 0.13699999, 1. , 1. ], [ 0.144714 , 0.14300001, 1. , 1. ], [ 0.150702 , 0.149 , 1. , 1. ], [ 0.150702 , 0.149 , 1. , 1. ], [ 0.155692 , 0.154 , 1. , 1. ], [ 0.16168 , 0.16 , 1. , 1. ], [ 0.16168 , 0.16 , 1. , 1. ], [ 0.167668 , 0.16599999, 1. , 1. ], [ 0.172658 , 0.171 , 1. , 1. ], [ 0.172658 , 0.171 , 1. , 1. ], [ 0.178646 , 0.177 , 1. , 1. ], [ 0.184634 , 0.183 , 1. , 1. ], [ 0.184634 , 0.183 , 1. , 1. ], [ 0.190622 , 0.189 , 1. , 1. ], [ 0.195612 , 0.19400001, 1. , 1. ], [ 0.2016 , 0.2 , 1. , 1. ], [ 0.2016 , 0.2 , 1. , 1. ], [ 0.207588 , 0.206 , 1. , 1. ], [ 0.212578 , 0.211 , 1. , 1. ], [ 0.212578 , 0.211 , 1. , 1. ], [ 0.218566 , 0.21699999, 1. , 1. ], [ 0.224554 , 0.223 , 1. , 1. ], [ 0.224554 , 0.223 , 1. , 1. ], [ 0.230542 , 0.229 , 1. , 1. ], [ 0.235532 , 0.234 , 1. , 1. ], [ 0.235532 , 0.234 , 1. , 1. ], [ 0.24152 , 0.23999999, 1. , 1. ], [ 0.247508 , 0.24600001, 1. , 1. ], [ 0.247508 , 0.24600001, 1. , 1. ], [ 0.252498 , 0.25099999, 1. , 1. ], [ 0.258486 , 0.257 , 1. , 1. ], [ 0.258486 , 0.257 , 1. , 1. ], [ 0.264474 , 0.26300001, 1. , 1. ], [ 0.27046201, 0.26899999, 1. , 1. ], [ 0.27545199, 0.27399999, 1. , 1. ], [ 0.27545199, 0.27399999, 1. , 1. ], [ 0.28143999, 0.28 , 1. , 1. ], [ 0.28742799, 0.28600001, 1. , 1. ], [ 0.28742799, 0.28600001, 1. , 1. ], [ 0.292418 , 0.29100001, 1. , 1. ], [ 0.298406 , 0.29699999, 1. , 1. ], [ 0.298406 , 0.29699999, 1. , 1. ], [ 0.30439401, 0.303 , 1. , 1. ], [ 0.31038201, 0.30899999, 1. , 1. ], [ 0.31038201, 0.30899999, 1. , 1. ], [ 0.31537199, 0.31400001, 1. , 1. ], [ 0.32135999, 0.31999999, 1. , 1. ], [ 0.32135999, 0.31999999, 1. , 1. ], [ 0.32734799, 0.32600001, 1. , 1. ], [ 0.33233801, 0.331 , 1. , 1. ], [ 0.33832601, 0.33700001, 1. , 1. ], [ 0.33832601, 0.33700001, 1. , 1. ], [ 0.34431401, 0.34299999, 1. , 1. ], [ 0.35030201, 0.34900001, 1. , 1. ], [ 0.35030201, 0.34900001, 1. , 1. ], [ 0.35529199, 0.354 , 1. , 1. ], [ 0.36127999, 0.36000001, 1. , 1. ], [ 0.36127999, 0.36000001, 1. , 1. ], [ 0.367268 , 0.366 , 1. , 1. ], [ 0.37225801, 0.37099999, 1. , 1. ], [ 0.37225801, 0.37099999, 1. , 1. ], [ 0.37824601, 0.377 , 1. , 1. ], [ 0.38423401, 0.38299999, 1. , 1. ], [ 0.38423401, 0.38299999, 1. , 1. ], [ 0.39022201, 0.389 , 1. , 1. ], [ 0.39521199, 0.39399999, 1. , 1. ], [ 0.4012 , 0.40000001, 1. , 1. ], [ 0.4012 , 0.40000001, 1. , 1. ], [ 0.407188 , 0.40599999, 1. , 1. ], [ 0.41217801, 0.41100001, 1. , 1. ], [ 0.41217801, 0.41100001, 1. , 1. ], [ 0.41816601, 0.417 , 1. , 1. ], [ 0.42415401, 0.42300001, 1. , 1. ], [ 0.42415401, 0.42300001, 1. , 1. ], [ 0.43014199, 0.42899999, 1. , 1. ], [ 0.435132 , 0.43399999, 1. , 1. ], [ 0.435132 , 0.43399999, 1. , 1. ], [ 0.44112 , 0.44 , 1. , 1. ], [ 0.447108 , 0.44600001, 1. , 1. ], [ 0.447108 , 0.44600001, 1. , 1. ], [ 0.45209801, 0.45100001, 1. , 1. ], [ 0.45808601, 0.45699999, 1. , 1. ], [ 0.45808601, 0.45699999, 1. , 1. ], [ 0.46407399, 0.463 , 1. , 1. ], [ 0.47006199, 0.46900001, 1. , 1. ], [ 0.475052 , 0.47400001, 1. , 1. ], [ 0.475052 , 0.47400001, 1. , 1. ], [ 0.48104 , 0.47999999, 1. , 1. ], [ 0.487028 , 0.486 , 1. , 1. ], [ 0.487028 , 0.486 , 1. , 1. ], [ 0.49201801, 0.491 , 1. , 1. ], [ 0.49800599, 0.49700001, 1. , 1. ], [ 0.49800599, 0.49700001, 1. , 1. ], [ 0.50399399, 0.50300002, 1. , 1. ], [ 0.50998199, 0.509 , 1. , 1. ], [ 0.50998199, 0.509 , 1. , 1. ], [ 0.51497197, 0.514 , 1. , 1. ], [ 0.52095997, 0.51999998, 1. , 1. ], [ 0.52095997, 0.51999998, 1. , 1. ], [ 0.52694798, 0.52600002, 1. , 1. ], [ 0.53193802, 0.53100002, 1. , 1. ], [ 0.53792602, 0.537 , 1. , 1. ], [ 0.53792602, 0.537 , 1. , 1. ], [ 0.54391402, 0.54299998, 1. , 1. ], [ 0.54990202, 0.54900002, 1. , 1. ], [ 0.54990202, 0.54900002, 1. , 1. ], [ 0.554892 , 0.55400002, 1. , 1. ], [ 0.56088001, 0.56 , 1. , 1. ], [ 0.56088001, 0.56 , 1. , 1. ], [ 0.56686801, 0.56599998, 1. , 1. ], [ 0.57185799, 0.57099998, 1. , 1. ], [ 0.57185799, 0.57099998, 1. , 1. ], [ 0.57784599, 0.57700002, 1. , 1. ], [ 0.58383399, 0.583 , 1. , 1. ], [ 0.58383399, 0.583 , 1. , 1. ], [ 0.58982199, 0.58899999, 1. , 1. ], [ 0.59481198, 0.59399998, 1. , 1. ], [ 0.60079998, 0.60000002, 1. , 1. ], [ 0.60079998, 0.60000002, 1. , 1. ], [ 0.60678798, 0.60600001, 1. , 1. ], [ 0.61177802, 0.611 , 1. , 1. ], [ 0.61177802, 0.611 , 1. , 1. ], [ 0.61776602, 0.61699998, 1. , 1. ], [ 0.62375402, 0.62300003, 1. , 1. ], [ 0.62375402, 0.62300003, 1. , 1. ], [ 0.62974203, 0.62900001, 1. , 1. ], [ 0.63473201, 0.634 , 1. , 1. ], [ 0.63473201, 0.634 , 1. , 1. ], [ 0.64072001, 0.63999999, 1. , 1. ], [ 0.64670801, 0.64600003, 1. , 1. ], [ 0.64670801, 0.64600003, 1. , 1. ], [ 0.65169799, 0.65100002, 1. , 1. ], [ 0.657686 , 0.65700001, 1. , 1. ], [ 0.657686 , 0.65700001, 1. , 1. ], [ 0.663674 , 0.66299999, 1. , 1. ], [ 0.669662 , 0.66900003, 1. , 1. ], [ 0.67465198, 0.67400002, 1. , 1. ], [ 0.67465198, 0.67400002, 1. , 1. ], [ 0.68063998, 0.68000001, 1. , 1. ], [ 0.68662798, 0.68599999, 1. , 1. ], [ 0.68662798, 0.68599999, 1. , 1. ], [ 0.69161803, 0.69099998, 1. , 1. ], [ 0.69760603, 0.69700003, 1. , 1. ], [ 0.69760603, 0.69700003, 1. , 1. ], [ 0.70359403, 0.70300001, 1. , 1. ], [ 0.70958197, 0.70899999, 1. , 1. ], [ 0.70958197, 0.70899999, 1. , 1. ], [ 0.71457201, 0.71399999, 1. , 1. ], [ 0.72056001, 0.72000003, 1. , 1. ], [ 0.72056001, 0.72000003, 1. , 1. ], [ 0.72654802, 0.72600001, 1. , 1. ], [ 0.731538 , 0.73100001, 1. , 1. ], [ 0.737526 , 0.73699999, 1. , 1. ], [ 0.737526 , 0.73699999, 1. , 1. ], [ 0.743514 , 0.74299997, 1. , 1. ], [ 0.749502 , 0.74900001, 1. , 1. ], [ 0.749502 , 0.74900001, 1. , 1. ], [ 0.75449198, 0.75400001, 1. , 1. ], [ 0.76047999, 0.75999999, 1. , 1. ], [ 0.76047999, 0.75999999, 1. , 1. ], [ 0.76646799, 0.76599997, 1. , 1. ], [ 0.77145803, 0.77100003, 1. , 1. ], [ 0.77145803, 0.77100003, 1. , 1. ], [ 0.77744597, 0.77700001, 1. , 1. ], [ 0.78343397, 0.78299999, 1. , 1. ], [ 0.78343397, 0.78299999, 1. , 1. ], [ 0.78942198, 0.78899997, 1. , 1. ], [ 0.79441202, 0.79400003, 1. , 1. ], [ 0.80040002, 0.80000001, 1. , 1. ], [ 0.80040002, 0.80000001, 1. , 1. ], [ 0.80638802, 0.80599999, 1. , 1. ], [ 0.811378 , 0.81099999, 1. , 1. ], [ 0.811378 , 0.81099999, 1. , 1. ], [ 0.817366 , 0.81699997, 1. , 1. ], [ 0.82335401, 0.82300001, 1. , 1. ], [ 0.82335401, 0.82300001, 1. , 1. ], [ 0.82934201, 0.829 , 1. , 1. ], [ 0.83433199, 0.83399999, 1. , 1. ], [ 0.83433199, 0.83399999, 1. , 1. ], [ 0.84031999, 0.83999997, 1. , 1. ], [ 0.84630799, 0.84600002, 1. , 1. ], [ 0.84630799, 0.84600002, 1. , 1. ], [ 0.85129797, 0.85100001, 1. , 1. ], [ 0.85728598, 0.85699999, 1. , 1. ], [ 0.85728598, 0.85699999, 1. , 1. ], [ 0.86327398, 0.86299998, 1. , 1. ], [ 0.86926198, 0.86900002, 1. , 1. ], [ 0.87425202, 0.87400001, 1. , 1. ], [ 0.87425202, 0.87400001, 1. , 1. ], [ 0.88024002, 0.88 , 1. , 1. ], [ 0.88622802, 0.88599998, 1. , 1. ], [ 0.88622802, 0.88599998, 1. , 1. ], [ 0.89121801, 0.89099997, 1. , 1. ], [ 0.89720601, 0.89700001, 1. , 1. ], [ 0.89720601, 0.89700001, 1. , 1. ], [ 0.90319401, 0.903 , 1. , 1. ], [ 0.90918201, 0.90899998, 1. , 1. ], [ 0.90918201, 0.90899998, 1. , 1. ], [ 0.91417199, 0.91399997, 1. , 1. ], [ 0.92016 , 0.92000002, 1. , 1. ], [ 0.92016 , 0.92000002, 1. , 1. ], [ 0.926148 , 0.926 , 1. , 1. ], [ 0.93113798, 0.93099999, 1. , 1. ], [ 0.93712598, 0.93699998, 1. , 1. ], [ 0.93712598, 0.93699998, 1. , 1. ], [ 0.94311398, 0.94300002, 1. , 1. ], [ 0.94910198, 0.949 , 1. , 1. ], [ 0.94910198, 0.949 , 1. , 1. ], [ 0.95409203, 0.954 , 1. , 1. ], [ 0.96008003, 0.95999998, 1. , 1. ], [ 0.96008003, 0.95999998, 1. , 1. ], [ 0.96606803, 0.96600002, 1. , 1. ], [ 0.97105801, 0.97100002, 1. , 1. ], [ 0.97105801, 0.97100002, 1. , 1. ], [ 0.97704601, 0.977 , 1. , 1. ], [ 0.98303401, 0.98299998, 1. , 1. ], [ 0.98303401, 0.98299998, 1. , 1. ], [ 0.98902202, 0.98900002, 1. , 1. ], [ 0.994012 , 0.99400002, 1. , 1. ], [ 1. , 1. , 1. , 1. ]],'f'), 'maxi': 10.0, 'mini': 0.0} apply( cm.configure, (), cfg) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/0000755000175000017500000000000012326214512023205 5ustar moellermoellerViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/leftarrow1.png0000644000175000017500000000127511462612423026011 0ustar moellermoellerPNG  IHDRa pHYs  tIME 'ʄ\IDAT8˅[HQ?3j:8YH QFEPBR E]|*| z!P% Ƃ +^2$$+!PJ""22:3QLݰp8ku6k+aR@40t/i2F]k]SxdRj\k77d@zGAAMxE;r{2 !O>Pu-܏ ML&,m>)"q"- s{( I44&"h"sY@ v۬ R͆#E#'hwϱ=e@(dPW';;;3/mu`}=la"?y 4aK=H3מO[ Oo(@4}ƴoՍMa6iluخ{}IzXv|DcR6ư-HZtJݓRi#Tc8zQJ4E먛UW7뷝aD i5;'#~ 8蝍[ ?oNuMv(R{)fNf(Mqׯ(D6732#? 0gQ1ZBt`]^:ʠTA-F VGkrjL.C՚HH+Jש( Oܘ  #.'7A!Created with The GIMP!,@ "A8&.Č9.+2<&2S1i`#> @@;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/16x16/_redo.gif0000644000175000017500000000164611545155744025575 0ustar moellermoellerGIF89aC  !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~!Created with GIMP! ,n H"t<HJ֍8mg3|J%NA'J ASҢ(SϔHdْ'Ϙ,R<ҥN8t,I(J6c("S 1׮;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/16x16/_undo.gif0000644000175000017500000000164611545155744025611 0ustar moellermoellerGIF89a  !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~!Created with GIMP! ,n HcG)X]kʛd>)"ʔSLdȑ? ApH$~2 rārSpY(Qd!RI5iԐ3gB"Dqȵׁ;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/16x16/fileopen.gif0000644000175000017500000000201710405340372026262 0ustar moellermoellerGIF89a%%$##$.-7: : D%DN6NTR9R$Y>Y(`7ZJd? A DHKNDRVS""Y(Q''^%/X..`-.c11b22d-7`44d66f78i99h;;j5@i>>kAAn?IqISzT^[_Si[h_ihmdqhtqwozrzq}r{{ž£ĪêūĬƭŦǦȪűȫɱʲɪʳìˮ˴˭̲ͱϷ˳ιιϻɴѻлѻӿԼ־!Created with The GIMP! ,@ H@-v4QJTϝ7ejp00p8?lڸЉ[a% !;n@C%I F .T1C  5a,)b$lЀB (`lAq!4Q$L&AjEĂf|$)J`9L(/2I8hHQ" ˔$Dx؀@;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/16x16/float.gif0000644000175000017500000000116010412574451025571 0ustar moellermoellerGIF89a^   # 8 //014^b iv w y z ή}ɪȬĞǽǾƨ쾎Źƶ!Created with The GIMP! ,@  >>JKHBGMLILLN 0! <+:#)\]ȂQ8M[R6=ZX949W,(5&3'/?1b$ 1\ QD (T"R"6 J%Z<aʕ+XNTy2;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/16x16/npr.png0000644000175000017500000000150210517526652025310 0ustar moellermoellerPNG  IHDRabKGD pHYs  tIME SRIDAT8ˍ[HSldz9q464I"ՃIKoPOERT$a/JT&%a6Nsz } D>oGJs@OMs=rRmjϦE#EzqhB3m9e8=]`F.hMs4O"H*bYmo]DkS6vv7jO]&T)!+"#5!#9&$'!%1#%,#&'0U ,U )f#Y3K 1C8 */#8.'+.7-E#+<0>&-3'*A%-8/,&-M,-+$,G+,4!+VG -,bN% 9J"/D18K+6569P):Jj :iY(1_%3=5:*:UMgOc[)8)<`Mv1J5>O4=Y*?j<=EI7D`-<UqKx??A;>SN9BV~ Ui3C^T)Eu[oE?I?>cX8Dq-;k0@,Hly+6`6C~*3JBGAFM0Hs8Fi`DHIQBG9IdAHT>H]b{IGI.6Z@K@Ie _ bv `3Ox1BgMm2:FQh2?HR^oKRW3ERPV lqp8XzVt|@RoFWy5S]bdDXWeuDUJlK]No\okszXy_vh{rzu!Created with The GIMP! , H fm.a6"bļiD  ң$(G#&/ F„ ųtfޤ5ZU#Yfͦr!Sr 42>4h -#c@Bq…߃{\0 ;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/16x16/textBox.gif0000644000175000017500000000034410405340372026117 0ustar moellermoellerGIF89a333QQQbbb!Created with The GIMP,@P`diBcl"σ>b߸#@a+^P@,Z !zӫSZ g4\|FΦ+;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/16x16/undo.gif0000644000175000017500000000103211545155744025437 0ustar moellermoellerGIF89aCDEEFHJJMMMNOOOPOOQQSSSSTUWXX Z^bidddgh#jklm&l"mn%r&r's(t.u/x1y%?~;=DE]fdeg!Created with GIMP! ,b3"B>?@A:9<;;=4 !%078*) 65,12.-/  $&'(+# ߂;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/16x16/vol.png0000644000175000017500000000133711044412327025304 0ustar moellermoellerPNG  IHDRh6 pHYs  tIME 8}~IDAT(oE޼]ۉ]AHZUz@+^N6 Nn띝ٙᧇqZ\{giD1 1O~UI 8~o݇[i}!" >., \:f}$R\}NoJ\%iS`cɪm !-mA ѭCXof&D4.} p1X ~Yűii~x<&dy{w4T ksk!X Ԩ9 h֮b2رzܹ2::e!. 3`!Z]EXIBm ΆPlIEXo¯DD$ɼجqČ0;ȍ(Qvy:K橒dbEs<aDD` ~WSPj"ѧqVc ]GXA# "H7?6\'n&\=xbt>*^"&j'_umI7~wi_Lϟ\`fET{2fbO'O}6MϋQq8ᓡNqlk׏LJt\< F6DJ dF&IENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/22x22/0000755000175000017500000000000012326214505023766 5ustar moellermoellerViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/22x22/3Dgeom.gif0000755000175000017500000000224210404676727025613 0ustar moellermoellerGIF89aVy_ gݎ ߍ/$"&!"Δ>("#*Rv1'((),.=n))14L?E-|Sy00FQ=C ,is?;;   RZAPVf :w*  + ^g/5b_i1 O6.;soz- "&&T\vJ(R~y%( .·z43҃)>>x?:=ګ>>܎<5DߒOOWWSᚫX✧4Y䧫 1  " ")%%5AGP!Created with The GIMP!,@ 7&X@B6w=_@*]ܡ6-.M} 0 F ^T-bմ{7N+9dQ#Jң2!%XbEE .T@& /00-RR[(:#NJM\8r-H1PԠsTXpݪП0Mi 8OڑHb ذ p E o7!@بsa=p! ,Xĸnjig dP^Ψ3,&2X1rc "Bbv͛v4!хD0(6M7"FI d*4s)6''4V;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/22x22/PyShell.gif0000644000175000017500000000127610412574451026046 0ustar moellermoellerGIF89aRTTT\\\```bbbdddmmmͼĹ̻!Created with The GIMP! ,@}>FFXjeԄ  K `۷;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/22x22/_redo.gif0000644000175000017500000000175211545155744025565 0ustar moellermoellerGIF89aC  !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~!Created with GIMP! , H*\Ȱ!A<|"q0JNg( (zv$6l״M4?Q+_x#Ġ(S4R)Q@)ȤIσK(JO"ϛ% <2 =wP$B'mԡC1H*Ao0Bӆ.C ,LĊ"B$2ʖ3kެ9 ;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/22x22/_undo.gif0000755000175000017500000000175411545155744025606 0ustar moellermoellerGIF89a  !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~!Created with GIMP! , H*\Ȱ@:vs`yF'QL٧%2ԩML,|rE85E!%HO$HQ&$2<~A2)B&ԩs̑J :#'(X Aj &\eSJ(Yd!I5iҨACf̘2hyE-Om("B0j̹s;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/22x22/fileopen.gif0000755000175000017500000000226710404676727026305 0ustar moellermoellerGIF89a"{ %#+ '* &,-+-18A"8;<AF=J N(HSVX,JV-M&LS1M)O*R,S$ci:Z'b.dB_2fEj7j4s4y=u7t6z6yAx9|WsSyG~O|D}T~GO~ZMnzP`GHwQ_SLO\nU^_kTmnNpPmqsfhact䀟kp虜Ř₪晤˒suww史蔱⁶뇼况Ӕ鲲ɓ쭴֍ő؞옾픿ӓڷͺśϛݘֻ̧ذժ޸!Created with The GIMP! ,@ HA cnءsH(>n̎rɣ'n۲`\:QgQCF fK[!#A1i(b0իX2d4htM;vy{ IK݆ s"=u褁3˕,L:0X(ibQƋ.HaAtn3f\"D范S΅5إ+7>UU˓2'*C5jMAUJi4Fɟ8o|,)q=e{MEwPicE E\8aH2KPTE(L+ц? #0`HN;P. &~@VlU<1EA Z@;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/22x22/filesave.gif0000755000175000017500000000230010404676727026266 0ustar moellermoellerGIF89a ; =ACHLO$N!"T +V(([*,Y-,`(2^+2d'8c/5h:Pw7UQNtIS|QR}TRxQS~GXRTWU{MZ}V[YZS_X]T`__YeZfcc`dXheegdgg\liifjamgkll`pdpjneqfrlsnrkwquqxszxxu|pv}w~}}sz{vw}}~¦âğŨƪ¥ǫ¬çĮũƤǯưǫȬɲɮʳʯ˩̲ŵ˫Ͷ̱Ͳγиϼʹз˸̵һҹ;ζϽп¿оѿҷӻ!Created with The GIMP! ,@ H_E.[TO#- < /aVi:jh0$l܍@ZHT0w3{),}!ӻH@hHI)(FDOVBiX!"C7|޿ZYNMg(@F 4סּZȵ] ^E#He~]qCKbTŒ10d&q՞wG-"^ 7ÊNNbW?NCK Kϗ[@$8}pb N@41:eĔ v΋NoG*[`S sV$֏҂-b\)$;&sì;UV [0f˰M6c`3B→L!FAI :\0" a1/@FZeL H}ji zӰsVXZ5*^Ek}ҜHD@pqnq  >' :o\,OOJ#d4'kČy˰{jKO!\x#niъ vFAqthBHs"Ѝ[ 2"oÖ5.Nug|[fI0PNAb ~n$ ^*=^8e Ggq+Gm(:6<A#j^9$@1_xrXzд+Pl (Zr}8tn06> CD7Mwy \d˵IENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/22x22/redo.gif0000644000175000017500000000114011545155744025415 0ustar moellermoellerGIF89auIIIJJKLMMNNOOOPPPQQQRSTTUUXXXXY Y Y Z [ [[[\ ]`beffgiim.l!n4n&r'r+r&s't-t}+u,v-v-v0w2z3z4{5|=|6}7}F}<>KCPCGSPRSb\ajkuvwy!Created with GIMP! ,GLNOJ:?\grtsjbSXhklmponqi['QZM13HYaecdfT#D`^_]- 9WUV6 |/jB#AT@"X$4`Ǐ A;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/22x22/sep.gif0000755000175000017500000000013710404676727025265 0ustar moellermoellerGIF89a!Created with The GIMP!,@b|:/ݺ۟P;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/22x22/stereo.gif0000755000175000017500000000210410467165025025764 0ustar moellermoellerGIF89a &     3  $" '13 .&5=/3&-"/$; $=%A(!& '6 +$b#G$<-'*O !b H*A&5%$&0%6%"/$C$>&T)!+"#5!#9&$'!%1#%,#&'0U ,U )f#Y3K 1C8 */#8.'+.7-E#+<0>&-3'*A%-8/,&-M,-+$,G+,4!+VG -,bN% 9J"/D18K+6569P):Jj :iY(1_%3=5:*:UMgOc[)8)<`Mv1J5>O4=Y*?j<=EI7D`-<UqKx??A;>SN9BV~ Ui3C^T)Eu[oE?I?>cX8Dq-;k0@,Hly+6`6C~*3JBGAFM0Hs8Fi`DHIQBG9IdAHT>H]b{IGI.6Z@K@Ie _ bv `3Ox1BgMm2:FQh2?HR^oKRW3ERPV lqp8XzVt|@RoFWy5S]bdDXWeuDUJlK]No\okszXy_vh{rzu!Created with The GIMP! , H"ܧO!sY0T6:ZqKɓ 6: C'vȀFP z:>B73ҤH.10er~jd#AI ٴa V8@ n$sl٢EeȎ=ɺ柌%(5[LڴfkHt%\z`F⚴Ş #`.{ ` ͢#@&<&XCkאI"AfA @:$wYr֩kνȽ /{y;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/22x22/textBox.gif0000755000175000017500000000060310404676727026131 0ustar moellermoellerGIF89a"'''333666KKKQQQ___bbbmmmzzz!Created with The GIMP,@hH,38PgJM.v4`L.!S0ETaNcog`xoK ` ip  `ȿppA;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/22x22/undo.gif0000755000175000017500000000113411545155744025437 0ustar moellermoellerGIF89anBEFGHHIIJKKKKKLMMMNNNOPPQRSSTVVVWXYZ ZZ [ \[ ]^] ^ ^] ^ `__cdceefijjkllmmmn"o%r&r&r&s(s(t-v-v-w1y3z3z4{<<=BDGPQQWRSUWkzvvvx왴棼坽!Created with GIMP! ,QChN-gml6,akijf8"[ecdbe`2M_]YXZ\^W#+(1RUV:%. DSTE 7POP5 HLJK) $GFEI9&* !@B?zرN1Ƌ4@E,iȱ#@;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/22x22/vol.png0000644000175000017500000000223711044412327025276 0ustar moellermoellerPNG  IHDRKl pHYs  tIME 8 |L>IDAT8-IoE^^=!Hq#q) d1'cKum Xs87#ND7(#@_xJ HB4n*ڙI1TjLښagw] |V7Ņq,AlTZi;!e~+, KUX-` PR9H˗7[ޡ!]EtЊn| ]nP{[.+A>+]ӇTF\0ŻK^F j<>U.ufk ʰ{-7PU33Mu^#2j_L4X7 /fˠ_]{F`mPq9*oZ{{ɋօP?_ w@!oE?e-I)V@%0JhO=u8UE]UAT eH1&Kt ES"~hLE^sĜ(#4D\+̳^ {/]DCqgemᵎ֨J1"#)D$ ANZ;D+8( T>rDD fEH8 c Q(wATXa'D1Yv*`6ce`1uz֦rȳxBI4S )yܿ1Nڏm E!ۦAV_}Wyb.cAt;cƇ_~ϼ01j*n/TJ>vkO^|Ӎ{ )`%8xǬhD'}&) d^~h+AX᳸Ѭ@Ӱu#iSxT:/f|\<4MF<)OPW=Ry"TrZuzcLIyNIb9K*C]1Q7=ihsmr"8{=7#jp 2IENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/0000755000175000017500000000000012326214510023764 5ustar moellermoellerViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/3Dgeom.gif0000755000175000017500000000272710404676727025625 0ustar moellermoellerGIF89a  ej*Ip9qQ%hUf}hxvt|   ~,9HVHHkz&".2;>GJPT]d=,$&99SSoo58%9=8 !E$7Rl@A) iO6s/5\A`r "$>8SGukܰ\ \7AJmN# .{G"| hJ("TYa1$fe#?jE^|!DlEk&BlD6đ)|`BDBAV%H 0lA =dET #0H#

Ƞ@:gS$#!?g'#+)i^͕5zINT>.͚5l&Eq{6d B&ؐ*QB- Sl؅PBh!o|$Hbq`Aw0A qqEH`0톇 lH(ir G["iCh!r$8RI r IB#sbٜZx֞}oa衈&u"N pTj饘fZ)4ި`ީP@;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/_redo.gif0000644000175000017500000000222212035335646025554 0ustar moellermoellerGIF89a   !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~!Created with GIMP! ,  H*\ȰÇ#J=䩣1i8Պ6ma˚T̝CGr`PJEƨYV5l׎j OQ` ?2E0brɉI?nP )U\z%kV]Z,A )L.b&(PB xI#DQd$C&W D(%><?QQɒ&m\Ӈ6Pp?V!%aY9;ȡdC#ȕӡ3vU[H$8qҫf 捛pD)2~"XƀiDAfaDEPN(! A h("A;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/_undo.gif0000755000175000017500000000221711545155744025603 0ustar moellermoellerGIF89a   !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~!Created with GIMP! ,  H*\ȰÇ#Jh F]\GSzF);NN^ySLY2e>-iBʔJ^ }K#5L&N #ʔӧ6!b'w1bkWF!+5Ė-DaR!]%H92ϟ?wͻ.C#D )M?~AbDq"v "<{$m)lԱsL# LD8qЁA#H 2E\Nd DpYÝ;6eXTK0Y<_ 5iQ 1c̔=#LF[,a?@DO[haLDBtEq҈$h(R;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/busy.gif0000755000175000017500000000143310404676727025462 0ustar moellermoellerGIF89a)skcZJsRJ!!!!!!))!!11))!!11J119999c99BBZBBBBRJJ99JJRRJJRR11ZZZZ99cc{11kkss{{s99c11Z11c99ބ{{{{{{ssskkkcccZZZRRRJJJ999)))!W,)GI>.)$ -?IEDDEEFKO.,330, *FJJQ$06:750)!HHJLR))5\p'IH4l_&OD 1\Hx% EI"%L8XB!Na @0$۾Z`|J 6`sCI0@ $HJBҌ .-3=x 1cB7̙QTaRH?x@CQq¸(y4D# /`0DTv\|i.K;J3%:5ڄ0Bh0mw{ ͖e"IWu}4 By5o ^X[(asV~Ю!,}y? xI^ƍ;OO?}8#> cxphaHfY!df=ER !iڍ+_9%Kt<93??q\Pz_gf 8S7n d$++횕 qfs8R!48O&Mg/OժVqbjj+Y٭g?wD,\.bJ%Jj5q˟i@qOJ%NQ8˲#|vvv ᥒ]|ns t LFuDz,In> 0%(z}Y{|4T#(Je˲e]padd27M;uxf:b}|5MQiAAx|X~qm|R(iGiHh\PGKEpwCo~,@VX_bq0T*7oéTMSxvRw- E},ˊ'A.sӴ#ٯzj=h#,bm7ggg5M;88($)b"}ۚ;΢ۻJKdVVHlZ(o{oYV(|ؕcuYtQ Ua l۶,˶mGtõXizsOOx~qd2ٮTtzSF"h6p{y菳!t<X^vZ(JAt]0 ?x䟍9A 3IENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/fileopen.gif0000755000175000017500000000327110404676727026303 0ustar moellermoellerGIF89a$$s#"' !&*** %+*(%5 0)6+48=1 ;=?A;<IFGMKDGOUOJOMSQc#U]*X[u+z7tfkCyar=`s@{ZyavP{HK~nv:GFBQwNcR^TYzNScyap\Ym\VNdQr}ъ_冖f_pxoƀzdu䇝kÛhyw⁩䘤ry˒զ䉱x牴耵Ȅ쁹љ椳ԏ錽ǭ֤髺ڒŷ׾̡ẾΕÿћּ̾ܥزް!Created with The GIMP! ,$$@ H~YŰT)O ai!pP*gk׮v$F:t0uIe?y4CJI gg(Vtߤ)ʒ&MҤƉ,Dt hEJh@2d8d@A  0o6א>tm[f*U~㷏e9svˌC$sU3MٯSz1rF%,48`D@篸|Ŝ#+WKOν9#.ަ,}Dm[dmzv3s<&#M'c\dGO9DV!!P,E IIJ'\s9XC 2RK-J!oFWB $0(!5̊va4q5ЁX,Ab$i8d30  )@Ip"dC@v?cO;68C.JݣF*iBs1Hs3 )0¨H. n 9 1s7l &Q8 0ܓ} 2X&J$a$ 2rK;Ce SNf<rc|'-=m /})7l  b߰r:{JeHA%HR$,)D P'PB$Lbq"'"$boaD H0 G>x/kAB ;C/AC2J%GN08i `8liHpFHrAKsCJyJKj>PwKMwASzIP8WQR}KU~RV{HZG^VXL]W\LbT`]^Wc\a_cZfXhgd]icgdlamgkdpjn\urnjqgs_xosjvnuquh{swryvyxxn}kv}||ryqvx{|àäé¨ƢǠ¥ǨȤɨŰʮī˫ǥȮͦɱǮʰдʷıͷͻȭджֹи˺Ѿ̷ӺβպڽϽÿӻؿ!Created with The GIMP! ,$$@ H ZGn\}XX9c3^pAC0\@B `(@7Sx?a>sެ˕(O(DBEM{F|2kޜY.0Nx08eu/^uЍ[7iNJ#w4JE4Y\BeR%H D:M6TX ͊.=X!$}5sAJmOQs^|Fg 3M1.*-Y!E8!O/lӎ:N8ML1 +pb$iP .X": / J'xI$,bH C pqF1tM54s 1r *x^@B$4НA3쁅YL18 ^\I$s 1ޥf馜;>&8d>j>ܳ/*sECR{N#A7CpbGL(X%\MM8`>րQ- 5|slx8pM6X3lHAtl3/RK#4GLaEI 1D M0#L0*EZRvqL`dA=q ,O?䳚ks7Tf4r $\P>ӎ;V5CL/ȣޮP{ȭį̲z»˷ʽĩʸʾʺnïʱɵ¸Ȯzɱ!Created with The GIMP! , @ c*\a @ŋ3jAď C9H*Iȑ$I MMI4E|AqO#Rb 蠁ѦNFaD*4QBۨ0\q;seJ!rʩ]> u]׮1[GLвe M6zfH,1AʀqaϠClA˗\ZG:%-N6]DN8>,sL_צ͘A̲]5GϜ@Z,D9dZ/}ܿ~V+ Ͽ@D1XF 4QE@1ؠF >(P 6p‡  " @-(@<6cJ&XS" 0 5H͓PF1A;D-}ЁdbT3N8ࠩfDԃ 0(Ē )r'Bߟkr,r(|ಋ.7.TK3,Ch R Al,Z$C/XP6oP6t6i5 N^iM/4F1;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/gohome.gif0000755000175000017500000000015110404676727025752 0ustar moellermoellerGIF89a,H-sfxbdǕiN-A wy0oSnYaJi zR';ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/home.gif0000755000175000017500000000016410404676727025430 0ustar moellermoellerGIF89a,S]3 dޢ5hH53dֹo*c#=+N 5y*]Jq֮mQ;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/hsg.gif0000755000175000017500000012440010404676727025261 0ustar moellermoellerGIF89am[7#c?=M ] "OIE %0z!X2,==(!r)nqY$iV6Gk)},b$xi5^"*L)6U- _%,A#Q+'N'Ep#&IX0s#$Jp#V/?9' Ph-f+9@"%J$ [&& &P=v5d61'\/3['1hCv4,#Ip?t687\\>QETeA,/#6[#x: (*0|;05.bADkC!l9W'e*1IkGfBDh=vO5bO3l:c=F !}=qBh0/z)=B{*Mw UDFUvMB~VAZ A}RG$,HOPN I{ZP>Vw|Z]Q#88XUI34 OPO~0UwKO}=AO\&b$[UyZR}P}sOOXAPFdKb@`fef_ecCOdTUU^\KWee][>%[YebVYW0P#eeddl!q%carr\Rgc}jJ>pofeh:bfM`cl'klholfcxcpaUOf=jRd`onlizndXh0gabbdd^e^llsskwnjjldbjl_eUbdbkkl|zzubf[msQNYU(ԤF͊WIeU)Qޔاtf\.Y~.v޿q]sŽ>vwˉ/K83_#3痨S^ͺר[G>~k\op` N}Ɲ;sk;w 盷ݽ{70p䵕sƌٵ˾_p ՍݸqPN?SL3P 504@c˄b ~jNxX塧͈s];S65۔#=UN5#.0S6腈8#[=ϒ׹CϓO6y]>u&5T3ls}"c/hr/i̛gϝ *,|Bʄ*)0Z(ç-$4r"K|3ᠶhO)> 35T3Xb;ɓ$=vN#YШ YdG7SIUŽtpt(>wڑ,e+< ʹAmkBG<YpmP ]*J҇*ߘ^u9UZR+HB):A8FhB8,XL5JSb4- xJS*SGP TPӠ* JBR, &(D.@a&nqatu`U0: ?z< 3SJO EV0P@?W?VJ%\▬%uC y\==ƳJD. ZQ{# Qg"9t3SnxF,d[YaGz#&4Z@FvC./ay.QE06L#F we Ƌ% !%ط0@n FpDaQ@TyPvlA%L1=ALq4Jw8INb%'9L3ri8E(0OSgAG5OU|CV,U`RVeKEˢ4hjPUNuRKR`po8! y+gU. GC+ta ghVޣ lI7˅/hXȈF4fqbSP{H kIO]G}CTLJE򿚘0Ujf. b` Z Ӄ% }`F> iG;+_9>OPJJY4ܰE1e*%w-kErh<{۠:Œ}T+.B 0.̊1!W%gzWꡭ⑛l<07\XDmwCL(MR|jNћDէ0E1y 7ցK` @*v[ Wae|]g Vݵˀ2B(2kP_i bzT]R޸7]kw>$[iĵstj@}&AދD@{4Xu" H7Ur"! P:u1OPoaS,ƠXL_3W(P)ȀOP22>pb` A` kP H 8X8* `-6`+0k "t2.3 ǐ}!GPue4 ҥQQ +] 083bMTNE2$ņ q vM`&pz-:2 0eur"[ [O`+0 p4')G(BJJ$32VF!&(2$ @U10``<#( P 099(#،#86X1`P Đ-]W @J2 @0 @`R w]u   -gR R.t`q /paV$ t`iyg9…e PIEQtixhLY6iV`.:^ V"{H% sm| R~ x4btD@tXiT^T^YN*x@J<7`lKu` =7rkVց)V4b ~ (s !#",5r QUYX#D\0MoF-`Qu,0-e+G$P%Rb,,NR%W G8@qS[9[@X܀siͰ 1(&H9YP_XZH8  z@ РWŠ~(6 ʡ  hiIB eZWkiIJV;3>$`"+$Ur%GF$65 W }ޢwPCU6@$XGMY"#" qzdLN` bwJvP#6R/vbK'  v\ ^i*%`0P p `r Ъ 0t r<&:2`(U@\P+*.ti2 52Ô7C '(&Q|b|ﱅ%+MXϴC6p(:Pl!p؇pA: \$Z}gOQC[ӝE! l3@ga6 ` R:WP'pP(TS= =hSR*EZT`*)#::y W۪ r ^@eJ0@c4muM@dEe0hwK`ƠHJ `֪@)eԂ-!y҄rSYq Bu:Ԅ邆pTT}]ȅ,3$$P,,,BGH>syPpM'!tf@z@ D7Jͥ G'P-˲0p_p{_``2 ʈEB(t<3>w@Rw^jmP&+2 0rrЪ}]{^ wi i `>|` |~tx~ rr~55,/^Y hK >YJ' .sL(/p/} O@ DPB >QDFXFy5RS&XJ"r/or^lęS,An3 .]dZDTRM>UBwӓGڝMjڮUcL;o5_~1xo/ȓxIGxI'I +|}6'j>|ϽjqCp9Q"sAUPdQU75؃O\pykމB ~g؁Gc|avU|1)k 'YxiY4G9wuOSV%-4H&YR[Kt~F_hY|93ayH+LHQ,jdUjbfxYǝu9E QPEwFN=ޫu,FX #~0R` `S`iYHi&R8"$XD#ofk(Ty{eL*d2 2X Ce[*ėQ|eZji6n${FfSl1EYVE>EM3Ij,ϙrhutuU]%mv3N࠾B`{ƯAPC ՇC|`0 Eb1^ VЀD  8@VR3(‚g`F!P$@0 dNhB A / > , @x g 54i #5Q- EV0#p":I% -4LQ% |C MQaaXtC;Gܡ}!`^ӝzӓ ^_ W/` mz$̔> (9C*:ӞDP|FKf|*",@D @8(f&.$HBB:رZC >!Z|\Dڥ ߝL;WQ !4Х:1MCdtPB b0%09 FF5Z bTa3cX30SDQ02q,NR\0U2@PU=@jVz3 B [X1lx.q"u<9RTO x3FZO9*=  ְ`b  9+\R"#lF$Bèqd ôP0F ,0!Є! A &pAn]?Dcpm,#P+ _!N{ e(p~D2 퇻H^w3"C`Ρsx@/hp . uU>s.Jc֘AQTx<8f5F8Z8T6lo}+-iVDQz I XhF"tPp\mVBd&#c1d\ `Bp&pI@C1 l Є > 7B :ρ׻FAB]4:Ӆ"^D7P+C7hc=H` ]ҭH4?)dѕI]N? -P.ge3UCPE @"}6a/LHPѦva"0@'LlɏA0b D3v1 4.#h0CG2 dt#$) G&LcLDgU:p01;ѴO16Nb;Y]$@ PCdЃTnTEa,zxz2{R݌ԈS14 TPF2fZ Y^&%/FgxmKYi evB&UoEaݰCvX ZfjU%;?5jh ,a:! |ˇAa}nuE,J{H)~cp1  dAp Ȟ9(  I؇>Ģ吇} M]^@T^PD]K9Ђ4Ђ ,5!&|W8}K 0 C=kA܆+ZcO$4[!t+jPONOPD(R\q.BOY!+aKaH=؃zM)[Y|'$)/љ-.)ʩi᳇0Y)[H*H.%`Q: 0E PEH@WD@XEYE \$]EWth a 4S$ ,-0 Q1H,^ C&B68<zGFHA!y\H,4HO`]Z:8w@`F=hjBB*iyDP;##Rcҩ5[Cw ?@P ʟT(T PT%(> hJ  AHGpGxWp̃>pS8"=DRX)1PuROƔ{k(c^2: cEIG΋ÕH\&:@I@T}MI9W-BO$Na[,g+W97$+H$,A R#3-*ޚ%IT8T#; m$Dq0)! s"Cp:01GClhEYY-ȃ#4F)+;C,$ A䱆ii$]HhFQȭiA;RE `,i)*!|(ac@TЪ38arDwxn :[P +@Gb3C/B0~j}';',!ԂTd,-L̉NSwKXKWhT#PCʨTO*;22S9'!'('؁{̀-0>.(^*xʥ}Rn#Xڛ?m[tUi,\Q=fMRsE6}#pa0<>8*)r+rƮr0;r|ZZvz܁9!]Ȁ9Ҟw%S!=LKw??wTxY}| xt F X{^ fhd!#XŸ")!&8&F__X#!nO9E! V]6yeGNɢze!EqR''uy'y'}'eԓc(z*=SO=Xz8j64)3ԣ0:N>:sN;`5T 3bM5۔hN 4HK8X;/OjOO;ओ9;b)r9CJ(= 0 nm~-:Xk:ߠc742PL1P8@c-|RFmn#k裏;^p;l5]5ރKUW9Cn*롒#ðf ޶I b/I'8㊣Q&R`m EK!Wk423H ):6TN\TN95 +l5ό35ƿ@𬕺B[j/C@c$K`]d@I_:7i.p4N"8|% H:Bo.(GKƚZ_蝻u*W(+U.~ @얗ًu{0R)Ƣ("+XrHF9>@:Ψq[8odp Z#(j=~Br" NhB 91 ThѢFA hdX/NJYd[C#,]#|]5(.JJV:уVG|F ԎDckj֤"1! = 0qs`R0a`C0؇5ʑ= cn4߾! iZw ,f)T^.%$! XJRdb#8Ґn)Hҿp6Bu.٥8U`)t&&z9I~Q S̡QpB` bpr{g@3L$B5aHmVt':q`@bmPCڰ`_W:BP]pH!lU뗿)8v  ^ԀX"FC jkDsCB@@Px >r|`o2(RV jo?  D!WЃ2fPX)0#Қ) aܗ fi(, 0?&he۰YP0GC QV0 g^*:R,kЈ?y/axլj)V( ̀ g DPR,~ץ *,4MP 7A uF\ SZ7qUG20vCd0ȾAh[ b##"HBh!LX,eh2  +0i2 (7UΎy\5^ v50J@B|X)LؤM= ;q]mJ3@iyU"qB A$5/W4 , \1MLEyBeEH#B!@A Ȁ `#|&ّ)- XƑpÚa1,u]P@W1a3YȨ C;Jt L=C N|]nb 0T)zA: Mˆ6`!C;ȃ1 Ћ2eQ P yX` X3/0A]![  @@#Ѐ`T ,C-LD$Bx (Tނ2$Y  #@*@L` @4 P.=Lނ8%,9!8H%BFdN,B6C\LG}l ܋0L>`Ϥ%P Z=%3XXЀ7Aչ#tϠ "6_ɗ'zl"OS 9 /H#2`U_ &2 ^$@E0Ly#$&`%V܅h$&20B/d09, L5AB„ QEp(ȁĀ f)TAk'Y 2l42T &*I!Dt),Nt˴*HCǠ5.0KP39" @h[eQ=SPi Ь,B\X~-4M5P4I%3ԀᝁuXyq`BA(B]ؓ5LU D+0;`%$AT##h.Mi&iAH`x'|*TBAt t ))RCLg^/Mb3h^d" (|B1c%2qJgM\ӱL44  % c"hX$V0Y)|!<16}j;;^J556e&A\]|0lpYi˜H <i+aYh1Ti_AETW*' B ,Z@|@ %P2$( '&λIBN%q 8!:&LB,,]S|Oj(ϰDS'y"ЀJBXfѩQ5W|ݚhJ&뇱A6bAY]Ђ54TAC&CA42Ź%j}AVX ˍ2>MԄE@M.~p@ @XrAM VDžNY!WʠC@ ʘ ޡ*R`(U)|Bvω>FVj5M5-詊X+No]B, ՀX!H\B7;IapMUJ#`vCm&p7X=S$y  `c .Brp r;Bk[U5SK|9X̃:k7C20X#_$4̛J9Ÿ^|Eg'LȘ% t0 @k݀۰kkC1'U 6SRõɼT H')T'T&3&8B!vޜbc|X3c.$0THT8ӥrl Lتoa B" B U`6pT[ד*#a뻒>葔}_ ̼ z<^n|dCׁːH8B8`B&$;cvb2ۮ)̲NrA}MF#tTDjD"H%#!XO*"ǯ@Tݨ #LyHA0(򇝗${сQ~ Z~ 0#B%Aq4;DJ6ufA5I)e/T NͫB+m(&BҼмp ̼W DT@^A&82۾) ##<5u5WB3N6'@:5jO4uaC!Fq.^1fxl4ku%U0\Fe1aPJH\t1c'X"CGhPDqRZSm״E *5]c&\9 VXERZ ܹv䵣5О{\\6`V (*òVRlW_<?0kVf͝1tiӤECJ\SB%f :K_|ƒKI֬b# 1,Ѐ{wɐP'r(Ć:լ8/E /Y&׿k۶c`6A -X `zI0\Y9;ddI* 9gv'~ǝvyzhiCiqwZcS0lH5"8RSnl_1e1hYc}hrfrZGjtz6RƝp˜4 C  WrF܉FwQ~і8Jl 'kBeV۩'lgh "@=%12ChBMlA8a5>( dd lgocQDHkQf1ˁb0خU!ʀ[!l3l+ lqi9tsxM\mWzGzZ]%`kpIw F5((zȉj]csŷё/)FmC0hM64+ ,8! 3_eRE+ZV.6 N!bl@-I@k\Ć ep a&jOZ.2|C&ŘBv rˇ;Ǘ"EpG\UN[ݪ* b=YV6Amu$pkΕ,1W94ќ I< *`>0En@'P([UD 3zhX(T6zlsQ (a;Ҵ#7X8B:A`yR[*Pt0j8c'1¤yvUB# / fX ␊T2P2,[LL,kTB-nM 0*g3v_!(@>(a.0 pgT8 E-畇i!_* J =CChÙBLʟYB^vB4IO6e̠LGr3bTtat"M*[X1nNPv Ab :R,n"w4`/ ^l=H| @ R2vAJ3;0CujZ)s?3hZ!>{(ma@@P&8OZ;F qr P 1EC-3>=gey{jn2chI$zN€5X \54{6sSa"/@ K/ ؛̼,J;]$< >h},2d  >7YPld+\IRIzzLn2Z1~aTX*o>C&Al^b ([a   !PgTAPP z`p0rF``X40XڃaC @֩3n(ja d& ` < @˿$cnV h 2@֮`zLH 22 2N0V&kأ97XpL(7\olŴ;п (1:ĶDb!pbbB1G)F A`_t j+X ΀ J@geDzeA@` @f&pm>aX|d`!1d71}\1^0*CH w|WYY *N`K18IAklXV&,50}BveHo<}o22Y!BD{(RStF1s1X`J@373373E`! VSd`5@fsD,#6|LLaAe~7XK@A~9\1`ʫ.L l#2D #14< ƿlS@*Fi<㎵

S*kr %I&$P1VFQ > 4P4 PIU r Ba/ V 8, xŇ<=n<n2cAI?`AAzA'dhIp!N A)a`/`dTJ& A Y ztZG%xtG`[)``4 Ifg(HV4eBLT<&~C= 9^WDhN4`vGw@mΫ>b?.T= U6#NFblb`1nl6f3:2@Jf%BJ)IH: N@G Sap/X`O`kk`['`[`V _VƇP `P%1gW^FR+5N!72K 8VotWd`mn$<4..)@&@QN"4`e``lgiW?RglJ'p<@$8B͞z & ae 4lk{wN6XcoVQ%1E:>Pa( ^1k҇ c5dag@W+$WGs}:@s؁ ̆zghI3agj7q6@8x;޺&( Ȉ$bD! R(yl{Gy[ [v[kGd9j,u %}%1d`Ġ B ]#1!]  N9A9C:H]wXm\iܭfPDxEC/WwEΦK,~! E>v؀7lvNyg N3 e?2rŌ0:L@9J lH!ePAOn_?m`w=t `鹞b"|I8Z^xxBG b x `:x ;:@ hl @$k2G7_ (6X3cvIchF:*Y%(F'&tuv7j#!% @E"p4$:Bqb !bx(H!UaHq0?1r`oZL8#\WX쒦bf8f|M|m D ;: g, 4C$A YQ74JzN`N$n=W=c}A9#@b/[6ZºǣE@U ]ؙ.#`mj!:!]`ƒƀ{o1J>0C3dmɠ}}D!ZA!!# ȫvaji |!j`39 Dl`2+d `Ֆu>4XW>6U?y> @8"Ze|$o4$ۯ>"`gK^/uLa?eY]{L}AZ!gjɾ3aa!)ERo%TtM8Xf|??avYya󃝪fwt#?ٯʪ3" <0… :|1ĉ+Z1ƍ;z2ȑ$K<2ʕ,[| 3̙4kڼ3Ν<{ 4СD=4ҥL:} 5ԩTV V6Ŗ굫Yk?u_ZdM=۶h5<,a~DCOhzt;ԓ?:t?JCX*O=ԣO=9zN:ފ?ci3+8 l#j:>=ʣ=.N[30L@:-<2͠3:@S2Nk>|> ZO<@ NK,88Ì.Vò6T?Np4./PB-܌pLkquQo|M{+=u^+_k5nm袻=h܏34==?C7<L3tm)F"-'>(̺Z>ԚN:N|խBݲ6ŪwjuHCϷ{:;l?\rtN[8mԋ^b3+c^;G:Q.n޲,O+VZ7d8cƐ Uh clA=+-db9a !:[:1(>b5]`k㡵ZӰ6:M-՘.t \LF5%+ vmkbWA^Q[[B. XFBcH /9I_| i,HCh@dq N2D-2 cbU\VF4'7p9u`k挭*VǸrUP6L-#yLeWg=)Jº#˶Ulc(G1Zs eqChPGgY2|dxb)dl}2eCQJġp? )N dfcY;M؟M@3qkeBY/<ƃa":DVPl#3F]LG:87)Yߐ4PƘ<8Y|C,HQuá~RSp/ K#P<&TK(j!ux-f\<:׹ZΫBZE^cۄ#i0\*M} N^Z+^3¶sFҏms-*J-D!@c w7aLbHDMh~%Fb<e(h@)Pi}ql$MuvrVUV ڎw[)85ViUcԪ)}k)ss VX*cPSwc eE,7 x1a-11zڲA]0kOmwe8 /NL"g=(7Q󊯈K284/Wpw_cm1JJR;Mpl =-^}J.VUi.KUR$\q|#xTyFVc)`6 X <,pXq1a i p^ _uY$K2|(\ֲ͓ÇZ4WG_84EniV5@gU^#C|6y}p\su b sytQ>TzPjP!nzSH;Lplwߡ-V*P1!I_1Q GTbINe J35p<35]e7Kx hvDG=3,jrO ]mqrԢmv@5Wpm}.r Uv%ry U E= @ 5 }f/L>tp?$`& ?`B0 o? ;g1> P@ddO0d 0CpfICXh Kd #p_=Yi1VpX`X_ qwes r1 3A2f:̧ m@[:ɦ[d^^^^x h tq € PYWx@  9cH x lpI~G@ mc$M`z` R_OKMF0u3͐ 0/h` f 0|c (4 P 5i$8 uY xx_<ȃ 'hLpe0+*ã* jmpj`0P0`Y:WȐ[ I^x UEЕc&Y) \   4h}q 0 8zD~RKhOYh@FpFQa@hE= K` |`F`Pwi&0tC- +s` ` HivYBDD_=5 In"nXv sM$69J+ WtѦHɏiH 6s[tdυcvYunTtgg iVg qxPd dp7`--KWai؀O@P@ @ H8=tx FP}&aC 4 HI (8X}_0 P8'f gAj9 ^P&uRmi yVxy50}Ȗlx@̥ *x6 Гg@ec:{piJm<>pAd R)UpORxKMKs0W0 ph ri|00 _@4KiupC:ЎЎ& U.)@ SmfPu>꣮: xjit2@ =@u}A`oЩcеjk̩  fpxۙ@ G M w>v {WPI-`v  `y8 ;ȃ_=+Xxty(0qw PKt'j( ] pT\Ig@m:@ a|pppp@5r̅@B@ YZt?ЙUYcU`f@Vp[@ P [ @TE0PM + X CCW`4 882 -+Q0@ 0#ٳg#D8dqyu }Kh;0t%PV(;(е` ƪx8cX^ptG ٶAe6B%,:Z Y 6dsZ[M$'FglzbȆl0VIp ]TT T@v`PDJpB{UpXg+Qu. #22Pi@C`|`$yEJӖ0XCKoEs`QQ yO40k.;H j2jc_`[ZZrx6|4U @ RHpP tA,6/.:fc22k{?@utc@aТXc`1R0 H ک=yD P@՘gXJ2EE0& 5 ug\w0`xgw3y?`p r?sx;셫-0t?)%?H[c+.N>3A.p So˚le8Z]s;SbQo@+ʂj$5LwD;*7Z s̉cj LGTq mռ Z8 V gXpC p5(D J87lJ`}8LXB* .P.  ð /; ~0 Hi -8{7poD AС@8BX3&;?Tr.r6LC?.v+m[-v !*M{+оRG*#TԺ6G ~OlF?Gk8 c-XҼ_?C683QP8T @w;X`J...M׃]Pɻ @` 9= Gn3i@K0EN 3҉.4@. yc쭜fլئ"՗[ JH +pp #!x= -"PД.K2Nu` h٨ 0uC0FP|м0+vhw=?U5tpsw[L&+..41c9/2 P= 6I Υ GBlSz{ȹy.M++acM,y˒zc7ոpZ [`p0F p ]8ǀ @R / P K0A0O>%*َk2 P1g 䙼8wx]ƠsJGitʇATB5#B]c[sڄU% V@, c`T' 'stG\#OsK8JAZ @ /5YFG˃\Z-ֳ   @ Ј`A= ٠0 yDɟy:~uИ:٩` N幓Ƃ>P4~/Sle T1Śg$fȲ%F[1mj,Y0LYby4i-eSQi挙.fY:M8p†=',8_Ŗ[*Wqqᒄ +ˊ rvvur!E-j@Aj׶9vxb]K״cp*ӸM[6xYN-<28D+0Gؤ(#6I&_6Gr#%K|yB=,>6W[No@lrđx /t Aa£Ŗb(&l ~CLіgyk#QN|1ȋArGwYG,TA*@J+-]^4p Y6غ w8$ۢ d^#;#N#0 hHΌRtҹ"T7^5QGkR`i) xB'P ,=(br,B C,Y¼Pv$*n %Bm&hq=4v:p/؍]K=0& `Cw]CLyZ)Q|Z{q|'yPd3A]K/g K܅YDP eJ<9iIdy, Ҥl`Kē&V{ Q5p[|C7XtTƉ0>TeP ᜰNc"䵄/X>upƉQbD`Sh&ȇ>$ 2jԂ@slfP#X%?,CDel e $bnbE2R&GP-jZn8ruԣKbWmPMg*u˻ Y-1E˽fH*r4)Ow$KV" Z `'42a{pF ͆(yCRr_.Y'qX a4Ezky{& dB)H2Ā h|pe-d`JK Pl1Ӆ!"(ƈTdFD.v ݽ¨ϓ)&à%-Xb.L^&6l|ɳf'Ê6< ;iU RҜf]Ee- ]cC-4C!`VG7M7vF6p'o|QI81C#.1c#qj9 @&h&T@@ d`W("@o5ۙ{m%^`݈ʒ\@:/E;``C?:8x8`0ӊXk T6a; +UyZpH`sU .A `d؞3B)!cJ$Ae+0+ h 10. ' AC#>8p6겆P4ڹGtDH? 0h4逆(h@PHb %7\c%MIdH' kZŞS;5؂IEFSD@@@DJ E_qvҹs, 2CzXYdHmȆZ(#}C 3)(YЈ(~/nPc0 h p̑1Jp̃̃@ hL-ͅlԼXMpռ l ,(;Ȏ\WCC> `k V4؋=\I 4 BR8,O;AĠI [F@8+O785U8+DPT Qzq;>aۃs`Qr2Y0*Ȋ#$8p4횞P-Hm2첅x@xT#Ϭ4ͅ\ MLMMlٜ۹s޹Rٜt S$@/[CtAIRԳU@ON̅\OUpŵ0@Vb P5` ʲaW],ɊYТ,EB뱩 "%  =P%B8#:82< Ш'MpмM/ SXl6RrxAr7}R$͆J7'mK5eRrˌ,(J`c8S>\d׸6h@݂Cla f/` \XP RN(U<ap+-qxPPV 7ը +XSYc J˚ R.~Ɉ0 !kQkuBȁu̓kh3؃^ +u~ч|Xw LȠȉ8F&e| PJ>zvGd5ky !>[Q&("(p-8i_4~\D l0؃$&anhøM>L:mFxE9gtB5cY%,bO]EIV` I<+CMc3[$|JdwȆA&֊ 1qKS,dNȄOPN锆G!G@ he{+{i(pG fyg$! `pۖk2NVxxLȆPV$>h02h2]&4`\CAB$!њ@ljMNoBE Mk:/-q|k3禫j&\wg.SFu@aXD JŮKdlX/a`J3XvXul?N1KjP[R44Aۮm!(,PHJePAԬP`vqQJ؄[8;-T Wr:WX$fQfSK'β7ؚIA5 $~kkk+Ι奃W^X gP|<8 [I=8C )=0W|k˞~$_~! aJi!m)G`Vj2,ґx`% ?`:ӈAȃ4PX<) Y_8ba*TP" );#$Fhg!:)1ؠ#ͣM9#`h43.YbLH!uTR\$Cl,PPUc0l]U 3buZ=hV%O>sM5f.ʖɌbu 8d>|S*D1G1]8@c*4&[ :n=EhB1䀂p -k )6I8lF$CbHָa޾6S9~U&+an*"UoaQcV;J"bIV[O9\3V=N6܌fq(' BYhs ,h1@ƠB ħrsEml &첉2}$G~.}MkprۯkGsarw(-Шc8)nxh 42ړRdhOtE'/e:B,48㑌 5 h0O!> lՈj>aaٲ8P0`,Pe]IW95Մ$L:s`3 5rAd-1BN tjx,(QFUR- NOmŃIoyRCsIK=eHmbd  L2}" E&`APX19b>SN/]q4ͅO"TLd 7|RO%4<fA$\*`RN\䐃;'s;$֚pի:׾v5-0hbW5 )H + @ Mb3UnJTn74 A я>(Cm$ӿ|勓i({#!Z/Ԍ38UsQFΎ-#3&c-mqlHBdI%F6|C4n@P0i#"W@. '@BЅS:B/0 p0W-k"ڋ^|XryAn\pZP_5|p, M CQM *nuXSo QH 3WE#U<2؋YGQ`KA!'-{ƶ%nsJ<9-(-h@@c4Ae 1'FvQx0P#ta F pC PT`p!:습fWx]3\ e A.P_A6(G?*x@rس;F7l 'ά0T`kٻAFǴF2m/m!-{ Siyk):-lA3{+K.Xo'T"f0@F0t$#LJCS B- ;t >؛kB8I@.sG}QJ4  d1`G.)B>Q(-A@Xq=nX'( \M5D7dņȁ4t \s=3PrAq} XxəC"Ia"AeB0TTTXL, 8-@B$!A $ 1$2a24h,pB- @tJ k ieEP-[g!Pg Q] Bb  nDBjS,Qߘ0}Ā#|e5ĺI >i@4 :G ) b UN5VEPXX䛔 PX5#< 3XC8VT4P#b 8A,0$@!AXP tw20>-tA/%)⽓$X dLrb&~M@W@dHOI>P 鐼(x]G<,O !#xr(4B5v~pDŽ# %P WJyllc`HE_>N5$$C:@)`ΙXf^u]#4hWW aȖuNR@RYz!Z^LG٣ !P$Amx* !f|@ @ A Ȁ L!$,rJs@s"Rub PiB!Ф\pZ]O*'O֟dinP.E , dX%y^ KW-؞hCP4x5$P?y]ia5 *LE>~r#8AA0K AB$$*Xwx]Ϫ""D|@2AŜX|ĄX@@m:dtL^8U 8I&d |L)rڤa^)sbLA 0-kZ h*A_U$>EӣjFtu4,ΑcERcPHa<AD"āQ@ *5BEx6*BBzhC $AAE"!5)T%<| dm@ӽ3r%;unnL5"Z<Yndzks*,G-,q*, @B/=>'f>Н8pEHNlglYֈb\9Dj,DyH5h0AjIJ0",*("*4o*$d *00!;>Qq%XH@Gtrk0G&BWJ^; <(rOj"B˦=8A$!pFj (@5=U*`^61X>ealT*eHFS(AUOcY҈P/8sVd!Qs`z3` B*!(/89\˙t}˲0A3 ?ٓFTi [n!1p&pAr |@)I(x@EwA(@T2=>) j渊bL(240)_* D D>VqD A2p /6V,P/ ؞|i 3c EB"5%1CQDQ\8{q)N9C>C8Q;@`Z >@;4GXA@1 l# @ POA)XUA'i?B40GܓUV-ÝP5 Ch@&ʴ(:{e=,'j -D!(BwAY鹐W+q5t@h,ۓ-DK3X;V{㐦XeQ 3v}yw0PxDC)]kgm8ȏ<Ƀ~蓼(7Ȁ  @뻾h! !&}E_F_ArFP QkqLIʼfD&aU䊤@(iu 6З/P5c.f6.]ծi;w-:(nQS;yٕT.qra#Y$N Ćf:I掛7` Az4˟L6]B٪jfŠZqYٲʖUHn+|lUW_`z{(N ep@ >p|0l  5T9.)_H§B(b@1{۪,[B"`9ztөW~{v':}֝wZ5frU|Vp dv |,7jGwhq)OIcAĐP6 50:d`F\P⸦ΩSV!Į0h BKVYEVM*2jg,s4% G͢` 4L ׆{gu344Ƨ4'$ɤ 9 7D"-0NE8 :Mc4dP8mX暥ևډRG/P[8@y(NJFp|Pꨤ L(Z`+qJ,INo7S;GTBe '@%_ʖAhq t:K-+)&R7a ~4EC :V!FY[lojc'qIO=fJuJe%C$ҁIQ-TbOg8c`OlkW7O)}R(xS@,ԠF2D!',0 ьq؃@3 >T!|E! 2n8Q8&A霠x9l͂)bg'@ĩ]`n̢2SȨyX̨F5.2#B= M>p0PqjP@xa `A2o|,n;P&!6&R`"c,[)F2,%DKHoV!HH@_X2ь rP|)$\7LA8+^(kE0:TM*G!F8uag{Kta B{5QOkXG` 0aDjޤm!!HH e'f4 .h^Bi+]1EV09qeRibsY&HT9]Q2 ̒d@D:b*;Y5Xi›YjʹN^D*XC*\>z@Npno,H?~b@׶%2FHT0̙(Zl tOWYB  s[ePBrJcioQ—AWZN! " UKm&XD˶Z\2ʌCNt¹B#R60zR#3 \h"D˚@f99`FزĨDր hrWZ(8Bt` X`Rc\*f0AQ +XBLqC Di|ÉQPMYouh}O}8Eg{Eh+p3  l&7 !4-VZq7Pns' H g> ]A_0# ! ` KAm=ǭH;~H sV:ypfmdA.b|] CRVlX1'9pjT%?:4CwV1cXc6:UsģǦWO `hO$"B 0A_.TT)ۧZLpuߛx\|T@13̀ @m/fOA>^^8`E8ڭ cQrIЂ*A x@ l v,@;x : PVI1-7H4~H Qdg. QyRRo SAq=ʉ+XXpAoXҌb f" LЀ 08tS!~NJ4.U@ r@@ 6D@Dㄆ%xr 6PPh *X߆6(B@4 NT 2y #O cgr >ʩ lHa+   a. =bz$E$g(2[!kdDHЦN p'4 b@(ϬHOdI4BA8C%8K#۰t/,Q0  O Q >0A` ` 12Tb3.=BB<43@>Z.K㼰dR4|"n%PccXrvcVeI[Gkf: 1o= /1={=sЪ Ta HNTcJ>&M,J>6PȈ@ B@CT tH"t^ދ'JH C 8 NRGME~T.!1Њ/InJ4=!!:JF.j Kk LkhI YAƈȂf?L} v DO7Z*JJh4$㎓` RLR0  8%T 6xB Ί]^!V%V (!KT  *H]EʔO7$ D4 QEۦ, jHsaI0xkvfLdqdouaӁXM.TY{\8LM8) 2aa 5Cew9a#ZIWw; ş9P:֖j':h=7vTLZw[ڥxj:XQB0,ä᥇v9֛%6WکG m1qaګZǚ0 ;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/icon-focus.gif0000644000175000017500000000047011435772645026543 0ustar moellermoellerGIF89a f3p= p@MY0\)f3p@YsŲ̲Ҽ̿!Created with The GIMP! , 'dih ϟLJa4oH "Yπ-|$Ǭj-r+ y}baX׈1 >yOqYmfn1]8e8bbgh%`XZ3OR|h2J>*x>( >,7 FQ()!;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/idle.gif0000755000175000017500000000143510404676727025417 0ustar moellermoellerGIF89a)RJB{skJB!!!!!!!!))!!1111))1111!!9911c9999BBBBBBJJRJJ99JJRRJRR11ZZZZ99cc1{1cckkss{{1c19k91Z11R1քތ9Z9Ƅ{{{{ssskkkcccZZZRRRJJJ999))),)@M,-162/,$ )UOLLNNOPRSU[MIC..CHSZ\\[XSM%189971*OJJKKLPPWG  IRXRSTTUWX[RB/% 'DMOAZQ,FpH!(O,kI_\2T!*MhE!,EA+Z@`0H*UXaEKL|H*] 4bAa(FE䠡b 0((ЀW6^aA0iFQd1B,"ia< qKt XC,\i A!,X(@ 㐖t Ţeq"(.`YZRT;ç ;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/info.gif0000644000175000017500000000261310431142040025401 0ustar moellermoellerGIF89a z{}~}}ؕG^I^K^K^L^Tj[uO^O^P^Q^R^R^S^S^blew3؀فڂقۇ݄چڈۊۈݍގސܒܕݗݘݙޛޒ㙾㚿᧫ũŴ›ߝߟߗӢƞèǬǹȳй!, /H*\ȰÁ )B' G*%j$Ftq *Ye#N^j$qc^έ7m,Wr1gzm7fz"5 Qc`j6wḉㆍ:0&8ʚ.8txak‡GʜQΕ^B'D\!;iSR E1mfp`:D2'?ȩPK,YlE9XDnjFa L,DF -L ڐ 2h +hqD <sTc[ccH#M ܀,_ЊOWm⢾~omK˹'f_@vq<9r^#̸!$G;$E1,0c+Fެ(\ZŇܐ`WթVK‰"%PmHhϠ[ &iJ3?˭pH8Dz9L=+8i޼ _ ` b"Hj(q$W^,Yv9YDC*|2̐٦4^7e'm,QHo !]`լ8b*HHZ8"4R{yusos8epٍ;-F6 u4LŽ*$I>Hvrn<gaj|ɠ30mspD큲[BZH;I dah ܅kIIx]6c\"BAS1j\/HRj ʊ\:+`MN!/ 4M#D, ə35ڕT*OM.3.kPV8PȚZV,+c$;/&ͭڱ{ w홃-9dG HXAbK$aɦh.238ҿX9^$tݿ91޷KO5{:{…I%21C@tCwa9/BTYNR/1Kb.NE㰷B2f޹ P^lsJVJKarO0AI>ONŊ9޷0qߙ@II΀IPh`>qnT܎l-!}d?2rEX3C]Qm*>pp/ٷx^'`J9;H9-7{HWfdϧI:9 -G>} iYw'z-WTw]ծ9;dd,Ky,.{ Gn:c0 %0wЩX\ZIQe7UGi;}7}ro,vfo0kPonL$"&8a! \* 8-PNvYieqXciL{ WVO>sBАs``hH^ .ZT%P>z^Kn3ͩck͂+tg wv|J;ʔ0%-™39iosv'S =r0*odX%ZSk2Sje&&θ9jG׭3֩˹-?8\_۹ ƒ`j`̹[GB`Tzi7ѣ[Ӭ3T6¹X^&E΂ ¶l1:=kWSU?r qTM8ԅ0AB<> K7ߕ̲XhIENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/redo.gif0000644000175000017500000000225511545155744025427 0ustar moellermoellerGIF89a CCDEFFHHIIJJJJJKKLLLMMNNOOOPPPPQQQQQRRRRSSSSSSSTTTUUUUUVVWW VWWW VXXXYYY Y YZ[[[\\ [ ^ _ _ _^ _a^ ` ` abddgghhmo%klm n!n)n!o"o)os y$q$q+q&r's(s*t*t6t+u*v,v-w.w.w.w0x;w1y3y1z2z3{4{5{4{4|3~7}7}8}8~E};G=>?Q@ARBQCFGHITTbfXWZYrswkxyststu{܍ጮ앲䊳᛻!Created with GIMP! ,  H*\ȰÇ#JȰ$J&Q a,Z4ht)S%b8}GܸqyC"WN9VkظeӶ5c0b/Z:iBWd̔[֌؟ qPdgʑ0Z0M+_ &,iBek֭Zt 1C\LJU) @!'F"*K! Vq'OC,VH ӥ96\AćL0–<{GϞ:EH@DPwС qjic@Ka24@I54!)>'8 `<@;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/redraw.gif0000755000175000017500000000145510404676727025770 0ustar moellermoellerGIF89a)݄QIA9IzƜsssQcY!߼9cccs{k9!Υ ZZZ9(ϳ11YIqnzRRRA0!ƃr9p9991AYWQOJJJ!(ףQOkkk8ZVb9armJGzz1xb^Y0Wb_jfb1a)))IGIG!Made with GIMP!,)    !"#$%& ' (! )*#+,-' .^(˂//`(!c!Hdl_h"QF)Hc 9 U"NXh ^Ċ;d0۾Z`tPG!?HDAp$HJqьEb-3 #yG 1@7̙>P$߸Ck%K!y{4dǍ `D=8x N=a$PpUԃYӵ''FDit)45Zrd !G7Nح;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/sep.gif0000755000175000017500000000013410405340354025245 0ustar moellermoellerGIF89a !, @!xDrz(鋷-`&~lDv1t ;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/stereo.gif0000755000175000017500000000247510467165025026001 0ustar moellermoellerGIF89a  &     3  $" '13 .&5=/3&-"/$; $=%A(!& '6 +$b#G$<-'*O !b H*A&5%$&0%6%"/$C$>&T)!+"#5!#9&$'!%1#%,#&'0U ,U )f#Y3K 1C8 */#8.'+.7-E#+<0>&-3'*A%-8/,&-M,-+$,G+,4!+VG -,bN% 9J"/D18K+6569P):Jj :iY(1_%3=5:*:UMgOc[)8)<`Mv1J5>O4=Y*?j<=EI7D`-<UqKx??A;>SN9BV~ Ui3C^T)Eu[oE?I?>cX8Dq-;k0@,Hly+6`6C~*3JBGAFM0Hs8Fi`DHIQBG9IdAHT>H]b{IGI.6Z@K@Ie _ bv `3Ox1BgMm2:FQh2?HR^oKRW3ERPV lqp8XzVt|@RoFWy5S]bdDXWeuDUJlK]No\okszXy_vh{rzu!Created with The GIMP! ,  H*\ȰC{p7vH/|w ,8p⑊%Gb4,Ȗ7iצɎ-iI…V]=KS@ Xޮ]LlњMC˂]%= nd kr潲!ƾHwO@yo5M31w".Q>72;P@ sD#7}cN.j104 JL3ȬW`@M2.$@ A@+ Hat 3 ,A4@ /BSH-]*SYЛ !JB:AXRQ( `  hi~bڦX*ꨞj *jꧫ*;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/textBox.gif0000755000175000017500000000021410404676727026131 0ustar moellermoellerGIF89a ق, e޼c+P)L[}&9HѐRBi4dȖ۬Tb,g>/~#dznfVU;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/undo.gif0000755000175000017500000000224111545155744025441 0ustar moellermoellerGIF89a BBEFGHHIIIJJJJJKKKKKLLLLMMMMMNNNNNOOPPPPQQQQQQQRRRRRSSSSRSSSTSSTTTUUTTUVVVVVXXXXYYYZZ Z[\\\^]] ^ ^^ ` aa bcddffgghiijkllllmm mqnqn n!n#p#q$q%q%r&r)t*t*t*u+u+u,v .w/w.x7x1y2y2z4{7{5}8}9~9~<<>J>@@ABCDEDEGGGHUaVWWYXXYZ[goiy~pssssstu狲!Created with GIMP! ,  H*\ȰÇ#JP" ʣA1)3@/I6 VX-{\_v`‰XbŎ!3 L_ZUEFD!rZ՚˕WdтEIɊ?P4b8$*ԧ1=|h2m N UA%K&9𐄈&E(!$z0CD-bH-h`a#2Th!AaN\A >H!B/j'>d a#ʕ4Y*` ř:zٳO:s9L`Ct mƃnFO7@\lq (0E +>P@&(4hD;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/32x32/vol.png0000644000175000017500000000421111044412135025267 0ustar moellermoellerPNG  IHDR  pHYs  tIME 76MM(IDATHUɎq#sU# vl C譟 7~v`H 6=UuuUݺ?E$>2tqq Sw\O?|w⫯wqs3ӹXCf"\R Pl,O0 Ȁ*H 7xXd19pdȲ[rD8v@t $f]6U֝N(p$-#MƜkHiwrJ::|{?Fk eey ?0cA)iJØG<4HQqp(Nbji'_j}?LfA0T_~'zM\X&fP"M.Mm(_ 3puϞ&0N-ңBAC>èNzHCO>$:Xn%$a?qdNZ J *e^Yٺnip8N].ɧѷtwGӖ ȪԲ(Vx؉”vF?{'M U!yc}DwNvxjne)BjRYYAnm 0n㋛>;ήyym" B- 4t` 1]CD%(G")3 MnU"& [l$4:L2Dn'k%O|(A>|T9u۱PޏcbbE.]ܤtzVCYFfAXHJ(*'a"4y)[G4̜D)6"3+3 b&{Qx Ɯ09 =ԧ6fV"7LmQ&bOv+RRyp$w'枘gbC-xr!CB$N bav%[p# naGL1byfBHDUhfAŻ!{D 0H^=SYxɫWJij8l*6dV?>);=Bf"fuv>aO=듼_lٓ_wߥ4 PZEUarnVL>$Z>tG('6pdU4mYuw".MX6̝ܺ'NQɯ կ~JʚX?X=Zp>.G]Qϊp"4Y.wOr$*gʄ s ɠM+Y MU( %(;nx32e[*|EMóJ0$0c61AJtw,H+e&4%)v9rp1]0cۮ/<IENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/48x48/0000755000175000017500000000000012326214511024003 5ustar moellermoellerViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/48x48/3Dgeom.gif0000644000175000017500000000424710405340326025617 0ustar moellermoellerGIF89a00w? m M6+u :p G6" ݚ&'ݓ $σ #+͘AG(9Qh"!Q :!+b^2)j-7'/E'1=nA7f2r#:Hw,6 NTAX@DT^86886?~3.Ry5?DQ=Rb_Ynt: Cw, gT(@%$y"pkKfLz*p8pA!_zw<>}KTXMUQQUG QYDNUgy (dY^-V]CQXv=v !%  9T B7LSamQQ_iH*3Y Kbcn;`6xP?>loyix7q} k5pz&NZt o|4v#%'g.PhpzX",Ĥi8LbL}{|psZ\n5υd`/փsȳ:sa(# *O602袋,b":Gnxܦx-T$Ck4䖴 ! 0@ 0԰Aˉ$PwIKeקK2UuD\B"Uk1ew& 4RI%< $p(Y2T>0CK2%8#7h#'hˆdUA"ԇ,吆#QMN^;O37ňQMDKPz*t58<ܣϊ3#b¬ci1Y[aAL2E:=ԃ`<#c8<c8"ȗ7pv hx#axN`]S,FB<5D3P*rI[$)X4ׯ-c-d/lthent`"7&n@Hde8JmQc~o t #Bn 0H Qu {q4 S3i@Z?qbK@h Mt"Y\WN 8>PR 7>`j',OG]#E$yk2F!@ |%X -UA6DB6PD01|ep g;lp:rmd8]*x!>2srx{E0A n#ZY쁏r*H ;qbR*EXv-x` G:Ag*c#4o Ӓ @V. ^#>sKciFc(/ZH)61 [cXqG< z%;jljY)qdV9̱|cd%<b;Ŕ(Y71L wLFj.N!J^php1 eL.xR]jeD\E\*RɳOat ϣH*NOJԣ@hʵׯ`sI:Nу͞?|Āq(LHA'Ϝ< !BtÇQQKnzaInxbƣOw4JL5+N:HȞ-*MFm9{ NȅD =(N@QsL0DHt&1kM$}.)D->,?PDMYHatE4{qDžfa_nabH\R,B|HrJ,2ITB kjH (P H 4!B 8p!֔c,=ɲ+($+OMxNMBC`҂jEig-yb杼Y$ˠj衈& +@!y p `饘f馛 @:֕jꩨaq 8b#""VF^"첶2BUԐ0!2CM dd .܀4Ⱥ8Үƫ :`Ⱦǿ}o ‚(p‚X(HƮR +rr|' ol('&A& -(#a,a#1ʚi%2L{<4 ,PA  00)Tw 3H%{B 6D1&0B 2 ȫb$xL "* )pyf89+T杬fUtV[,!f|fRPpSHnUNd,>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~!Created with GIMP! ,00 H*\ȰÇ#JHŋ3jȱ#C9sIRH7bQPF"%$Bld%͚>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~!Created with GIMP! ,00 H*\ȰÇ#JHŋ3jȱB:v<>G # )(vڭHM4X&`BESlkL7)[L2]-iSJC X0`4]B#)`*_X`=RSI)a2ʔǦNڄ(hSHԧNC )N _tE^D"ٍ1%ʒPM(qCȓBd\@r0=rk2|ٞ'~7ҧW$ G<П?%K(QD1āE yHQāDDd|Gd$qJ`A4Q0DEJSGDqdDD=OTVP QDDItCI8rafrL(BF HaaCqFqgoEX?EaI0GPLod)nEjtgGȩN@F \ƬFlULEIeYD1 DUiDԢq؎1fH:QF,eNK-i!+ "E`ƿѯ[XBG$DT`oS!$+(HBkQ4l8;{g\\mmn"+Iz*5iS(U!M*5~5}`'p.v,}~efgggv>Ll97NzFg~|{w4al677s^gYV(n .z=jRT*EmWJ(h4e~P(mA%I$y^\& 8رF45 HS,s HD Fwm@ZZZrX,ffH$w:&rhD\BI^wXqIJR 0 H$BT*0 [[Dx<>??O$$I$0|ʝ-?X,F4M {7}`uPiZ‚ND"j/]d4~f(*Xt:Ͳ힙!" VUUmj9rDWWW{<FJZ[[fnkm<' N8{7oFd$I]]p]]ӫd(;99 ,lƱ148qsssZpGwMϯbl6KAhaH$Bt$a&Y,J$k6zX|qceRFZb˗Zm<?y$ މT^N8G͆_{t1KD4ι陘عs'A!PGoooYYY8z&IN!pOɫ]oK~#S!C7V) i4~.iSVVv)JH( H32uxWAadRTNMMٳj-//QVV^;t咰=*ohꇆ"@_KK:BD"j5nܹ{3gHd2f6+.S@DrH,ޤ¾p^WC@`יT z}.X, ˕/Nmm-V+_C&+w4鏦x 6[aS`>EQ!dz1q Bk:8BT6nrt8jN$L&z dv^G._tTjbѬ1_NFaX,x<}}}|](&&&Ξ={8N]~_SS#xKQ[~ǰH$ںva\>999gH$·|:IRlAP_|-Hww+2.NiskөVu:L&K qJKKqz| 3G'}bwRg:(R54Hʻ+h49/.w.|.a]!dY]ZZ B4MsW__N%IP,qXں4_xݷ@ b1 XʼnD.$&t:opEr%byg+gż^'BVn2d2I$@dgn***nܸ@Zwtζ<#Iw&d|{6/ |Zd2G+˙>>DqJjkk+ !$HbXSS@ JOѣ BT^''BKYz7Vdn|58ՖHPPB~_&E"2x</WDp:E2Fp˾p!KPSS߿pppzzfO<=!] vHIENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/48x48/fileopen.gif0000644000175000017500000000447510405340326026305 0ustar moellermoellerGIF89a00n| $# (%$&,* *,)'1,152593><4F;B>=FIPE EMG0HQTOR"U)OYZ V7T'[^3UaF[(b2c)ak*f>]7e#m/e2f;i%mPd+rMh6o-o[f8o9lAmOi4w1u>u7tZpgoEz3~cs?C{A{\yJL|T~n{PIHm}P>U\zUZU{OTulXad|^ManꁓZsSh⋓epa|ڇi‚֐nyh֋ޚ{悪v䝪ѩỳ̇쌻虵摹ԧ֡䘽˜ےР꾺̸بܾЧѤ٧֤ߴ!Created with The GIMP! ,00@ H*\hЏ#c޵k7O1?T rjEcV*4xDz_{0ɜh.ܴi±#NՁ& fڶ;7nؤI)TZZ;vta"  9FsΚdjiҴi%Bzڤ #eNJ#NÇ @` @Lɹxءc7n\j᪩VkWlP6B?~(>zܩsG\7kq⇔g'S;t!K͞](O&E@#| 'P4Q;saGS8u9#$(ӎ2SkcN<2 UJxL&ϠӏgtT6qp1\81?T(‰''bDzQUa _dz|X00PW4bJ=9#P,3K+ Hi!D!!P0<0AFBp@"Wq@%2"J+@`tELC0@ %l@b *Ohci=VLk ,8Au@bhr$0 pclxQG`BO.nxA~dhP!Bu)5"K0ϼcӝC9rE qv SJ)ϥf=gHaF 4< ,:/%+y>ļ{L2@B^A$ '/ !K8|NB0 Q"Hb$؆.;Y=+|E.8OaS|BЅ.V&ڊ#0scG>Cw8(ɨE+Pa $,uhÅ Gb!],X:nCTPqDD CI v |23@,(/Л} /X X4Βɵp"x 6A$ZD$01@U%<QE9#*xH-G80~V 2e>|c7:xtjq^$6?|j5 d"b"$ ) jV C$@:Ahi0@`(lgK;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/48x48/filesave.gif0000644000175000017500000000463410405340326026277 0ustar moellermoellerGIF89a00B? > G FC9 I F MFJ@ROVG IU R"N%O X#Y$J#"["%Q&]&&Y-W *U))\&/[ 3]--`'2X./]+2d,5a31e'9d07j58`0;a.>j4?f;=f<HpDFp7M=NuCLuELzIKu*u!Eo3LRE "<Gƀ[ "OK|u@Bd:888>7xt0w kcXȱ8H"zHbEY(hC0GHwģ 9t! `BcCȆ;􎬴phG;&X5J! Th t=CXxe\"[P'$1N0yC~Xa :@B mҺ0ba4#:A lCЕ+D M6fFa d,P-G8ņZF Kp .ɃA4=0+up3( AqAb G챯~5h/ 1c"J T$D F+:1yc @\dG&8GBB FPOHpD+txT7qf8a^ VHtXfs"`>bB%ZhD%2a Kblh@D <ġэ yPCTF B f!CC&E)r r0:!|8C BA05 eEjҦODBmf P 0s 0&p,@Q% \CAs3 an0X@8@N@20 |@_R@;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/48x48/float.gif0000644000175000017500000000376510412574451025620 0ustar moellermoellerGIF89a00    3 5$  %D&& 'G@ M O e !Y xH"L#TJ# /Q-K/W.Q0Y| 2[  y   " !'ikhoqn]t^vYVdwax^Ytvsh{yzxa^g~|}{ie\Se\ttpJqu[c[vxf}xCPA{O~tـ|{>цȖKǙ_{•~zȢrřrԣcĠϠ|ΡbKŮϨ1ǰQ˷˷ҺȸǠñ³̐i^þɾ¾ĹϽ>ʾ˴ӏnȍƶɾƬǸǿ̗΍a!Created with The GIMP! ,00@  *\ȰÇ4 B2jȱGBX0Q /HpXɲ˗0aY͛8s2g O(LܟM.-IcO>k^SADވid)LHq:5g_MFȁ&hxLc'4(h #H/֜cN8ýs+Z56+Lsn0SLSL0@48c m`P*f1WvJ _-ԧ닠w h sP7qFF8suXc@%( Wɪ/?cpy>Vt:8Bu#NB@(tWY9(@S[1$X6 u09uE@:g2$e֒%{fo=`ϼlk7LglIVvP ~ODW~e,+C&%[Wo7ד>Va;47xحT^K/E 8worܬ4W|_,W֬!.M( YYsn`&GEnf8 NgFOMfK%{O{iF$H@ɇӔՄz5zj]@4%Qw2ceyyÆkj9.I MrіֽWm6 ~y Q B9)-y *eqW?lᅯ(we7yfh!dN!@.21#.@D$bHuE2k0|+xnh8 %jvHV#;DFuH!1l CMWd۰w<%Y^ZUu /H>^HHT!7#2 K c{O`+Ilac !p fmӻ2o-NgASW׫LѣtGoov'\Y5 4-B`{EXI DLib`ԃD(vԆ8\>og<9h]No..R*YhY,/oރC뚚=g.58*RrL?"4]CO{3j*DMTK+>^{/3GUK2V9Go$)zm+|N@JAʅ/cX"PMb)Qױ Xb >0A)%!${kYZ"vb#'ӈSs-e fGn\ȝp,]7F(hj:aXb+[qJ[,fFV!jbTӁm$QO4yh+ 7?0%sg[]_X ]u.o.C+@01&Pф[u 3AE CA?0z"a~p.^NsM Νy"N.qE("q&:$B A#"ćᘗⶐ)Pm4\LALlOMZkLT]h[9nCZaڌX,r|ٯ *Tzn?H$B"pJx4k$O%N%ٵcIFśGCLtm'cUhFO}9$khS)$xN "  @ :WG } ;>](dz5o3參rz?AmiLJۂ=ퟋ߮\4ޘ1#Q[ &&b`Hli#Gг_H|KwT8*-M9}&;ʐ@RWw2%.*Z_naԓqي=cCY8b -q& 8UbaaHd,wWctuP6X'/kER,=ɸex}5݉pnJ?[WTlkq@X` ",bض f4fOb<o`q  MTGAJ(]E"ͥ(p8&Hh&m>_;+:;w$Ϙy\ѝ:.ۅfjډgN4$}. /xx#fʺ8Gϻڑ䥸 __x闌mC^!4Imp~'dŒ oܑL9>P. jACൽz1 ܑGuX@oH &ֱtTWLVOьk$@Z@_׳T2s$4#CaAzz^ mF Dy GnpOgJUoUƸ+t[ǰ TE%nI**Ao1֠Q` AZRl 5ncx)j7Q[RY :dD8l^5$6THpdYTZBJ/xF5HCȉU%>S |f􌢌 T0`h F6ji5'x e_h8LAQ{ ړ,x/.'e]e/;Άjt0r'Q htZbb֬+V ^Os4w˽U*6 ޾^TZ_+34R鿮'>NpZ;Z7no#AMYԦtZz٬]ϭ7m¶94)AB~I<8p7)~}37Ip=r]SY4R(A933V]R8SuE0&::FAt2$n] KEyy~;UF20wͺRdBdK?#Zq0a 9GnŌ̻ y꠩/7w>@bՓ)=Fe2Vla  V "A~6okCiJ$C $#GD(GߚW QYu$IJlﻛ=6U[7DfS>I| ޞ4/ImaM;4tqQu-l,bR}Fc'b4ќh 2L& (5wQ:]f3=2Mt1+榾5x4锔젴|sWsLH$Ve4v$7o)6S!))P 29RƎ#ӻW cˤ=Ay9 "xzQY%~aJڒ45KQ";leLʬx4gHH$fŖ2+ 'OL$=ijcY>jfEKNz4Mu3#¢qLP|wD7s}R{I?䂩ys(:[o=,gW8=>gigpu dW2o̜.yo8X3}d1փKEdWl&k +kIÛIagݣ%Wv4jb4\YLh>Mii= c;ѠF7Ͻg,&L8д' ?_ω]zoA6?^®]6mC(lD2djj=hg ih(gߙ$y̸ dRb'ز𪙜OҾ9Ctcэ?m l(,rHځg 4|$a/Tlh(rV)3Q7q h<Sq!@P0 &d&:@}f#Vs㙺eޑi?{njWQ>i43z%, V{`sAr' 7O 3%g7rwVI_t:>q^ < -6HdH}ҳȔzxK-YhJH:P[ycrӼyl\ ~[nT ˡP;  u/U^,g_EG}BB$R?K%g.FODjH.2!6H[g\*)#.k6S mB(ubI#~IENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/48x48/redo.gif0000644000175000017500000000275711545155744025454 0ustar moellermoellerGIF89a00FHHIIIEJIJKJKLKGNHMOH LQ MPQQNRRRSRNSTOTVUVPUWVQWXPQYZ[ W QW\]^X^__`aZZ[b[dcbfcij(_fdfelmf g mo#h$in%kotuo(lw(j*m+lpq+n.pry0o#s#v4q&t(u+v*y9v-x/y ~1z=x>y3|3{?{5|A{7}@~8~D}::-<>>?QAKACUEDA6GNIRILZTXdOQL\a\^]pmaTk[Wjfvqi~g|~zbd|re~yzی艭ށ㉴㛸衸מ!Created with GIMP! ,00 H*\ȰÇ#JHŋ3jȱ#9uB Rp4ꕮ_ve0LtTˢ[̰/޼w ԧBpi,\zۺ_zYu/`fm>ٳGn]{БoJٹr)G\tIN]9bx\Ζ&ST|!7mc{V_X#TEtlqd ; lڴgϠA _Ph D`@~uQXk1+pBРL/&hJA`PA!P dP -ˇ&T)!+"#5!#9&$'!%1#%,#&'0U ,U )f#Y3K 1C8 */#8.'+.7-E#+<0>&-3'*A%-8/,&-M,-+$,G+,4!+VG -,bN% 9J"/D18K+6569P):Jj :iY(1_%3=5:*:UMgOc[)8)<`Mv1J5>O4=Y*?j<=EI7D`-<UqKx??A;>SN9BV~ Ui3C^T)Eu[oE?I?>cX8Dq-;k0@,Hly+6`6C~*3JBGAFM0Hs8Fi`DHIQBG9IdAHT>H]b{IGI.6Z@K@Ie _ bv `3Ox1BgMm2:FQh2?HR^oKRW3ERPV lqp8XzVt|@RoFWy5S]bdDXWeuDUJlK]No\okszXy_vh{rzu!Created with The GIMP! ,00 H*\ȰÇ#JHŃxq9vsGϞ|(u,KTfDpQ'MEʑDnZK);yiC(3pBcfC̘AO*e12c4dѡJ<ݹH/_̜2OV0:ծAnܐ8pĈa"&'ojD6l fP*w4:ؐ=A$<EN؁&!Pa#[ >@yЋB(p|h2t#VL9NIGavA*3 B,93O57vU"4pVeѢe 'P)1J2CdTH5  Mam@) T)&E 6ۀSԃ%s9̸">hA Ǖx#4\34:$\@"$H8yf2E+ &ʀm ,͔d4L30nhP ;0&ݔSN=7qC  xsK3Dm3 sK-c@a76Lh;3 Hv $,}J+mcv<<#:΃'O OFAFpҧ7*@-22cx9 31*PUP 46#o<4Өb.@C, ]$c9S[R7:Zj6z%_14LcE.M. ,''~:v6 %k KH )$сps4M6T[*hM#L@d$n lm:j6 Ç pE0@za P/\|/Ȥ cX C=`B[@ $iDCcP$.ȠF8&HALRlьktѻILa B*@E A4 cPB N0 o6p*PMP Ru~@&X`C&PPPxRp xb$0NpW9x̣:mc:8 _<F:2;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/48x48/textBox.gif0000644000175000017500000000116310405340326026130 0ustar moellermoellerGIF89a00"666JJJQQQ___bbbsss!Created with The GIMP,00@@pH,$q0.tJZU FxLWTDX5 õsލw$ }mQ i[ur\RgyQtĺ {VԵSotYk_H 6ZȰ ! @ŋ)> i]?="BI%OL˕/[ XM2}Tϟ@ :#ȎR&f\4Fojl?GiaN;{`) ԫպҶkҼi>nuB?A .ӕ5CeX&ysBt#J#Y ;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/48x48/undo.gif0000644000175000017500000000271111545155744025456 0ustar moellermoellerGIF89a00BDBEFFGHDHHIEIJEIJKLJKFKGLMLNLOOP MP MQRPNRRRNSTSRTOUSTSTUONVUUUVPVWQXQ WZYZ R[ W[\\]^YX]]^_^_Y`a`ZaZb \ b b"]gcch%^idjdkleelmf m!g n!hno&j&i&juo(l)jpq.n/n0m r1o"t2p#s3r&t(u(v*w-x~/y1{1z!2{3|3{=|5|A|7}*:}&|p.aؕB>"b5d"zr #<)wU~Ѧ'`@ B4`wk^[a#}+ڑ)A@Ԅ0+aV|rtxBȯ WC]ȓܡ lnGoQ"("*:a(6!S먖19  jvǻ帳e/u-&+њDHd&d";*azXVy|4[8Ѐ"f8N~w?@6FP*D"JWX8yl\)@u`2<|c{fwn=}X!j oN`Py߾t}ÏZu*V:(`0 kv佒RsiżX#٪M5 8hC_;q+?-W Kj]r2{?ȟux6,E[Kك% z"϶Ϗiyu-Ӥj Jq dOQD\-U˛$b54Tn?/˘.xqg8.3nO?c `PU >椐RePj?MӲ̥d@1ټ{XJid>Op!jkpXxnC'˿L"P0H 0#t*EUea``(c8Թ!SZVT7gq:y 9\?kD{ EADO_: !!&^cb.])Fћe%} :?Ώ..u<=Wַoo~ѭ~]!td U5JRI!IP晄yzZGaw7[mAX{*G {صh/I~YЉ"QDE]@<ကJP  b$r<#u,PJ]7$%) %_NLRxObR@#T@(@PRqH^ZZz*C8BRM)>Xi%Q~(|o;HB$@ A% )c }){ffh 0bXa5%7N|n1[kUu:EUT@! 'B T$d]78h.VɅ<f5 #ҵ,uA׉*iB=H"EOsFP?:0 at}k5'rWYu7u ф;D)0OG6kukn&@u7 B္W`m,S2c!IQ EIM(iщ݋)"y:=LY)eo'p$EPݽ{L+,66 J+rQc jPp%""$T!)B "4/9uW8#,@B%j-DQjjf3˸ s?D3K:h@R8("":033wA+^=Lg5n6R^f#% DOMS(w0@hțnW D܆ukbAɷݾE!Bf@ BHW#T) {,3N6 TO1XEf厗[8 rx:n9bܔ $fz $Qծ8"F[^~, B4 ݧ־x4sj6Z͵.y)Y㻴ᦽISDŽEͩ!RD=-ֲ+d\ g7ؖFpRZCak qKݞ!DNÿWR[0e! }W~&h$7LЭ|~<o>7mzv\lëߌ?b$Or*ͽֺhM9cP Z vkɚޗ)B`\]N1=ZXz pOq|blnoՓ,kçn,:CpGe65;9KF,0wKu]6/~:@qoMA!sWr/Y! 脛Z眛#W^=|!+}FqYNiꯃZ6W:_d8\YIo-.7f)/bhMEՓ^,wQZK^ajD3WsqХ*aԼs'i tPs6)Pku8grx?k_qtS)1!t@fR sA-`yi6Wf.8"8hd{A[φλ;o{?,jfcskdq )u0!*Aq *yeFpr 4B~[Mk)f˳J,/-J0q{w)?\kGpbUHu$@4litXuuڬc7yDЀX* SZHɷg_^Mw9R0STЉ YsV{}UMCgi$d!Ri$ho^o]i[V:ِV+H*йt }lK)6Ol?%D cۀ# IENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/64x64/0000755000175000017500000000000012326214512024000 5ustar moellermoellerViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/64x64/3Dgeom.gif0000644000175000017500000000567110405340316025614 0ustar moellermoellerGIF89a@@  ] k b `=6(j T./ˑ9$ϐE@c^#$`!6\?(&t$AQ1Dq'&..*j `!4sh02/:*(N;(@pR~MIg*HUBXq5:38SE3} }LL4.8<Tub_ ^e>WfU>A|=Cy+9^>Ft.(g>5jJDIl o?u;v3&o}( ! wJOe&gMWG67SY/0V R\<}L!NKEER[SRZa51 I =K!&X`J 0>Xeocn2sYTQcl3 cp)7pclHtmvdqCcMFm{²?q~=Jahmu~"(%h,w?FVU&-#|/O-4cLj>Yp"oo뜅2.׹eg~}@8wB7Ұy8K56 -JKMBq[Nϖ"b !Q^yeefEiͤcstqQ # ,"+/E}rܴ9۵Yb(WSOIe! `iٟG0w(a(BZk1YqG%,tvA r lCNmn{ȓ9ᄳ 4Ā4B gcF!nw a23ېsj:У>C<O< f8X,5:P[YqC@yA9g}ccX  M4#r`# wI-S)$J+s&%WtƉ"ZtLp?46BX, FH1s6㌂9dA[4@K.]Kt=#*P @Mwưy!K^֝_Mk#@C:U)I_6T $07'@Z!hGDǼ=R ! l834I : n#x9h݁B_>@&fgxCC~x4àJ.~qͥRHH_<$:=:CiD!2(:cMMA*`C'T:kԪAbUG3>"FaE04J8 Z1sel=4N9¡]9љZ$%)eQA=ُ<8;`K;uj\8s iW(E !_9qFʃIL}SD+~Ȏ<ARYL/xɤxRvy3($B/ʖ]엷$&K!$!L?p"--f'C&Tk( !͘V3ȋ$dn&sҘN.#HPLt$>r ? Z`$+hhJm L#0Ax Sh;ܡ~(' m%W(h·riRnY*MmjT`,JZ𖣈tTr0&Yb(m JSqc"S.|ţ$U*\ 颺5dz`,\US1–8LcR&%<@50% hȎN; A U`T,ږ-O}ȣ( 6<34跰DJ04aFx"|O4[#ȏ7L%=NT,`,Q:\[P vc~P60^aSt'؆6|!CdaQڃP@e!P.̯ Gaw<2V`c\ կ, XSC j `x6I:l3Gz8h:` 9yl)“K/'=~BC&` :L-acGP3hY0թС0p7>?Y`H6+9&R2WW"Є+X?"OHunSV]`}E_\Q4J*|!Dg6"=xlnqg].k:]R0$xt!ޓx=-F gزGwL_ 3ps&qz vK7f nӓ􄞟+G%YA馜vc"HUb2ۨB 2yLIаL4!Rl B+83!0.̕ 0 qxsP*L@2 +$c* +>q(֬NP'`7A[ 5 \5CL3}xp u6tj`el2Z;W,e78<<34)PdpAPG-TWmQ[ 0 (`Eih?lp[YDYG#y1 /C0>L/Ijp %!G&bL1gc.\r!w0$h*h+";+R'8Gjġ|#+$̷ΊDI7h. LLx!,*ȐC`xqdo- 68Ѕ2P1c5`64WBeO 1Y,08Y `,h0JƲc=T,!F,XU 71 8 h!3L| F|D X PXA/V#P `BFV` 7lADA1qK[p8;6AH#D  (#[he؂gyF/ў\)xCƬfYZ nzӛKxbyFu#/>FG0k^|g YNy10{'<-O}sf/?Ot2. :gY2AъZͨF7zQa8j)AHJWҖ0U颤;A #@5[قJԢ&)nHMRԦ:l ;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/64x64/_redo.gif0000644000175000017500000000376411545155744025606 0ustar moellermoellerGIF89a@@C  !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~!Created with GIMP! ,@@ H*\ȰÇ#JHŋ3jȱǏ CIɓ āƍ˗oY6z"HQ!:D(О8il%CB5LX`„ #9c4-% 8t Yr%._( STAh.dּwN]Ǐљmc"%G+\A7tڭSСSgsF)NYl7oݢK 7l΀Qx(1jҜ!+Xe͞IVڴYf-X&>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~!Created with GIMP! ,@@ H*\ȰÇ#JHŋ3jȱǏ CIɓб"f˔ tٵ[4ya-p0Z,>]PJЉ:~]2V0qBV,k zkӌE ݪNaeʒ)SL'@Y4A*JCz `ÀJ-TA(-\p} W.ݫ* J(SĊWУC% ֩Gj<1^ɔ0u$2ʔO2 Q+L`|k!M>uϿ~Otb cHM@@2 %D(FfH 9fܡH$0b"#'6#kveaH"(ȏ"䐆b"?&1LԘQ|S]AF|qǖwG ) [⑇nDR\W\aE]"(zyYoJ$Ĥqe t H w!&!AĪC*DH<yǭGQN aDjbBH$F~l}R$qLHᅦz+nmT)q*pǼ_DjKФSu$\wQH.F\CFp̡*K qEI2cAr\q!FA-'DkLA[@GܐH QXGQpAeFZDp TQDL@@[ LlaFpao!dlASKuГ;PDAQG0ana:azja\X䐦OLZPDP.sQFk$򪻱6{N!EQLag[FQ! kUk~gAcOf>F[02L >!~b؂%!+#<@. g!Fg z'5iB'-`wCza jV؛ DXG@+`A [b+Ho;[Vz@x@2fj P!RYS6Vōp#Fĺ IBL"O;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/64x64/dashboard.png0000644000175000017500000001041510513527775026454 0ustar moellermoellerPNG  IHDR@@% pHYs  tIME 08{/tEXtCommentCreated with The GIMPd%nIDAThZypWZZeY/O|"ӱ@b;3ɄcI203Lm푪ݩڝdra2 )nHd vmc $˶,Ke˺ݭVKG/äb[Jzw{0 χ("BӴT*u ::ʲ\^ZZ*Jý>>`ð,_WXl"069,Z[[?]VVfXnܸrt5kFh(bz~Hlٲp8|UJO7͎~r9aZV(^zGD$i4˫)i~j{g.06цׯWTT@AA+WW###>22t:׭[g6l6 ǥP(({D"\80 d26o*\Ҷ H[lj^`0~VVx^foZe2YRRa:άnD955U\\T*^>SPhX`qq1h#GD"a4kjj$ffvvV*&$$܉n.DMGámzeXLsIH$[PP')P(T/vݺYΛcPaH\YU;qW+rH$Qɱv?8''e\>oRvR{#3߳T$<5.cgy?(~t D6ir2d1/o\~,|>KМ^\A%bt]֎Ol׶ehЅ 'p5kޗ],FxfͿ>OqNltfD"OK,^+Ύ3)* bLðoSRu%JFw>c}D\g<8/6 n|>_b^2MCF#iii766hӳPE0nO>d߾}8^|V^'@ؽ[:(WTTnڴ z=ՃAL&DyKbbbXj*$0x p2< ghh/p88r9EM,r^6@;Ogrw?ʿ[ޱ#G+z::v{&N겲|T$9> /~gAWj!S6; GKV. Vq\>00s?H$بHLLLX, @_3Ĺ[$KǬy"-[*ڪyGZZZ`eڵ۷'%%3gh }׮U]:%KfkjLN <Y|yvv\.GQByyyMMMnð4TRrD@bbb4τ# p` Q"bMzjdU?}萃S'N›RR"eddTEhjjv̵5OeuVVVI?2e9 [ZJ˽^oRRxx<˲EC˦ٸq\>$GϜ)R`X$6# /zX$INhJ4˲q&Λl!e2爥P*T* A<O,qi0^{5qȑW_}z7R^8oeV01ؐeiiipx 5 Bvnk^/WI;::v܉ R B^v,<yI3Mqz Ye>2a-LРhmL~x<evZ"S dbqU1oD^X,P]]=622'N:uTBBF ===4MwwwSŕ6^С.%rcivEmL0 ĝLaMӷnݚ 7{3A" }H\.L${\r;(**Dht8w /ǹVN1OlQF LOOD"Xk׮I䢢"p8w\`)IRZZŎ;g>oq~e 8ges޼IPDII^OJJZz5l޼4 BW\I7L&ӢCR+VD"068Pl^_ \x MLm,|t:G}@ sssUUU#//$Idz I0¢ 6 $Z6}uJ>Y *͙3O=(2̪͛{{{cN &)99;R(Bvbq!n-Kq:G+= \C-MOO(z'H$\g}k;_P˗/www8q> :t ~:'I~?#sxC$-{jymmmccc{ӧO(:;;xA]]]gg'TTTL;suuu۷͑HD$4_~yܒS!ah|V^nnn3;D&0,5CA4MGѹ9 Xu\$I.eD$ol"7D9(GgjdlbbΛm }JIIYzs:7$IJ$8p[ Iq򔔔[@[[[zz(Mӵ###Fihhh)Cl,F._zQ)!3i%48eJR bKKp` Y)(l6X,\455t:֮]"( rQUnt1LyJe@ O~{J.Wر(w_dbbZ2W p.=qDSSٳgb6iaÖY_A^ثh'Z^NmrIENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/64x64/fileopen.gif0000644000175000017500000000643010405340316026271 0ustar moellermoellerGIF89a@@ o z%$ !%$+'*' &,, ,+6393.8?B;=<GB FKOH J)H O-JT'LRY'UW^8U*[\AWae6Y%`=\8[B_,g-h7f$m,e1i(kWdOh?l.t3o,q9pKk9q9u:{dpFzXuGvUx8muIEHlxVo{PIGs[kPTeIz]Y[bTXe؃uM^c䂏WjcaQqoށgĐdpl|ߘeՕwx內ݍۃs{Ћ䡩ʧ~|낸㊷竲Բ魳ϳʐ푿ڨ՚짿὾ȕгݼܰծ޹!Created with The GIMP! ,@@@ H*\ȰB?>an:v@zMg I1^=~۹S͝Ra\؁4gn,Se˗Xǯ+N}&CmGO)<``&JgQ ac/3v\rET)TJɚu<.SK <`@m{)͚Hh^fjӦDԑ3 (@X„ )hpa8 .^uh9[mz;ݝ+-0ӌ/30r(( "t܀k0IDb6؄͈ 844L2 cK-J($䔎=邏7d\ 3@.C̐|q  <@LRJő.pDIQ5Xc}; !0y~s O9|R%R >uPC ,$dOisv= =gSNPZ(S& ,Q ՚]0s "[HПdcO>c<?M; #M0j1sjhaG@OL+VXFd!i\/M41w\vIZ^(B :L GC_mkh4pPpЍqjTC('EB3qCT؜Ӥ h@՚/!02!5":эe,pFZq G"9,|Zn%9aHћ\r>v!q.q0g T80 u,@|'x ҃5`ցq#XF1Ytⓝ&F5;a Xx*P8@A D |P Mh.r`%>;@YZ eb0f6Q $" `=z~3`&<͓]؅\vkAV|`$@0$8Cx$a72 ΅$t%uX0LgJӂ0!jJ$? B"6((!0!'$Z?H"Fjr9 O#n^`ZUVR DApf2Tu܂oBQh}li]WoR( a"nTqPxoTuNC0cȃKMoN Vk:x[۶*f|b B8ACH+ ]$X1Z&e|UъW-'tzf뚄OЁ ]8LR!y8\M$i0co~#'O o<%cB<^y/9I|І9AjC}yH@=;lI9q. wD%DEGT‰CpP dŪ@8a':.{9"a2-`Ђ Qc9&3K' "p\0Hd98FDhD# 1J|%LS A@0%i@4FDsC]8aM#i*PaΠe\x4@Q^>jD<[i嵉O%g9hP ᶼe;MQ"qi㊈@8EVrT:þLWC,@Fsh`-q\d/faz%"Y0PN09k!%RXðr+Zkc}Hp:0u( s 4BFR&ֈ5DWהx r=!#Su+`#A=  bB^B%Fv< 2bj]W8E F4 rާ;AryԤQ \8%vK0`[7! Y'y &;(B `9KLgt<M|Sʀ/I Z삛$P %$bKw)ٟ:QOn~ 0s~G T84= PW1OM% *M G w1"D `L0["C2p 2 DX0 v (d|0'SpfS8laet`eaNBfxf(7lGEUr8tX4;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/64x64/filesave.gif0000644000175000017500000000675110405340316026274 0ustar moellermoellerGIF89a@@B > @ F < 9 I@ MG H?;RIPFVMX"LU'f!M!S X#"[(S&&Y-W%(T!(`!,W/j))\5o2\'0\)0b0/c/2Z%7b.4g):e27^!?v4:m.>j9OvEKzLK|JOs:UIPIR{CU|SQvOSxPR}B\XU{J\XYV[R^UaZ_Oe^_WfZfcc`debcg^jgijgam]ngk[teqkoaukrppiuosbzrvlwquh{ryzzyykqx}}{ru|yv~¤çŤħæɫǨǫ¤ʨŮū˱˥ȫȮ±ǭʰдʸƱͷέдԶɼʺŴѺѱԹٽιּÿ׺׿!Created with The GIMP! ,@@@ H*\XPW6q-:l2&엲l԰,ZIeʒ) .]bޒg+7 it}篨Q0bԹPJ RAqܘaaA}fMo߸iƍiؤIc,ٱz :]Zt.Y4!"#AnԨv,X/_œ.;wΩ+7N6kRgׯ\fRjK8YBDG ,܂Z:Y^nзmvfư&l-W\J5*(O2w ($p4݁sǖpT IƬԒK*I&JI%EI-!DQt UdR9pb"z UrI2錓3Տ=ؠfSYk t} 6/BK/R*J+f$R |pQ\R=Ba4ŬB*dO>0{= Ub / XJ. LC-0A=(t@2 l,LnA 6A ur_XӐ9wT9tcpDl o& .<2@BCڐKYѿ0`+h R"0&*FkCs%BYL}^| )8\KXHU!08pbHq+xmL qu-NMF XI ]3%8CB86R㌺H*HHH L!sZw51 e0` @ !C"@8>*Wk29 oa&OI7(Ȁ,xp!)@}x+ bE,b X'(?Fs`bPW_HFqUX"Ӹx;:s#a Đ&=[@( ӃH ~('QbCԆtLcp%̈OQGB*Ơ`/ ^bUn_U j<}bڳ'vGݻw qJbj ~.YJp^?>uJ,dʼY3gȇ'&Fl 0}x>dISݺur;%O>Rd];uq{Vw3] :u햞e= R%K$qB ȟO׏T Հؔ[Pb'cQƃy=:kVvx5ԸɹP̺H# 5(PSͺ3s0 T[)FS>G%vء c_!o=O<2.,<<4C.`$<3 98 48 - C 2|hM_{M5` 6lM8{EMS bGB2 F:r|$IJZ@ $)!J1$\L*WVL%@Zʒ A@[e0kIb Al 3a~C <CE"<kC;k:n 0.a'cA \0g#GXЃ5<#=qyܣ(FAx#MQckJzB/>9@l-!ΠG'yKjnbp"@E00 e:|aNEħpʭs: G(g7PB*c0ݪ b87`1bcpr+ݪ׷0*BR"0)zPezPPƶKmYZʘkRDcbqK4 |br"7rQpaj" ?N6/7)*x$a?H)CC~]Bz&$2AxVRHqoj=E/!`Dq ¼ Q4GqzE2=,-{5xtT2偏y胢hAL-AɁ!Ɠ <0֌f"&3x2ahA~G;PPSzF!&FP~G@;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/64x64/npr.png0000644000175000017500000001634210517526652025326 0ustar moellermoellerPNG  IHDR@@iqbKGD pHYs  tIME ,9oIDATxwy?}Ue  T@H4ے)ML1LbDZbmP AFHu-ڦ3;m7̚(9Ŋ̙=}ʽiMjs3ѢyE7DXǝ.c+6'}r_t[%$X+!_ ̞YPChzܺl[&4tN[{E5cTΙOlosEjd#&+` fl_߲t &z988YULı̰yE+}-v>!}䄩>|F銬'1ɡC'ZCd}١@C`mdȠ\ H\ _J Cע Ak'OG:*ØĖ6hÇ mzO\KbDF*4L 6hBã{в!D"~m#>̍Y;˳>\W?sb3=G_w:_86Ŋ_2()$RhBC rnݍս>xMߜr娮{{l^Ͻo1qpDk!q"GqfPJdP]wr$W+,nŧ澏L %n ;LΏdI;֐H\:Ķtґ!P(Gb#hRGHh.HǟFvE*ܱH",U80eO+/{[^ֶnÇ ά8.tnG9: |l=A ͥP. J YnNfT(z:$_|WP'y5Q|>3so0XG \@|l†{z8`x"f{BHe[ B FRK"亿=ᲲgBw1h̝c~&Iʩ4 eK|eB9GJT i l '~@;BA6vqH)A#k/T&#P ;)F˱ߒe\m*FU8sk@D`̪KM{F!Vhg=> ?a`L,ea+%ppl/\@eAſt~yۭ =| 2m]OhR<׬ݻԴ΀yWk(NUB!v!XY+W顐JQbM[!T.+ԙ 2+\n[B$J٘(&>$m(FMd|`y)K]4c[9ǵ V!p,Fk"WhJNstwDJN)mIw `6i;ma:{Hj= `[!cs}՘ǜo{锦UM{}XީHY ppH\AdI:$Uq\IH,:)\J qGyΌd:i%)h8@[{Ѣ6Ogӟ_w󼭾"ϲ,J&>4o;bϱ<ݹHX mSyhv@Yw܍r88.] t)nK ϦWvpl`Ց9SO}&JOBs|_5fEZT[T 7ퟱ Hă42)%`;6Xw[9>FtF}Qa0|O((؋"KD sSq$d cp'}Z[']/t0oM.[ $chY.R!\$9:8^|y)$3nZI{1ZR/ea0;"p)g6c[8Ӛ[#s]FhLٙUyIem XUs_̦$$ټ,RJ\ź,81|:qO`ޏ3(?#Hi>]Qr le$d '"%QyYZ@{#lcԩ~ywv%C漚&0>d/h*a6ŐFn!6rP27D0l dhZ^kXVWT_؋ߪshYM_Mp5tY]t,I({7(&=ko-(ڲ8QŢkes٤L o"HD I:&PzU#4b&fD˧h[ "0NSZ3u%'IIB$*X@L1PAMpΉQ!NWw-f% Zm C8ھUs?7?~7B/krx&ϵ8 3~Ṉt R]_n7wg`6xdKYv>~0yc|dHH(QΉߑ= A7qs-l.q?Әx)c諊,&H$mE4Hd+ufO僃{ĀƲ&!LdXn .t[G*IW *FzcQ9\E^'=OpxOcR2N gwp'^]h=~+{ k2޼2mK6vt (2h01Hj;9.Jgǎukf_;aZ]9>\.N:dF/y'S4xZ@+W%(8vJ`Fg>U|TDB??&~QKٙh#3McFJwww/._pXmw;Po9yF T `) 6ђ.,Gwc;6֠Ş7j, H'0#:." l#=L=[/jw]x"uA:0ęg 88)r=%9{307M-R9B}WW.tfbW=)\BW@{ b0P_ &Y oU@^P,S8T#oǾ  |w2a^I(3h;vIJؘ1O2f-1TSgjT.R7Ǐ$hN\Dv܄ד}̛f֬~lO$mSNѱc<m8ƣԘ#T7WF2)R%ӫiNᇷBQickoXylH0.'e}Cm-8C- H7~*yPe(W6]}Sa[6_`6w4Ayn)=E.p7_)@ ⚸ʭ Z#&s+:UbܨݸKI`%&"DZ}l. jB*0NU4v/sg\TE '2Db;`I:Ӌv9yC^c_uao7Nnh/ eZ??a;W^yQ. &3J }wQ8MB,9u/s}*5ۍ1BCh)bULih%60C|W4J:FJAgՋJXC6к15rbl^%H ?th423CwSa$8#J,@vf]t-`aj29{e^o]HbVLJKfw=C]BQ^B<XuN~W `YC:k0V}%6_2~stY`p ؟Fԝ? | ד~*ǒDssbIZ x&7:yQ?I*9/2USG|5= 2|.:KE̙`;صk+i}qe8v+nxnc?y!-J/wR4͞/2~ ʼnwm.y1NdAs÷< SL< ;mHd:$cK;Ƒw:x|4cYhǿ<ފWd4|׹";@w@}l4_ڷyAvڏ ?~0`XBo,W9r!>eRԵvTZƟW7綣ȼYNS-£fyyXVl2mפR7n;a ?Ҽ iٿP*@5w+A@P{;)*wv7O`:.TL|gphFtqC\TR{tVc{J}O3 XɢAb227]K |&DZFn&ֲFF> >&C@%@ SJ*9\:Ip?o+Vy[ߥ:ÔigHt݅,l#9>n,t,c3Wc=MV*M2#lȢӸ] < C>YOͬYEYb瑚S&<0;cYOީgs+T5L@He@X7I~Pr v(ڥBs[T~nwR~j.wOa@%znkN-j'9= P P6=ʳTXP>y'n5qG`XZޟ9Js*>*$ Y]P[xvזpH^^ g08̵o ⯆ClO2g:keT?RG+apEo159i`;gi3sGWî3TЛ_]Gݾ 3C`:g9NKZ %ຉT$ #N'Bۭ7"um!m_zqV8B9״ B ^by ޖIWe|J<7óGٿ?eyKIENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/64x64/redo.gif0000644000175000017500000000360611545155744025442 0ustar moellermoellerGIF89a@@F DHHIJJJFKLMGLOMOPQOMQQRQQSSOTNUNUUVUPVQWYZQ WZ[]]Y]Y^_`a[aZ[bd cf"^g$^cijede+afemmg#h#j&j&ipoqp*k+l,mqy!s1p#t0s4o#v$u=p&t3s{(u(v)w+v+w}.{/yEv ~0z1z3{@z%6|6~7~J|B}N};O~/=?JQ#CSFDONI^,HNJ]M3\Pd^]a\\\bjagtcelpyqilq|yuu~}y|{~݊ㅬ쇳炳荲㒶ᗹؖ옼砽!Created with GIMP! ,@@ H*\ȰÇ#JHŋ3jȱǏ CIɓ ݸsKwVAiLB Yɓ'$ByxȒ!^$%P9&k&FQ3h1fh;gרEz8!E ].RF<{ o_>{޵# T-H|Jǯ>}BLzt?$[`QR1oɫǻwlPBC!ĻlTA3@"L$;#TPB{`PD"D5pB%jG` T1(+6(/{ pPΈ!XZR i#,Q" tkF}FD\s C DѴNQ7tDkAGtñrQtͅ spn/={!{졷ȁP@GppNQٓfԑ7Nd: NpA p`@!?P!QKPȋ< 7˽oǗD|`/?[٫O!-Np?.8 ; ' F*8Ѓt ,ŀ8 @0t ,C-x@p;H R5*%\ -a r-*ă0t.Sb>p@T"B8E 0@Lx6pH:xtc@;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/64x64/sep.gif0000644000175000017500000000024510405340316025255 0ustar moellermoellerGIF89a@!Created with The GIMP!,@@9!T|"_nhMDʮo]޲ b+xhT"&tiY~;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/64x64/stereo.gif0000644000175000017500000000515410467165025026005 0ustar moellermoellerGIF89a@@ &     3  $" '13 .&5=/3&-"/$; $=%A(!& '6 +$b#G$<-'*O !b H*A&5%$&0%6%"/$C$>&T)!+"#5!#9&$'!%1#%,#&'0U ,U )f#Y3K 1C8 */#8.'+.7-E#+<0>&-3'*A%-8/,&-M,-+$,G+,4!+VG -,bN% 9J"/D18K+6569P):Jj :iY(1_%3=5:*:UMgOc[)8)<`Mv1J5>O4=Y*?j<=EI7D`-<UqKx??A;>SN9BV~ Ui3C^T)Eu[oE?I?>cX8Dq-;k0@,Hly+6`6C~*3JBGAFM0Hs8Fi`DHIQBG9IdAHT>H]b{IGI.6Z@K@Ie _ bv `3Ox1BgMm2:FQh2?HR^oKRW3ERPV lqp8XzVt|@RoFWy5S]bdDXWeuDUJlK]No\okszXy_vh{rzu! ,@@ H*\ȰÇ#JHŋ3jȱGcFvإKΞ;zɴf}&M;mpYsGں1m*řsR,6mֲZ۔h&\ƍF *yE #vj,X*OR;ǭ'>r!rX\h`ŋ!f̠ܧO*eA\qcWʌ;4J1:TOwb;%/_9>gr"eSڵcx0)1e͗]Z{Jd p԰S'h ,e?a"F (b!oX-AHt@ |I)8RQah7HEwD.!`A&'b #"r2v#P@B+Ѐq58 sX7YL`0A $\(@1$$,fl!$'Ҧ9sc9%TLpOd` p+kLaR 3&@?fs\L $ `N@65 ="8@]PUi4PehJ=dH@)KUH}J FTxt\UƐ=9u)]M@te *44:EtCHЀPF < 8i ԃ*$! > Ff0J)Jj `@5V-BXw@)LU&@2zACmM`nN&*!@Vb@Ё0: ج&T4@%X:Zx #-m@e0Q`o'dJ8@`2yhPS|8WPng=πe>04-E;щV4lIKw͖t3}iN3Ӡu;ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/64x64/textBox.gif0000644000175000017500000000071110405340316026121 0ustar moellermoellerGIF89a@@ lll!Created with The GIMP,@@@PI8N!dihR$tmxg끥`H,Hb`ШtNR6&0x-t43|Nr,z .VYSzL"^bKM?\,O{~kW UxtaZĚg}f~RƉڣ)$օ6<䗽ΙH*\Hp@{"r(yԣKƏfE6vW1 Œ*ND#/"-vdə+e̩3"(*ryWMHp=*&HBW:Uh՟$TkMDb*%ٲ&zTj׵CڦĉVݺ"";ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/64x64/undo.gif0000644000175000017500000000345311545155744025456 0ustar moellermoellerGIF89a@@DB DGFDIHHIIJIJKJKFHGKLGLNGL MOO MPQ MQRQNRPRQRQSTSTMONUSTSTUOUUUVVQXQ WRQZ R[[X\X]Y_^_Y_``Za[a[ b \df"]gchijd(_dkfemgfmg#h$ino&io(k)j*mp+k+lqrz r0o y#s~&t%u&v&w(u5t+v8u-x/y1z!"3{?z4|Hy5|6}7}C{8~D~:8C<-Ӽ~C0xӎt:SLlzbFbgUq6KAsK fLΐ ٙHY<䦅턒\junT2+as!#Ne9rV]5Q-i), tF<2(!$P0P9Sj+m\~`Hdžf]/ǫi>F9G Q sI'3@# 8%r$$h.-bNjU\j/ |8\]9U>Ӝ:BhM DB5s쾴!nG0w'yޙaX!zz"g|7YW-Vڊx~"B@}k="۩ɓ|uX*.% "sGI(pEܼ}78*\Jؠ_OG߶_ -EGҢ *EB(PtoF{Fp 3:@4hjJf.=Y*+y'ʃKo4hVl=ٯ=ߘӆUplJM4P?!Ci(g,kr̍9[T8 \p =vŹ^ĒۥfJlB}^\QL!Ѐ򋗸=rSCVڢ(zp>cQJVa&Kt|V" JKTƌoF{qlY<tŷ뷌y|yB%*4c@P_\m>² B iiˢzvD4UҘRkN`d9̻hHϮl:)K0I^ܽ߻[k=Ub **FSi̋2kK ,B 4H0͸zkǤGHGrrOFkބR1jatGca)?ǫ}p<[wCJǏp oQ&7X#Xkkq{!Hn?_^С]36C:].hET\FbK7w`'.3Mws5|2 J΁ Z@ ȸIۡ0:֊Ha 0=՛k]W2vocon3sgFW.wޝ6;ܿlp1Yo<{2=}7nnJ}.<Ó;3 4'- mFvǥƟ/O. ͍h x/Ow;d\h%ʼkGwyv _8+o|K8HR{ެ[trJ}$ @-)4HT[{0 ww ӑdDVZ5~I"DZI6q9 |:W6ʽz ?k7Ƿ7/"=0ɓ&ݾS2OH$%wKf8,8- CEB3n޹U˫Ermcjr%6m gд8|D]l}z8\_[5̒Vّ{2Ol$A`uv{ (ֺsOשtj=E~Qxvx?-ddL]ag1 8TO8.ُg~sHiRH7v:%7! BBI>3w-0|8OHwx]lz fH' L\k9%&3S^Mi"{}s ~@a䜕Rgˢq,XcD3[gX stoxa6dZ$AGhDܺafk]6-O &̲UuM0>5^|$wݾ^]5\~E1s 5fyDyXm LDBaf K͜FPaZL,Bn3E2#3^fR,oVkg5qq?3CvA$Z"{WI1IF3׸4I @iV3R᤮CJkd~ԨBaX|R}yYJ;_oi9wdg42n pOCffd%O)"B CbjF+g[J<ϙ$a@H@@ !*A4kgs7y9C2J8hK$){2>c<4YY*@("ZКj ri8!Z؃":`j)Gi \wI8vs[#q }Q;BlB!Z#'൮s32t =1P\;)sZ )! 43p@\3rvhuLAVLr BDю:؆TlFRe~ vjJ`,ŧM'WxwXkKH-N $_Kۀ4<}Vn E0V uHJB wj*JN\,^Ipȡ0Ќ0&f"-n6dԚ J<s `=T4IB8 qo mڌZBd02'ie_qo$o <ܱ_3*h?f@WZi2v!j]J1B)Е3NkYIZ%-x85Nz-E9nI*a%@hF3Ic|rTTڴPH ϧjUmꖥZE]r$(9'Cs 4dڐ:X_FdfQ2Mzꨰ.'HRRi T5!(#Z^mRaZ*5i%!c;#I3Ѵslm9^LwQOY3Sn0Fs5lD*ݡiFհ)3"h P 3w_Ѡ* *]|VZU5ߒ j3"vfμi ғ'@)$@DCJ"w$uZ]RZHÐ+PW,S`2V<T4k090 9Swti?@m`f`fh&]Tť88"_|~YSSY>s`Sۢrwo{q[˯,up]3{yB)2h7q!+TrF%h݋ʏr?wR7伂5eztwyT^a@fmMzݢU05"4v@Vp?f\zg܌;Nj; tI5}oQ;_Ka4֮r_NuT=Պt jh270Z */ŎTjzR8v>P[Du{Ǯ#M0\BϟǩOw4HWYhx‘`Jfy1A%eiqN?7_͎\KW03S]ABjeIOSYi:8sb DgC).uvg8-ZE[-|pz';3SDhyݩ{t/^n,ʻϵw~v6Q HD$Eb4vR[>(k[gH*wH 9Ep{xE„RJ$ "孧w\[jՂ۔vƏc`{EEVݎPV˔sÒ?/f3wT&%pn)UJ)߮ 3@AA>Ź (K5|k=L rQfjѦy))/ֳv>\t2mU/ :CfBÃAH oI Wuu;nCE1iEm6/0[ZL5ҒOlT+)=|z+%y7KJ82X )QCIt^[^ݮ;+ǏJlSxꎖmWΧ|jm7ΛC"+hн场lh V=&hB ZqCߧ/ P|NږsGe}|c=S/a_#Pk5B2JAI XB])%jemXjEjLAՈhhɡU)f_XE?jeS׵af{GOq2\\ڿ~-"&)d@SXJ)}%J.C}5Bk]~oKhn1%nݶ0uEL/:{Rgǯ|~Ɨ`yx-Yu99GSǔV*`";X0;o#ioI% uKg|լȑ]c ߀(ܽ$q?^|=/q_u|yvy8^J]2uy,u$0kEX"fsv`Bh0Ff]grquD>5_l~Z4  f{[ ..Anaz̛S-5c|ܰr2"캮aR7)6:HܽR?<)3 J̡1=@3+eP ;ӯwj?}Mm~7n`v{߯E  ݺod]8bŸ˧v>RK7ԄW6nq:·VZ7KFY&Ff23TW1d;n*o<eTP#vA^B{}1*tCj2҈f]VI~\};r/C/ ^Un|kIENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/Grid3D/0000755000175000017500000000000012326214512024261 5ustar moellermoellerViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/Grid3D/VolRen.png0000644000175000017500000000764511044412143026204 0ustar moellermoellerPNG  IHDRK2c&bKGD pHYs  tIME;;z 2IDATh;]Y_{}1cD )" Z:!DI"Q(D D a&x칾uLQ=MȒNs^k?_-Co]w]pz71ݒ1%.))5v 뷤YqXάn߱<}p=OpfIR!ȫ Eu~rtb{('dֽ_X]k og  !8GL $R"tFkrBV;dYs(;P`5oD9wvF\Ь*b$)bBj $Bh + (&SR/ݯ_s Vfzfz'Dg'sֳUjD CJL#H &\DHAVh+rh K;YnVbڧtkZRJR\ 5RI 8>J &)2TwƓ?.ckwh5k|at!DL7! Ԋ`=yH+L2 $bt!EUb[Kp=1ƻxzEd-N+fo/Ӭxgi G\X.1K*#HyFJG)%TZ&H)G,wQoߘ兎ɷj˓497X㰍g=)BPRbnH^ S8lRI֐U|I2Cr]uVO ,,׳۫#Lttˎnc'3]uA ~c{7[b!15g<އ Ҁ"BxRc x헴C蓌 W7]۝зsg E-YChqc:K !@,H1 5%Y\Y$Af4|$!8Y`3]}Baמ5sp8oMf=wC$+Z![uQ\IG;ov\e?Fۆvin '/2P%ĐktӐ~\@ Ɉ`,yVgK!I1E\kY!zK>|YBaӃ%s]G0BD9!$6-!DʭBJqI1"$r\} ˆ2fm>b{O1Rt"+}k81zWq3W 2o<Pd$-7) uTlqB-YpƑB$3lkJbBgP1DE$t֨.Ұ>_7c;Tɫ#ͬ!D^h2(st.)|D(4@.V#B(,J2D~!9ڻyc5ȲbQJֲ#8hi)$R()ѹ"/3ٺ=˳ZI,dLbe]B‡GbdBR]TTl.;v9'+9FgC\|@}kԊvmZ+ui-J {)&DۡFybL`9)7p.4ysYC51$ռe,g hpjb\:Yo=m!Z^~]!r!NTux[:KQf:Wfђ<:ҫ\q -1$L!*#Ӛ\5nձ?㌧k ͢#-Jfe%Fj|'˫E]ӎC~i{\H)\@gzgL9.rMtilg!Q3pؑbu o!q&(& t]\wkl_$ET.G?<&:OB J:%\7)ET&-;b0h(R U e AHWg/梚Ɗfٰ8]Oxs`BJlFkIbpL H-1Pt1}`9[CDZ |%%3]9~,No^H6E$&1P\}mnMW.~.4jQ夤o-CȡIRKRH9iW[HJ۷,O8{>jkwebSso{eBUlO\P "r*)9?\rZ\|[O 㦉f[gYq{̏h˿pҡ{V<}#510h*-zʺd9VkKf`ڈ!J+foZG@@"hbkΕk?uw\ogrv[S1 ZVe{$ (1ӝ)S$HƳd! Ěwס⭯K{?l_yYݿ`{nk1crh- >FJB՘r477˄@ }U]`:C` "'0]z3og8;x޵.Xz~r wvF-{Dw,%=Uj>8 (!HJ'#sR2(n с@pv>#Ξ}煃5Ԋ9w5o;W~UC a44Q]B )yàbq)I1wñ簶6 j[7np\q\fvJw*l8D"6G#tZ,~(6~> B$lź5ttnm_ra>{уORdHm1!h*h k1*M6z@JRRcVޘ7Oٿʽ}w?i>?t}_?6)Dt4Ԝ9 pMEE5@D3_b5BlBV䦳ԭ?zB{ݛ^qEGG;Lbq_7/?͹,M^lQ&!0}C|#!$fGOaKvM!@ *K/#6NbmRedeB.̞PÛW^z3#~ӬF4a8/=5/n )+eExďsϙ)z>Q?i9FsIC!ܓ>D~5?ΆIE/OvYp)k IENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/Grid3D/add.png0000644000175000017500000000174511044412143025522 0ustar moellermoellerPNG  IHDR szzbKGD pHYs  tIME;kGtEXtCommentCreated with The GIMPd%nIIDATXõW=A}U% zY6@d7Z0  CaM##e2Qa>^z3?U4S "eϟ+3Pzv5;fA3aF]=`@oPc h%>X NJ ]CgBՀ; {wLvQ2y0h44qBV0ЙweÑQ#W)%̈>OKc!2/~pp𰔂3DTu?itځR o7KDl9rRDJP +l}Txg; ގ f 0ԓdefiC `>|lkXDM Z&ԄBfT<vP5&8 UJ#aN"s` L2+y ^]dHie6yQ ZZMFM>h:w*P-Hcb|ɠhb#j"n> " JTʻ>&j T7mP|Sh\Djs(@G6 (;}p7pĂU"W~Ԁ Lwǫ=܍tíU坙~7`K.8X7}#RaV "NΞ\4y3lSmq,'@X<1Z- F0ruJXPF6 :_32ื^TlalC=v.oD2IENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/Grid3D/add_rem.png0000644000175000017500000000075711044412143026367 0ustar moellermoellerPNG  IHDRK2c&bKGD pHYs  c ?tIME%5 X!|IDAThAj0EGwo]@Э >IV z M7I)&G(v(,M )i&R{O90 \߇_ut```AX>j U Vs!knm*knΗo;M:E]G:?|X```AXEsUD1Fë{12!z`eus.AI`hzUDZ<~QK`tμxA|̳qGεs)81 +\\CчJeVY7zpAYc2k̗,֓~/=LO`ksĬSiΜعuJIENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/Grid3D/iso.png0000644000175000017500000001032711044412143025560 0ustar moellermoellerPNG  IHDRK2c&bKGD pHYs  tIME*+]dIDATh}eWYk}{)`Q T0CM4C4@h5 JRB4*ĚRKЖ~L|޹{a:w bWsgw=yYO8 !D0/ [v/̷ b[}_ǀ# ~kz ^WDp׆n U`y bWuȇz} /t!0E R11QdB)!!Ǿw}_oN<[@qV$1Ex {z%^ϻ~jXԈN|L+穧 87=;+Zχ=- ZPqV\q[K&j6q@ok{=kڝoah5AQcyٲ",.B(!Lax_B3)Ln߃Rq1w, g+V@V ٻey}+}to:~!8j]ONY$1ͦPAI"BFL&BȀaϷၣ]xG[`zEI677#oj iTJNiY"D"Xcut`~c`@-M.t^ \ sPE"@}PeX\Q'PT˰tMɓRyDb睗$K>ڻD4DLHWQEC4-0èR.K[atj_}'UV@Ty) e4ؿ_+ϫυUc^gtS)Ŵޘ{%1姪VSM8]֨12UR>5f)VfIkF,2NeLP"FcC^$DqxN&hCF#HS(KN>+fN4"Bczu Va$W{6)  ڢ2 EkWhlY[Vj-(!B!DEQBI'vUMts7Q8G U2RPLˠ* "k{_(Wq6@l ql .)A}Ɓa8~M嗳#{Wr(F|6&Y||@?Tʫcgϰ /+E}V^bZLpq[tZqD0FAM+A B`A7xxG=>atj"Hj5l4A[pB1蓥C)*G@v 7,/oSOUӢ b1p7ѯTb Ŵ[DQX1>xJ'v aʈU0("%"Dy#-" dx2 kwv ]S`M$ibm,th˹ KF8:Q&#:1"v*}Ga&1MzI"!3& ȩ38Bk߅j گ(|!"jvN~Kn/e,`-\ޣ#D ţe0B,9M?BNjr. /a.'iy ҆hѠ(KԌ !M!B׹@y3LpΡ;MɦĈ$`L1 T9 ǹd#<ĕ1طo4-isS>P!LP#|yij(.˦TF@an",{@ۆ7$Ic&dA5&OJTlgI_5w\ >Nٌ;f-xllx?A5a.^!." AaLɬHsseuQ {(E*EJ(ǘ6-:C( !!ka<.~i wgTG+K {,ȑ4 <#1p}#\DNڲ49Im8ApC,AJ[`Lyܜes3ac#\b#x+!8iOa6gc97pf(iwk'+S*KÄIܛ1gsL"QJÚ(,dYeW@MX}`vLVOՕy\M"D"c%1|" ǫ⋢0k ׂ[5kUefUC ":NIb=IG#&Ya="bވ  p_C FGjŋr e !c:8ƨ⊂|2yaլl"\y ZSpnm4 n:xp4>*[ӗǦ UV6kpӽG[xnG8d7'$$vM0SnR~\Ӂ;#P7+[-LOq;/r npvȏxVc4<7ΙӤ/;F`N}Ӝg[}\l:t=3Ї[;x&sv3ICyi6d'u|;~4s0颞)SNWjϐɺX,yn<7OCFa_PaIENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/Grid3D/ortho.png0000644000175000017500000000716711044412143026131 0ustar moellermoellerPNG  IHDRK2c&bKGD pHYs  tIME ymtEXtCommentCreated with The GIMPd%n IDAThyu_e̼Y51Z !G-$nX /q2cc*U v*8R$6K9`y0hlyKn!i43ZH*}wso5cUK5ϓ/3PS!1lEq8GO}.'ǦҲ{qEial,My;N5ؿb|/ %!X?2m谸\1JNePU[cmkQk"v+{[@) oaΊY2eO#] W\y/Y֏$9V j ($h,HMD-nIG1f}-7Y2uP\NTa=nι#g}9ї&KԖ.3b^w%_-I6|r%xN=$NzϢ3;*L6@_{r+^3gr VXTd̦ʜ}ɔӵךCԗtֲ'.uV 쬿 x"Fmy wF-Ly2 t^ɦcPLb3"xmqv>L 'Zw^V\4?fsr-Hteb_#$e̍9.>Ϸdmfqy9昲UadӶӒOLTt|0dĊOf1Cafca/Tyk*ПK=ԔUB%,j3%7m&y.xd墆n2k[g{ =u.{OD-lj}wzk'dY{_ߣkĖa*I#$"$qJ@rRA^G۞V ^ks--RX)AjT9 u.A}]l;q0eH!*5B 0@UR@D&b|ZjU^+qMκY,~r0|GUŨIř<:d[.ʏJRԧI#=rQR??&rɐA8nW$gj %drhF(NQӅ2|a D}Hk%mHb? t J)f$Q>M .aL_ab]lkȧ]&u+^rΛݣpZp//?x۵,+OcH@o~Jy=1@u< A-z2(S7HUiHW|q?~^_!3;7 p+ϒV.gy-IݳsO C>}6slYHȢ7u!~ys$HyZ٘[ P#WGW+{&tg~nxn;JG_Vu!fbjYh'䌐 LE:zYgog1{&40'ٟ1]˚+l=Bfvag%|D_Bݶ~[vާunvT c+0_r GB&ïЌXvjiC A` ~߅9^?QOFq3ɤ3a,sXHj;El + ~,uqb +0-u@k1/}X:H[3²)A3ΌK;P b=[x("c+󔳇O2+86͟剥oNb`z\<++. /?;Bbo&i/`ْZ?d} CZ=nͲ-v| aE/|-JƳ*39uXq.Å1Y bg6uzMGm7 Yf'Om]IS[쬉 A ⡑^k`?O|G"O\1ptDyS#JNH*%F3+?ʿ3de׳+jL֦dsv#H}qdXltgK[hxLʍeO`K,~r簗^xaz B16+QۿA/VϮWE쪹9J[~gXdYP>`A/ֵDZZ!\sjû#{$Rqm 3,L0o~LTەK88ğ[l?ávn$8~05V}ir m n,db*h?P1MWXNuLE{|PÞ4֓ZE$ʍKouOҾXu?$sZ!N6იD@n o!*MRWʃAKQ]a^ߛ>=શ tg29qZ.zѿb91v>%}RiGR.?%|Y[p1Fx>r w.>2a) Ud|*\<<0< Vm;9 p#D8 Qv}C8Q|ևxh7D7{_x"j>So%M#h' OhǃT͆6f pxC }3xfp 7k<bH:XIENDB`ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Icons/Grid3D/rem.png0000644000175000017500000000112711044412143025547 0ustar moellermoellerPNG  IHDR szzbKGD pHYs  tIME -j@tEXtCommentCreated with The GIMPd%nIDATX;nA Dٓ:1`Ñ/侀TgȢڊLDŪ7n`'5f;_qU Adm[Yl wADdnd&R"HORl=0z* hwQڀ әTP{3Ak<bG5٧*)z<߼N@چEW%I [ig 53Z2dfUNkd|`63""" color = [1.0,0.2,0.2,0.2] c = self.vf.setbackgroundcolor(color) error1 = "Error: color length should be 3" self.assertEqual(c,error1) def test_settingbgcolor_invalid_input_3(self): """tests command with invalid input with string """ color = "ftfr" c = self.vf.setbackgroundcolor(color) error2 = "Error: color type can't be string" self.assertEqual(c,error2) ################widget tests################### def test_settingbgcolor_widget(self): """tests selecting color in widget""" color = [1.0,1.0,0.0] c = self.vf.setbackgroundcolor form = c.showForm('setbackgroundcolor', modal=0, blocking=0) c.color_cb(color) self.assertEqual(self.vf.GUI.VIEWER.currentCamera.backgroundColor[:-1],color) form.withdraw() class setAntiAliasngTest(DejaVuCommandBaseTests): def test_setantialiasing_1(self): """tests setting antialiasing val to 3""" aa = 3 triangle=IndexedPolylines('mytriangle',vertices=[[-15,0,0],[0,-10,0],[15,10,0]], faces=((0,1),(1,2),(2,0),)) self.vf.GUI.VIEWER.AddObject(triangle) c = self.vf.setAntialiasing(aa) self.assertEqual(self.vf.GUI.VIEWER.GUI.nbJitter.get(),aa) def test_setantialiasing_2(self): """tests setting antialiasing val to 15""" aa = 15 triangle=IndexedPolylines('mytriangle',vertices=[[-15,0,0],[0,-10,0],[15,10,0]], faces=((0,1),(1,2),(2,0),)) self.vf.GUI.VIEWER.AddObject(triangle) c = self.vf.setAntialiasing(aa) self.assertEqual(self.vf.GUI.VIEWER.GUI.nbJitter.get(),aa) def test_setantialiasing_3(self): """tests setting antialiasing val to 66""" aa = 66 triangle=IndexedPolylines('mytriangle',vertices=[[-15,0,0],[0,-10,0],[15,10,0]], faces=((0,1),(1,2),(2,0),)) self.vf.GUI.VIEWER.AddObject(triangle) c = self.vf.setAntialiasing(aa) self.assertEqual(self.vf.GUI.VIEWER.GUI.nbJitter.get(),aa) def test_setantialiasing_invalid_input(self): """tests command with invalid input""" aa =1 triangle=IndexedPolylines('mytriangle',vertices=[[-15,0,0],[0,-10,0],[15,10,0]], faces=((0,1),(1,2),(2,0),)) self.vf.GUI.VIEWER.AddObject(triangle) c = self.vf.setAntialiasing self.assertRaises(ValueError,c,aa) ###############widget tests###############3 def test_settingantialiasing_widget(self): """tests by selecting antialiasing val in widget""" aa = 2 c = self.vf.setAntialiasing form = c.showForm('setAntialiasing', modal=0, blocking=0) cf = c.cmdForms['setAntialiasing'] ebn = cf.descr.entryByName cmdW = ebn['value']['widget'] cmdW.select_clear(0,last=1) cmdW.select_set(1) val = cmdW.getcurselection()[0] self.assertEqual(val,aa) form.withdraw() if __name__ == '__main__': unittest.main() ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Tests/test_dependencies.py0000644000175000017500000000163411216031312027267 0ustar moellermoeller# ################################################################# # Author: Sowjanya Karnati ################################################################# # #Purpose:To update dependencies list # # $Id: test_dependencies.py,v 1.4 2009/06/17 00:03:22 vareille Exp $ from mglutil.TestUtil.Tests.dependenciestest import DependencyTester import unittest,sys, os d = DependencyTester() result_expected =[] class test_dep(unittest.TestCase): def test_dep_1(self): if os.name != 'nt': #sys.platform != 'win32': result = d.rundeptester('ViewerFramework') if result !=[]: print "\nThe Following Packages are not present in CRITICAL or NONCRITICAL DEPENDENCIES of ViewerFramework :\n %s" %result self.assertEqual(result,result_expected) else: self.assertEqual(result,result_expected) if __name__ == '__main__': unittest.main() ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Tests/test_grid3DCommands.py0000644000175000017500000000414211377327177027465 0ustar moellermoeller#$Header: /opt/cvs/python/packages/share1.5/ViewerFramework/Tests/test_grid3DCommands.py,v 1.3 2010/05/26 23:27:59 annao Exp $ # #$Id: test_grid3DCommands.py,v 1.3 2010/05/26 23:27:59 annao Exp $ import unittest, sys, os, time from ViewerFramework.VF import ViewerFramework ct = 0 totalCt = 8 vf = None class Grid3DTest(unittest.TestCase): """Base class for grid3DCommands unittest""" def setUp(self): global vf if not vf: #print "creating vf" vf = self.vf = ViewerFramework(withShell=0) else: self.vf = vf def tearDown(self): global ct ct = ct + 1 if ct == totalCt: self.vf.Exit(0) def test_Grid3DCommands_1show_hide(self): """Tests if we can call show/hide methods of Grid3DCommands""" self.vf.Grid3DCommands.show() self.vf.Grid3DCommands.hide() def test_Grid3DCommands_2read(self): """Tests read method""" self.vf.Grid3DReadAny(os.path.join('Data', 'small.C.map')) def test_Grid3DCommands_3select(self): """Tests select methods""" self.vf.Grid3DCommands.mlb.selection_set('end') def test_Grid3DCommands_4_Isocontour(self): """Tests add Isocontour""" self.x = 10 #addBar expects event with x attribute self.vf.Grid3DCommands.Isocontour() self.vf.Grid3DIsocontour.ifd[0]['widget'].addBar(self) def test_Grid3DCommands_5_OrthoSlice(self): """Tests OrthoSlice""" self.vf.Grid3DCommands.OrthoSlice() def test_Grid3DCommands_6_VolRender(self): """Tests VolRender""" if self.vf.Grid3DCommands.Checkbuttons.has_key('VolRen'): self.vf.Grid3DCommands.VolRen() else: print "Volume Renderer is not tested " def test_Grid3DCommands_7_Isocontour(self): """Tests back to Isocontour""" self.vf.Grid3DCommands.Isocontour() def test_Grid3DCommands_8_remove(self): """Tests remove method""" self.vf.Grid3DAddRemove.remove() if __name__ == '__main__': unittest.main() ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Tests/Data/0000755000175000017500000000000012326214513024106 5ustar moellermoellerViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/Tests/Data/small.C.map0000644000175000017500000000226011045636637026112 0ustar moellermoellerGRID_PARAMETER_FILE small.gpf GRID_DATA_FILE small.maps.fld MACROMOLECULE test.pdbqx SPACING 0.375 NELEMENTS 4 4 4 CENTER 2.428 0.829 -7.491 5748.116 556.877 129.421 398.203 3378.924 11233.164 876.219 146.509 696.979 10147.929 6351.294 595.773 123.379 637.095 10142.922 1348.534 203.459 63.615 300.147 2780.459 214.163 50.889 22.577 80.839 432.248 38799.773 1813.697 195.351 815.371 12356.466 100059.516 3326.393 296.962 1820.337 60509.605 48401.797 1979.121 245.172 1817.041 54064.129 5271.640 550.662 117.447 687.143 10155.243 532.229 103.448 37.468 148.963 1108.342 76056.398 2551.867 224.876 877.253 15093.590 100040.125 4766.470 346.605 2159.542 76071.117 96045.859 2788.550 283.894 1982.310 67832.797 8387.935 689.053 133.721 746.736 12387.775 650.707 123.704 42.059 161.850 1218.715 22760.137 1310.872 153.947 413.225 4361.326 60510.363 2341.234 220.172 880.201 16735.623 28086.135 1410.914 179.791 879.330 15149.129 3636.253 403.587 86.170 381.956 3689.019 378.920 82.275 29.594 97.979 581.090 2912.273 450.276 98.913 134.310 705.967 5230.034 516.930 95.042 225.278 1704.932 3038.074 350.033 74.110 208.880 1594.082 740.238 130.793 38.967 108.964 645.011 130.137 34.311 14.957 39.660 179.645 ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/regression/0000755000175000017500000000000012326214513024313 5ustar moellermoellerViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/regression/test_ChangeFont.py0000644000175000017500000000274607723714315027763 0ustar moellermoeller# # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/regression/test_ChangeFont.py,v 1.2 2003/08/29 18:17:49 sophiec Exp $ # # $Id: test_ChangeFont.py,v 1.2 2003/08/29 18:17:49 sophiec Exp $ # """ This module implements a set of functions to test the changeFont command """ import sys from mglutil.regression import testplus vf = None # The mglutil.gui.InputForm.Tk.gui.regression.test_InputForm.py test needs # to be run prior to this suite of tests. def setup(): from ViewerFramework.VF import ViewerFramework global vf vf = ViewerFramework() vf.setUserPreference(('trapExceptions', '0'), topCommand = 0) def quit(): vf.Exit(0) def test_changeFont1(): """ Function to test changeFont command """ vf.changeFont(('charter',12,'normal'), log = 1) assert vf.GUI.ROOT.option_get('font','*')=='charter 12 normal' def test_changeFont2(): """ Function to test changeFont command doitWrapper NB: 7/8: this may fail because lastCmdLog isn't a string anymore... """ vf.changeFont.doitWrapper(('charter',12,'normal'), log = 1) assert vf.GUI.ROOT.option_get('font','*')=='charter 12 normal' harness = testplus.TestHarness( __name__, connect = setup, funs = testplus.testcollect( globals()), disconnect = quit ) if __name__ == '__main__': print harness sys.exit( len( harness)) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/regression/test_VFCommand.py0000644000175000017500000003011210651433475027544 0ustar moellermoeller## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by # # $Header: /opt/cvs/python/packages/share1.5/ViewerFramework/regression/test_VFCommand.py,v 1.5 2007/07/24 17:30:37 vareille Exp $ # # $Id: test_VFCommand.py,v 1.5 2007/07/24 17:30:37 vareille Exp $ # """ This module implements a set of functions to test the VFCommand class """ import sys from mglutil.regression import testplus from mglutil.gui.InputForm.Tk.gui import InputFormDescr, InputForm from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ListChooser import numpy.oldnumeric as Numeric import Tkinter, Pmw vf = None descr = None # The mglutil.gui.InputForm.Tk.gui.regression.test_InputForm.py test needs # to be run prior to this suite of tests. def setup(): from ViewerFramework.VF import ViewerFramework global vf vf = ViewerFramework() def createFormDescr(): global descr descr = InputFormDescr(title = 'My Form') descr.append({'name':'checkbutton', 'widgetType':Tkinter.Checkbutton, 'wcfg':{'text':'Checkbutton', 'variable':Tkinter.IntVar()}, 'gridcfg':{'sticky':'w'}}) descr.append({'name':'radioselect', 'widgetType':Pmw.RadioSelect, 'listtext':['rb1', 'rb2', 'rb3','rb4', 'rb5', 'rb6', 'rb7', 'rb8', 'rb9','rb10', 'rb11', 'rb12'], 'wcfg':{'labelpos':'n', 'label_text':'Radiobuttons: ', 'orient':'vertical', 'buttontype':'radiobutton'}, 'gridcfg':{'sticky':'w'} }) descr.append({'name':'radioselect2', 'widgetType':Pmw.RadioSelect, 'listtext':['rb1', 'rb2', 'rb3','rb4', 'rb5', 'rb6', 'rb7', 'rb8', 'rb9','rb10', 'rb11', 'rb12'], 'wcfg':{'labelpos':'n', 'label_text':'Radiobuttons: ', 'orient':'horizontal', 'buttontype':'radiobutton'}, 'gridcfg':{'sticky':'w'} }) entries = [('Chocolate',None), ('Vanilla', None), ('Strawberry', None), ('Coffee',None), ('Pistachio', None), ('Rasberry',None), ] descr.append({'name':'listchooser', 'widgetType':ListChooser, 'wcfg':{'entries':entries}, 'gridcfg':{'sticky':'w'} }) def quit(): vf.Exit(0) ################################################################### ## TESTING LOG STRING.... ################################################################### def test_LOGS(): """ """ vf.source("test2.py") logfile = open("mvAll.log.py") ################################################################### ## TESTING COMMANDS USING BUILDFORMDDESCR AND SHOWFORM ################################################################### def test_CommandShowForm_1(): """ Function to test creation of an inputForm in a command by the guiCallback showForm is called with default arguments not specified """ createFormDescr() ############################################################## from ViewerFramework.VFCommand import Command class MyCmd(Command): def doit(self): pass def __call__(self): self.doitWrapper() def buildFormDescr(self, formName='myGUI'): if formName == 'myGUI': idf = descr return idf def guiCallback(self): val = self.showForm('myGUI') ########################################################## myCmd = MyCmd() vf.addCommand(myCmd, 'myCmd', None) vf.myCmd.guiCallback() assert isinstance(vf.myCmd.cmdForms['myGUI'], InputForm) def test_CommandShowForm_2(): """ Function to test creation of an inputForm in a command by the guiCallback specifying the sFrameCfg argument """ createFormDescr() ############################################################## from ViewerFramework.VFCommand import Command class MyCmd(Command): def doit(self): pass def __call__(self): self.doitWrapper() def buildFormDescr(self, formName='myGUI'): if formName == 'myGUI': idf = descr return idf def guiCallback(self): val = self.showForm('myGUI', sFrameCfg={'hull_width':500, 'hull_height':600, 'hull_bg':'Red'}) ########################################################## myCmd = MyCmd() vf.addCommand(myCmd, 'myCmd2', None) vf.myCmd2.guiCallback() assert isinstance(vf.myCmd2.cmdForms['myGUI'], InputForm) def test_CommandShowForm_3(): """ Function to test creation of an inputForm in a command by the guiCallback testing the okCfg and cancelCfg arguments """ createFormDescr() ############################################################## from ViewerFramework.VFCommand import Command class MyCmd(Command): def doit(self): pass def __call__(self): self.doitWrapper() def buildFormDescr(self, formName='myGUI'): if formName == 'myGUI': idf = descr return idf def validate_cb(self): self.action = 'validating' self.value = 1 def dismiss_cb(self): self.action = 'dismissing' self.value = 0 def guiCallback(self): val = self.showForm('myGUI', okCfg={'text':'Validate', 'command':self.validate_cb}, cancelCfg={'text':'Dismiss', 'command':self.dismiss_cb}) if self.action == 'validating': assert self.value elif self.action == 'dismissing': assert not self.value ################################################################# myCmd = MyCmd() vf.addCommand(myCmd, 'myCmd3', None) vf.myCmd3.guiCallback() assert isinstance(vf.myCmd3.cmdForms['myGUI'], InputForm) def test_CommandShowForm_4(): """ Function to test creation of an inputForm in a command by the guiCallback Testing the initFunc argument """ createFormDescr() ############################################################## from ViewerFramework.VFCommand import Command class MyCmd(Command): def doit(self): pass def __call__(self): self.doitWrapper() def buildFormDescr(self, formName='myGUI'): if formName == 'myGUI': idf = descr return idf def initialize(self, form): w = form.descr.entryByName['listchooser']['widget'] w.add(('Coconut', None)) def guiCallback(self): val = self.showForm('myGUI', initFunc=self.initialize) form = self.cmdForms['myGUI'] ent = form.descr.entryByName['listchooser']['widget'].entries assert 'Coconut' in map(lambda x: x[0], ent) ################################################################# myCmd = MyCmd() vf.addCommand(myCmd, 'myCmd4', None) vf.myCmd4.guiCallback() assert isinstance(vf.myCmd4.cmdForms['myGUI'], InputForm) ################################################################### ## TESTING COMMANDS USING GETUSERINPUT ################################################################### def test_CommandGetUserInput_1(): """ Function to test creation of an inputForm in a command by the guiCallback getUserInput is called with default arguments not specified """ createFormDescr() ############################################################## from ViewerFramework.VFCommand import Command class MyCmd(Command): def doit(self): pass def __call__(self): self.doitWrapper() def guiCallback(self): idf = descr val = self.vf.getUserInput(idf) ########################################################## myCmd = MyCmd() vf.addCommand(myCmd, 'myCmd', None) vf.myCmd.guiCallback() def test_CommandGetUserInput_2(): """ Function to test creation of an inputForm in a command by the guiCallback specifying the sFrameCfg argument """ createFormDescr() ############################################################## from ViewerFramework.VFCommand import Command class MyCmd(Command): def doit(self): pass def __call__(self): self.doitWrapper() def buildFormDescr(self, formName='myGUI'): if formName == 'myGUI': idf = descr return idf def guiCallback(self): idf = descr val = self.vf.getUserInput(idf, sFrameCfg={'hull_width':500, 'hull_height':600, 'hull_bg':'Red'}) ########################################################## myCmd = MyCmd() vf.addCommand(myCmd, 'myCmd2', None) vf.myCmd2.guiCallback() def test_CommandGetUserInput_3(): """ Function to test creation of an inputForm in a command by the guiCallback testing the okCfg and cancelCfg arguments """ createFormDescr() ############################################################## from ViewerFramework.VFCommand import Command class MyCmd(Command): def doit(self): pass def __call__(self): self.doitWrapper() def validate_cb(self): self.action = 'validating' self.value = 1 def dismiss_cb(self): self.action = 'dismissing' self.value = 0 def guiCallback(self): idf = descr val = self.vf.getUserInput(idf, okCfg={'text':'Validate', 'command':self.validate_cb}, cancelCfg={'text':'Dismiss', 'command':self.dismiss_cb}) if self.action == 'validating': assert self.value elif self.action == 'dismissing': assert not self.value ################################################################# myCmd = MyCmd() vf.addCommand(myCmd, 'myCmd3', None) vf.myCmd3.guiCallback() def test_CommandGetUserInput_4(): """ Function to test creation of an inputForm in a command by the guiCallback Testing the initFunc argument """ createFormDescr() ############################################################## from ViewerFramework.VFCommand import Command class MyCmd(Command): def doit(self): pass def __call__(self): self.doitWrapper() def initialize(self, form): w = form.descr.entryByName['listchooser']['widget'] w.add(('Coconut', None)) def guiCallback(self): idf = descr val = self.vf.getUserInput(idf, initFunc=self.initialize) form = self.cmdForms['myGUI'] ent = form.descr.entryByName['listchooser']['widget'].entries assert 'Coconut' in map(lambda x: x[0], ent) ################################################################# myCmd = MyCmd() vf.addCommand(myCmd, 'myCmd4', None) vf.myCmd4.guiCallback() harness = testplus.TestHarness( __name__, connect = setup, funs = testplus.testcollect( globals()), disconnect = quit ) if __name__ == '__main__': print harness sys.exit( len( harness)) ViewerFramework-1.5.7~rc1+cvs.20140424/ViewerFramework/testdir/0000755000175000017500000000000012326214513023611 5ustar moellermoeller