command.c

Go to the documentation of this file.
00001 
00002 /*  $Id: command.c 1254 2006-04-12 20:27:14Z sethdill $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 #include "frontier.h"
00029 #include "standard.h"
00030 
00031 #include "kb.h"
00032 #include "memory.h"
00033 #include "mouse.h"
00034 #include "strings.h"
00035 #include "resources.h"
00036 #include "shell.rsrc.h"
00037 #include "lang.h"
00038 #include "langsystem7.h"
00039 #include "miniwindow.h"
00040 #include "process.h"
00041 #include "cancoon.h"
00042 #include "scripts.h"
00043 #include "command.h"
00044 
00045 
00046 
00047 #define cmdtextitem 1
00048 
00049 
00050 
00051 static hdlprocessrecord quickscriptprocess = nil;
00052 
00053 
00054 
00055 static boolean cmdsavestring (short stringnumber, Handle htext) {
00056 #pragma unused(stringnumber)
00057 
00058     /*
00059     the cmd dialog only has one string, so we ignore the stringnumber param.
00060     
00061     set the script string in the cancoondata record, for saving -- so we have 
00062     a permanent copy of the last script he wrote across invocations of the
00063     program.
00064     
00065     1/21/93 dmb: don't set superglobals manually anymore
00066     
00067     5.0d14 dmb: hscriptstring is now a text handle, not a hdlstring.
00068     */
00069     
00070     Handle h; /* 2004-12-03 creedon - temporary handle */ 
00071     register hdlcancoonrecord hc;
00072     
00073     assert (cancoonglobals != nil);
00074     
00075     hc = cancoonglobals; /*copy into register*/
00076     
00077     if (!equalhandles (htext, (**hc).hscriptstring)) {
00078     
00079         if ((**hc).hscriptstring == nil) { /* 2004-12-03 creedon, aradke */
00080             copyhandle (htext, &h);
00081             (**hc).hscriptstring = h;
00082             }
00083         else
00084             copyhandlecontents (htext, (**hc).hscriptstring);
00085         
00086         (**hc).fldirty = true;
00087         }
00088     
00089     return (true);
00090     } /*cmdsavestring*/
00091     
00092     
00093 static boolean cmdloadstring (short stringnumber, Handle *h) {
00094 #pragma unused(stringnumber)
00095 
00096     /*
00097     1/21/93 dmb: don't set superglobals manually anymore
00098     
00099     5.0d14 dmb: hscriptstring is now a text handle, not a hdlstring.
00100     */
00101     
00102     assert (cancoonglobals != nil);
00103     
00104     return (copyhandle ((**cancoonglobals).hscriptstring, h));
00105     } /*cmdloadstring*/
00106 
00107 
00108 static boolean cmderrorroutine (long refcon, long lnum, short charnum, hdlhashtable *htable, bigstring bsname) {
00109 #pragma unused (refcon, htable)
00110 
00111     /*
00112     a lang error occurred; select the offending text in the quickscript window
00113     */
00114     
00115     #ifdef flnewfeatures
00116     
00117     if (bsname != nil) { /*request is for name*/
00118         
00119         getstringlist (commandlistnumber, commandtitlestring, bsname);
00120         
00121         return (true);
00122         }
00123     
00124     #endif
00125     
00126     if (!startcmddialog ())
00127         return (false);
00128     
00129     if (!shellpushglobals (miniwindow))
00130         return (false);
00131     
00132     charnum = langgetsourceoffset (lnum, charnum);
00133         
00134     minisetselect (charnum, charnum);
00135     
00136     shellpopglobals ();
00137     
00138     return (true);
00139     } /*cmderrorroutine*/
00140 
00141 
00142 static boolean cmdtexthit (Point pt) {
00143 #pragma unused (pt)
00144 
00145     /*
00146     2.1b6 dmb: use debugging context for zooming, if available
00147     */
00148     
00149     if (keyboardstatus.ctmodifiers && mousestatus.fldoubleclick) {
00150         
00151         bigstring bs;
00152         hdlhashtable hcontext = nil;
00153         
00154         minigetselstring (0, bs);
00155         
00156         if (scriptgetdebuggingcontext (&hcontext)) /*guaranteed to be non-nil*/
00157             pushhashtable (hcontext);
00158         
00159         langzoomobject (bs);
00160         
00161         if (hcontext != nil) {
00162             
00163             pophashtable ();
00164             
00165             scriptunlockdebuggingcontext ();
00166             }
00167         }
00168     
00169     return (true);
00170     } /*cmdtexthit*/
00171 
00172 
00173 static boolean cmdprocesscallback (void) {
00174     
00175     miniinvalicon (idcommandconfig);
00176     
00177     return (true);
00178     } /*cmdprocesscallback*/
00179 
00180 
00181 static pascal void *cmdthreadmain (tythreadmainparams hprocess) {
00182     
00183     /*
00184     2.1b2 dmb: use getobjectmodeldisplaystring to diplay result
00185     
00186     2.1b4 dmb: use the debugger context, if available (i.e. a script 
00187     is currently suspended).
00188     
00189     4.0.1b1 dmb: pass name of thread to initprocessthread; call exitprocessthread
00190     */
00191     
00192     register hdlprocessrecord hp = (hdlprocessrecord) hprocess;
00193     tyvaluerecord val;
00194     bigstring bsresult;
00195     hdlhashtable hcontext = nil;
00196     boolean fl;
00197     
00198     initprocessthread (BIGSTRING ("\x0c" "quick script")); /*must call from every thread main*/
00199     
00200     if ((**hp).fldisposewhenidle)
00201         fl = false;
00202     else {
00203         
00204         if (scriptgetdebuggingcontext (&hcontext))
00205             (**hp).hcontext = hcontext;
00206         
00207         fl = processruncode (hp, &val);
00208         
00209         if (hcontext != nil)
00210             scriptunlockdebuggingcontext ();
00211         }
00212     
00213     disposeprocess (hp);
00214     
00215     if (!fl)
00216         setbooleanvalue (false, &val);
00217     
00218     getobjectmodeldisplaystring (&val, bsresult); /*hashgetvaluestring (val, bsresult)*/
00219     
00220     disposetmpvalue (&val);
00221     
00222     minisetwindowmessage (idcommandconfig, bsresult); /*can't assume miniwindow is around anymore*/
00223     
00224     quickscriptprocess = nil; /*clear "semaphore"*/
00225     
00226     exitprocessthread ();
00227     
00228     return (nil);
00229     } /*cmdthreadmain*/
00230 
00231 
00232 static boolean cmdiconhit (void) {
00233     
00234     /*
00235     5/21/91 dmb: run the string as a process so we can handle errors nicely.
00236     
00237     8/20/91 dmb: when the process completes, we're in another thread and can't 
00238     assume that the window is around anymore, let alone that its globals are 
00239     set.  to handle this (crashing) situation, use new minisetwindowmessage 
00240     to display the result.
00241     
00242     10/25/91 dmb: check new process's disposewhenidleflag before running it.
00243     
00244     10/27/91 dmb: don't dispose result value if processruncode returns false
00245     
00246     12/12/91 dmb: extract the text handle from the dialog record's TE record to 
00247     overcome the miniwindow's string-oriented architecture.  Unfortunately, the
00248     text also saved in the database as a string, to this is just a band-aid, not 
00249     a real fix.
00250     
00251     2.1a6 dmb: reworked threading for thread mgr 1.1
00252     
00253     2.1b2 dmb: pass -1 for errorrefcon instead of zero to prevent top level 
00254     lexical scope from being transparent (i.e. visible to subroutines)
00255     
00256     5.0d14 dmb: minidialog now uses full text handles, not bigstrings
00257     
00258     5.0b17 dmb: minigetstring result is ours to consume
00259     */
00260     
00261     Handle hscript;
00262     hdltreenode hcode;
00263     boolean fl;
00264     hdlprocessrecord hprocess;
00265     register hdlprocessrecord hp;
00266     hdlprocessthread hthread;
00267     
00268     if (quickscriptprocess != nil) {
00269         
00270         sysbeep ();
00271         
00272         return (false);
00273         }
00274     
00275     if (!langpusherrorcallback (&cmderrorroutine, (long) -1))
00276         return (false);
00277     
00278     minigetstring (0, &hscript);
00279     
00280     fl = langbuildtree (hscript, false, &hcode); /*consumes htext*/
00281     
00282     langpoperrorcallback ();
00283     
00284     if (!fl) /*syntax error*/
00285         return (false);
00286     
00287     langerrorclear (); /*compilation produced no error, be sure error window is empty*/
00288     
00289     if (!newprocess (hcode, true, &cmderrorroutine, (long) -1, &hprocess)) {
00290         
00291         langdisposetree (hcode);
00292         
00293         return (false);
00294         }
00295     
00296     hp = hprocess; /*copy into register*/
00297     
00298     (**hp).processstartedroutine = &cmdprocesscallback;
00299     
00300     (**hp).processkilledroutine = &cmdprocesscallback;
00301     
00302     #ifndef oldthreads
00303     
00304     if (!newprocessthread (&cmdthreadmain, (tythreadmainparams) hp, &hthread)) {
00305         
00306         disposeprocess (hp);
00307         
00308         return (false);
00309         }
00310     
00311     quickscriptprocess = hp; /*can only run one of these at a time*/
00312     
00313     return (true);  
00314     
00315     #else
00316     
00317     quickscriptprocess = hp; /*can only run one of these at a time*/
00318     
00319     if (!innewprocessthread (&hthread)) /*not in new thread -- we're done with synchonous stuff*/
00320         return (true);
00321     
00322     if ((hthread == nil) || (**hp).fldisposewhenidle)
00323         fl = false;
00324     else
00325         fl = processruncode (hp, &val);
00326     
00327     disposeprocess (hp);
00328     
00329     if (!fl)
00330         setbooleanvalue (false, &val);
00331     
00332     hashgetvaluestring (val, bsresult);
00333     
00334     disposetmpvalue (val);
00335     
00336     minisetwindowmessage (idcommandconfig, bsresult); /*can't assume miniwindow is around anymore*/
00337     
00338     quickscriptprocess = nil; /*clear "semaphore"*/
00339     
00340     endprocessthread (hthread);
00341     
00342     return (false); /*if we got here, hthread was nil*/
00343     
00344     #endif
00345     } /*cmdiconhit*/
00346 
00347 
00348 static boolean cmdgettargetdata (short id) {
00349     
00350     /*
00351     we don't want our script to operate on our window
00352     
00353     2.1b14 dmb: make sure that the current process and our process aren't 
00354     both nil before rejecting targetship.
00355 
00356     5.0b6 dmb: allow wp verbs to target QuickScript
00357     */
00358     
00359     if ((currentprocess != nil) && (currentprocess == quickscriptprocess))
00360         return (false);
00361     
00362     return (id == -1) || (id == idwordprocessor);
00363     } /*cmdgettargetdata*/
00364 
00365 
00366 static void cmdcheckrunbutton (void) {
00367     
00368     /*
00369     boolean fl = debuggingcurrentprocess () || !processisoneshot (false);
00370     */
00371     
00372     boolean fl = (quickscriptprocess == nil) /*&& !processbusy ()*/ ;
00373     
00374     (**minidata).fliconenabled = fl;
00375     } /*cmdcheckrunbutton*/
00376 
00377 
00378 static boolean cmdsetfields (void) {
00379     
00380     register hdlminirecord hm = minidata;
00381     bigstring bs;
00382     
00383     (**hm).idconfig = idcommandconfig;
00384     
00385     (**hm).windowtype = ixcommandinfo;
00386     
00387     getstringlist (commandlistnumber, runiconstring, bs);
00388     
00389     copystring (bs, (**hm).iconlabel);
00390     
00391     getstringlist (commandlistnumber, commandtitlestring, bs);
00392     
00393     copystring (bs, (**hm).windowtitle);
00394     
00395     (**hm).savestringroutine = &cmdsavestring;
00396     
00397     (**hm).loadstringroutine = &cmdloadstring;
00398     
00399     (**hm).texthitroutine = &cmdtexthit;
00400     
00401     (**hm).iconenableroutine = &cmdcheckrunbutton;
00402     
00403     (**hm).iconhitroutine = &cmdiconhit;
00404     
00405     (**hm).gettargetdataroutine = &cmdgettargetdata;
00406     
00407     (**hm).cttextitems = 1;
00408     
00409     (**hm).textitems [0] = cmdtextitem;
00410     
00411     return (true);
00412     } /*cmdsetfields*/
00413 
00414 
00415 boolean startcmddialog (void) {
00416     
00417     return (startminidialog (idcommandconfig, &cmdsetfields));
00418     } /*startcmddialog*/
00419 
00420 
00421 boolean cmdstart (void) {
00422     
00423     return (ministart (idcommandconfig));
00424     } /*cmdstart*/
00425 
00426 
00427 
00428 

Generated on Wed May 31 18:19:45 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6