home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1996 March / macformat-035.iso / Shareware City / Developers / ICAppSourceKit1.2 / ICTextWhats.p < prev    next >
Encoding:
Text File  |  1995-11-07  |  12.5 KB  |  443 lines  |  [TEXT/CWIE]

  1. unit ICTextWhats;
  2.  
  3. interface
  4.  
  5.     uses
  6.         ICWindowGlobals;
  7.  
  8.     function WhatOpenText (wt: WindowType; item: integer): OSErr;
  9.     function WhatFlushText (wt: WindowType; item: integer): OSErr;
  10.     function WhatCloseText (wt: WindowType; item: integer): OSErr;
  11.     function WhatClickText (wt: WindowType; item: integer; er: eventRecord): OSErr;
  12.     function WhatKeyText (wt: WindowType; item: integer; er: EventRecord): OSErr;
  13.  
  14.     (* danger, layer break! *)
  15.     function HaveTextSelection (wt: WindowType): boolean;
  16.     procedure AdjustTextMenu (wt: WindowType);
  17.     procedure DoTextMenu (wt: WindowType; menuitem: integer);
  18.     procedure SelectTextItem (wt: WindowType; item: integer);
  19.  
  20. implementation
  21.  
  22.     uses
  23.         ICTypes, ICAPI, Dialogs, Scrap, TextUtils, Menus, Fonts,
  24.  
  25.         ICGlobals, ICMiscSubs, ICSubs, ICText, ICDialogs, ICDocument {X};
  26.  
  27.     const
  28.         tf_single_line = 0;
  29.         tf_pstring = 1;
  30.         tf_scrambled = 2;
  31.         tf_monospace = 3;
  32.  
  33.         tf_single_line_mask = $0001;
  34.         tf_pstring_mask = $0002;
  35.         tf_scrambled_mask = $0004;
  36.         tf_monospace_mask = $0008;
  37.  
  38.     procedure DrawTextProc (window: DialogPtr; item: integer);
  39.         var
  40.             r: Rect;
  41.             savefont, savemode, savesize: integer;
  42.             saveface: Style;
  43.     begin
  44.         savefont := window^.txFont;
  45.         saveface := window^.txFace;
  46.         savemode := window^.txMode;
  47.         savesize := window^.txSize;
  48.         TextDraw(windowinfo[GetWindowType(window)].items[item]^.data);
  49.  
  50.         GetDItemRect(window, item, r);
  51.         InsetRect(r, -3, -3);
  52.         PenNormal;
  53.         FrameRect(r);
  54.         TextFont(savefont);
  55.         TextFace(saveface);
  56.         TextMode(savemode);
  57.         TextSize(savesize);
  58.     end;
  59.  
  60.     function HaveTextSelection (wt: WindowType): boolean;
  61.         var
  62.             start_sel, end_sel: integer;
  63.     begin
  64.         HaveTextSelection := false;
  65.         if GetSelectedItem(wt) > 0 then begin
  66.             TextGetSelect(windowinfo[wt].items[GetSelectedItem(wt)]^.data, start_sel, end_sel);
  67.             HaveTextSelection := (start_sel <> end_sel);
  68.         end; (* if *)
  69.     end; (* HaveTextSelection *)
  70.  
  71.     procedure AdjustTextMenu (wt: WindowType);
  72.         var
  73.             enable_cut, enable_paste, enable_select_all: boolean;
  74.             offset: longint;
  75.             mh: MenuHandle;
  76.             texth: Handle;
  77.             text_size: longint;
  78.             search_text: integer;
  79.             cr_pos: longint;
  80.             item: integer;
  81.             err: OSErr;
  82.             sel_start, sel_end: integer;
  83.     begin
  84.         item := GetSelectedItem(wt);
  85.         if (wt <> WT_None) & (item > 0) then begin
  86.             enable_cut := HaveTextSelection(wt);
  87.             offset := 0;
  88.             enable_paste := (GetScrap(nil, 'TEXT', offset) > 0);
  89.             TextGetSelect(windowinfo[wt].items[item]^.data, sel_start, sel_end);
  90.             TextGetSize(windowinfo[wt].items[item]^.data, text_size);
  91.             enable_select_all := (sel_start <> 0) or (sel_end <> text_size);
  92.         end else begin
  93.             enable_cut := false;
  94.             enable_paste := false;
  95.             enable_select_all := false;
  96.         end; (* if *)
  97.         (* deal with the nasty paste problem, ie preventing them pasting CRs into single line fields *)
  98.         if enable_paste & TPbtst(windowinfo[wt].items[item]^.flags, tf_single_line) then begin
  99.             texth := NewHandle(0);
  100.             err := MemError;
  101.             if err = noErr then begin
  102.                 offset := 0;
  103.                 text_size := GetScrap(texth, 'TEXT', offset);
  104.                 if text_size > 0 then begin
  105.                     search_text := $0D0D;
  106.                     cr_pos := Munger(texth, 0, @search_Text, 1, nil, 0);
  107.                     if cr_pos < 0 then begin
  108.                         enable_paste := true;
  109.                     end else if (cr_pos = text_size - 1) then begin
  110.                         enable_paste := (cr_pos > 0);
  111.                     end else begin
  112.                         enable_paste := false;
  113.                     end; (* if *)
  114.                 end else begin
  115.                     enable_paste := false;
  116.                 end; (* if *)
  117.             end; (* if *)
  118.             if texth <> nil then begin
  119.                 DisposeHandle(texth);
  120.             end; (* if *)
  121.             if err <> noErr then begin
  122.                 enable_paste := false;
  123.             end; (* if *)
  124.         end; (* if *)
  125.         (* deal with locked items *)
  126.         if item > 0 then begin
  127.             if IsLocked(wt, item) then begin
  128.                 enable_paste := false;
  129.                 enable_cut := false;
  130.             end; (* if *)
  131.         end; (* if *)
  132.         (* hit the menu items *)
  133.         mh := GetMenuHandle(M_Edit);
  134.         SetItemEnable(mh, EM_Undo, false);
  135.         SetItemEnable(mh, EM_Cut, enable_cut);
  136.         SetItemEnable(mh, EM_Copy, enable_cut);
  137.         SetItemEnable(mh, EM_Paste, enable_paste);
  138.         SetItemEnable(mh, EM_Clear, enable_cut);
  139.         SetItemEnable(mh, EM_SelectAll, enable_select_all);
  140.     end;
  141.  
  142.     procedure JustSelectTextItem (wt: WindowType; item: integer);
  143.     begin
  144.         if GetSelectedItem(wt) > 0 then begin
  145.             TextActivate(windowinfo[wt].items[GetSelectedItem(wt)]^.data, false);
  146.         end;
  147.         TextActivate(windowinfo[wt].items[item]^.data, (FrontWindow = windowinfo[wt].window) & InForeground);
  148.         windowinfo[wt].selected_item := item;
  149.     end; (* JustSelectTextItem *)
  150.  
  151.     procedure SelectTextItem (wt: WindowType; item: integer);
  152.     begin
  153.         JustSelectTextItem(wt, item);
  154.         TextSetSelect(windowinfo[wt].items[item]^.data, 0, 32767);
  155.     end;
  156.  
  157.     procedure DoTextMenu (wt: WindowType; menuitem: integer);
  158.         var
  159.             data: Ptr;
  160.             texth: Handle;
  161.             offset: longint;
  162.             search_text: integer;
  163.             cr_pos: longint;
  164.             item: integer;
  165.             text_size: longint;
  166.     begin
  167.         item := GetSelectedItem(wt);
  168.         data := windowinfo[wt].items[item]^.data;
  169.         case menuitem of
  170.             EM_Cut:  begin
  171.                 TextCut(data);
  172.             end;
  173.             EM_Copy:  begin
  174.                 TextCopy(data);
  175.             end;
  176.             EM_Paste: 
  177.                 if IsLocked(wt, item) then begin
  178.                     LockedAlert(wt, item);
  179.                 end else begin
  180.                     if TPbtst(windowinfo[wt].items[item]^.flags, tf_single_line) then begin
  181.                         texth := NewHandle(0);
  182.                         if texth <> nil then begin
  183.                             offset := 0;
  184.                             text_size := GetScrap(texth, 'TEXT', offset);
  185.                             if text_size > 0 then begin
  186.                                 search_text := $0D0D;
  187.                                 cr_pos := Munger(texth, 0, @search_Text, 1, nil, 0);
  188.                                 if cr_pos > 0 then begin
  189.                                     SetHandleSize(texth, cr_pos);
  190.                                 end; (* if *)
  191.                                 TextClear(data);
  192.                                 TextInsert(data, texth);
  193.                             end; (* if *)
  194.                         end; (* if *)
  195.                         DisposeHandle(texth);
  196.                     end else begin
  197.                         TextPaste(data);
  198.                     end; (* if *)
  199.                 end; (* if *)
  200.             EM_Clear:  begin
  201.                 if IsLocked(wt, item) then begin
  202.                     LockedAlert(wt, item);
  203.                 end else begin
  204.                     TextClear(data);
  205.                 end; (* if *)
  206.             end;
  207.             EM_SelectAll:  begin
  208.                 TextSetSelect(data, 0, 32767);
  209.             end;
  210.             otherwise
  211.                 ;
  212.         end; (* case *)
  213.     end; (* DoTextMenu *)
  214.  
  215.     type
  216.         memBlock = packed array[0..16000000] of byte;
  217.         memBlockPtr = ^memBlock;
  218.  
  219.     function BlockCompare (lhs, rhs: univ Ptr; size: longint): boolean;
  220.         var
  221.             i: longint;
  222.             tmplhs, tmprhs: memBlockPtr;
  223.     begin
  224.         BlockCompare := false;
  225.         tmplhs := memBlockPtr(lhs);
  226.         tmprhs := memBlockPtr(rhs);
  227.         for i := 0 to size - 1 do begin
  228.             if tmplhs^[i] <> tmprhs^[i] then begin
  229.                 exit(BlockCompare);
  230.             end; (* if *)
  231.         end; (* for *)
  232.         BlockCompare := true;
  233.     end; (* BlockCompare *)
  234.  
  235.     procedure ScrambleHandle (texth: Handle);
  236.         var
  237.             l: longint;
  238.             tmptext: memBlockPtr;
  239.     begin
  240.         tmptext := memBlockPtr(texth^);
  241.         for l := 1 to GetHandleSize(texth) do begin
  242.             tmptext^[l - 1] := band(bxor(tmptext^[l - 1], $55 + l), $FF);
  243.         end; (* for *)
  244.     end; (* ScrambleHandle *)
  245.  
  246. {$PUSH}
  247. {$R-}
  248.     procedure BlockFill (p: univ ptr; len: longInt; value: integer);
  249.     begin
  250.         while (len > 0) do begin
  251.             p^ := value;
  252.             len := len - 1;
  253.             longInt(p) := longInt(p) + 1;
  254.         end;
  255.     end;
  256. {$POP}
  257.  
  258.     function WhatOpenText (wt: WindowType; item: integer): OSErr;
  259.         var
  260.             err: OSErr;
  261.             key: Str31;
  262.             attr: longint;
  263.             texth: Handle;
  264.             junk: longint;
  265.             flags: longint;
  266.             pstring: boolean;
  267.             scrambled: boolean;
  268.             font, size: integer;
  269.             r: Rect;
  270.     begin
  271.         windowinfo[wt].items[item]^.data := nil;
  272.         windowinfo[wt].items[item]^.spare_data := nil;
  273.         texth := nil;
  274.         key := windowinfo[wt].items[item]^.key;
  275.         flags := windowinfo[wt].items[item]^.flags;
  276.         pstring := TPbtst(flags, tf_pstring);
  277.         scrambled := TPbtst(flags, tf_scrambled);
  278.         if TPbtst(flags, tf_monospace) then begin
  279.             font := monaco;
  280.             size := 9;
  281.         end else begin
  282.             font := systemFont;
  283.             size := 12;
  284.         end; (* if *)
  285.         err := ICMapErr(ICGetPrefHandle(GetInstance, key, attr, texth));
  286.         if err = noErr then begin
  287.             ProcessAttributes(wt, item, attr);
  288.             if pstring then begin
  289.                 junk := Munger(texth, 0, nil, 1, @junk, 0);
  290.             end; (* if *)
  291.             if scrambled then begin
  292.                 ScrambleHandle(texth);
  293.             end; (* if *)
  294.             err := TextCreate(windowinfo[wt].items[item]^.data, windowinfo[wt].window, item, font, size, IsLocked(wt, item));
  295.         end; (* if *)
  296.         if err = noErr then begin
  297.             SetDItemHandle(windowinfo[wt].window, item, @DrawTextProc);
  298.             TextInsert(windowinfo[wt].items[item]^.data, texth);
  299.         end; (* if *)
  300.         if (err = noErr) & scrambled then begin
  301.             windowinfo[wt].items[item]^.spare_data := windowinfo[wt].items[item]^.data;
  302.             windowinfo[wt].items[item]^.data := nil;
  303.             GetDItemRect(windowinfo[wt].window, item, r);
  304.             OffsetRect(r, 16000, 0);
  305.             TextMove(windowinfo[wt].items[item]^.spare_data, r);
  306.             BlockFill(texth^, GetHandleSize(texth), ord('•'));
  307.             err := TextCreate(windowinfo[wt].items[item]^.data, windowinfo[wt].window, item, font, size, IsLocked(wt, item));
  308.             if err = noErr then begin
  309.                 TextInsert(windowinfo[wt].items[item]^.data, texth);
  310.             end; (* if *)
  311.         end; (* if *)
  312.         if texth <> nil then begin
  313.             DisposeHandle(texth);
  314.         end; (* if *)
  315.         WhatOpenText := err;
  316.     end; (* WhatOpenText *)
  317.  
  318. (* *)
  319.  
  320.     function WhatFlushText (wt: WindowType; item: integer): OSErr;
  321.         var
  322.             err: OSErr;
  323.             key: Str31;
  324.             texth: Handle;
  325.             oldtexth: Handle;
  326.             attr: longint;
  327.             junk: longint;
  328.             i: integer;
  329.             flags: longint;
  330.             pstring: boolean;
  331.             scrambled: boolean;
  332.     begin
  333.         texth := nil;
  334.         oldtexth := nil;
  335.         key := windowinfo[wt].items[item]^.key;
  336.         flags := windowinfo[wt].items[item]^.flags;
  337.         pstring := TPbtst(flags, tf_pstring);
  338.         scrambled := TPbtst(flags, tf_scrambled);
  339.         err := ICMapErr(ICGetPrefHandle(GetInstance, key, attr, oldtexth));
  340.         if err = noErr then begin
  341.             if pstring and (GetHandleSize(oldtexth) = 0) then begin
  342.                 SetHandleSize(oldtexth, 1);
  343.                 err := MemError;
  344.                 if err = noErr then begin
  345.                     oldtexth^^ := 0;
  346.                 end; (* if *)
  347.             end; (* if *)
  348.         end; (* if *)
  349.         if err = noErr then begin
  350.             texth := NewHandle(0);
  351.             err := MemError;
  352.         end; (* if *)
  353.         if err = noErr then begin
  354.             if scrambled then begin
  355.                 TextGet(windowinfo[wt].items[item]^.spare_data, texth);
  356.             end else begin
  357.                 TextGet(windowinfo[wt].items[item]^.data, texth);
  358.             end; (* if *)
  359.             if scrambled then begin
  360.                 ScrambleHandle(texth);
  361.             end; (* if *)
  362.             if pstring then begin
  363.                 if GetHandleSize(texth) > 255 then begin
  364.                     SetHandleSize(texth, 255);
  365.                 end; (* if *)
  366.                 i := GetHandleSize(texth) * $0101;                    (* puts it into both bytes! *)
  367.                 junk := Munger(texth, 0, nil, 0, @i, 1);            (* if this errors, we lose *)
  368.             end; (* if *)
  369.             if not IsLocked(wt, item) & ((GetHandleSize(texth) <> GetHandleSize(oldtexth)) | not BlockCompare(texth^, oldtexth^, GetHandleSize(texth))) then begin
  370.                 err := ICMapErr(ICSetPrefHandle(GetInstance, key, ICattr_no_change, texth));
  371.                 if err = noErr then begin
  372.                     DirtyDocument;
  373.                 end; (* if *)
  374.             end; (* if *)
  375.         end; (* if *)
  376.         if texth <> nil then begin
  377.             DisposeHandle(texth);
  378.         end; (* if *)
  379.         if oldtexth <> nil then begin
  380.             DisposeHandle(oldtexth);
  381.         end; (* if *)
  382.         WhatFlushText := err;
  383.     end; (* WhatFlushText *)
  384.  
  385. (* *)
  386.  
  387.     function WhatCloseText (wt: WindowType; item: integer): OSErr;
  388.         var
  389.             flags: longint;
  390.             scrambled: boolean;
  391.     begin
  392.         flags := windowinfo[wt].items[item]^.flags;
  393.         scrambled := TPbtst(flags, tf_scrambled);
  394.         TextDestroy(windowinfo[wt].items[item]^.data);
  395.         if scrambled then begin
  396.             TextDestroy(windowinfo[wt].items[item]^.spare_data);
  397.         end; (* if *)
  398.         WhatCloseText := noErr;
  399.     end; (* WhatCloseText *)
  400.  
  401. (* *)
  402.  
  403.     function WhatClickText (wt: WindowType; item: integer; er: eventRecord): OSErr;
  404.     begin
  405.         JustSelectTextItem(wt, item);
  406.         TextClick(windowinfo[wt].items[item]^.data, er);
  407.         WhatClickText := noErr;
  408.     end; (* WhatClickText *)
  409.  
  410.     function WhatKeyText (wt: WindowType; item: integer; er: EventRecord): OSErr;
  411.         var
  412.             flags: longint;
  413.             scrambled, single_line: boolean;
  414.             ch: char;
  415.             sel_start, sel_end: integer;
  416.     begin
  417.         flags := windowinfo[wt].items[item]^.flags;
  418.         scrambled := TPbtst(flags, tf_scrambled);
  419.         single_line := TPbtst(flags, tf_single_line);
  420.         ch := chr(BAND(er.message, charCodeMask));
  421.         if (single_line and (ch = chr(13))) or (scrambled and ((ch <> chr(8)) and (ch < ' '))) then begin
  422.             SysBeep(1);
  423.         end else begin
  424.             if IsLocked(wt, item) and DirtyKey(ch) then begin
  425.                 LockedAlert(wt, item);
  426.             end else begin
  427.                 if scrambled then begin
  428.                     TextGetSelect(windowinfo[wt].items[item]^.data, sel_start, sel_end);
  429.                     TextSetSelect(windowinfo[wt].items[item]^.spare_data, sel_start, sel_end);
  430.                     TextKey(windowinfo[wt].items[item]^.spare_data, er);
  431.                     if (ch <> chr(8)) & DirtyKey(ch) then begin
  432.                         er.message := ord('•');
  433.                     end;
  434.                     TextKey(windowinfo[wt].items[item]^.data, er);
  435.                 end else begin
  436.                     TextKey(windowinfo[wt].items[item]^.data, er);
  437.                 end; (* if *)
  438.             end; (* if *)
  439.         end; (* if *)
  440.         WhatKeyText := noErr;
  441.     end; (* WhatKeyText *)
  442.  
  443. end. (* TextWhats *)