tablepopup.c

Go to the documentation of this file.
00001 
00002 /*  $Id: tablepopup.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 #ifdef WIN95VERSION
00032 #include "WinLand.h"
00033 #endif
00034 
00035 #include "cursor.h"
00036 #include "dialogs.h"
00037 #include "kb.h"
00038 #include "memory.h"
00039 #include "menu.h"
00040 #include "ops.h"
00041 #include "popup.h"
00042 #include "quickdraw.h"
00043 #include "resources.h"
00044 #include "strings.h"
00045 #include "threads.h"
00046 #include "frontierwindows.h"
00047 #include "shellhooks.h"
00048 #include "shell.rsrc.h"
00049 #include "langexternal.h"
00050 #include "langinternal.h"
00051 #include "windowlayout.h"
00052 #include "tableinternal.h"
00053 #include "tablestructure.h"
00054 #include "tableverbs.h"
00055 #include "claybrowser.h"
00056 #include "iowaverbs.h" /*3/18/92 dmb*/
00057 
00058 
00059 
00060 #define sortpopuplist 156
00061 
00062 #define ctsorts 3
00063 
00064 #define sortpopuptitlestring (ctsorts + 1)
00065 
00066 
00067 #define kindpopuplist 157
00068 
00069 #define ctkinds 25
00070 
00071 #define kindpopuptitlestring (ctkinds + 1)
00072 
00073 
00074 #define ixfirstefptype 16
00075 
00076 #define ixbinarytype 24
00077 
00078 #define firstefptype outlinevaluetype
00079 
00080 
00081 
00082 typedef struct tykindmenuinfo {
00083     
00084     //byte *bsitem; /*the text of the menu item*/
00085     
00086     tyvaluetype type; /*the associated value type*/
00087     } tykindmenuinfo;
00088 
00089 
00090 static tykindmenuinfo kindmenuinfo [] = { /*menu contents, in menu order*/
00091 
00092      {/*Boolean*/ booleanvaluetype},        /*1*/
00093     
00094      {/*Character*/ charvaluetype},         /*2*/
00095     
00096      {/*Number*/ longvaluetype},            /*3*/
00097     
00098      {/*Float*/ doublevaluetype},           /*4*/
00099     
00100      {/*Date*/ datevaluetype},          /*5*/
00101     
00102      {/*Direction*/ directionvaluetype},    /*6*/
00103     
00104      {/*String*/ stringvaluetype},      /*7*/
00105     
00106      {/*-*/ novaluetype},                   /*8*/
00107     
00108      {/*String4*/ ostypevaluetype},     /*9*/
00109     
00110      {/*Enumerator*/ enumvaluetype},        /*10*/
00111     
00112      {/*File Specifier*/ filespecvaluetype}, /*11*/
00113     
00114      {/*Alias*/ aliasvaluetype},            /*12*/
00115     
00116      {/*Object Specifier*/ objspecvaluetype}, /*13*/
00117     
00118      {/*Address*/ addressvaluetype},        /*14*/
00119     
00120      {/*-*/ novaluetype},                   /*15*/
00121     
00122      {/*Table*/ tablevaluetype},            /*16*/
00123     
00124      {/*WP-Text*/ wordvaluetype},           /*17*/
00125     
00126      {/*Picture*/ pictvaluetype},           /*18*/
00127     
00128      {/*Outline*/ outlinevaluetype},        /*19*/
00129     
00130      {/*Script*/ scriptvaluetype},      /*20*/
00131     
00132      {/*MenuBar*/ menuvaluetype},           /*21*/
00133     
00134      {/*-*/ novaluetype},
00135     
00136      {/*List*/ listvaluetype},              /*23*/
00137     
00138      {/*Record*/ recordvaluetype},          /*24*/
00139     
00140      {/*Binary*/ binaryvaluetype}           /*25*/
00141     };
00142 
00143 #define ctkindmenuitems 25
00144 
00145 static boolean tablemapmenutovaluetype (short ixmenu, tyvaluetype *valuetype) {
00146     
00147     register tyvaluetype vt;
00148     
00149     if (ixmenu > ctkindmenuitems)
00150         return (false);
00151     
00152     vt = kindmenuinfo [ixmenu - 1].type;
00153     
00154     *valuetype = vt;
00155     
00156     return (vt != novaluetype);
00157     } /*tablemapmenutovaluetype*/
00158 
00159 
00160 static boolean tablemapvaluetypetomenu (tyvaluerecord val, short *ixmenu) {
00161     
00162     register short ix;
00163     
00164     if (val.valuetype == externalvaluetype)
00165         val.valuetype = (tyvaluetype) (firstefptype + langexternalgettype (val));
00166     
00167     for (ix = 0; ix < ctkinds; ++ix) {
00168         
00169         if (kindmenuinfo [ix].type == val.valuetype) {
00170             
00171             *ixmenu = ix + 1;
00172             
00173             return (true);
00174             }
00175         }
00176     
00177     *ixmenu = 0;
00178     
00179     return (false);
00180     } /*tablemapvaluetypetomenu*/
00181 
00182 
00183 static boolean coercionpossible (hdlhashtable ht, tyvaluerecord val1, tyvaluetype valuetype2) {
00184     
00185     /*
00186     return true if a variable of type valuetype1 could be coerced to type valuetype2.
00187     
00188     5/6/93 dmb: added support for new types, using brute force approach instead of 
00189     second-guessing the language
00190 
00191     5.0a16 dmb: allow coercion between string and anything
00192     */
00193     
00194     register tyvaluetype vt1 = val1.valuetype;
00195     register tyvaluetype vt2 = valuetype2;
00196     boolean fl;
00197     
00198     if (vt1 == vt2) /*same type, coercion is unnecessary, but certainly possible!*/
00199         return (true);
00200     
00201     if (vt2 == binaryvaluetype) /*everything converts to binary*/
00202         return (true);
00203     
00204     if (vt2 == stringvaluetype) /*everything converts to string*/
00205         return (true);
00206     
00207     if (vt1 == externalvaluetype)
00208         return (firstefptype + langexternalgettype (val1) == vt2);
00209     
00210     if (vt1 == binaryvaluetype) {
00211         
00212         vt1 = langgetvaluetype (getbinarytypeid (val1.data.binaryvalue));
00213         
00214         if (vt1 >= firstefptype)
00215             return (vt1 == vt2);
00216         }
00217 
00218     if (vt1 == stringvaluetype) { /*special cases for converting from a string*/
00219         if (vt2 == wordvaluetype
00220                 || vt2 == outlinevaluetype
00221                 || vt2 == scriptvaluetype) {
00222             return (true);
00223             }
00224         }
00225     
00226     shellpusherrorhook ((errorhookcallback) &falsenoop);
00227     
00228     disablelangerror ();
00229     
00230     tablepushcontext (ht, vt2);
00231     
00232     if (!copyvaluerecord (val1, &val1))
00233         fl = false;
00234     
00235     else {
00236         
00237         fl = coercevalue (&val1, vt2);
00238         
00239         cleartmpstack ();  /*disposevaluerecord (val1, true)*/
00240         }
00241     
00242     tablepopcontext (ht, vt2);
00243     
00244     enablelangerror ();
00245     
00246     shellpoperrorhook ();
00247     
00248     return (fl);
00249     
00250     } /*coercionpossible*/
00251 
00252 
00253 static boolean getcoercionstring (tyvaluetype valuetype, bigstring bs) {
00254     
00255     if (valuetype == enumvaluetype)
00256         return (langgetmiscstring (enumstring, bs));
00257     
00258     return (langgettypestring (valuetype, bs));
00259     } /*getcoercionstring*/
00260 
00261 
00262 static boolean tablefillkindpopup (hdlmenu hmenu, short *checkeditem) {
00263     
00264     tyvaluerecord val;
00265     register short i;
00266     register short ixmenu;
00267     register boolean flenabled;
00268     tyvaluetype valuetype;  
00269     hdlhashtable ht;
00270     bigstring bspath;
00271     bigstring bsitem;
00272     hdlhashnode hnode;
00273     
00274     tablegetcursorinfo (&ht, bspath, &val, &hnode);
00275     
00276     for (i = 0; i < ctkinds; i++) {
00277         
00278         ixmenu = i + 1;
00279         
00280         switch (val.valuetype) {
00281             
00282             case novaluetype:
00283                 flenabled = i <= ixbinarytype;
00284                 
00285                 break;
00286             
00287             default:
00288                 tablemapmenutovaluetype (ixmenu, &valuetype);
00289                 
00290                 flenabled = coercionpossible (ht, val, valuetype);
00291             }
00292         
00293         getstringlist (kindpopuplist, ixmenu, bsitem);
00294         
00295         if (!pushpopupitem (hmenu, bsitem, flenabled, 0))
00296             return (false);
00297         } /*for*/
00298     
00299     tablemapvaluetypetomenu (val, checkeditem);
00300     
00301     return (true); 
00302     } /*tablefillkindpopup*/
00303 
00304 
00305 static boolean tablekindrecalc (tyvaluetype valuetype) {
00306     
00307     /*
00308     create a string that looks like "x.y = long (x.y)" and run it
00309     
00310     for external types, make the string look like "external ("efp", "new", @x.y)"
00311     
00312     12/13/90 dmb: external type coersion now relies on handers: "efp.new (@x.y)".
00313     
00314     1/25/91 dmb: always exit edit mode (not just for external types)
00315     
00316     2.1b2 dmb: establish context for recalc using new tablepush/popcontext
00317     
00318     5.1.5b12 dmb: don't use full path to item, just use name. tablepushcontext always
00319     sets our table now.
00320     */
00321     
00322     register tyvaluetype vt = valuetype;
00323     tyvaluerecord val;
00324     tyexternalid externalid = 0;
00325     hdlhashtable ht;
00326     bigstring bs;
00327     bigstring bspath;
00328     bigstring bsscript;
00329     byte bsefp [16];
00330     ptrstring pbsparse;
00331     boolean fl;
00332     hdlhashnode hnode;
00333     
00334     if (!tableexiteditmode ())
00335         return (false);
00336     
00337     if (vt >= firstefptype) { /*a virtual external value - convert to normal*/
00338         
00339         externalid = (tyexternalid) (vt - firstefptype);
00340         
00341         vt = externalvaluetype;
00342         }
00343     
00344     if (!tablegetcursorinfo (&ht, bs, &val, &hnode))
00345         return (false);
00346     
00347     if (val.valuetype == vt)
00348         return (true); /*no change*/
00349     
00350     //if (!langexternalgetquotedpath (ht, bs, bspath))
00351     //  return (false);
00352     copystring (bs, bspath);
00353     
00354     langexternalbracketname (bspath);
00355     
00356     if (vt == externalvaluetype) {
00357         
00358         if (val.valuetype == novaluetype) {
00359             
00360             pbsparse = (ptrstring) "\x12" "lang.new (^1, @^0)";
00361             
00362             langgettypestring ((tyvaluetype) (outlinevaluetype + externalid), bsefp);
00363             
00364             pushstring (BIGSTRING ("\x04" "type"), bsefp);
00365             }
00366         else if (val.valuetype == stringvaluetype) {
00367             
00368             switch (externalid) {
00369                 
00370                 case idwordprocessor:
00371                     copystring ((ptrstring) "\x0f" "wp.settext(x); ", bs);
00372                     break;
00373 
00374                 case idoutlineprocessor:
00375                 case idscriptprocessor:
00376                     copystring ((ptrstring) "\x37" "op.insert(x, down); op.firstsummit(); op.deleteline(); ", bs);
00377                     break;
00378                 
00379                 default:
00380                     return (false);
00381                 }
00382 
00383             pbsparse = (ptrstring) "\x44" "local (x=^0); lang.new (^1, @^0); target.set (@^0); ^2target.clear()";
00384             
00385             langgettypestring ((tyvaluetype) (outlinevaluetype + externalid), bsefp);
00386             
00387             pushstring (BIGSTRING ("\x04" "type"), bsefp);
00388             }
00389         else
00390             pbsparse = (ptrstring) "\x11" "unpack (@^0, @^0)";
00391         }
00392     else {
00393         
00394         if (val.valuetype == externalvaluetype) {
00395             
00396             if (vt == stringvaluetype)
00397                 pbsparse = (ptrstring) "\x36" "local (x = string (^0)); table.moveAndRename (@x, @^0)";
00398             
00399             else {
00400                 
00401                 assert (vt == binaryvaluetype);
00402                 
00403                 pbsparse = (ptrstring) "\x0e" "pack (^0, @^0)";
00404                 }
00405             }
00406         else {
00407             
00408             if (!getcoercionstring (vt, bs))
00409                 return (false);
00410             
00411             pbsparse = (ptrstring) "\x0c" "^0 = ^2 (^0)";
00412             }
00413         }
00414     
00415     parsedialogstring (pbsparse, bspath, bsefp, bs, nil, bsscript);
00416     
00417     tablepushcontext (ht, vt);
00418     
00419     fl = langrunstring (bsscript, bs);
00420     
00421     tablepopcontext (ht, vt);
00422     
00423     return (fl);
00424     } /*tablekindrecalc*/
00425 
00426 
00427 static boolean tablekindpopupselect (hdlmenu hmenu, short itemselected) {
00428 #pragma unused (hmenu)
00429 
00430     tyvaluetype valuetype;
00431     
00432     if (!tablemapmenutovaluetype (itemselected, &valuetype)) 
00433         return (false);
00434     
00435     return (tablekindrecalc (valuetype));
00436     } /*tablekindpopupselect*/
00437 
00438     
00439 boolean tablekindpopuphit (Point pt) {
00440 #pragma unused (pt)
00441 
00442     /*
00443     5/6/93 dmb: added support for new types
00444     */
00445     
00446     register hdltableformats hf = tableformatsdata;
00447     Rect r;
00448     
00449     r = (**hf).kindpopuprect;
00450     
00451     return (popupmenuhit (r, true, &tablefillkindpopup, &tablekindpopupselect));
00452     } /*tablekindpopuphit*/
00453     
00454 
00455 void tableupdatekindpopup (void) {
00456     
00457     register hdltableformats hf = tableformatsdata;
00458     bigstring bs;
00459     
00460     getstringlist (kindpopuplist, kindpopuptitlestring, bs);
00461     
00462     drawpopup ((**hf).kindpopuprect, bs, true);
00463     } /*tableupdatekindpopup*/
00464     
00465     
00466 static boolean tablefillsortpopup (hdlmenu hmenu, short *checkeditem) {
00467     
00468     hdlhashtable ht;
00469     bigstring bs;
00470     short i;
00471     boolean flenabled;
00472     short sortorder;
00473     
00474     tablegetcursorinfo (&ht, bs, nil, nil);
00475     
00476     flenabled = tablegetsortorder (ht, &sortorder);
00477     
00478     for (i = 1; i <= ctsorts; i++) {
00479         
00480         getstringlist (sortpopuplist, i, bs);
00481         
00482         if (!pushpopupitem (hmenu, bs, flenabled, 0))
00483             return (false);
00484         } /*for*/
00485     
00486     *checkeditem = 1; /*default, defensive driving*/
00487     
00488     switch (sortorder) {
00489         
00490         case sortbyname:
00491             *checkeditem = 1;
00492             
00493             break;
00494             
00495         case sortbyvalue:
00496             *checkeditem = 2;
00497             
00498             break;
00499             
00500         case sortbykind:
00501             *checkeditem = 3;
00502             
00503             break;
00504         } /*switch*/
00505         
00506     return (true); 
00507     } /*tablefillsortpopup*/
00508 
00509 
00510 static boolean tablesortpopupselect (hdlmenu hmenu, short itemselected) {
00511 #pragma unused (hmenu)
00512 
00513     hdlhashtable ht;
00514     bigstring bs;
00515     
00516     register short sortorder = sortbyname; /*default*/
00517     
00518     switch (itemselected) {
00519         
00520         case 1:
00521             sortorder = sortbyname;
00522             
00523             break;
00524             
00525         case 2:
00526             sortorder = sortbyvalue;
00527             
00528             break;
00529             
00530         case 3:
00531             sortorder = sortbykind;
00532             
00533             break;
00534         } /*switch*/
00535     
00536     tablegetcursorinfo (&ht, bs, nil, nil);
00537     
00538     tablesetsortorder (ht, sortorder);
00539     
00540     return (true);
00541     } /*tablesortpopupselect*/
00542 
00543     
00544 boolean tablesortpopuphit (Point pt) {
00545 #pragma unused (pt)
00546 
00547     register hdltableformats hf = tableformatsdata;
00548     Rect r;
00549     
00550     r = (**hf).sortpopuprect;
00551     
00552     return (popupmenuhit (r, true, &tablefillsortpopup, &tablesortpopupselect));
00553     } /*tablesortpopuphit*/
00554     
00555 
00556 void tableupdatesortpopup (void) {
00557     
00558     register hdltableformats hf = tableformatsdata;
00559     bigstring bs;
00560     
00561     getstringlist (sortpopuplist, sortpopuptitlestring, bs);
00562     
00563     drawpopup ((**hf).sortpopuprect, bs, true);
00564     } /*tableupdatesortpopup*/
00565 
00566 
00567 boolean tablesetitemname (hdlhashtable ht, bigstring bsname, hdlheadrecord headnode, boolean flediting) {
00568     
00569     /*
00570     12/17/91 dmb: added name validation
00571     
00572     1/3/92 dmb: check for just case change (equalidentifiers), and don't 
00573     ignore hashsetnodekey result
00574     
00575     4.1b2 dmb: now resort, using the appropriate level call based on flediting
00576     
00577     5.0.1 dmb: special case for xml
00578     
00579     6.2b16 AR: Take headnode param instead of bsnew bigstring.
00580     */
00581     
00582     hdlhashnode hnode;
00583     bigstring bskey, bsnew;
00584     boolean flvalidate = true;
00585     long newlength;
00586     
00587     assert (headnode != nil);
00588     
00589     if (!hashtablelookupnode (ht, bsname, &hnode)) /*internal error*/
00590         return (false);
00591     
00592     gethashkey (hnode, bskey);
00593     
00594     newlength = gethandlesize ((**headnode).headstring);
00595     
00596     if (newlength == 0) { /*don't permit empty name*/
00597         
00598         if (!isemptystring (bskey)) /*has a name -- leave it unchanged*/
00599             return (true);
00600         
00601         return (false);
00602         }
00603     
00604     if (flvalidate && newlength > 255) {
00605             
00606         alertstring (itemnametoolongstring);
00607         
00608         return (false);
00609         }
00610     
00611     opgetheadstring (headnode, bsnew);
00612     
00613     if (equalstrings (bsnew, bskey)) /*no change*/
00614         return (true);
00615     
00616     if (equalidentifiers (bsnew, bskey)) /*just a case change*/
00617         flvalidate = false;
00618     
00619     if (flvalidate) {
00620         
00621         #ifdef xmlfeatures
00622         if (!(**ht).flxml)
00623         #endif
00624             if (hashtablesymbolexists (ht,  bsnew)) {
00625                 
00626                 alertstring (itemnameinusestring);
00627                 
00628                 return (false);
00629                 }
00630         }
00631     
00632     if (!hashsetnodekey (ht, hnode, bsnew))
00633         return (false);
00634     
00635     #ifdef xmlfeatures
00636     if (!(**ht).flxml)
00637     #endif
00638         
00639         if (flediting)
00640             hashresort (ht, hnode);
00641         else
00642             tableresort (ht, hnode);
00643     
00644     return (true);
00645     } /*tablesetitemname*/
00646 
00647 
00648 
00649 typedef struct typopupkindinfo {
00650     bigstring bstitle;
00651     short zoomkind;
00652     boolean flkindok;
00653     } typopupkindinfo;
00654 
00655 
00656 #ifdef MACVERSION
00657 static typopupkindinfo *zoominfoptr;
00658 
00659 static boolean tablekindhitroutine (DialogPtr pdialog, short itemhit) {
00660     
00661     switch (itemhit) {
00662         
00663         case -1: /*initialize*/
00664             setdialogradiovalue (pdialog, firstkinditem, lastkinditem, zoominfoptr->zoomkind);
00665             
00666             setdialogtext (pdialog, valuenameitem, zoominfoptr->bstitle);
00667             
00668             break;
00669         
00670         case okitem:
00671             zoominfoptr->zoomkind = getdialogradiovalue (pdialog, firstkinditem, lastkinditem);
00672             
00673             getdialogtext (pdialog, valuenameitem, zoominfoptr->bstitle);
00674             
00675             zoominfoptr->flkindok = true;
00676             
00677             return (false);
00678         
00679         case cancelitem:
00680             zoominfoptr->flkindok = false;
00681             
00682             return (false);
00683         
00684         case valuenameitem:
00685             break;
00686         
00687         default:
00688             setdialogradiovalue (pdialog, firstkinditem, lastkinditem, itemhit - firstkinditem);
00689             
00690             break;
00691         }
00692 
00693     return (true);
00694     } /*tablekindhitroutine*/
00695 #endif
00696 
00697 #ifdef WIN95VERSION
00698 LRESULT CALLBACK tablekindDialogCallback(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
00699     
00700     typopupkindinfo * p;
00701 
00702     switch (message) {
00703         
00704         case WM_INITDIALOG:
00705             centerdialog (hwnd);
00706 
00707             p = (typopupkindinfo *) lParam;
00708 
00709             SetWindowLong (hwnd, DWL_USER, lParam); 
00710 
00711             CheckRadioButton (hwnd, IDC_RADIO1, IDC_RADIO6, IDC_RADIO1 + p->zoomkind);
00712 
00713             SendDlgItemMessage (hwnd, IDC_EDIT1, EM_SETLIMITTEXT, (WPARAM) sizeof(bigstring) - 2, 0);
00714             SetDlgItemText (hwnd, IDC_EDIT1, stringbaseaddress (p->bstitle));
00715             SendDlgItemMessage (hwnd, IDC_EDIT1, EM_SETSEL, (WPARAM) (INT) 0, (LPARAM) (INT) -1);
00716 
00717             SetFocus (GetDlgItem (hwnd, IDC_EDIT1));
00718             return (false);
00719 
00720         case WM_COMMAND:
00721             p = (typopupkindinfo *) GetWindowLong (hwnd, DWL_USER);
00722 
00723             switch (LOWORD(wParam))
00724                 {
00725                 case IDOK:
00726                     GetDlgItemText (hwnd, IDC_EDIT1, stringbaseaddress(p->bstitle), sizeof(bigstring) - 2);
00727                     setstringlength (p->bstitle, strlen(stringbaseaddress(p->bstitle)));
00728 
00729                     p->flkindok = true;
00730 
00731                     EndDialog (hwnd, TRUE);
00732                     return TRUE;
00733 
00734                 case IDCANCEL:
00735                     p->flkindok = false;
00736 
00737                     EndDialog (hwnd, FALSE);
00738                     return TRUE;
00739 
00740                 case IDC_RADIO1:
00741                 case IDC_RADIO2:
00742                 case IDC_RADIO3:
00743                 case IDC_RADIO4:
00744                 case IDC_RADIO5:
00745                 case IDC_RADIO6:
00746                     if (HIWORD(wParam) == BN_CLICKED) {
00747                         p->zoomkind = LOWORD(wParam) - IDC_RADIO1;
00748                         }
00749                     break;
00750 
00751                 default:
00752                     break;
00753                 }
00754 
00755         default:
00756             break;
00757         }
00758 
00759     return FALSE;
00760     } /*tablekindDialogCallback*/
00761 #endif
00762 
00763 //RAB: 1/21/98 This dialog shows the user the current title and
00764 //      allows that to be changed and to select a kind for the item
00765 //      The bstitle parameter is an in/out parameter having the 
00766 //      default string to show and returns with the users result.
00767 //      The kind parameter is also an in/out for which button is
00768 //      default and returns with the user value.
00769 //      The procedure returns true if everything worked and the
00770 //      user presses ok, otherwise it returns false.
00771 static boolean showpopupkinddialog (typopupkindinfo * pki) {
00772 #ifdef MACVERSION
00773     zoominfoptr = pki;
00774 
00775     if (!customdialog (newvaluedialogid, 1, &tablekindhitroutine))
00776         return (false);
00777     
00778     if (! pki->flkindok)
00779         return (false);
00780 
00781     return (true);
00782 #endif
00783 
00784 #ifdef WIN95VERSION
00785     int res;
00786 
00787     nullterminate (pki->bstitle);
00788 
00789     releasethreadglobals ();
00790 
00791     res = DialogBoxParam (hInst, MAKEINTRESOURCE (IDD_DIALOGTABLEENTRY), hwndMDIClient, (DLGPROC)tablekindDialogCallback, (LPARAM) pki);
00792     
00793     grabthreadglobals ();
00794 
00795     if (res > 0)
00796         return (true);
00797     
00798     return (false);
00799 #endif
00800     } /*showpopupkinddialog*/
00801 
00802 
00803 boolean tablepopupkinddialog (void) {
00804     
00805     typopupkindinfo pki;
00806     tyvaluerecord val;
00807     hdlhashtable ht;
00808     hdlhashnode hnode;
00809     
00810     tablegetcursorinfo (&ht, pki.bstitle, &val, &hnode);
00811     
00812     pki.zoomkind = 0;  //default to table
00813 
00814     if (! showpopupkinddialog (&pki))
00815         return (false);
00816 
00817     if (!opsetheadstring ((**outlinedata).hbarcursor, pki.bstitle))
00818         return (false);
00819     
00820     opvisibarcursor ();
00821     
00822     opupdatenow ();
00823     
00824     return (tablekindpopupselect (nil, (short)(pki.zoomkind + ixfirstefptype)));
00825     } /*tablepopupkinddialog*/
00826 
00827 
00828 typedef struct tyancestor {
00829     
00830     hdlhashtable htable;
00831     
00832     hdlhashnode hnode;
00833     } tyancestor, tyancestry [];
00834 
00835 
00836 typedef tyancestry *ptrancestry, **hdlancestry;
00837 
00838 
00839 static hdlancestry hancestry;
00840 
00841 static boolean flinhibitmenupush;
00842 
00843 static hdlexternalvariable clientvariable;
00844 
00845 static boolean flmenubarscript;
00846 
00847 
00848 static boolean ancestorroutine (hdlhashtable htable, hdlhashnode hnode) {
00849     
00850     /*
00851     5.0.2b21 dmb: don't popup file windows table or its ancestors
00852     
00853     5.1.5 dmb: don't inhibit the root of guest databases
00854     */
00855     
00856     tyancestor ancestor;
00857     
00858     if (flinhibitmenupush)
00859         return (true);
00860     
00861     ancestor.htable = htable;
00862     
00863     ancestor.hnode = hnode;
00864     
00865     if (!enlargehandle ((Handle) hancestry, sizeof (ancestor), &ancestor))
00866         return (false);
00867     
00868     if (htable == filewindowtable)
00869         flinhibitmenupush = true;
00870     
00871     return (true);
00872     } /*ancestorroutine*/
00873 
00874 
00875 static boolean tablefilltitlepopup (hdlmenu hmenu, short *checkeditem) {
00876     
00877     hdlhashtable htable;
00878     bigstring bsname;
00879     register short i;
00880     short ctancestors;
00881     
00882     if (clientvariable != (hdlexternalvariable) rootvariable) {
00883         
00884         if (!findvariablesearch (roottable, clientvariable, true, &htable, bsname, &ancestorroutine))
00885             return (false);
00886         
00887         ctancestors = gethandlesize ((Handle) hancestry) / sizeof (tyancestor);
00888         
00889         for (i = 0; i < ctancestors; ++i) {
00890             
00891             gethashkey ((**hancestry) [i].hnode, bsname);
00892             
00893             if (!pushpopupitem (hmenu, bsname, true, 0))
00894                 return (false);
00895             }
00896         }
00897     
00898     if (!flinhibitmenupush)
00899         if (!pushpopupitem (hmenu, nameroottable, true, 0))
00900             return (false);
00901     
00902     *checkeditem = -1; /*select, but don't check, the first item*/
00903     
00904     return (true); 
00905     } /*tablefilltitlepopup*/
00906 
00907 
00908 static boolean tabletitlepopupselect (hdlmenu hmenu, short itemselected) {
00909 #pragma unused (hmenu)
00910 
00911     /*
00912     note: the last item, "root", is really just a dummy which has no matching element 
00913     in the array.  the first item in the array will actually go to the parent table, 
00914     which is the one named in the second menu item.
00915     
00916     8.0.4 Radio PBS: Fixed a crashing bug when no item is selected and itemselected is garbage.
00917     */
00918     
00919     tyancestor ancestor;
00920     bigstring bsname;
00921     tyvaluerecord val;
00922     hdlwindowinfo hinfo;
00923         
00924     if (itemselected > 128) /*8.0.4 PBS: when no item is selected, itemselected is very large. Don't crash.*/
00925         return (true);
00926 
00927     if (itemselected == 1) {
00928         
00929         if (!flmenubarscript) /*it's the object itself; nothing to do*/
00930             return (true);
00931         
00932         val.valuetype = externalvaluetype;
00933         
00934         val.data.externalvalue = (Handle) clientvariable;
00935         
00936         if (!langexternalwindowopen (val, &hinfo))
00937             return (false);
00938         
00939         shellbringtofront (hinfo);
00940         }
00941     else {
00942         
00943         ancestor = (**hancestry) [itemselected - 2];
00944         
00945         gethashkey (ancestor.hnode, bsname);
00946 
00947         if (!tablezoomfromtable (ancestor.htable))
00948             return (false);
00949         
00950         if (!tablezoomtoname (ancestor.htable, bsname))
00951             return (false);
00952         }
00953     
00954     if (keyboardstatus.floptionkey)
00955         shellclosewindow (shellwindow);
00956     
00957     return (true);
00958     } /*tabletitlepopupselect*/
00959 
00960 
00961 static void localtoscreenrect (WindowPtr w, Rect *r) {
00962     
00963     /*
00964     convert the rectangle inside w to global coordinates on the desktop.
00965     */
00966 
00967 #ifdef MACVERSION
00968     localtoglobalrect (w, r);
00969 #endif
00970 
00971 #ifdef WIN95VERSION
00972     POINT winpt;
00973     
00974     winpt.x = (*r).left;
00975     winpt.y = (*r).top;
00976     
00977     ClientToScreen (w, &winpt);
00978     
00979     offsetrect (r, (short)(winpt.x - (*r).left), (short) (winpt.y - (*r).top));
00980 #endif
00981     } /*localtoscreenrect*/
00982 
00983 
00984 boolean tableclienttitlepopuphit (Point pt, hdlexternalvariable hvariable) {
00985     
00986     /*
00987     4/15/92 dmb: build and track a popup in the object's title bar of its ancestry,
00988     much like the folder popup in the Finder.
00989     
00990     if something is selected, zoom to it.
00991     
00992     6/25/92 dmb: added flmenubarscript hack to quickly implement support for 
00993     -- you guessed it -- menubar scripts.
00994     */
00995     
00996     boolean fl = false;
00997     
00998     Rect r;
00999     bigstring bs;
01000     short ctpixels;
01001 
01002 #ifdef MACVERSION
01003 
01004     #if TARGET_API_MAC_CARBON != 1
01005     
01006         //Code change by Timothy Paustian Sunday, April 30, 2000 9:18:54 PM
01007         //Leave this till later, but I have a feeling these are going to be 
01008         //a real pain in Mac OS X
01009         //Friday, May 5, 2000 10:36:39 PM
01010         //I think I know how to handle this now.
01011         //Code change by Timothy Paustian Sunday, May 21, 2000 9:28:04 PM
01012         //I checked this out and it seems to work just fine.
01013         CGrafPtr deskport;
01014         #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
01015         deskport = CreateNewPort();
01016         #else
01017         deskport = NewPtr(sizeof(CGrafPort));
01018         #endif
01019     #endif
01020 #endif
01021     
01022     if (hvariable == nil) /*defensive driving*/
01023         return (false);
01024     
01025     getlocalwindowrect (shellwindow, &r);
01026 
01027     localtoscreenrect (shellwindow, &r);
01028     
01029     localtoglobalpoint (shellwindow, &pt);
01030 
01031 #ifdef MACVERSION   
01032     #if TARGET_API_MAC_CARBON != 1
01033         if (!pushdesktopport (deskport)) /*failed to open up a port on the whole desktop*/
01034             return (false);
01035     #endif
01036 #endif
01037     
01038     windowgettitle (shellwindow, bs);
01039     
01040     ctpixels = stringpixels (bs) + 10; /*five pixels of white space on each side*/
01041     
01042     r.bottom = r.top;
01043     
01044     r.top = r.bottom - doctitlebarheight;
01045 
01046 #ifdef MACVERSION   
01047     r.left += (r.right - r.left - ctpixels) / 2;
01048 #endif
01049     
01050     r.right = r.left + ctpixels;
01051     
01052 #ifdef WIN95VERSION
01053     r.right += 24;  /* account for sysmenu and border */
01054 #endif
01055 
01056     flmenubarscript = false;
01057     
01058     if (pt.v > r.bottom) { /*we're being called for a menubar script; must adjust*/
01059         
01060         pt.v -= 50;
01061         
01062         flmenubarscript = true;
01063         }
01064     
01065     if (!pointinrect (pt, r))
01066         goto exit;
01067     
01068     if (!newemptyhandle ((Handle *) &hancestry))
01069         goto exit;
01070     
01071     flinhibitmenupush = false;
01072     
01073     clientvariable = hvariable;
01074     
01075     pt.v = (short) r.top;
01076 
01077     globaltolocalpoint (shellwindow, &pt);
01078 
01079     r.left = pt.h - 12; /*position relative to cursor*/
01080     
01081     r.top = pt.v;
01082 
01083     fl = popupmenuhit (r, false, &tablefilltitlepopup, &tabletitlepopupselect);
01084 
01085     disposehandle ((Handle) hancestry);
01086     
01087     exit:
01088 
01089 #ifdef MACVERSION
01090     #if TARGET_API_MAC_CARBON != 1
01091 
01092         popdesktopport (deskport);
01093         #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
01094          DisposePort(deskport);
01095         #else
01096         DisposePtr(deskport);
01097         #endif
01098     #endif
01099 #endif
01100 
01101     return (fl);
01102     } /*tableclienttitlepopuphit*/
01103 
01104 
01105 
01106 

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