Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

UIText.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2011 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: UIText.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.193 $      $Date: 2011/03/29 19:02:35 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *
00019  * This is the User Interface for text commands.  It reads characters from
00020  * the console, and executes the commands.
00021  *
00022  * This will use the Tcl library for general script interpretation, which
00023  * allows for general script capabilities such as variable substitution,
00024  * loops, etc.  If Tcl cannot be used, text commands will still be available
00025  * in the program, but the general script capabilities will be lost.
00026  ***************************************************************************/
00027 
00028 #ifdef VMDPYTHON
00029 #include "PythonTextInterp.h"
00030 #endif
00031 
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <ctype.h>
00035 
00036 #include "UIText.h"
00037 #include "TextEvent.h"
00038 #include "CommandQueue.h"
00039 #include "Inform.h"
00040 #include "config.h"
00041 #include "utilities.h"
00042 #include "PlainTextInterp.h"
00043 #include "VMDApp.h"
00044 #include "TclTextInterp.h"
00045 #include "Molecule.h"
00046 #include "MoleculeList.h"
00047 #include "SymbolTable.h"
00048 
00049 #if defined(VMDTKCON)
00050 #include "vmdconsole.h"
00051 #endif
00052 
00054 
00055 // constructor
00056 UIText::UIText(VMDApp *vmdapp, int guienabled)
00057 #ifdef VMDVRJUGGLER
00058   : UIObject(vmdapp), _isInitialized(false) {
00059 #else
00060   : UIObject(vmdapp) {
00061 #endif
00062 
00063   // UIText logs all commands
00064   tclinterp = NULL;
00065   pythoninterp = NULL;
00066 
00067 #if defined(VMDTKCON)
00068   cmdbufstr = new Inform("", VMDCON_ALWAYS);
00069 #else
00070   cmdbufstr = new Inform("");
00071 #endif
00072 
00073   // UIText logs all commands
00074   for (int i=0; i<Command::TOTAL; i++) command_wanted(i);
00075 
00076   // Initialize the Tcl interpreter if enabled
00077 #ifdef VMDTCL
00078   tclinterp = new TclTextInterp(app, guienabled);
00079 #ifdef VMDTKCON
00080   // hook the default tcl interpreter into vmdcon as default.
00081   vmdcon_set_status(vmdcon_get_status(), ((TclTextInterp *)tclinterp)->get_interp());
00082 #endif
00083 #endif
00084 
00085   // The Python interpreter is initialized on first use.
00086   // However, if there's no Tcl interpreter, initialize the Python interpreter
00087   // right away.
00088 #ifdef VMDPYTHON
00089   if (!tclinterp)
00090     pythoninterp = new PythonTextInterp(app);
00091 #endif
00092 
00093   // start with the Tcl interpreter by default, if it exists.  If there is
00094   // no Tcl interpreter, go with Python.  Last resort: PlainTextInterpreter
00095   // (which has nothing to do with crypto, by the way).
00096   if (tclinterp)
00097     interp = tclinterp;
00098   else if (pythoninterp)
00099     interp = pythoninterp;
00100   else
00101     interp = new PlainTextInterp;
00102 
00103   reset();
00104 }
00105 
00106 // This is called in VMDApp::VMDinit just before reading the .vmdrc file.
00107 // It has to be done after the previous initialization because the
00108 // event look was not yet available.
00109 void UIText::read_init(void) {
00110   interp->doInit();
00111 #ifdef VMDVRJUGGLER
00112   _isInitialized = true;
00113 #endif
00114 }
00115 
00116 // destructor
00117 UIText::~UIText(void) {
00118   if (tclinterp) tclinterp->logfile_cb("exit");
00119 #ifdef VMDTCL
00120   delete tclinterp;
00121 #endif
00122 
00123 #ifdef VMDPYTHON
00124   delete pythoninterp;
00125 #endif
00126   delete cmdbufstr;
00127 }
00128 
00129 #ifdef VMDVRJUGGLER
00130 bool UIText::isInitialized(){
00131   // msgInfo  << "isInitialized()" << sendmsg;
00132   return _isInitialized;
00133 }
00134 #endif
00135 
00136 int UIText::save_state(const char *fname) {
00137   if (tclinterp) {
00138     JString cmd("save_state ");
00139     cmd += "{";
00140     cmd += fname;
00141     cmd += "}";
00142     return tclinterp->evalString((const char *)cmd);
00143   }
00144   return FALSE;
00145 }
00146 
00147 // specify new file to read commands from
00148 void UIText::read_from_file(const char *fname) {
00149 #ifdef VMDVRJUGGLER
00150   if (isInitialized()) {
00151     // msgInfo << "is Initialized" << sendmsg;
00152   } else {
00153     msgInfo << "is not Initialized" << sendmsg;
00154   }
00155 
00156   if (_isInitialized) {
00157     // && interp){   // prevent segfault when this is called during init 
00158     //    msgInfo  << "interp not null;" << sendmsg;
00159     interp->evalFile(fname);
00160   } else {
00161     msgInfo  << "not ready to read " << fname  << sendmsg;
00162   }
00163 #else
00164   interp->evalFile(fname);
00165 #endif
00166 }
00167 
00168 // check for an event; return TRUE if we found an event; FALSE otherwise
00169 int UIText::check_event(void) {
00170 
00171   // no tk event handling when building as a shared object 
00172   // for embedding in python.
00173 #if defined(VMD_SHARED)
00174   return FALSE;
00175 #endif
00176 
00177   // let the text interpreter have control for a while
00178   // If a Python interpreter has been initialized, let it do the Tk updates.
00179   // Python takes care of updating Tk; if we try to update Tk from within
00180   // Tcl when Tkinter widgets have been created, we crash and burn as Tk
00181   // is not thread safe.
00182   // If Python was not able to update Tk, possibly because Tkinter was not
00183   // found, then use the Tcl interpreter. 
00184   if (!pythoninterp || (pythoninterp && !pythoninterp->doTkUpdate())) {
00185     if (tclinterp) {
00186       tclinterp->doTkUpdate();
00187     } else {
00188       // last resort - use whatever interpreter we've got.
00189       interp->doTkUpdate();
00190     }
00191   }
00192   interp->doEvent();
00193   return TRUE; 
00194 }
00195 
00196 int UIText::act_on_command(int cmdtype, Command *cmd) {
00197   if (tclinterp) {
00198     // log command, if possible
00199     if (cmd->has_text(cmdbufstr)) {
00200       tclinterp->logfile_cb(cmdbufstr->text());
00201 #ifdef VMDVRJUGGLER
00202       if (app->jugglerMode == VRJ_MASTER) {
00203         app->logfile_juggler(cmdbufstr->text());
00204       }
00205 #endif
00206       cmdbufstr->reset();
00207     }
00208   }
00209   if (cmdtype == Command::INTERP_EVENT) {
00210     // downcast to InterpEvent
00211     InterpEvent *event = (InterpEvent *)cmd;  
00212     if (tclinterp)
00213       event->do_callback(tclinterp);
00214     // ACK!  This used be "else if (pythoninterp)", which means python
00215     // callbacks never get called if you build with Tcl.  
00216     if (pythoninterp)
00217       event->do_callback(pythoninterp);
00218      
00219   } else {
00220     return 0;  // no action taken
00221   }
00222   return 1;    // used the command
00223 }
00224 
00225 int UIText::change_interp(const char *interpname) {
00226   if (!interpname) return FALSE;
00227   if (!strupcmp(interpname, "tcl")) {
00228     if (tclinterp) {
00229       msgInfo << "Text interpreter now Tcl" << sendmsg;
00230       interp = tclinterp;
00231       return TRUE;
00232     } else {
00233       msgErr << "Sorry, no Tcl text interpreter available" << sendmsg;
00234       // try for Python
00235       interpname = "python";
00236     }
00237   } 
00238   // fall through to Python if no Tcl interpreter is available
00239   if (!strupcmp(interpname, "python")) {
00240     if (pythoninterp) {
00241       msgInfo << "Text interpreter now Python" << sendmsg;
00242       interp = pythoninterp;
00243       // On MACOSX, when we change to the Python interpreter _after_ the
00244       // first time it's created (i.e. gopython, EOF, gopython), we get
00245       // kicked out right away because for some reason stdin has the EOF
00246       // flag set.  So, we clear the EOF flag here.
00247       clearerr(stdin);
00248       return TRUE;
00249     } else {
00250 #if defined(VMDPYTHON) 
00251       pythoninterp = new PythonTextInterp(app);
00252       if (pythoninterp) {
00253         msgInfo << "Text interpreter now Python" << sendmsg;
00254         interp = pythoninterp;
00255         return TRUE;
00256       } else {
00257         msgErr << "Sorry, unable to start Python text interpreter" << sendmsg;
00258       }
00259 #else
00260       msgErr << "Sorry, this version of VMD was compiled with Python support disabled" << sendmsg;
00261 #endif
00262     }
00263   } else {
00264     msgErr << "Unsupported text interpreter requested" << sendmsg;
00265   }
00266   return FALSE;
00267 }
00268 

Generated on Wed May 23 01:50:28 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002