opwinpad.c

Go to the documentation of this file.
00001 
00002 /*  $Id: opwinpad.c 355 2005-01-11 22:48:55Z andreradke $    */
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 #ifdef MACVERSION 
00029     #include <standard.h>
00030 #endif
00031 
00032 #ifdef WIN95VERSION 
00033     #include "standard.h"
00034 #endif
00035 
00036 #include "config.h"
00037 #include "dialogs.h"
00038 #include "memory.h"
00039 #include "strings.h"
00040 #include "quickdraw.h"
00041 #include "font.h"
00042 #include "cursor.h"
00043 #include "file.h"
00044 #include "ops.h"
00045 #include "resources.h"
00046 #include "search.h"
00047 #include "shell.h"
00048 #include "shellhooks.h"
00049 #include "shellundo.h"
00050 #include "lang.h"
00051 #include "langexternal.h"
00052 #include "langinternal.h"
00053 #include "tablestructure.h"
00054 #include "process.h"
00055 #include "op.h"
00056 #include "opinternal.h"
00057 #include "opverbs.h"
00058 #include "wpengine.h"
00059 #include "scripts.h"
00060 #include "kernelverbdefs.h"
00061 #if MACVERSION
00062     #include "osacomponent.h"
00063 #else
00064     #define havecomponentmanager() (false)
00065 #endif
00066 
00067 
00068 
00069 #define opstringlist 159
00070 #define optypestring 1
00071 #define scripttypestring 2
00072 #define opsizestring 3
00073 
00074 #define operrorlist 259
00075 #define noooutlineerror 1
00076 #define internalerror 2
00077 #define namenotoutlineerror 3
00078 #define namenotscripterror 4
00079 #define rejectmenubarnum 5
00080 
00081 
00082 
00083 enum {
00084     runbutton = 1,
00085     
00086     debugbutton,
00087     
00088     recordbutton,
00089     
00090     stepbutton,
00091     
00092     inbutton,
00093     
00094     outbutton,
00095     
00096     followbutton,
00097     
00098     gobutton,
00099     
00100     stopbutton,
00101     
00102     killbutton,
00103     
00104     localsbutton,
00105     
00106     installbutton
00107     };
00108 
00109 
00110 
00111 #define maxchainedlocals 80 /*limit for local table nesting in debugged process*/
00112 
00113 #define maxnestedsources 40 /*local handlers count as nested sources*/
00114 
00115 
00116 
00117 typedef struct tysourcerecord {
00118     
00119     WindowPtr pwindow; /*window containing running script; nil if closed or unknown*/
00120     
00121     hdlhashnode hnode; /*hash node containing script variable*/
00122     
00123     hdloutlinerecord houtline; /*script outline itself*/
00124     } tysourcerecord;
00125 
00126 
00127 typedef struct tydebuggerrecord {
00128     
00129     hdlprocessrecord scriptprocess;
00130     
00131     tysourcerecord scriptsourcestack [maxnestedsources]; /*for stepping other scripts*/
00132     
00133     short topscriptsource; /*source stack pointer*/
00134     
00135     short sourcesteplevel; /*level in source stack at which we suspend after step/in/out*/
00136     
00137     tydirection stepdir; /*left,right,down & flatdown for out,in,step & trace*/
00138     
00139     short lastlnum; /*the last line number stepped onto*/
00140     
00141     hdlhashtable hlocaltable; /*the most local table in our process*/
00142     
00143     hdlhashnode localtablestack [maxchainedlocals]; /*nodes of tables in the runtimestack*/
00144     
00145     /***Handle localtableformatsstack [maxchainedlocals]; /*nodes of tables in the runtimestack*/
00146     
00147     short toplocaltable; /*table stack pointer*/
00148     
00149     /*
00150     short deferredbuttonnum; /*see scriptdeferbutton%/
00151     
00152     WindowPtr deferredwindow; /*ditto%/
00153     */
00154     
00155     hdlheadrecord hbarcursor; /*the headline we've most recently shown*/
00156     
00157 #ifdef flcomponent
00158     ComponentInstance servercomp; /*component that we have open for this script*/
00159 
00160     OSType servertype; /*the component's type*/
00161     
00162     OSAID idscript; /*while recording, this is the id of the script*/
00163 #endif
00164     
00165     short lastindent;
00166     
00167     boolean flscriptsuspended: 1; /*user is debugging a script*/
00168     
00169     boolean flstepping: 1; /*single-stepping thru scripts*/
00170     
00171     boolean flfollowing: 1; /*does the bar cursor follow the interpreter?*/
00172     
00173     boolean flscriptkilled: 1; /*true if the script has been killed*/
00174     
00175     boolean flscriptrunning: 1; /*true when the script is running*/
00176     
00177     boolean flwindowclosed: 1; /*false if script's window is open*/
00178     
00179     boolean fllangerror: 1; /*are we stopped with an error?*/
00180     
00181     boolean flrecording: 1; /*are we recording into this script?*/
00182     
00183     boolean flcontextlocked: 1; /*is out context being operated on externally?*/
00184     
00185     long scriptrefcon; /*copied from outline refcon*/
00186     } tydebuggerrecord, *ptrdebuggerrecord, **hdldebuggerrecord;
00187 
00188 
00189 static hdldebuggerrecord debuggerdata = nil;
00190 
00191 
00192 static boolean scriptinruntimestack (void) {
00193     
00194     /*
00195     is the current script part of the current process?
00196     
00197     6/24/92 dmb: compare outlines in loop, not windows; windows may not yet 
00198     be assigned into stack (if opened manaually or by Error Info)
00199     */
00200     
00201     register hdldebuggerrecord hd = debuggerdata;
00202     register short ix;
00203     
00204     for (ix = 0; ix < (**hd).topscriptsource; ix++) { /*visit every window in stack*/
00205         
00206         /*
00207         if (outlinewindow == (**hd).scriptsourcestack [ix].pwindow) {
00208         */
00209         
00210         if (outlinedata == (**hd).scriptsourcestack [ix].houtline) {
00211             
00212             if (ix == 0) /*main source window.  make sure same script is displayed*/
00213             
00214                 return ((**hd).scriptrefcon == (**outlinedata).outlinerefcon);
00215             
00216             return (true);
00217             }
00218         }
00219     
00220     return (false);
00221     } /*scriptinruntimestack*/
00222 
00223 
00224 static void scriptkillbutton (void) {
00225     
00226     /*
00227     11/5/91 dmb: use new scriptprocess field to make kill more explicit
00228     */
00229     
00230     register hdldebuggerrecord hd = debuggerdata;
00231     
00232 //  processkill ((**hd).scriptprocess);
00233     
00234     (**hd).flscriptkilled = true;
00235     
00236     (**hd).flscriptsuspended = false; /*allow script to resume, so it can die*/
00237     } /*scriptkillbutton*/
00238 
00239 
00240 static boolean scriptnewprocess (short buttonnum) {
00241 
00242     Handle hlangtext = nil;
00243     bigstring bsresult;
00244 
00245     if (!opgetlangtext (outlinedata, false, &hlangtext))
00246         return (false);
00247     
00248     langrunhandle (hlangtext, bsresult);
00249     
00250     alertdialog (bsresult);
00251     
00252     return (true);
00253     } /*scriptnewprocess*/
00254 
00255 
00256 static boolean scriptbutton (short buttonnum) {
00257     
00258     register hdldebuggerrecord hd = debuggerdata;
00259     
00260     if (buttonnum != localsbutton) /*exit edit mode on any button hit except locals*/
00261         opsettextmode (false);
00262     
00263     switch (buttonnum) {
00264         
00265         case runbutton:
00266             if (scriptnewprocess (runbutton))
00267                 shellupdatenow (outlinewindow);
00268             
00269             return (true);
00270             
00271         case killbutton:
00272             scriptkillbutton ();
00273             
00274             return (true);
00275         } /*switch*/
00276     
00277     return (true);
00278     } /*scriptbutton*/
00279 
00280 
00281 static boolean scriptbuttonenabled (short buttonnum) {
00282     
00283     register short x = buttonnum;
00284     register hdldebuggerrecord hd = debuggerdata;
00285     register boolean flscriptrunning = (**hd).flscriptrunning;
00286     register boolean flscriptsuspended = (**hd).flscriptsuspended;
00287     register boolean flrunningthisscript;
00288     
00289     if (outlinedata == NULL)
00290         return (false);
00291 
00292     flrunningthisscript = flscriptrunning && scriptinruntimestack ();
00293     
00294     if (flscriptrunning) {
00295         
00296         if ((x != installbutton) && (x != killbutton)) /*rule 3*/
00297             if (!flrunningthisscript)
00298                 return (false);
00299         }
00300     
00301     if ((**hd).flrecording)
00302         return (x == stopbutton);
00303     
00304     if ((**hd).flcontextlocked)
00305         return (false);
00306     
00307     /*
00308     else {
00309         
00310         if ((x != runbutton) && (x != debugbutton) && (x != installbutton)) /*rule 1%/
00311             return (false);
00312         }
00313     */
00314     
00315     switch (x) {
00316         
00317         case runbutton:
00318             return (!flscriptrunning);
00319         
00320         case debugbutton:
00321             return (!flscriptrunning && ((**outlinedata).outlinesignature == typeLAND));
00322         
00323         case stopbutton:
00324             return (!flscriptsuspended);
00325         
00326         case gobutton:
00327             return ((flscriptsuspended || (**hd).flfollowing) && !(**hd).fllangerror);
00328         
00329         case followbutton:
00330         case stepbutton:
00331         case inbutton:
00332         case outbutton:
00333             return (flscriptrunning && flscriptsuspended && !(**hd).fllangerror);
00334         
00335         case localsbutton:
00336             return (flscriptrunning && flscriptsuspended); /*(**hd).flstepping && (!(**hd).flfollowing))*/
00337         
00338         case killbutton:
00339             return (flscriptrunning);
00340         } /*switch*/
00341     
00342     return (true);
00343     } /*scriptbuttonenabled*/
00344 
00345 
00346 static boolean scriptbuttondisplayed (short buttonnum) {
00347     
00348     register hdldebuggerrecord hd = debuggerdata;
00349     register hdlprocessrecord hp = (**hd).scriptprocess;
00350     register boolean flscriptrunning = (**hd).flscriptrunning;
00351     register boolean flrunningthisscript;
00352     register boolean fldebuggingthisscript;
00353     register short x = buttonnum;
00354     
00355     flrunningthisscript = flscriptrunning && scriptinruntimestack (); /*1/2/91*/
00356     
00357     fldebuggingthisscript = flrunningthisscript && (**hp).fldebugging;
00358     
00359     if ((**hd).flrecording)
00360         return ((x == recordbutton) || (x == stopbutton));
00361     
00362     switch (x) {
00363         
00364         case recordbutton:
00365         case runbutton:
00366         case debugbutton:
00367             return (!flscriptrunning);
00368         
00369         case stopbutton:
00370             return (fldebuggingthisscript && !(**hd).flscriptsuspended);
00371         
00372         case gobutton:
00373             return (fldebuggingthisscript && (**hd).flscriptsuspended);
00374         
00375         case followbutton:
00376         case stepbutton:
00377         case inbutton:
00378         case outbutton:
00379         case localsbutton:
00380             return (fldebuggingthisscript);
00381         
00382         case killbutton:
00383             return (flscriptrunning);
00384         } /*switch*/
00385     
00386     return (true);
00387     } /*scriptbuttondisplayed*/
00388 
00389 
00390 static boolean scriptbuttonstatus (short buttonnum, tybuttonstatus *status) {
00391     
00392     (*status).flenabled = scriptbuttonenabled (buttonnum);
00393     
00394     (*status).fldisplay = scriptbuttondisplayed (buttonnum);
00395     
00396     (*status).flbold = false; /*our buttons are never bold*/
00397     
00398     return (true);
00399     } /*scriptbuttonstatus*/
00400 
00401 
00402 static boolean opverbsetscrollbarsroutine (void) {
00403 
00404     register ptrwindowinfo pw = *outlinewindowinfo;
00405     register ptroutlinerecord po = *outlinedata;
00406     
00407     (*pw).vertscrollinfo = (*po).vertscrollinfo;
00408     
00409     (*pw).horizscrollinfo = (*po).horizscrollinfo;
00410     
00411     (*pw).fldirtyscrollbars = true; /*force a refresh of scrollbars by the shell*/
00412     
00413     return (true);
00414     } /*opverbsetscrollbarsroutine*/
00415 
00416 
00417 static void opverbsetcallbacks (hdloutlinerecord houtline) {
00418     
00419     register hdloutlinerecord ho = houtline;
00420     
00421     (**ho).setscrollbarsroutine = &opverbsetscrollbarsroutine;
00422     
00423     /*link in the line layout callbacks*/ /*{
00424     
00425         (**ho).drawlinecallback = &claydrawline;
00426         
00427         (**ho).postdrawlinecallback = &claypostdrawline;
00428         
00429         (**ho).predrawlinecallback = &claypredrawline;
00430         
00431         (**ho).drawiconcallback = &claydrawnodeicon;
00432         
00433         (**ho).gettextrectcallback = &claygettextrect;
00434         
00435         (**ho).geticonrectcallback = &claygeticonrect;
00436         
00437         (**ho).getlineheightcallback = &claygetlineheight;
00438         
00439         (**ho).getlinewidthcallback = &claygetlinewidth;
00440         
00441         (**ho).pushstylecallback = &claypushnodestyle;
00442         
00443         (**ho).postfontchangecallback = (opvoidcallback) &claybrowserinitdraw;
00444         
00445         (**ho).getfullrectcallback = (opgefullrectcallback) &claygetnodeframe;
00446         }*/
00447     
00448     } /*opverbsetcallbacks*/
00449 
00450 
00451 static void opverbcheckwindowrect (hdloutlinerecord houtline) {
00452     
00453     register hdloutlinerecord ho = houtline;
00454     hdlwindowinfo hinfo = outlinewindowinfo;
00455         
00456     if ((**ho).flwindowopen) { /*make windowrect reflect current window size & position*/
00457     
00458         Rect r;
00459         
00460         shellgetglobalwindowrect (hinfo, &r);
00461         
00462         if (!equalrects (r, (**ho).windowrect)) {
00463         
00464             (**ho).windowrect = r;
00465             
00466             (**ho).fldirty = true;
00467             }
00468         }
00469     } /*opverbcheckwindowrect*/
00470 
00471 
00472 static void opverbresize (void) {
00473     
00474     opresize ((**outlinewindowinfo).contentrect);
00475     } /*opverbresize*/
00476 
00477 
00478 boolean opverbclose (void) {
00479     
00480     register hdloutlinerecord ho = outlinedata;
00481     
00482     opverbcheckwindowrect (ho);
00483     
00484     killundo (); /*must toss undos before they're stranded*/
00485     
00486     if ((**ho).fldirty) { /*we have to keep the in-memory version around*/
00487         
00488         (**ho).flwindowopen = false;
00489         
00490         opcloseoutline (); /*prepare for dormancy, not in a window anymore*/
00491         }
00492     
00493     return (true);
00494     } /*opverbclose*/
00495 
00496 
00497 static boolean opverbsetfont (void) {
00498     
00499     return (opsetfont ((**outlinewindowinfo).selectioninfo.fontnum));
00500     } /*opverbsetfont*/
00501 
00502 
00503 static boolean opverbsetsize (void) {
00504     
00505     return (opsetsize ((**outlinewindowinfo).selectioninfo.fontsize));
00506     } /*opverbsetsize*/
00507 
00508 
00509 static boolean opwinnewrecord (void) {
00510     
00511     register hdloutlinerecord ho;
00512     
00513     if (!opnewrecord ((**outlinewindowinfo).contentrect))
00514         return (false);
00515     
00516     ho = outlinedata; /*copy into register*/
00517     
00518     (**outlinewindowinfo).hdata = (Handle) ho;
00519     
00520     (**ho).flwindowopen = true;
00521     
00522     (**ho).fldirty = true; /*needs to be saved*/
00523     
00524     opverbsetcallbacks (ho);
00525     
00526     return (true);
00527     } /*opwinnewrecord*/
00528 
00529 
00530 static boolean opwindisposerecord (void) {
00531 
00532     opdisposeoutline (outlinedata, true);
00533     
00534     outlinedata = nil;
00535     
00536     (**outlinewindowinfo).hdata = nil;
00537 
00538     return true;
00539     } /*opwindisposerecord*/
00540 
00541     
00542 static boolean opwinloadfile (hdlfilenum fnum, short rnum) {
00543     
00544     Handle hpackedop;
00545     register hdloutlinerecord ho;
00546     boolean fl;
00547     long ixload = 0;
00548     
00549     if (!filereadhandle (fnum, &hpackedop))
00550         return (false);
00551     
00552     fl = opunpack (hpackedop, &ixload);
00553     
00554     disposehandle (hpackedop);
00555     
00556     if (!fl)
00557         return (false);
00558     
00559     ho = outlinedata; /*remember for linking into variable structure*/
00560     
00561     (**outlinewindowinfo).hdata = (Handle) ho;
00562     
00563     (**ho).flwindowopen = true;
00564     
00565     (**ho).fldirty = true; /*never been saved, can't be clean*/
00566     
00567     opverbsetcallbacks (ho);
00568     
00569     return (true);
00570     } /*opwinloadfile*/
00571 
00572 
00573 static boolean opwinsavefile (hdlfilenum fnum, short rnum, boolean flsaveas) {
00574     
00575     Handle hpackedop = nil;
00576     boolean fl;
00577     
00578     if (!oppack (&hpackedop))
00579         return (false);
00580     
00581     fl = 
00582         fileseteof (fnum, 0) &&
00583         
00584         filesetposition (fnum, 0) &&
00585         
00586         filewritehandle (fnum, hpackedop);
00587     
00588     disposehandle (hpackedop);
00589     
00590     return (fl);
00591     } /*opwinsavefile*/
00592 
00593 
00594 boolean opstart (void) {
00595     
00596     /*
00597     set up callback routines record, and link our data into the shell's 
00598     data structure.
00599     */
00600     
00601     ptrcallbacks callbacks;
00602     register ptrcallbacks cb;
00603     
00604     opinitdisplayvariables ();
00605     
00606     shellnewcallbacks (&callbacks);
00607     
00608     cb = callbacks; /*copy into register*/
00609     
00610     loadconfigresource (idscriptconfig, &(*cb).config);
00611     
00612     (*cb).config.flnewonlaunch = true; // *** need to update resource
00613 
00614     (*cb).configresnum = idscriptconfig;
00615         
00616     (*cb).windowholder = &outlinewindow;
00617     
00618     (*cb).dataholder = (Handle *) &outlinedata;
00619     
00620     (*cb).infoholder = &outlinewindowinfo;
00621         
00622     (*cb).initroutine = &wpinit;
00623     
00624     (*cb).quitroutine = &wpshutdown;
00625     
00626     (*cb).setglobalsroutine = &opeditsetglobals;
00627     
00628     (*cb).newrecordroutine = opwinnewrecord;
00629     
00630     (*cb).disposerecordroutine = opwindisposerecord;
00631     
00632     (*cb).loadroutine = opwinloadfile;
00633     
00634     (*cb).saveroutine = opwinsavefile;
00635     
00636     (*cb).updateroutine = &opupdate;
00637     
00638     (*cb).activateroutine = &opactivate;
00639     
00640     (*cb).getcontentsizeroutine = &opgetoutinesize;
00641     
00642     (*cb).resizeroutine = &opverbresize;
00643     
00644     (*cb).scrollroutine = &opscroll;
00645     
00646     (*cb).setscrollbarroutine = &opresetscrollbars;
00647     
00648     (*cb).mouseroutine = &opmousedown;
00649     
00650     (*cb).keystrokeroutine = &opkeystroke;
00651     
00652     (*cb).getundoglobalsroutine = &opeditgetundoglobals;
00653     
00654     (*cb).setundoglobalsroutine = &opeditsetundoglobals;
00655     
00656     (*cb).cutroutine = &opcut;
00657     
00658     (*cb).copyroutine = &opcopy;
00659     
00660     (*cb).pasteroutine = &oppaste;
00661     
00662     (*cb).clearroutine = &opclear;
00663     
00664     (*cb).selectallroutine = &opselectall;
00665     
00666     (*cb).fontroutine = &opverbsetfont;
00667     
00668     (*cb).sizeroutine = &opverbsetsize;
00669     
00670     (*cb).setselectioninforoutine = &opsetselectioninfo;
00671     
00672     (*cb).idleroutine = &opidle;
00673     
00674     (*cb).adjustcursorroutine = &opsetcursor;
00675     
00676     (*cb).setprintinfoproutine = &opsetprintinfo;
00677     
00678     (*cb).printroutine = &opprint;
00679     
00680     (*cb).settextmoderoutine = &opsettextmode;
00681     
00682     (*cb).cmdkeyfilterroutine = &opcmdkeyfilter;
00683     
00684     (*cb).closeroutine = &opverbclose;
00685     
00686     (*cb).buttonroutine = &scriptbutton;
00687     
00688     (*cb).buttonstatusroutine = &scriptbuttonstatus;
00689     
00690     if (!newclearhandle (longsizeof (tydebuggerrecord), (Handle *) &debuggerdata)) /*all fields are cool at 0*/
00691         return (false);
00692     
00693     return (true);
00694     } /*opstart*/
00695 
00696 
00697 
00698 
00699 
00700 

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