123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735 |
- MODULE WMSearchComponents; (** AUTHOR "staubesv"; PURPOSE "Search components"; *)
- IMPORT
- Inputs, Strings, Texts, TextUtilities, UTF8Strings, WMWindowManager,
- WMRectangles, WMGraphics, WMMessages, WMComponents, WMStandardComponents, WMTextView, WMEditors;
- CONST
- SearchStringMaxLen = 128;
- TYPE
- SearchString* = ARRAY SearchStringMaxLen OF CHAR;
- UcsSearchString* = ARRAY SearchStringMaxLen OF Texts.Char32;
- StackData = POINTER TO ARRAY OF LONGINT;
- PositionStack = OBJECT
- VAR
- data: StackData;
- size, top: LONGINT;
- PROCEDURE & Init*;
- BEGIN
- size := 32;
- NEW(data, 32);
- END Init;
- PROCEDURE Push(l: LONGINT);
- BEGIN
- IF top = size THEN Expand END;
- data[top] := l;
- INC(top);
- END Push;
- PROCEDURE Pop(): LONGINT;
- VAR val: LONGINT;
- BEGIN
- IF top > 0 THEN
- DEC(top);
- val := data[top];
- ELSE
- val := -1;
- END;
- RETURN val;
- END Pop;
- PROCEDURE Expand;
- VAR
- newSize, i: LONGINT;
- newData: StackData;
- BEGIN
- newSize := 2*size;
- NEW(newData, newSize);
- FOR i := 0 TO size-1 DO
- data[i] := newData[i];
- END;
- size := newSize;
- data := newData;
- END Expand;
- PROCEDURE Invalidate;
- BEGIN
- IF size > 32 THEN Init END;
- top := 0;
- END Invalidate;
- END PositionStack;
- TYPE
- Highlight = POINTER TO RECORD
- this : WMTextView.Highlight;
- next : Highlight;
- END;
- Highlights = OBJECT
- VAR
- textView : WMTextView.TextView;
- highlights : Highlight;
- PROCEDURE Add(from, to : LONGINT);
- VAR h : Highlight;
- BEGIN {EXCLUSIVE}
- NEW(h); h.next := highlights; highlights := h;
- h.this := textView.CreateHighlight();
- h.this.SetColor(LONGINT(0FFFF0080H));
- h.this.SetKind(WMTextView.HLOver);
- h.this.SetFromTo(from, to);
- END Add;
- PROCEDURE RemoveAll;
- VAR h : Highlight;
- BEGIN {EXCLUSIVE}
- h := highlights;
- WHILE (h # NIL) DO
- textView.RemoveHighlight(h.this);
- h := h.next;
- END;
- highlights := NIL;
- END RemoveAll;
- PROCEDURE &Init*(textView : WMTextView.TextView);
- BEGIN
- ASSERT(textView # NIL);
- SELF.textView := textView;
- END Init;
- END Highlights;
- TYPE
- SearchPanel* = OBJECT(WMComponents.VisualComponent)
- VAR
- wrap, caseSensitive, backwards*, highlightAll : BOOLEAN;
- upperPanel, lowerPanel: WMStandardComponents.Panel;
- searchBtn, replBtn, replAllBtn, closeBtn, wrapBtn, caseSensitiveBtn, directionBtn, markAllBtn : WMStandardComponents.Button;
- searchEdit-, replEdit-: WMEditors.Editor;
- searchLabel, replLabel: WMStandardComponents.Label;
- textView: WMTextView.TextView;
- text: Texts.Text;
- pos, len: LONGINT;
- hitCount : LONGINT;
- posValid : BOOLEAN;
- positionStack: PositionStack;
- highlights : Highlights;
- lastPos : LONGINT;
- lastBackwards : BOOLEAN;
- PROCEDURE & Init*;
- BEGIN
- Init^;
- SetNameAsString(StrSearchPanel);
- wrap := FALSE;
- caseSensitive := TRUE;
- highlightAll := FALSE;
- hitCount := 0;
- backwards := FALSE;
- lastPos := -1; lastBackwards := FALSE;
- NEW(upperPanel);
- upperPanel.alignment.Set(WMComponents.AlignTop);
- upperPanel.bounds.SetHeight(20);
- AddInternalComponent(upperPanel);
- NEW(searchLabel);
- searchLabel.alignment.Set(WMComponents.AlignLeft);
- searchLabel.bounds.SetWidth(40); searchLabel.fillColor.Set(LONGINT(0FFFFFFFFH));
- searchLabel.alignH.Set(WMGraphics.AlignCenter);
- searchLabel.SetCaption("Search");
- upperPanel.AddInternalComponent(searchLabel);
- NEW(searchEdit);
- searchEdit.alignment.Set(WMComponents.AlignLeft);
- searchEdit.bounds.SetWidth(200); searchEdit.multiLine.Set(FALSE);
- searchEdit.tv.borders.Set(WMRectangles.MakeRect(3, 3, 1, 1));
- searchEdit.tv.showBorder.Set(TRUE);
- searchEdit.fillColor.Set(LONGINT(0FFFFFFFFH));
- searchEdit.onEnter.Add(SearchHandler);
- searchEdit.text.onTextChanged.Add(TextChanged);
- searchEdit.tv.SetExtFocusHandler(FocusHandler);
- searchEdit.tv.textAlignV.Set(WMGraphics.AlignCenter);
- upperPanel.AddInternalComponent(searchEdit);
- NEW(replLabel);
- replLabel.alignment.Set(WMComponents.AlignLeft);
- replLabel.bounds.SetWidth(50); replLabel.fillColor.Set(LONGINT(0FFFFFFFFH));
- replLabel.alignH.Set(WMGraphics.AlignCenter);
- replLabel.SetCaption("Replace");
- upperPanel.AddInternalComponent(replLabel);
- NEW(replEdit);
- replEdit.alignment.Set(WMComponents.AlignClient);
- replEdit.bounds.SetWidth(150); replEdit.multiLine.Set(FALSE);
- replEdit.tv.borders.Set(WMRectangles.MakeRect(3, 3, 1, 1));
- replEdit.tv.showBorder.Set(TRUE);
- replEdit.tv.textAlignV.Set(WMGraphics.AlignCenter);
- replEdit.fillColor.Set(LONGINT(0FFFFFFFFH));
- replEdit.onEnter.Add(ReplaceHandler);
- upperPanel.AddInternalComponent(replEdit);
- NEW(lowerPanel);
- lowerPanel.alignment.Set(WMComponents.AlignTop);
- lowerPanel.bounds.SetHeight(20);
- AddInternalComponent(lowerPanel);
- NEW(searchBtn);
- searchBtn.alignment.Set(WMComponents.AlignLeft);
- searchBtn.caption.SetAOC("Search");
- searchBtn.bounds.SetWidth(80);
- searchBtn.onClick.Add(SearchHandler);
- lowerPanel.AddInternalComponent(searchBtn);
- NEW(replBtn);
- replBtn.alignment.Set(WMComponents.AlignLeft);
- replBtn.caption.SetAOC("Replace");
- replBtn.bounds.SetWidth(80);
- replBtn.onClick.Add(ReplaceHandler);
- lowerPanel.AddInternalComponent(replBtn);
- NEW(replAllBtn);
- replAllBtn.alignment.Set(WMComponents.AlignLeft);
- replAllBtn.caption.SetAOC("Replace All");
- replAllBtn.bounds.SetWidth(80);
- replAllBtn.onClick.Add(ReplaceAllHandler);
- lowerPanel.AddInternalComponent(replAllBtn);
- NEW(wrapBtn);
- wrapBtn.alignment.Set(WMComponents.AlignLeft);
- wrapBtn.caption.SetAOC("Wrap");
- wrapBtn.isToggle.Set(TRUE);
- wrapBtn.SetPressed(wrap);
- wrapBtn.onClick.Add(WrapHandler);
- lowerPanel.AddInternalComponent(wrapBtn);
- NEW(caseSensitiveBtn);
- caseSensitiveBtn.alignment.Set(WMComponents.AlignLeft);
- caseSensitiveBtn.caption.SetAOC("CaseSensitive");
- caseSensitiveBtn.isToggle.Set(TRUE);
- caseSensitiveBtn.SetPressed(caseSensitive);
- caseSensitiveBtn.bounds.SetWidth(80);
- caseSensitiveBtn.onClick.Add(CaseSensitiveHandler);
- lowerPanel.AddInternalComponent(caseSensitiveBtn);
- NEW(directionBtn);
- directionBtn.alignment.Set(WMComponents.AlignLeft);
- directionBtn.caption.SetAOC("Backwards");
- directionBtn.isToggle.Set(TRUE);
- directionBtn.SetPressed(backwards);
- directionBtn.bounds.SetWidth(80);
- directionBtn.onClick.Add(DirectionHandler);
- lowerPanel.AddInternalComponent(directionBtn);
- NEW(markAllBtn);
- markAllBtn.alignment.Set(WMComponents.AlignLeft);
- markAllBtn.bounds.SetWidth(80);
- markAllBtn.caption.SetAOC("Highlight");
- markAllBtn.isToggle.Set(TRUE);
- markAllBtn.SetPressed(highlightAll);
- markAllBtn.onClick.Add(HighlightAllHandler);
- lowerPanel.AddInternalComponent(markAllBtn);
- NEW(closeBtn);
- closeBtn.alignment.Set(WMComponents.AlignLeft);
- closeBtn.caption.SetAOC("Close");
- closeBtn.bounds.SetWidth(80);
- closeBtn.onClick.Add(CloseHandler);
- lowerPanel.AddInternalComponent(closeBtn);
- NEW(positionStack);
- END Init;
- PROCEDURE SetToLastSelection*;
- VAR
- currentSearchString, searchString : SearchString;
- selectionText : Texts.Text; from, to : Texts.TextPosition;
- a, b : LONGINT;
- BEGIN
- searchString := "";
- IF Texts.GetLastSelection(selectionText, from, to) THEN
- selectionText.AcquireRead;
- a := MIN(from.GetPosition(), to.GetPosition());
- b := MAX(from.GetPosition(), to.GetPosition());
- IF ((b - a) <= SearchStringMaxLen) THEN
- TextUtilities.SubTextToStr(selectionText, a, b - a, searchString);
- END;
- Strings.TrimWS(searchString);
- selectionText.ReleaseRead;
- END;
- searchEdit.GetAsString(currentSearchString);
- IF (searchString # "") & (searchString # currentSearchString) THEN
- searchEdit.SetAsString(searchString);
- searchEdit.text.AcquireRead;
- searchEdit.tv.selection.SetFromTo(0, searchEdit.text.GetLength());
- searchEdit.text.ReleaseRead;
- END;
- END SetToLastSelection;
- PROCEDURE SetText*(t: Texts.Text);
- BEGIN
- text := t;
- posValid := FALSE
- END SetText;
- PROCEDURE SetTextView*(tv: WMTextView.TextView);
- BEGIN
- IF (textView # tv) THEN
- textView := tv;
- IF highlights # NIL THEN
- DisableUpdate; highlights.RemoveAll; EnableUpdate; textView.Invalidate;
- END;
- NEW(highlights, textView);
- END;
- posValid := FALSE;
- END SetTextView;
- PROCEDURE ToggleVisibility*;
- VAR searchString : SearchString;
- BEGIN
- IF ~visible.Get() THEN
- visible.Set(TRUE);
- searchEdit.SetAsString("");
- SetToLastSelection;
- searchEdit.SetFocus;
- ELSE
- searchEdit.GetAsString(searchString);
- IF searchString = "" THEN
- replEdit.SetAsString("");
- visible.Set(FALSE);
- IF (textView # NIL) THEN textView.SetFocus; END;
- ELSE
- searchEdit.SetAsString("");
- searchEdit.SetFocus;
- END;
- END;
- END ToggleVisibility;
- PROCEDURE HandlePreviousNext*(forward : BOOLEAN);
- VAR oldBackwards : BOOLEAN;
- BEGIN
- IF (textView # NIL) THEN textView.SetFocus; END;
- IF visible.Get() THEN
- oldBackwards := backwards;
- backwards := ~forward;
- SearchHandler(NIL, NIL);
- backwards := oldBackwards;
- END;
- END HandlePreviousNext;
- PROCEDURE HandleTab*() : BOOLEAN;
- BEGIN
- IF (visible.Get()) THEN
- (* hack - should not access hasFocus field *)
- IF searchEdit.tv.hasFocus THEN
- replEdit.SetFocus;
- replEdit.Invalidate;
- RETURN TRUE;
- ELSIF replEdit.tv.hasFocus THEN
- searchEdit.SetFocus;
- searchEdit.Invalidate;
- RETURN TRUE;
- END;
- END;
- RETURN FALSE;
- END HandleTab;
- PROCEDURE HandleShortcut*(ucs : LONGINT; flags : SET; keysym : LONGINT) : BOOLEAN;
- PROCEDURE ControlKeyDown(flags : SET) : BOOLEAN;
- BEGIN
- RETURN (flags * Inputs.Ctrl # {}) & (flags - Inputs.Ctrl = {});
- END ControlKeyDown;
- BEGIN
- IF (keysym = 06H) & ControlKeyDown(flags)THEN (* CTRL-F *)
- ToggleVisibility;
- ELSIF (keysym= 0EH) & ControlKeyDown(flags) THEN (* CTRL-N *)
- HandlePreviousNext(TRUE);
- ELSIF (keysym = 10H) & ControlKeyDown(flags) THEN (* CTRL-P *)
- HandlePreviousNext(FALSE);
- ELSIF (keysym = Inputs.KsTab) & (flags = {}) THEN (* TAB *)
- RETURN HandleTab();
- ELSE
- RETURN FALSE; (* Key not handled *)
- END;
- RETURN TRUE;
- END HandleShortcut;
- PROCEDURE FocusHandler(hasFocus: BOOLEAN);
- BEGIN
- IF textView = NIL THEN RETURN END;
- IF hasFocus THEN
- pos := textView.cursor.GetPosition();
- positionStack.Invalidate;
- END;
- END FocusHandler;
- PROCEDURE WrapHandler(sender, data: ANY);
- BEGIN
- wrap := ~wrap;
- END WrapHandler;
- PROCEDURE CaseSensitiveHandler(sender, data : ANY);
- BEGIN
- caseSensitive := ~caseSensitive;
- END CaseSensitiveHandler;
- PROCEDURE DirectionHandler(sender, data : ANY);
- BEGIN
- backwards := ~backwards;
- END DirectionHandler;
- PROCEDURE HighlightAllHandler(sender, data : ANY);
- BEGIN
- highlightAll := ~highlightAll;
- IF highlightAll THEN
- DisableUpdate; SearchAndHighlightAll; EnableUpdate; markAllBtn.Invalidate; textView.Invalidate;
- ELSE
- DisableUpdate; RemoveHighlights; EnableUpdate; textView.Invalidate;
- markAllBtn.SetCaption("Highlight");
- END;
- END HighlightAllHandler;
- PROCEDURE TextChanged(sender, data: ANY);
- VAR
- changeInfo: Texts.TextChangeInfo;
- from : LONGINT;
- BEGIN
- IF ~IsCallFromSequencer() THEN
- (* We need to use DisableUpdate/EnableUpdate in order to get reasonable performance... This requires
- the call to come from the component's sequencer *)
- sequencer.ScheduleEvent(SELF.TextChanged, sender, data)
- ELSE
- IF data IS Texts.TextChangeInfo THEN
- changeInfo := data(Texts.TextChangeInfo);
- IF (changeInfo.op = Texts.OpInsert) & (changeInfo.len = 1) THEN
- positionStack.Push(pos);
- IF highlightAll THEN DisableUpdate; RemoveHighlights; SearchAndHighlightAll; EnableUpdate; markAllBtn.Invalidate; textView.Invalidate; END;
- SearchAndHighlight(pos);
- ELSIF (changeInfo.op = Texts.OpDelete) & (changeInfo.len = 1) THEN
- from := positionStack.Pop();
- IF from = 1 THEN from := pos END;
- IF highlightAll THEN DisableUpdate; RemoveHighlights; SearchAndHighlightAll; EnableUpdate; markAllBtn.Invalidate; textView.Invalidate;END;
- SearchAndHighlight(from);
- ELSE
- positionStack.Invalidate();
- IF (textView # NIL) THEN textView.selection.SetFromTo(0, 0); END;
- IF highlightAll THEN DisableUpdate; RemoveHighlights; EnableUpdate; markAllBtn.Invalidate; textView.Invalidate; END;
- END;
- END;
- END;
- END TextChanged;
- PROCEDURE SearchHandler*(sender, data: ANY);
- BEGIN
- IF textView = NIL THEN RETURN END;
- SearchAndHighlight(textView.cursor.GetPosition());
- END SearchHandler;
- PROCEDURE ReplaceHandler(sender, data: ANY);
- VAR replStr : SearchString; ucsStr: UcsSearchString; idx: LONGINT;
- BEGIN
- IF text = NIL THEN RETURN END;
- IF posValid THEN
- replEdit.GetAsString(replStr);
- idx := 0;
- UTF8Strings.UTF8toUnicode(replStr, ucsStr, idx);
- text.AcquireWrite();
- Replace(ucsStr);
- text.ReleaseWrite();
- Highlight;
- SearchHandler(sender, data);
- END;
- END ReplaceHandler;
- PROCEDURE ReplaceAllHandler(sender, data: ANY);
- VAR
- searchStr, replStr : SearchString;
- ucsSearchStr, ucsReplStr : UcsSearchString;
- oldBackwards : BOOLEAN;
- idx: LONGINT;
- BEGIN
- IF text = NIL THEN RETURN END;
- replEdit.GetAsString(replStr);
- idx := 0;
- UTF8Strings.UTF8toUnicode(replStr, ucsReplStr, idx);
- searchEdit.GetAsString(searchStr);
- idx := 0;
- UTF8Strings.UTF8toUnicode(searchStr, ucsSearchStr, idx);
- text.AcquireWrite();
- text.AcquireRead();
- oldBackwards := backwards;
- backwards := FALSE;
- Search(ucsSearchStr, 0);
- WHILE posValid DO
- Replace(ucsReplStr);
- Search(ucsSearchStr, pos + len);
- END;
- backwards := oldBackwards;
- text.ReleaseRead();
- text.ReleaseWrite();
- END ReplaceAllHandler;
- PROCEDURE Replace(CONST ucsStr: ARRAY OF Texts.Char32);
- BEGIN
- text.Delete(pos, len);
- text.InsertUCS32(pos, ucsStr);
- len := TextUtilities.UCS32StrLength(ucsStr);
- posValid := FALSE;
- END Replace;
- PROCEDURE Search(CONST ucsStr: ARRAY OF Texts.Char32; from: LONGINT);
- BEGIN
- IF ucsStr[0] = 0 THEN posValid := FALSE; RETURN; END;
- IF caseSensitive & ~backwards THEN
- pos := TextUtilities.Pos(ucsStr, from, text);
- ELSE
- (* We want to search the text that's on the left hand side of the cursor. If we start searching at position 'from',
- we also consider the character at the current cursor position, which is on the left hand side of the cursro *)
- IF (backwards) & (from > 1) THEN DEC(from); END;
- pos := TextUtilities.GenericPos(ucsStr, from, text, ~caseSensitive, backwards);
- END;
- len := TextUtilities.UCS32StrLength(ucsStr);
- IF pos > -1 THEN posValid := TRUE
- ELSE posValid := FALSE
- END;
- END Search;
- PROCEDURE SearchAndHighlight(from: LONGINT);
- VAR searchStr : SearchString; ucsStr: UcsSearchString; length, idx : LONGINT;
- BEGIN
- IF text = NIL THEN RETURN END;
- searchEdit.GetAsString(searchStr);
- IF searchStr # "" THEN
- idx := 0;
- UTF8Strings.UTF8toUnicode(searchStr, ucsStr, idx);
- text.AcquireRead();
- Search(ucsStr, from);
- (* Detect whether we have found the last search result again but in different search direction *)
- IF (((pos = lastPos) OR (lastPos = -1)) & (lastBackwards # backwards)) THEN
- length := TextUtilities.UCS32StrLength(ucsStr);
- IF backwards THEN
- IF from >= length - 1 THEN
- Search(ucsStr, from - Strings.Length(searchStr));
- END;
- ELSE
- IF from + length < text.GetLength() THEN
- Search(ucsStr, from + Strings.Length(searchStr));
- END;
- END;
- END;
- IF (pos = -1) & wrap THEN
- IF backwards THEN
- Search(ucsStr, text.GetLength() - 1);
- ELSE
- Search(ucsStr, 0);
- END;
- END;
- text.ReleaseRead();
- END;
- lastPos := pos; lastBackwards := backwards;
- Highlight;
- END SearchAndHighlight;
- PROCEDURE SearchAndHighlightAll;
- VAR
- searchString : SearchString;
- ucsStr : UcsSearchString;
- caption : ARRAY 32 OF CHAR; nbr : ARRAY 12 OF CHAR;
- length, idx, pos : LONGINT; from : LONGINT;
- BEGIN
- IF (text = NIL) OR (highlights = NIL) THEN RETURN; END;
- hitCount := 0;
- searchEdit.GetAsString(searchString);
- IF searchString # "" THEN
- idx := 0;
- UTF8Strings.UTF8toUnicode(searchString, ucsStr, idx);
- length := TextUtilities.UCS32StrLength(ucsStr);
- from := 0; pos := 0;
- WHILE(pos >=0) DO
- text.AcquireRead;
- IF caseSensitive THEN pos := TextUtilities.Pos(ucsStr, from, text);
- ELSE pos := TextUtilities.GenericPos(ucsStr, from, text, ~caseSensitive, FALSE);
- END;
- text.ReleaseRead;
- IF pos >= 0 THEN
- INC(hitCount);
- highlights.Add(pos, pos + length);
- from := pos + 1;
- END;
- END;
- END;
- caption := "Highlight:";
- Strings.IntToStr(hitCount, nbr); Strings.Append(caption, nbr);
- markAllBtn.caption.SetAOC(caption);
- END SearchAndHighlightAll;
- PROCEDURE RemoveHighlights;
- BEGIN
- IF (highlights # NIL) THEN highlights.RemoveAll; END;
- END RemoveHighlights;
- PROCEDURE Highlight;
- VAR searchString : SearchString;
- BEGIN
- IF textView = NIL THEN RETURN END;
- IF posValid THEN
- textView.selection.SetFrom(pos);
- textView.selection.SetTo(pos + len);
- IF backwards THEN
- textView.cursor.SetPosition(pos);
- ELSE
- textView.cursor.SetPosition(pos + len);
- END;
- END;
- searchEdit.GetAsString(searchString);
- IF (searchString = "") THEN textView.selection.SetFromTo(0, 0); END;
- END Highlight;
- PROCEDURE CloseHandler(sender, data: ANY);
- BEGIN
- IF highlights # NIL THEN
- DisableUpdate; RemoveHighlights; EnableUpdate; textView.Invalidate;
- END;
- visible.Set(FALSE);
- IF textView # NIL THEN textView.selection.SetFromTo(0, 0); END;
- END CloseHandler;
- PROCEDURE SetSettings*(wrap, caseSensitive, backwards, highlightAll : BOOLEAN);
- BEGIN
- SELF.wrap := wrap;
- SELF.caseSensitive := caseSensitive;
- SELF.backwards := backwards;
- SELF.highlightAll := highlightAll;
- wrapBtn.SetPressed(wrap);
- caseSensitiveBtn.SetPressed(caseSensitive);
- directionBtn.SetPressed(backwards);
- markAllBtn.SetPressed(highlightAll);
- END SetSettings;
- PROCEDURE GetSettings*(VAR wrap, caseSensitive, backwards, highlightAll : BOOLEAN);
- BEGIN
- wrap := SELF.wrap;
- caseSensitive := SELF.caseSensitive;
- backwards := SELF.backwards;
- highlightAll := SELF.highlightAll;
- END GetSettings;
- PROCEDURE Finalize*;
- BEGIN
- Finalize^;
- IF searchEdit # NIL THEN searchEdit.text.onTextChanged.Remove(TextChanged); END;
- END Finalize;
- END SearchPanel;
- TYPE
- SearchWindow* = OBJECT(WMComponents.FormWindow)
- VAR
- searchPanel : SearchPanel;
- hasBeenClosed- : BOOLEAN;
- PROCEDURE SetTextView*(textView : WMTextView.TextView; text : Texts.Text);
- BEGIN
- ASSERT((textView # NIL) & (text # NIL));
- searchPanel.SetText(text);
- searchPanel.SetTextView(textView);
- END SetTextView;
- PROCEDURE &New*(textView : WMTextView.TextView; text : Texts.Text);
- BEGIN
- ASSERT((textView # NIL) & (text # NIL));
- hasBeenClosed := FALSE;
- NEW(searchPanel);
- searchPanel.fillColor.Set(WMGraphics.White);
- searchPanel.alignment.Set(WMComponents.AlignClient);
- searchPanel.bounds.SetExtents(700, 40);
- searchPanel.closeBtn.visible.Set(FALSE);
- SetTextView(textView, text);
- Init(searchPanel.bounds.GetWidth(), searchPanel.bounds.GetHeight(), FALSE);
- SetContent(searchPanel);
- SetTitle(Strings.NewString("Search"));
- WMWindowManager.DefaultAddWindow(SELF);
- END New;
- PROCEDURE Close*;
- BEGIN
- Close^;
- IF searchPanel.highlights # NIL THEN
- searchPanel.RemoveHighlights; searchPanel.textView.Invalidate;
- END;
- searchPanel.textView.selection.SetFromTo(0, 0);
- hasBeenClosed := TRUE;
- END Close;
- PROCEDURE HandleShortcut(ucs : LONGINT; flags : SET; keysym : LONGINT) : BOOLEAN;
- PROCEDURE ControlKeyDown(flags : SET) : BOOLEAN;
- BEGIN
- RETURN (flags * Inputs.Ctrl # {}) & (flags - Inputs.Ctrl = {});
- END ControlKeyDown;
- PROCEDURE HandlePreviousNext(forward : BOOLEAN);
- VAR oldBackwards : BOOLEAN;
- BEGIN
- IF searchPanel.visible.Get() THEN
- oldBackwards := searchPanel.backwards;
- searchPanel.backwards := ~forward;
- searchPanel.SearchHandler(NIL, NIL);
- searchPanel.backwards := oldBackwards;
- END;
- END HandlePreviousNext;
- BEGIN
- IF (keysym = 06H) & ControlKeyDown(flags)THEN (* CTRL-F *)
- searchPanel.searchEdit.SetAsString("");
- searchPanel.searchEdit.SetFocus;
- ELSIF (keysym= 0EH) & ControlKeyDown(flags) THEN (* CTRL-N *)
- HandlePreviousNext(TRUE);
- ELSIF (keysym = 10H) & ControlKeyDown(flags) THEN (* CTRL-P *)
- HandlePreviousNext(FALSE);
- ELSE
- RETURN FALSE; (* Key not handled *)
- END;
- RETURN TRUE;
- END HandleShortcut;
- PROCEDURE Handle*(VAR m: WMMessages.Message);
- BEGIN
- IF m.msgType = WMMessages.MsgKey THEN
- IF ~HandleShortcut(m.x, m.flags, m.y) THEN
- Handle^(m);
- END;
- ELSE Handle^(m)
- END
- END Handle;
- END SearchWindow;
- VAR
- StrSearchPanel : Strings.String;
- BEGIN
- StrSearchPanel := Strings.NewString("SearchPanel");
- END WMSearchComponents.
|