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

UIText.C

Go to the documentation of this file.
00001 /***************************************************************************
00002 *cr 
00003 *cr (C) Copyright 1995-2019 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.198 $ $Date: 2019年01月17日 21:21:02 $
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, int mpienabled)
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, mpienabled);
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 
00197 int UIText::act_on_command(int cmdtype, Command *cmd) {
00198 int action=1;
00199 
00200 #if defined(VMDNVTX)
00201 // log command in profiler, if possible
00202 int profile_pushed=0;
00203 if (cmd->has_text(cmdbufstr)) {
00204 profile_pushed=1;
00205 PROFILE_PUSH_RANGE(cmdbufstr->text(), 1); 
00206 }
00207 #endif
00208 
00209 if (tclinterp) {
00210 // log command, if possible
00211 if (cmd->has_text(cmdbufstr)) {
00212 tclinterp->logfile_cb(cmdbufstr->text());
00213 #ifdef VMDVRJUGGLER
00214 if (app->jugglerMode == VRJ_MASTER) {
00215 app->logfile_juggler(cmdbufstr->text());
00216 }
00217 #endif
00218 cmdbufstr->reset();
00219 }
00220 }
00221 
00222 if (cmdtype == Command::INTERP_EVENT) {
00223 // downcast to InterpEvent
00224 InterpEvent *event = (InterpEvent *)cmd; 
00225 if (tclinterp)
00226 event->do_callback(tclinterp);
00227 // ACK! This used be "else if (pythoninterp)", which means python
00228 // callbacks never get called if you build with Tcl. 
00229 if (pythoninterp)
00230 event->do_callback(pythoninterp);
00231 } else {
00232 action=0; // no action taken
00233 }
00234 
00235 #if defined(VMDNVTX)
00236 if (profile_pushed) {
00237 PROFILE_POP_RANGE(); // ensure we perform matching pop operation 
00238 }
00239 #endif
00240 
00241 return action; // return whether we used the command or not
00242 }
00243 
00244 
00245 int UIText::change_interp(const char *interpname) {
00246 if (!interpname) return FALSE;
00247 if (!strupcmp(interpname, "tcl")) {
00248 if (tclinterp) {
00249 msgInfo << "Text interpreter now Tcl" << sendmsg;
00250 interp = tclinterp;
00251 return TRUE;
00252 } else {
00253 msgErr << "Sorry, no Tcl text interpreter available" << sendmsg;
00254 // try for Python
00255 interpname = "python";
00256 }
00257 } 
00258 // fall through to Python if no Tcl interpreter is available
00259 if (!strupcmp(interpname, "python")) {
00260 if (pythoninterp) {
00261 msgInfo << "Text interpreter now Python" << sendmsg;
00262 interp = pythoninterp;
00263 // On MACOSX, when we change to the Python interpreter _after_ the
00264 // first time it's created (i.e. gopython, EOF, gopython), we get
00265 // kicked out right away because for some reason stdin has the EOF
00266 // flag set. So, we clear the EOF flag here.
00267 clearerr(stdin);
00268 return TRUE;
00269 } else {
00270 #if defined(VMDPYTHON) 
00271 pythoninterp = new PythonTextInterp(app);
00272 if (pythoninterp) {
00273 msgInfo << "Text interpreter now Python" << sendmsg;
00274 interp = pythoninterp;
00275 return TRUE;
00276 } else {
00277 msgErr << "Sorry, unable to start Python text interpreter" << sendmsg;
00278 }
00279 #else
00280 msgErr << "Sorry, this version of VMD was compiled with Python support disabled" << sendmsg;
00281 #endif
00282 }
00283 } else {
00284 msgErr << "Unsupported text interpreter requested" << sendmsg;
00285 }
00286 return FALSE;
00287 }
00288 

Generated on Tue Nov 18 02:48:13 2025 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002

AltStyle によって変換されたページ (->オリジナル) /