tableedit.c

Go to the documentation of this file.
00001 
00002 /*  $Id: tableedit.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 #include "frontier.h"
00029 #include "standard.h"
00030 
00031 #include "memory.h"
00032 #include "ops.h"
00033 #include "strings.h"
00034 #include "shell.h"
00035 #include "shellprivate.h"
00036 #include "shellundo.h"
00037 #include "langexternal.h"
00038 #include "opinternal.h"
00039 #include "tablestructure.h"
00040 #include "tableinternal.h"
00041 #include "wpengine.h"
00042 #include "claybrowser.h"
00043 #include "claycallbacks.h"
00044 
00045 
00046 
00047 boolean tablecelliseditable (hdlheadrecord hnode, short col) {
00048     
00049     /*
00050     return true if there should be an ibeam cursor in this cell.
00051     */
00052     
00053     hdlhashtable htable;
00054     bigstring bs;
00055     tyvaluerecord val;
00056     hdlhashnode hhashnode;
00057     
00058     if (!tablegetiteminfo (hnode, &htable, bs, &val, &hhashnode))
00059         return (false);
00060         
00061     switch (col) {
00062         
00063         case namecolumn: /*names are always editable*/              
00064             return (true);
00065         
00066         case valuecolumn: /*only scalar values are editable*/
00067             return ((val.valuetype != externalvaluetype) && (val.valuetype != codevaluetype));
00068         
00069         default: /*kind is not directly editable*/
00070             return (false);
00071         } /*switch*/
00072     } /*tablecelliseditable*/
00073 
00074 
00075 static boolean getvalueedittext (const tyvaluerecord *val, Handle *htext) {
00076     
00077     /*
00078     return the editable text corresponding to the value.
00079     */
00080     
00081     tyvaluerecord valcopy;
00082     bigstring bsvalue;
00083     
00084     switch ((*val).valuetype) {
00085     
00086         case stringvaluetype:
00087         case listvaluetype:
00088         case recordvaluetype:
00089             if (!copyvaluerecord (*val, &valcopy) || !coercetostring (&valcopy))
00090                 return (false);
00091         
00092             exemptfromtmpstack (&valcopy);
00093             
00094             *htext = valcopy.data.stringvalue;
00095             
00096             break;
00097         
00098         case binaryvaluetype:
00099             if (!bytestohex ((*val).data.binaryvalue, htext))
00100                 return (false);
00101             
00102             pullfromhandle (*htext, 2, 8, nil); /*get rid of the binary type*/
00103             
00104             break;
00105         
00106         default:
00107             hashgetvaluestring (*val, bsvalue);
00108             
00109             if (!newtexthandle (bsvalue, htext))
00110                 return (false);
00111             
00112             break;
00113         }
00114     
00115     return (true);
00116     } /*getvalueedittext*/
00117 
00118 
00119 boolean tablesetwpedittext (hdlheadrecord hnode) {
00120     
00121     /*
00122     2/7/97 dmb: adapted from tableeditentercell, but our role is 
00123     more focused: we just need to put the right text into the wp.
00124     */
00125     
00126     hdltableformats hc = tableformatsdata;
00127     short col = (**hc).focuscol;
00128     hdlhashtable htable;
00129     tyvaluerecord val;
00130     bigstring bs;
00131     boolean fl = false;
00132     Handle htext = nil;
00133     hdlhashnode hhashnode;
00134     
00135     (**hc).focuscol = 0; // reset
00136     
00137     switch (col) {
00138     
00139         case namecolumn:
00140             getheadstring (hnode, bs);
00141             
00142             fl = newtexthandle (bs, &htext);
00143             
00144             break;
00145         
00146         case valuecolumn:
00147             if (!tablegetiteminfo (hnode, &htable, bs, &val, &hhashnode))
00148                 break;
00149             
00150             if (val.valuetype == externalvaluetype) /*can't edit external in its cell*/         
00151                 break;
00152             
00153             pushhashtable (htable);
00154             
00155             fl = getvalueedittext (&val, &htext);
00156             
00157             pophashtable ();
00158             
00159             break;
00160         
00161         default:
00162             break;
00163         }
00164     
00165     if (fl) {
00166         
00167         fl = wpsettexthandle (htext);
00168 
00169         wpscroll (right, false, longinfinity);
00170         }
00171     
00172     if (!fl) { /*out of memory*/
00173         
00174         disposehandle (htext);
00175         
00176         return (false);
00177         }
00178     
00179     (**wpdata).flneverscroll = false; /*we'll handle all scrolling, visiing ourselves*/
00180     
00181     (**wpdata).flalwaysmeasuretext = false; //we don't need the size info
00182     
00183     wpupdate ();
00184     
00185     (**hc).editcol = col;
00186     
00187     (**hc).editnode = hnode;
00188     
00189     (**hc).editval = htext;
00190     
00191     return (true);
00192     } /*tablesetwpedittext*/
00193 
00194 
00195 boolean tablegetwpedittext (hdlheadrecord hnode, boolean flunload) {
00196     
00197     /*
00198     2/7/97 dmb: adapted from tableeditleavecell
00199     
00200     called when some action implies that the user is finished editing the cell.
00201     
00202     we attempt to save off the new value, or new name, potentially causing an 
00203     error if there was a duplicate name, or something bad about the value.
00204     */
00205     
00206     hdltableformats hc = tableformatsdata;
00207     short col = (**hc).editcol;
00208     tybrowserspec fs;
00209     tyvaluerecord val;
00210     bigstring bstext;
00211     boolean fl = false;
00212     Handle htext;
00213     tyvaluerecord newval;
00214     Handle x;
00215     hdlhashtable ht;
00216     boolean flmustexit;
00217     hdlhashnode hhashnode;
00218     
00219     //assert (hnode == (**hc).editnode);
00220     
00221     flmustexit = false; // ***flmustexiteditmode;
00222     
00223     if (!wpgettexthandle (&htext))
00224         return (false);
00225     
00226     texthandletostring (htext, bstext);
00227     
00228     if (!claygetfilespec (hnode, &fs)) { // a new node
00229         
00230         assert (col == namecolumn);
00231         }
00232     else {
00233 
00234         ht = fs.parID;
00235         
00236         if (!hashtablesymbolexists (ht, fs.name)) { /*node is gone!*/
00237             
00238             fl = true;
00239             
00240             goto exit;
00241             }
00242         }
00243     
00244     if (col == namecolumn) {
00245         
00246         if (isemptystring (bstext)) /*name wasn't changed; undo will be bogus*/
00247             killundo ();
00248         else
00249             fl = opsetheadstring (hnode, bstext); // must do first so we can 
00250         
00251         goto exit;
00252         }
00253     
00254     /*we were editing a value - run a script to do the assignment*/
00255     
00256     assert (col == valuecolumn);
00257     
00258     flmustexit = true; /*don't want to stick in edit mode w/out error dialogs*/
00259     
00260     if (equalhandles (htext, (**hc).editval)) { /*no change*/
00261     
00262         fl = true;
00263         
00264         goto exit;
00265         }
00266     
00267     if (!claylookupvalue (&fs, &val, &hhashnode))
00268         goto exit;
00269     
00270     if (isemptystring (bstext) && (val.valuetype != novaluetype) && (val.valuetype != stringvaluetype)) {
00271         
00272         fl = true;
00273         
00274         goto exit;
00275         }
00276     
00277     if (val.valuetype == binaryvaluetype) {
00278     
00279         OSType binarytype = getbinarytypeid (val.data.binaryvalue);
00280         Handle hbytes;
00281         
00282         if (!hextobytes (htext, &hbytes))
00283             goto exit;
00284         
00285         if (!setbinaryvalue (hbytes, binarytype, &newval))
00286             goto exit;
00287         
00288         if (hashtableassign (ht, fs.name, newval)) {
00289             
00290             exemptfromtmpstack (&newval);
00291             
00292             fl = true;
00293             }
00294         
00295         goto exit;
00296         }
00297     
00298     if (!copyhandle (htext, &x))
00299         goto exit;
00300     
00301     tablepushcontext (ht, val.valuetype);
00302     
00303     disablelangerror ();
00304     
00305     shellblockevents (); /*don't want backgrounding during assignment*/
00306     
00307     #ifdef version5orgreater
00308     
00309         if (langrun (x, &newval) && (newval.valuetype != externalvaluetype) && !isemptystring (bstext))
00310             disposehandle (htext);
00311         
00312         else {
00313             if (val.valuetype != stringvaluetype && !isemptystring (bstext)) {
00314             
00315                 byte ch = chdoublequote;
00316                 
00317                 if (copyhandle (htext, &x)) { /*2.1b2: try again, with quotes*/
00318                     
00319                     insertinhandle (x, 0, &ch, 1);
00320                     
00321                     enlargehandle (x, 1, &ch);
00322                     
00323                     if (langrun (x, &newval) && (newval.valuetype != externalvaluetype)) {
00324                         
00325                         disposehandle (htext);
00326                         
00327                         htext = nil;
00328                         }
00329                     }
00330                 }
00331             
00332             if (htext != nil)
00333                 setheapvalue (htext, stringvaluetype, &newval);
00334             }
00335     #else
00336     
00337         if (langrun (x, &newval) && (newval.valuetype != externalvaluetype) && !isemptystring (bstext))
00338             disposehandle (htext);
00339         
00340         else {
00341             byte ch = chdoublequote;
00342             
00343             if (copyhandle (htext, &x)) { /*2.1b2: try again, with quotes*/
00344                 
00345                 insertinhandle (x, 0, &ch, 1);
00346                 
00347                 enlargehandle (x, 1, &ch);
00348                 
00349                 if (langrun (x, &newval) && (newval.valuetype != externalvaluetype) && !isemptystring (bstext)) {
00350                     
00351                     disposehandle (htext);
00352                     
00353                     htext = nil;
00354                     }
00355                 }
00356             
00357             if (htext != nil)
00358                 setheapvalue (htext, stringvaluetype, &newval);
00359             }
00360     #endif
00361     
00362     htext = nil; /*it's been consumed, one way or another*/
00363     
00364     shellpopevents ();
00365     
00366     if ((val.valuetype == novaluetype) || coercevalue (&newval, val.valuetype)) {
00367         
00368         if (hashtableassign (ht, fs.name, newval)) {
00369             
00370             exemptfromtmpstack (&newval);
00371             
00372             fl = true;
00373             }
00374         }
00375     
00376     enablelangerror ();
00377     
00378     if (!fl) {
00379         
00380         sysbeep ();
00381         
00382         /*disposevaluerecord (newval, false);*/
00383         
00384         cleartmpstack ();
00385         }
00386     
00387     tablepopcontext (ht, val.valuetype);
00388     
00389     exit:
00390     
00391     disposehandle (htext);
00392     
00393     if (flunload) { /*exiting edit mode*/
00394         
00395         disposehandle ((**hc).editval);
00396         
00397         (**hc).editval = nil;
00398         
00399         (**hc).editnode = nil;
00400         }
00401     
00402     return (fl);
00403     } /*tablegetwpedittext*/
00404 
00405 
00406 boolean tableeditgetundoglobals (long *globals) {
00407     
00408     /*
00409     callback for undo mechanism.  this routine should stuff into the 
00410     globals parameter enough information to restore the undo context in 
00411     tableeditsetundoglobals below.  in the current undo implementation, there 
00412     is no "disposeundoglobals" callback, so nothing should be allocated by 
00413     this routine.
00414     
00415     for tables, the row & column of the cell being edited is all the 
00416     information we need
00417     
00418     4.1b2 dmb: need more info in globals now that leaving a cell can move it.
00419     */
00420     
00421     (**tableformatsdata).undocol = (**tableformatsdata).editcol;
00422     
00423     return (opeditgetundoglobals (globals));
00424     } /*tableeditgetundoglobals*/
00425 
00426 
00427 boolean tableeditsetundoglobals (long globals, boolean flundo) {
00428     
00429     if (!globals || !flundo)
00430         return (true);
00431     
00432     (**tableformatsdata).focuscol = (**tableformatsdata).undocol;
00433     
00434     return (opeditsetundoglobals (globals, flundo));
00435     } /*tableeditsetundoglobals*/
00436 
00437 

Generated on Wed May 31 18:20:02 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6