op.c

Go to the documentation of this file.
00001 
00002 /*  $Id: op.c 1209 2006-04-05 23:59:59Z karstenw $    */
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 "memory.h"
00032 #include "quickdraw.h"
00033 #include "scrap.h"
00034 #include "strings.h"
00035 #include "smallicon.h"
00036 #include "cursor.h"
00037 #include "kb.h"
00038 #include "ops.h"
00039 #include "mouse.h"
00040 #include "sounds.h"
00041 #include "timedate.h"
00042 #include "shell.h"
00043 #include "shellundo.h"
00044 #include "shell.rsrc.h"
00045 #include "lang.h"
00046 #include "langinternal.h"
00047 #include "op.h"
00048 #include "opinternal.h"
00049 #include "opicons.h"
00050 #include "oplineheight.h"
00051 #include "opdraggingmove.h"
00052 #include "scripts.h"
00053 #include "tablestructure.h" //7.0d5 AR
00054 #include "frontierwindows.h" /*7.0b10 PBS*/
00055 
00056 
00057 #ifdef appletinclude
00058     
00059     #define mousedoubleclick()      (mousestatus.fldoubleclick);
00060     #define mousestilldown()        (StillDown())
00061     #define pointinrect(pt, r)      (PtInRect (pt, &r)
00062     #define gettickcount()          (TickCount ())
00063     #define langzoomobject(bs)      ((void *) 0)
00064     #define uppercasechar(ch)       (toupper(ch))
00065 
00066 #endif
00067 
00068 
00069 WindowPtr outlinewindow; 
00070 
00071 hdloutlinerecord outlinedata; 
00072 
00073 hdlwindowinfo outlinewindowinfo; 
00074 
00075 
00076 
00077 tyopuserprefs opprefs = { true, false };
00078 
00079 static boolean flvisiforiconclick = false; /*makes it possible for 2clicking on icon 2 not be interrupted by horiz visi'ing*/
00080 
00081 
00082 
00083 
00084 static boolean opcantedittext (hdlheadrecord hnode) {
00085     
00086     register hdloutlinerecord ho = outlinedata;
00087     
00088     if ((**ho).flreadonly)
00089         return (true);
00090     
00091     return (!(*(**ho).caneditcallback) (hnode));
00092     } /*opcantedittext*/
00093     
00094 
00095 static boolean opcanteditcursor (void) {    
00096     
00097     return (opcantedittext ((**outlinedata).hbarcursor));
00098     } /*opcanteditcursor*/
00099     
00100 
00101 void opdirtyoutline (void) {
00102     
00103     /*
00104     2.1b4 dmb: update timelastsave on each change
00105     
00106     7.0b6 PBS: scripts can dirty a read-only outline.
00107     */
00108     
00109     register hdloutlinerecord ho = outlinedata;
00110     if (outlinedata==0) return;
00111     
00112     /*assert (!(**ho).flreadonly);*/ /*can't dirty a read-only outline*/
00113     /*7.0b6 PBS: scripts can dirty a read-only outline.*/
00114     
00115     if ((**ho).flwindowopen && (outlinewindowinfo != nil)) /*the window is dirty*/
00116         windowsetchanges (outlinewindow, true);
00117     
00118     (**ho).fldirty = true; /*the outline structure is dirty*/
00119     
00120     (**ho).flrecentlychanged = true; /*in case someone is maintaining a parallel structure*/
00121     
00122     (**ho).timelastsave = timenow (); /*modification time until saved*/
00123     } /*opdirtyoutline*/
00124 
00125 
00126 void opdirtyview (void) {
00127     
00128     /*
00129     the user has made a view-only change: cursor move, scroll, window resize, 
00130     expand, collapse, etc.  we want to record this fact, but will let opverbs 
00131     decide whether or not it's important.
00132     */
00133     
00134     (**outlinedata).fldirtyview = true; /*the outline structure is dirty*/
00135     } /*opdirtyview*/
00136 
00137 
00138 boolean opistextmode (void) {
00139     
00140     return ((**outlinedata).fltextmode);
00141     } /*opistextmode*/
00142 
00143 
00144 boolean ophaslinkedtext (hdlheadrecord hnode) {
00145     
00146     return ((*(**outlinedata).haslinkedtextcallback) (hnode));
00147     } /*ophaslinkedtext*/
00148     
00149 
00150 void opvisibarcursor (void) {
00151 
00152     boolean flhoriz = true;
00153 
00154     if ((**outlinedata).flhorizscrolldisabled)
00155         flhoriz = false;
00156     
00157     opvisinode ((**outlinedata).hbarcursor, flhoriz); 
00158     } /*opvisibarcursor*/
00159 
00160 
00161 void opschedulevisi (void) {
00162     
00163     (**outlinedata).flcheckvisi = true;
00164     
00165     (**outlinedata).timevisi = gettickcount ();
00166     
00167     if (flvisiforiconclick) {
00168         
00169         flvisiforiconclick = false; /*consume it*/
00170         
00171         (**outlinedata).timevisi += getmousedoubleclicktime ();
00172         }       
00173     } /*opschedulevisi*/
00174 
00175 
00176 static void opcheckvisi (void) {
00177     
00178     register hdloutlinerecord ho = outlinedata;
00179     
00180     if ((**ho).flcheckvisi && (**ho).flactive) {
00181         
00182         if (gettickcount () > (**ho).timevisi) {
00183         
00184             opvisibarcursor ();
00185         
00186             (**ho).flcheckvisi = false;
00187             }
00188         }
00189     } /*opcheckvisi*/
00190 
00191 
00192 void oppoststylechange (void) {
00193     
00194     /*
00195     5.0a13 dmb: preserve recentlychanged so style change won't force recompile
00196     */
00197     
00198     hdloutlinerecord ho = outlinedata;
00199     boolean flrecentlychanged = (**ho).flrecentlychanged;
00200 
00201     opsaveeditbuffer ();
00202     
00203     operasedisplay ();
00204     
00205     /*opsmashdisplay ();*/
00206     
00207     if (!(**ho).flreadonly) {
00208         
00209         opdirtyoutline ();
00210 
00211         (**ho).flrecentlychanged = flrecentlychanged; //don't dirty this flag on our account
00212         }
00213     
00214     (**outlinewindowinfo).selectioninfo.fldirty = true;
00215     
00216     opsetdisplaydefaults (ho);
00217     
00218     (*(**ho).postfontchangecallback) ();
00219     
00220     opgetscrollbarinfo (true);
00221     
00222     oprestorescrollposition ();
00223     
00224     opredrawscrollbars ();
00225 
00226     oprestoreeditbuffer ();
00227 
00228     opupdatenow ();
00229     } /*oppoststylechange*/
00230 
00231 
00232 static boolean undosetfont (Handle hdata, boolean flundo) {
00233     
00234     if (flundo)
00235         opsetfont ((short) ((long) hdata));
00236     
00237     return (true);
00238     } /*undosetfont*/
00239 
00240 
00241 boolean opsetfont (short fontnum) { 
00242     
00243     /*
00244     DW 8/21/93: allow font change for read-only outlines.
00245     */
00246     
00247     hdloutlinerecord ho = outlinedata;
00248     
00249     if ((**ho).fontnum == fontnum)
00250         return (false);
00251     
00252     pushundostep (&undosetfont, (Handle) ((long) (**ho).fontnum));
00253     
00254     (**ho).fontnum = fontnum;
00255     
00256     oppoststylechange ();
00257     
00258     return (true);
00259     } /*opsetfont*/
00260 
00261 
00262 static boolean undosetsize (Handle hdata, boolean flundo) {
00263     
00264     if (flundo)
00265         opsetsize ((short) ((long) hdata));
00266     
00267     return (true);
00268     } /*undosetsize*/
00269 
00270 
00271 boolean opsetsize (short fontsize) {
00272     
00273     hdloutlinerecord ho = outlinedata;
00274     
00275     if ((**ho).fontsize == fontsize)
00276         return (false);
00277     
00278     pushundostep (&undosetsize, (Handle) ((long) (**ho).fontsize));
00279     
00280     (**ho).fontsize = fontsize;
00281     
00282     oppoststylechange ();
00283     
00284     return (true);
00285     } /*opsetsize*/
00286     
00287 
00288 boolean opsetselectioninfo (void) {
00289 
00290     tyselectioninfo x;
00291     
00292     clearbytes (&x, sizeof (x)); /*initialize all fields to zero*/
00293     
00294     x.flcansetfont = true;
00295     
00296     x.flcansetsize = true;
00297     
00298     x.fontnum = (**outlinedata).fontnum; 
00299     
00300     x.fontsize = (**outlinedata).fontsize; 
00301     
00302     (**outlinewindowinfo).selectioninfo = x;
00303     
00304     return (true);
00305     } /*opsetselectioninfo*/
00306 
00307 
00308 boolean opsettextmode (boolean fltextmode) {
00309     
00310     /*
00311     switches between textmode and structure mode and vice versa.
00312     
00313     just hacks its way into opmoveto, which is equipped to deal with
00314     a mode change.
00315     */
00316     
00317     register hdloutlinerecord ho = outlinedata;
00318     
00319     if (opcanteditcursor ())
00320         return (true);
00321     
00322     if (fltextmode == (**ho).fltextmode) /*we're already in requested mode*/
00323         return (true);
00324     
00325     (**ho).flcursorneedsdisplay = true; /*make sure opmoveto does something*/
00326     
00327     (**ho).fltextmode = fltextmode;
00328     
00329     if (fltextmode)
00330         opclearallmarks ();
00331     
00332     opmoveto ((**ho).hbarcursor);
00333     
00334     opeditresetselpoint (); /*cursoring up & down should stick to new horiz position*/
00335     
00336     opschedulevisi ();
00337     
00338     return (true);
00339     } /*opsettextmode*/
00340 
00341 
00342 void optoggletextmode (void) {
00343     
00344     opsettextmode (!opistextmode ());
00345     } /*optoggletextmode*/
00346 
00347 
00348 static struct {
00349     
00350     long offset;
00351     
00352     hdlheadrecord hnode;
00353     } scanstate;
00354 
00355 
00356 static boolean opfindoffsetvisit (hdlheadrecord hnode, ptrvoid refcon) {
00357 #pragma unused (refcon)
00358 
00359     bigstring bs;
00360     short len;
00361     
00362     scanstate.hnode = hnode;
00363     
00364     scanstate.offset -= (**hnode).headlevel; /*account for leading tabs*/
00365     
00366     if (opnestedincomment (hnode))
00367         setemptystring (bs);
00368     else
00369         getheadstring (hnode, bs);
00370     
00371     len = stringlength (bs) + 1; /*leading tabs, text, trailing cr*/
00372     
00373     if (scanstate.offset <= len)
00374         return (false); /*terminate the traversal*/
00375     
00376     scanstate.offset -= len; 
00377     
00378     return (true); /*continue the traversal*/
00379     } /*opfindoffsetvisit*/
00380 
00381 
00382 #if isFrontier
00383 
00384 boolean opshowerror (long lnum, short charnum) {
00385     
00386     /*
00387     map a line number and character position onto a spot in the current
00388     outline structure.  we traverse the outline, counting nodes until we
00389     hit the line numbered "lnum".  then we expand to that node.
00390     
00391     if charnum is greater than zero, we position the text mode cursor on
00392     the indicated character.
00393     
00394     10/23/91 dmb: if charnum is less than zero, make sure we're not in 
00395     edit mode.
00396     
00397     2.1b5 dmb: handle encoded absolute offset for non-UserTalk outlines
00398     */
00399     
00400     hdlheadrecord hnodeerror;
00401     
00402     if ((**outlinedata).outlinesignature != typeLAND) {
00403         
00404         scanstate.offset = langgetsourceoffset (lnum, charnum);
00405         
00406         opsiblingvisiter ((**outlinedata).hsummit, false, &opfindoffsetvisit, nil);
00407         
00408         hnodeerror = scanstate.hnode;
00409         
00410         charnum = (short) scanstate.offset;
00411         }
00412     else {
00413         
00414         if (!opgetnthnode (lnum, &hnodeerror))
00415             return (false);
00416         }
00417     
00418     opclearallmarks ();
00419     
00420     opexpandto (hnodeerror);
00421     
00422     if (charnum >= 0) {
00423         
00424         opsettextmode (true);
00425         
00426         opeditsetselection (charnum, charnum);
00427         }
00428     else
00429         opsettextmode (false);
00430     
00431     return (true);
00432     } /*opshowerror*/
00433 
00434 #endif
00435 
00436 
00437 boolean opsetscrap (hdlheadrecord hnode) {
00438     
00439     /*
00440     7/9/91 dmb: in order to reliably dispose and export menubar scraps, 
00441     outline scraps are now hdloutlinerecords, not hdlheadrecords.  this 
00442     could use further cleanup; ultimately, we'd like to put packed outlines 
00443     onto the clipboard along with text
00444     
00445     9/9/91 dmb: we've been putting packed outlines onto the clipboard for 
00446     export for a while now.  now we want to maintain formatting info in the 
00447     structured scrap so it doesn't get lost when pasted into a table cell.
00448     
00449     2.1b5 dmb: grab the source outline's signature (can affect text scrap 
00450     conversion)
00451     
00452     5.0.2b17 dmb: set ctexpanded
00453     */
00454     
00455     register hdloutlinerecord ho;
00456     hdloutlinerecord houtline;
00457     
00458     if (hnode == nil) /*defensive driving*/
00459         return (false);
00460     
00461     if (!newoutlinerecord (&houtline))
00462         return (false);
00463     
00464     ho = houtline; /*copy into register*/
00465     
00466     (**ho).copyrefconcallback = (**outlinedata).copyrefconcallback;
00467     
00468     (**ho).textualizerefconcallback = (**outlinedata).textualizerefconcallback;
00469     
00470     (**ho).releaserefconcallback = (**outlinedata).releaserefconcallback;
00471     
00472     (**ho).outlinesignature = (**outlinedata).outlinesignature;
00473     
00474     opsetsummit (ho, hnode);
00475     
00476     opcopyformatting (outlinedata, ho); /*9/9/91*/
00477     
00478     opsetctexpanded (ho);
00479     
00480     (**ho).flbuildundo = false;
00481     
00482     return ((*(**outlinedata).setscrapcallback) (ho));
00483     } /*opsetscrap*/
00484 
00485 
00486 boolean opgetscrap (hdlheadrecord *hnode, boolean *fltempscrap) {
00487     
00488     /*
00489     7/9/91 dmb: outline scraps are now hdloutlinerecords, not hdlheadrecords
00490     */
00491     
00492     boolean fl;
00493     Handle hscrap;
00494     boolean fltemptext;
00495     hdloutlinerecord houtline;
00496     
00497     /*first see if scrap is, or can be converted to, an outline*/
00498     
00499     if ((*(**outlinedata).getscrapcallback) (&houtline, fltempscrap)) {
00500         
00501         *hnode = (**houtline).hsummit;
00502         
00503         if (*fltempscrap) {
00504             
00505             (**houtline).hsummit = nil; /*we've stolen it*/
00506             
00507             opdisposeoutline (houtline, false);
00508             }
00509         
00510         return (true); /*scrap manager was able to handle it*/
00511         }
00512     
00513     /*if actual scrap is (or can be converted to) text, convert to an outline*/
00514     
00515     if (!shellconvertscrap (textscraptype, &hscrap, &fltemptext))
00516         return (false);
00517     
00518     *fltempscrap = true;
00519     
00520     fl = optexttooutline (outlinedata, hscrap, hnode); /*memory leak?*/
00521 
00522     if (fltemptext)
00523         disposehandle (hscrap);
00524     
00525     return (fl);
00526     } /*opgetscrap*/
00527 
00528 
00529 static void opmarklevel (hdlheadrecord hnode) {
00530     
00531     hnode = op1stsibling (hnode);
00532     
00533     while (true) {
00534         
00535         opsetmark (hnode, true); /*set the marked bit*/
00536         
00537         if (!opchasedown (&hnode))
00538             break;
00539         }
00540     } /*opmarklevel*/
00541 
00542 
00543 static boolean opfindclickvisit (hdlheadrecord hnode, ptrvoid hclicked) {
00544     
00545     /*
00546     5.0a25 dmb: part of the shift-click operation, just find the 
00547     clicked node so we know what direction to go in
00548     */
00549     
00550     return (hnode != (hdlheadrecord) hclicked);
00551     } /*opfindclickvisit*/
00552 
00553 
00554 static boolean opancestormarked (hdlheadrecord hnode) {
00555     
00556     /*
00557     return true iff one of my ancestors is marked
00558     */
00559     
00560     while (opchaseleft (&hnode)) {
00561         
00562         if ((**hnode).flmarked)
00563             return (true);
00564         }
00565     
00566     return (false);
00567     } /*opancestormarked*/
00568 
00569 
00570 static boolean opshiftclickvisit (hdlheadrecord hnode, ptrvoid hclicked) {
00571     
00572     /*
00573     5.0a25 dmb: as part of the shift-click operation, we know that
00574     there aren't already any marked nodes except those we just visited
00575     
00576     5.0b1 dmb: we must keep maintain the rule: no children of marked 
00577     nodes can be marked
00578     */
00579     
00580     if (!opancestormarked (hnode)) {
00581     
00582         opclearmarks (hnode); /*make sure nothing subordinated is marked*/
00583         
00584         (**hnode).flmarked = true;
00585         
00586         if (++(**outlinedata).ctmarked == 1) // only thing marked now; barcursor was subordinate
00587             (**outlinedata).hbarcursor = hnode;
00588         }
00589     
00590     return (hnode != (hdlheadrecord) hclicked);
00591     } /*opshiftclickvisit*/
00592 
00593 
00594 static void opshiftclick (hdlheadrecord hnode, boolean flmarklevel) {
00595     
00596     hdlscreenmap hmap;
00597     hdlheadrecord hcursor = (**outlinedata).hbarcursor;
00598     tydirection dir;
00599     
00600     opnewscreenmap (&hmap);
00601     
00602     if (flmarklevel)
00603         opmarklevel (hnode);
00604     else {
00605         opdisabledisplay ();
00606                 
00607         opclearallmarks ();
00608         
00609         openabledisplay ();
00610         
00611         dir = flatdown;
00612         
00613         if (opbumpvisit (hcursor, dir, &opfindclickvisit, (ptrvoid) hnode))
00614             dir = flatup;
00615         
00616         opbumpvisit (hcursor, dir, opshiftclickvisit, (ptrvoid) hnode);
00617         }
00618     
00619     opanymarked ();
00620     
00621     opinvalscreenmap (hmap); /*inval all the dirty lines*/
00622     } /*opshiftclick*/
00623 
00624 
00625 static boolean opcmdclick (hdlheadrecord hnode) {
00626     
00627     /*
00628     5.0.2b8 dmb: try to make 2clicks always leave the node selected, and
00629     allow zooming
00630     
00631     7.0b15 PBS: if cmd-clicking, and the previous headline was in edit mode, ignore the click.
00632     This fixes a crashing bug, when hbarcursor != heditcursor.
00633     */
00634     
00635     hdlscreenmap hmap;
00636     hdlheadrecord hcursor = (**outlinedata).hbarcursor;
00637     
00638     opnewscreenmap (&hmap);
00639 
00640     if (((**outlinedata).hbuffer) && (hcursor != hnode)) /*7.0b15 PBS: was edit mode on? Then ignore the cmd key.*/
00641         goto noclick;
00642     
00643     if (!opanymarked ()) {
00644         
00645         if (hcursor != hnode)
00646             opsetmark (hcursor, true); // set the marked bit
00647         else
00648             goto noclick; // no change
00649         }
00650     
00651     if (mousedoubleclick ()) { //be sure to leave it selected
00652         
00653         (**outlinedata).hbarcursor = hnode;
00654         
00655         opsetmark (hnode, true);
00656 
00657         opinvalscreenmap (hmap);
00658         
00659         return (false); //  not consumed
00660         }
00661     
00662     opsetmark (hnode, !opgetmark (hnode)); /*toggle the marked bit*/
00663     
00664     if (opgetmark (hnode))
00665         (**outlinedata).hbarcursor = hnode;
00666     
00667 
00668 /*
00669     if (opgetmark (hnode))
00670         (**outlinedata).hbarcursor = hnode;
00671     else {
00672         if (mousedoubleclick ()) { //leave it selected
00673             
00674             opsetmark (hnode, true);
00675 
00676             goto noclick;
00677             }
00678         }
00679 */
00680     
00681     opinvalscreenmap (hmap); /*inval all the dirty lines*/
00682     
00683     return (true); // made a change
00684 
00685     noclick:
00686     
00687         disposehandle ((Handle) hmap);
00688 
00689         return (false);
00690     } /*opcmdclick*/
00691 
00692 
00693 void opresize (Rect r) {
00694     
00695     if (outlinedata != NULL) {
00696 
00697         #ifdef gray3Dlook
00698             insetrect (&r, 3, 3);
00699         #endif
00700         
00701         (**outlinedata).outlinerect = r;
00702         
00703         opsetdisplaydefaults (outlinedata);
00704         
00705         oppostfontchange (); //if in edit mode, adjust display area
00706         
00707         #ifndef appletinclude /*applet toolkit will call the reset scroll bar routine after resizing*/
00708         
00709             opresetscrollbars (); /*need this since scroll range depends on screenlines*/
00710         
00711         #endif
00712         
00713         #ifdef fldebug
00714             opvalidate (outlinedata);
00715         #endif
00716         }
00717     } /*opresize*/
00718     
00719 
00720 /*void opupdate (void) {
00721     
00722     opindenteddisplay ();
00723     } /%opupdate%/
00724 */
00725     
00726     
00727 boolean opdefaultadjustcursor (hdlheadrecord hnode, Point pt, const Rect *textrect) {
00728     
00729     /*
00730     5.0a4 dmb: recoded with slop, more consitency with opdefaultmouseinline
00731     
00732     also, we must always shape cursor if we return true, which we want to do
00733     since we're taking responsibility
00734     */
00735     
00736     Rect r = *textrect;
00737     
00738     r.left -= textleftslop;
00739     
00740     if (!opistextmode ()) /*more liberal with ibeams when in text mode*/
00741         r.right = r.left + opgetlinewidth (hnode) + textrightslop;
00742     
00743     if (pointinrect (pt, r))
00744         setcursortype (cursorisibeam);
00745     else
00746         setcursortype (cursorisarrow);
00747     
00748     return (true);
00749     } /*opdefaultadjustcursor*/
00750     
00751     
00752 boolean opsetcursor (Point pt) {
00753     
00754     /*
00755     set the mouse cursor according to the structure.  for example, if it is
00756     over text, use the I-beam.  if it isn't use the standard arrow.
00757     
00758     returns true if we set the cursor, false otherwise.
00759     */
00760     
00761     Rect linerect, textrect;
00762     hdlheadrecord hnode;
00763     
00764     if (!opdisplayenabled ())
00765         return (true);
00766     
00767     hnode = oppointnode (pt);
00768     
00769     if (hnode == nil) /*not pointing at a node at all*/
00770         goto arrow;
00771         
00772     if (opcantedittext (hnode))
00773         goto arrow;
00774         
00775     opgetnoderect (hnode, &linerect);
00776     
00777     opgettextrect (hnode, &linerect, &textrect);
00778     
00779     if ((*(**outlinedata).adjustcursorcallback) (hnode, pt, &textrect))
00780         return (true);
00781     
00782     arrow:
00783     
00784     setcursortype (cursorisarrow);
00785         
00786     return (true);
00787     } /*opsetcursor*/
00788 
00789 
00790 boolean opmousedown (Point pt, tyclickflags flags) {
00791     
00792     /*
00793     8/7/92 dmb: don't exit after expand/collapse; still allow drag
00794     
00795     8/28/92 dmb: added multiple selection code
00796     
00797     DW 8/30/93: if the cursor moved on this mouse click, don't allow 
00798     a double-click.
00799     
00800     5.0a2 dmb: exit after icon2clickcallback returns true; it may have 
00801     destroyed our context. anyway, we're done.
00802     */
00803     
00804     register hdloutlinerecord ho = outlinedata;
00805     hdlheadrecord origbarcursor = (**ho).hbarcursor;
00806     boolean fltextmode = (**ho).fltextmode;
00807     long initialticks = gettickcount (); 
00808     Rect iconrect, textrect;
00809     hdlheadrecord hcursor;
00810     long i;
00811     Rect r;
00812 
00813 #ifdef MACVERSION /*7.0b11 PBS: check for ctrl-clicking on Macs*/
00814 
00815     if (keyboardstatus.ctmodifiers && keyboardstatus.flcontrolkey)
00816 
00817         return (oprmousedown (pt, flags)); /*Call right-click routine.*/
00818 
00819 #endif
00820     
00821     if (!pointinrect (pt, (**ho).outlinerect))
00822         return (false);
00823     
00824     opdirtyview ();
00825     
00826     openabledisplay (); /*make sure no scripts have left us crippled*/
00827     
00828     /*determine the line number and rectangle for the mouse click*/ {
00829     
00830         long screenlines = opgetcurrentscreenlines (false) + 1;
00831         
00832         for (i = 0; i < screenlines; i++) {
00833             
00834             opgetlinerect (i, &r);
00835             
00836             if (pt.v <= r.bottom) /*we've reached the right line*/
00837                 goto L2;
00838             } /*for*/
00839                     
00840         opclearallmarks (); /*not pointing at any line, unmark everything and return*/
00841         
00842         return (true);;
00843         }
00844     
00845     L2:
00846     
00847     hcursor = oprepeatedbump (flatdown, i, (**ho).hline1, true);
00848     
00849     opgeticonrect (hcursor, &r, &iconrect);
00850     
00851     if (pointinrect (pt, iconrect)) {
00852 
00853         fltextmode = false; /*switch into structure mode*/
00854         
00855         flvisiforiconclick = true; 
00856         
00857         goto L1;
00858         }
00859     
00860     if (opcantedittext (hcursor))
00861         fltextmode = false;
00862     
00863     else {
00864         if (fltextmode || (!keyboardstatus.flshiftkey)) {
00865             
00866             opgettextrect (hcursor, &r, &textrect);
00867             
00868             if (!(*(**ho).mouseinlinecallback) (hcursor, pt, &textrect, &fltextmode))
00869                 return (true);
00870             }
00871         }
00872         
00873     L1:
00874     
00875     if (fltextmode != (**ho).fltextmode) { /*changed!*/
00876         
00877         (**ho).flcursorneedsdisplay = true; /*make sure opmoveto does something*/
00878         
00879         (**ho).fltextmode = fltextmode;
00880         
00881         opwriteeditbuffer ();
00882         }
00883     
00884     if (fltextmode) {
00885         
00886         opclearallmarks ();
00887         
00888         opmoveto (hcursor); /*potentially re-position the bar cursor*/ 
00889         
00890         opupdatenow (); /*be sure any changes are visible now*/
00891         
00892         opeditclick (pt, flags);
00893         
00894         if (keyboardstatus.ctmodifiers && mousestatus.fldoubleclick) {
00895         
00896             bigstring bs;
00897             
00898             if ((*(**ho).doubleclickcallback) ()) {
00899                 
00900                 opeditgetseltext (bs);
00901                 
00902                 langzoomobject (bs);
00903                 
00904                 opsetoutline (ho); /*zoomobject script may have changed it*/
00905                 }
00906             }
00907         
00908         return (true);
00909         }
00910     
00911     if (keyboardstatus.flcmdkey) {
00912         
00913         if ((*(**outlinedata).cmdclickcallback) (hcursor))
00914             return (true);
00915         
00916         if (opcmdclick (hcursor))
00917             goto drag;
00918         }
00919     
00920     if (keyboardstatus.flshiftkey) {
00921         
00922         opshiftclick (hcursor, mousestatus.fldoubleclick);
00923         
00924         goto drag;
00925         }
00926     
00927     if (keyboardstatus.ctmodifiers == 0)
00928         if (!opgetmark (hcursor))
00929             opclearallmarks ();
00930     
00931     opmoveto (hcursor); /*potentially re-position the bar cursor*/ 
00932     
00933     opupdatenow (); /*be sure any changes are visible now*/
00934     
00935     if (mousestatus.fldoubleclick) {
00936         if (langopruncallbackscripts (idopstruct2clickscript))
00937             return (true);  /*fuction consumed the click*/
00938 
00939         if ((*(**ho).icon2clickcallback) (hcursor)) /*callback consumed double-click*/
00940             return (true);
00941         
00942         if ((**outlinedata).hbarcursor == origbarcursor) /*cursor didn't move on this mouse click*/
00943             opexpandtoggle ();
00944         }
00945     
00946     drag:
00947     
00948     if ((**ho).flreadonly)
00949         return (true);
00950     
00951     while (mousestilldown ()) { /*wait until it qualifies as a dragging move*/
00952         
00953         opupdatenow ();
00954         
00955         if (opisdraggingmove (pt, initialticks)) {
00956             
00957             setcursortype (cursorfordraggingmove);
00958             
00959             opdraggingmove (pt, (**ho).hbarcursor);
00960             
00961             break;
00962             }
00963         } /*while*/
00964     
00965     return (true);
00966     } /*opmousedown*/
00967 
00968 
00969 static boolean opcmdmove (tydirection dir) {
00970     
00971     if (!opreorgcursor (dir, 1)) {
00972         
00973         shellouch ();
00974         
00975         return (false);
00976         }
00977     
00978     return (true);
00979     } /*opcmdmove*/
00980     
00981     
00982 boolean opmotionkey (tydirection dir, long units, boolean flextendselection) {
00983     
00984     register hdloutlinerecord ho = outlinedata;
00985     register hdlheadrecord hbarcursor = (**ho).hbarcursor;
00986     register boolean fltextmode = (**ho).fltextmode;
00987     hdlheadrecord hnewcursor;
00988     Point selpt;
00989     register boolean flmoved = false;
00990     
00991     opdirtyview ();
00992     
00993     while (--units >= 0) {
00994             
00995         if (!opmovecursor (hbarcursor, dir, 1, &hnewcursor)) 
00996             break;
00997         
00998         flmoved = true;
00999         
01000         if (flextendselection) {
01001             
01002             if (opgetmark (hnewcursor))
01003                 opsetmark (hbarcursor, false);          
01004             else {          
01005                 opsetmark (hbarcursor, true);
01006                 
01007                 opsetmark (hnewcursor, true);
01008                 }
01009             
01010             opinvalnode (hbarcursor); /*leave trail of invals*/
01011             }
01012         else
01013             opclearallmarks ();
01014         
01015         hbarcursor = hnewcursor;
01016         }
01017     
01018     if (!flmoved)
01019         return (false);
01020     
01021     if (fltextmode)
01022         opeditgetselpoint (&selpt);
01023     
01024     opmoveto (hnewcursor);
01025     
01026     if (fltextmode)
01027         
01028         switch (keyboardstatus.keydirection) {
01029             
01030             case left:
01031                 opeditsetselection (infinity, infinity);
01032                 
01033                 break;
01034             
01035             case right:
01036                 opeditsetselection (0, 0);
01037                 
01038                 break;
01039             
01040             case down: case flatdown:
01041                 opeditsetselection (0, 0); //start at first line...
01042                 
01043                 opeditsetselpoint (selpt); //... maintaining horizontal cursor position*/
01044                 
01045                 break;
01046             
01047             case up: case flatup:
01048                 opeditsetselection (infinity, infinity); //start at last line
01049                 
01050                 opeditsetselpoint (selpt); //... maintaining horizontal cursor position
01051                 
01052                 break;
01053 
01054             default:
01055                 /* do nothing */
01056                 break;
01057             } 
01058         
01059     return (true);
01060     } /*opmotionkey*/
01061 
01062 
01063 /*
01064 boolean opdefaultreturnkey (tydirection dir) {
01065     
01066     boolean flcomment = keyboardstatus.flshiftkey;
01067     
01068     return (opinsertheadline (emptystring, dir, flcomment));
01069     } /%opdefaultreturnkey%/
01070 */
01071 
01072 
01073 static void opreturnkey (void) {
01074 
01075     /*
01076     7.1b7 PBS: run a callback after a headline is created.
01077     */
01078     
01079     register tydirection dir;
01080     register hdloutlinerecord ho = outlinedata;
01081     Handle hstring;
01082     boolean flcomment = keyboardstatus.flshiftkey;
01083 /*
01084     boolean flsplit = keyboardstatus.flcmdkey && (**ho).fltextmode;
01085 */  
01086     (**ho).fltextmode = true;
01087     
01088     dir = right;
01089     
01090     if (!opsubheadsexpanded ((**ho).hbarcursor))
01091         dir = down;
01092         
01093     langopruncallbackscripts (idopreturnkeyscript); /* DW 1/19/00, let the opReturnKey callbacks have a chance to hook in */
01094     
01095 /*  if (flsplit) { /% AR 2/16/00, split the current headline at the cursor position %/
01096     
01097         long maxpos, startsel, endsel;
01098         
01099         opeditgetmaxpos (&maxpos);
01100         
01101         opeditgetselection (&startsel, &endsel);
01102         
01103         //set current headline to 0..startsel
01104                 
01105         if (!loadfromhandletohandle ((**ho).hbuffer, &startsel, 4, false, &hstring)) {
01106             ouch ();
01107             return;
01108             }
01109         
01110         opinsertheadline (hstring, dir, flcomment);
01111         }
01112     else
01113 */
01114         if (!newemptyhandle (&hstring))
01115             ouch ();
01116         else
01117             opinsertheadline (hstring, dir, flcomment);
01118 
01119     langopruncallbackscripts (idopinsertscript); /*7.1b7: callback after a headline is created.*/
01120 
01121     opdocursor (true);
01122     } /*opreturnkey*/
01123 
01124 
01125 static boolean openterkey (void) {
01126     
01127     optoggletextmode ();
01128     
01129     return (true);
01130     } /*openterkey*/
01131 
01132 
01133 static boolean opmovetovisit (hdlheadrecord hnode, ptrvoid refcon) {
01134 #pragma unused (refcon)
01135 
01136     (**outlinedata).hbarcursor = hnode; /*move cursor to first headline encountered*/
01137     
01138     return (false); /*stop visiting*/
01139     } /*opmovetovisit*/
01140 
01141 
01142 #ifdef version42orgreater
01143 
01144 static boolean oppartialsortedsearch (hdlheadrecord hfirst, bigstring bsname, short seek, hdlheadrecord *hnode) {
01145     
01146     /*
01147     2/5/97 dmb: logic cloned from tableeditsortedsearch
01148     
01149     just like opfindhead except that instead of looking for an exact match, 
01150     we find the first item that begins with the substring bsname.  if nothing 
01151     matches, return the first item that sorts aphabetically after bsname, or the 
01152     last item in the list.
01153     */
01154     
01155     register hdlheadrecord nomad, nextnomad;
01156     bigstring bskey;
01157     hdlheadrecord hbest = nil; /*no candidate found*/
01158     bigstring bsbest;
01159     short comp;
01160     boolean flwantexact = false;
01161     
01162     if (seek == 0) {
01163         
01164         flwantexact = true;
01165         
01166         seek = 1; /*next best thing*/
01167         }
01168     
01169     alllower (bsname);
01170     
01171     nomad = op1stsibling (hfirst);
01172     
01173     while (true) {
01174         
01175         opgetheadstring (nomad, bskey);
01176         
01177         alllower (bskey);
01178         
01179         comp = comparestrings (bskey, bsname);
01180         
01181         if (comp == 0) { /*an exact match*/
01182             
01183             if (flwantexact) {
01184                 
01185                 *hnode = nomad;
01186                 
01187                 return (true);
01188                 }
01189             }
01190         
01191         else if (comp != -seek) { /*a possible candidate*/
01192             
01193             if ((hbest == nil) || (comparestrings (bskey, bsbest) == -seek)) {
01194                 
01195                 copystring (bskey, bsbest);
01196                 
01197                 hbest = nomad;
01198                 }
01199             }
01200         
01201         nextnomad = (**nomad).headlinkdown;
01202         
01203         if (nextnomad == nomad)
01204             break;
01205         
01206         nomad = nextnomad;
01207         } /*while*/
01208     
01209     if (hbest == nil) { /*didn't find any item that would follow bsname*/
01210         
01211         *hnode = nomad; /*select last name*/
01212         
01213         return (false);
01214         }
01215     
01216     *hnode = hbest;
01217     
01218     return (true);
01219     } /*oppartialsortedsearch*/
01220     
01221 
01222 static bigstring bsopselection;
01223 
01224 static long timelastkey = 0L;
01225 
01226 
01227 static boolean opstructuretextkey (byte chkey) {
01228     
01229     /*
01230     add chkey to the typing buffer bstableselect, resetting the buffer 
01231     depending on elapsed time.  select the table entry that whose name 
01232     starts with a string equal to or greater than the resulting string.
01233     the net effect should be much like typing in standard file.
01234     
01235     note that statics  are used to retain information between calls.
01236     
01237     11/17/92 dmb: use time of event, not time we get here
01238     */
01239     
01240     register long timethiskey;
01241     hdlheadrecord hnode;
01242     
01243     timethiskey = shellevent.when; /*gettickcount ()*/
01244     
01245     if ((timethiskey - timelastkey) > (2 * getkeyboardstartrepeattime ()))
01246         setemptystring (bsopselection);
01247     
01248     timelastkey = timethiskey; /*set up for next time*/
01249     
01250     pushchar (chkey, bsopselection);
01251     
01252     oppartialsortedsearch ((**outlinedata).hbarcursor, bsopselection, 0, &hnode);
01253     
01254     opmoveto (hnode);
01255     
01256     return (true);
01257     } /*opstructuretextkey*/
01258 
01259 
01260 #ifdef PIKE
01261 
01262 static boolean opstructuretabkey (tydirection dir) {
01263     
01264     /*
01265     4/27/93 dmb: new feature -- tab/shift-tab to go next, prev alphabetically
01266     */
01267     
01268     hdlheadrecord hcursor = (**outlinedata).hbarcursor;
01269     bigstring bsname;
01270     short seek;
01271     hdlheadrecord hnode;
01272     
01273     setemptystring (bsopselection); /*reset*/
01274     
01275     opgetheadstring (hcursor, bsname); /*start with selected name*/
01276     
01277     if (dir == left) /*go prev, or next*/
01278         seek = -1;
01279     else
01280         seek = +1;
01281     
01282     if (oppartialsortedsearch (hcursor, bsname, seek, &hnode))
01283         opmoveto (hnode);
01284     else
01285         shellouch ();
01286     
01287     return (true);
01288     } /*opstructuretabkey*/
01289 
01290 #endif  /*PIKE*/
01291 #endif  /*version42orgreater*/
01292 
01293 boolean opkeystroke (void) {
01294     
01295     /*
01296     12/30/91 dmb: the backspace key (a.k.a. "Delete") now does an opclear 
01297     when in structure mode.
01298     
01299     6/25/92 dmb: let shift-arrow in text mode always be processed as text key
01300     
01301     8/28/92 dmb: added multiple selection code
01302     
01303     9/11/92 dmb: when cursoring off of multiselection, start from matching end
01304     
01305     7/26/93 DW: support for read-only outlines.
01306     */
01307     
01308     register hdloutlinerecord ho = outlinedata;
01309     char chkb = keyboardstatus.chkb;
01310     boolean fltextmode = (**ho).fltextmode;
01311     register tydirection dir = keyboardstatus.keydirection;
01312     long units;
01313     boolean flextendselection = keyboardstatus.flshiftkey;
01314     boolean floption = keyboardstatus.floptionkey;
01315     boolean flpreexpand = false;
01316     boolean flpostcollapse = false;
01317     boolean fldidsomething = false;
01318     
01319     #ifdef WIN95VERSION
01320         if (keyboardstatus.flcmdkey) {
01321             
01322             if ((keyboardstatus.ctmodifiers == 1) && (dir == up || dir == down))
01323                 return (opscroll (oppositdirection (dir), false, 1));
01324 
01325             floption = true;
01326             }
01327     #endif
01328 
01329     opdirtyview ();
01330     
01331     openabledisplay (); /*make sure no scripts have left us crippled*/
01332     
01333     if ((chkb == chtab) && opprefs.fltabkeyreorg) {
01334         
01335         if (keyboardstatus.flshiftkey)
01336             dir = left;
01337         else
01338             dir = right;
01339         
01340         #ifdef version42orgreater
01341         
01342             #ifdef PIKE
01343                 
01344                 /*PBS 7.0d9: structured tab keys for tables only. All other
01345                 types use the tab key to reorganize headlines.
01346                 What's bad is that sometimes for tables the outlinetype is 0.
01347                 It should be outlineistable.
01348                 This issue needs to be revisited.*/
01349 
01350                 if (      (**ho).flstructuredtextkeys
01351                      && (((**ho).outlinetype == outlineistable) || ((**ho).outlinetype == 0))) {
01352     
01353                     return (opstructuretabkey (dir));
01354                     } /*if*/
01355 
01356             #endif
01357 
01358         #endif
01359         
01360         if ((**ho).flreadonly)
01361             return (true);
01362         
01363         return (opcmdmove (dir));
01364         }
01365     
01366     if (!fltextmode) {
01367         
01368         if (chkb == chbackspace || chkb == chdelete) {
01369             
01370             if (opcanteditcursor ())
01371                 return (true);
01372                 
01373             return (opclear ());
01374             }
01375         
01376         if (dir != nodirection) {
01377             
01378             if (keyboardstatus.flshiftkey) /*extending selection*/
01379                 goto L1;
01380             
01381             else { /*moving off of selection -- make sure we move from right end*/
01382                 
01383                 if ((dir == up) || (dir == right))
01384                     dir = down;
01385                 else
01386                     dir = up;
01387                 
01388                 opvisitmarked (dir, &opmovetovisit, nil);
01389                 }
01390             }
01391         }
01392     
01393     if (opanymarked ()) {
01394         
01395         opclearallmarks ();
01396         
01397         fldidsomething = true;
01398         }
01399     
01400     if (fldidsomething)
01401         opupdatenow ();
01402     
01403     if (chkb == chreturn) {
01404         
01405         if ((**ho).flreadonly)
01406             return (true);
01407         
01408         opreturnkey ();
01409         
01410         return (true);
01411         }
01412     
01413     if (chkb == chenter) {
01414         
01415         if (keyboardstatus.ctmodifiers > 0) { /*at least one modifier key is down*/
01416             
01417             shellouch (); /*it wasn't caught by our owner*/
01418             
01419             return (true);
01420             }
01421         
01422         if (opcanteditcursor ())
01423             return (true);
01424             
01425         return (openterkey ());
01426         }
01427         
01428     if (keyboardstatus.flkeypad) {
01429         
01430         register hdlheadrecord hcursor = (**ho).hbarcursor;
01431         
01432         if (chkb == '+') {
01433             if (langopruncallbackscripts (idopexpandscript))
01434                 return (true);  /*fuction consumed the click*/
01435             
01436             return (opexpand (hcursor, 1, true));
01437             }
01438             
01439         if (chkb == '*') {
01440             if (langopruncallbackscripts (idopexpandscript))
01441                 return (true);  /*fuction consumed the click*/
01442             
01443             return (opexpand (hcursor, infinity, false));
01444             }
01445             
01446         if (chkb == '-') {
01447             if (langopruncallbackscripts (idopcollapsescript))
01448                 return (true);  /*fuction consumed the click*/
01449             
01450             return (opcollapse (hcursor));
01451             }
01452         } /*keypad expand/collapse keys*/
01453     
01454     if (!fltextmode) {
01455         
01456         if (isprint (chkb)) { /*switch into text mode before processing*/
01457             
01458             #ifdef version42orgreater
01459             
01460             if ((**ho).flstructuredtextkeys) {
01461                 
01462                 opstructuretextkey (chkb);
01463                 
01464                 return (true);
01465                 }
01466             
01467             #endif
01468             
01469             if (opcanteditcursor ())
01470                 return (true);
01471             
01472             opsettextmode (true); /*switch into textmode*/
01473             
01474             opeditselectall ();
01475             
01476             fltextmode = true; /*set local copy*/
01477             }
01478         }
01479     
01480     if (fltextmode) {
01481         
01482         if (arrowkey (chkb) && !(**ho).fllimittextarrows && !flextendselection && !opeditcango (dir)) {
01483         
01484             switch (chkb) {
01485                 
01486                 case chuparrow:
01487                     keyboardstatus.keydirection = flatup;
01488                     
01489                     break;
01490                 
01491                 case chdownarrow:
01492                     keyboardstatus.keydirection = flatdown;
01493                     
01494                     break;
01495                 }
01496             
01497             goto L1;
01498             }
01499         
01500         return (opeditkey ()); /*pass keystroke to TextEdit*/
01501         }
01502     
01503     L1: /*process keystroke as a structure command*/
01504     
01505     if (shellfilterscrollkey (chkb))
01506         return (true);
01507     
01508     dir = keyboardstatus.keydirection;
01509     
01510     if (keyboardstatus.flcmdkey)
01511         units = longinfinity;
01512     else
01513         units = 1;
01514     
01515     if (keyboardstatus.flshiftkey) { /*selection overrides modes & optionkey*/
01516         
01517         switch (dir) {
01518             
01519             case up:
01520             case left:
01521                 dir = up;
01522                 
01523                 break;
01524             
01525             case down:
01526             case right:
01527                 dir = down;
01528                 
01529                 break;
01530 
01531             default:
01532                 /* do nothing */
01533                 break;
01534             }
01535         
01536         goto motion;
01537         }
01538     
01539     if (floption && keyboardstatus.flcmdkey) { /*check for surface & dive keys*/
01540         
01541         switch (dir) {
01542             
01543             case down:
01544             case right:
01545                 flpreexpand = true;
01546                 
01547                 units = 1;
01548                 
01549                 break;
01550             
01551             case up:
01552             case left:
01553                 flpostcollapse = true;
01554                 
01555                 units = 1;
01556                 
01557                 break;
01558 
01559             default:
01560                 /* do nothing */
01561                 break;
01562             }
01563         
01564         goto motion;
01565         }
01566     
01567     if (!floption) {
01568     
01569         if (opprefs.flflatcursorkeys) { /*flat motion is default*/
01570             
01571             switch (dir) {
01572                 
01573                 case up:
01574                 case left:
01575                     dir = flatup;
01576                     
01577                     break;
01578                 
01579                 case down:
01580                 case right:
01581                     dir = flatdown;
01582                     
01583                     break;
01584 
01585                 default:
01586                     /* do nothing */
01587                     break;
01588 
01589                 }
01590             }
01591         else { /*default arrow keys, structure mode*/
01592             
01593             if (dir == left)
01594                 dir = flatup;
01595             
01596             if (dir == right)
01597                 dir = flatdown;
01598             }
01599         }
01600     
01601     motion:
01602     
01603     if (flpreexpand) {
01604     
01605         if (langopruncallbackscripts (idopexpandscript))
01606             return (true);
01607             
01608         opexpand ((**ho).hbarcursor, 1, true);
01609         }
01610     
01611     if (opmotionkey (dir, units, flextendselection)) { /*we were able to move*/
01612         
01613         if (flpostcollapse) {
01614             
01615             if (langopruncallbackscripts (idopcollapsescript))
01616                 return (true);
01617             
01618             opcollapse ((**ho).hbarcursor);
01619             }
01620         }
01621     else {
01622         
01623         if (!fldidsomething) /*kinda anti-climatic*/
01624             shellouch ();
01625         }
01626     
01627     return (true);
01628     } /*opkeystroke*/
01629 
01630 
01631 boolean opcmdkeyfilter (char chkb) {
01632     
01633     /*
01634     return false if we consume the cmd-keystroke, true if we want it passed
01635     on to the menubar.
01636     */
01637     
01638     if ((**outlinedata).flreadonly)
01639         return (true);
01640         
01641     switch (uppercasechar (chkb)) {
01642         
01643         case 'U':
01644             opcmdmove (up);
01645             
01646             return (false); /*cmdkey has been consumed*/
01647             
01648         case 'D':
01649             opcmdmove (down);
01650             
01651             return (false); 
01652             
01653         case 'L': case chtab:
01654             opcmdmove (left);
01655             
01656             return (false); 
01657             
01658         case 'R': case chbacktab:
01659             opcmdmove (right);
01660             
01661             return (false); 
01662         
01663         case ',':
01664             opexpandtoggle ();
01665             
01666             return (false);
01667             
01668         } /*switch*/
01669         
01670     return (true); /*we don't consume the keystroke*/
01671     } /*opcmdkeyfilter*/
01672 
01673 
01674 boolean opselectall (void) {
01675     
01676     if (opistextmode ()) { 
01677         
01678         opsettextmode (true);
01679         
01680         opeditselectall ();
01681         }
01682     else {
01683         hdlscreenmap hmap;
01684         
01685         opnewscreenmap (&hmap);
01686         
01687         opmarklevel ((**outlinedata).hbarcursor);
01688         
01689         opinvalscreenmap (hmap);
01690         }
01691     
01692     return (true);
01693     } /*opselectall*/
01694 
01695 
01696 void opgetcursorinfo (long *row, short *col) {
01697     
01698     /*
01699     translate the cursor position into a set of numbers.
01700     */
01701     
01702     opgetscreenline ((**outlinedata).hbarcursor, row);
01703     
01704     *col = 0; /*no info for this yet*/
01705     } /*opgetcursorinfo*/
01706     
01707     
01708 void opsetcursorinfo (long row, short col) {
01709 #pragma unused (col)
01710 
01711     /*
01712     translate a row and column position into the outline's internal data
01713     structure.
01714     */
01715     
01716     (**outlinedata).hbarcursor = 
01717         
01718         oprepeatedbump (flatdown, row, (**outlinedata).hsummit, true);
01719     } /*opsetcursorinfo*/
01720     
01721  
01722 boolean opcloseoutline (void) {
01723     
01724     /*
01725     the outline in outlinedata is going into dormancy -- its window is closing,
01726     but we have to hold on to it, probably because it's dirty.
01727 
01728     save off all window-dependent structures.
01729     */
01730 
01731     opsaveeditbuffer ();
01732     
01733     return (true);
01734     } /*opcloseoutline*/
01735     
01736     
01737 boolean opopenoutline (void) {
01738     
01739     /*
01740     the outline in outlinedata is coming out of dormancy.  undoes what 
01741     opcloseoutline does.
01742     */
01743     
01744     oprestoreeditbuffer ();
01745     
01746     return (true);
01747     } /*opopenoutline*/
01748     
01749 
01750 static void opcheckreopen (void) {
01751     
01752     /*
01753     check to see if outline has been closed and re-opened.  now that its window
01754     is allocated, it's been displayed, it's safe to show the window-dependent
01755     stuff.
01756     */
01757     
01758     if ((**outlinedata).flreopenpending) {
01759         
01760         (**outlinedata).flreopenpending = false; /*must be reset every time*/
01761         
01762         opopenoutline ();
01763         }
01764     } /*opcheckreopen*/
01765 
01766 
01767 void opidle (void) {
01768         
01769     opinvaldirtynodes ();
01770     
01771     opcheckvisi ();
01772     
01773     if ((**outlinedata).fltextmode) 
01774         opeditidle ();
01775     } /*opidle*/
01776 
01777 
01778 void opactivate (boolean flactivate) {
01779     
01780     opcheckreopen ();
01781     
01782     (**outlinedata).flactive = flactivate;
01783     
01784     opresetscrollbars ();
01785     
01786     if ((**outlinedata).fltextmode)
01787         opeditactivate (flactivate);
01788     else {
01789         if (opanymarked ())
01790             opsmashdisplay ();
01791         else
01792             opdocursor (true);
01793         }
01794     
01795     if (flactivate)
01796         opcheckvisi ();
01797     } /*opactivate*/
01798 
01799 

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