richsearchwinc.c
来自「linux下的E_MAIL客户端源码」· C语言 代码 · 共 559 行
C
559 行
/* * $Id: RichSearchWinC.C,v 1.3 2000/05/07 12:26:11 fnevgeny Exp $ * * Copyright (c) 1994 HAL Computer Systems International, Ltd. * * HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. * 1315 Dell Avenue * Campbell, CA 95008 * * Author: Greg Hilton * Contributors: Tom Lang, Frank Bieser, and others * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * http://www.gnu.org/copyleft/gpl.html * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <config.h>#include "RichSearchWinC.h"#include "MimeRichTextC.h"#include "MimeRichTextP.h"#include "RegexC.h"#include "WArgList.h"#include "HalAppC.h"#include "TextMisc.h"#include "rsrc.h"#include <Xm/Form.h>#include <Xm/PushB.h>#include <Xm/TextF.h>#include <Xm/Label.h>#include <Xm/ToggleB.h>/*--------------------------------------------------------------- * Constructor */RichSearchWinC::RichSearchWinC(Widget parent, const char *name, ArgList argv, Cardinal argc) : HalDialogC(name, parent, argv, argc){ rich = NULL; WArgList args;//// Create appForm hierarchy//// appForm// Label stringLabel// TextField stringTF// ToggleButton caseTB// ToggleButton backTB// ToggleButton wildTB// args.Reset(); args.TopAttachment(XmATTACH_FORM); args.LeftAttachment(XmATTACH_FORM); args.RightAttachment(XmATTACH_NONE); args.BottomAttachment(XmATTACH_NONE); Widget stringLabel = XmCreateLabel(appForm, "stringLabel", ARGS); args.TopAttachment(XmATTACH_WIDGET, stringLabel); args.RightAttachment(XmATTACH_FORM); stringTF = CreateTextField(appForm, "stringTF", ARGS); args.Reset(); args.TopAttachment(XmATTACH_WIDGET, stringTF); args.LeftAttachment(XmATTACH_FORM); args.RightAttachment(XmATTACH_NONE); args.BottomAttachment(XmATTACH_NONE); caseTB = XmCreateToggleButton(appForm, "caseTB", ARGS); args.TopAttachment(XmATTACH_WIDGET, caseTB); wildTB = XmCreateToggleButton(appForm, "wildTB", ARGS); args.TopAttachment(XmATTACH_WIDGET, wildTB); backTB = XmCreateToggleButton(appForm, "backTB", ARGS); XtManageChild(stringLabel); XtManageChild(stringTF); XtManageChild(caseTB); XtManageChild(wildTB); XtManageChild(backTB); XtAddCallback(caseTB, XmNvalueChangedCallback, (XtCallbackProc)ToggleCase, this); XtAddCallback(wildTB, XmNvalueChangedCallback, (XtCallbackProc)ToggleWild, this);//// Create buttons// AddButtonBox(); Widget findPB = XmCreatePushButton(buttonRC, "findPB", 0,0); Widget donePB = XmCreatePushButton(buttonRC, "donePB", 0,0); Widget helpPB = XmCreatePushButton(buttonRC, "helpPB", 0,0); XtAddCallback(findPB, XmNactivateCallback, (XtCallbackProc)DoFind, this); XtAddCallback(donePB, XmNactivateCallback, (XtCallbackProc)DoHide, this); XtAddCallback(helpPB, XmNactivateCallback, (XtCallbackProc)HalAppC::DoHelp, (char *) "helpcard"); XtManageChild(findPB); XtManageChild(donePB); XtManageChild(helpPB); ShowInfoMsg(); // Add message line HandleHelp();} // End constructor/*--------------------------------------------------------------- * Method to display the search window */voidRichSearchWinC::Show(MimeRichTextP *text){ rich = text; HalDialogC::Show(rich->pub->MainWidget());}voidRichSearchWinC::Show(Widget over){ HalDialogC::Show(over);}voidRichSearchWinC::Show(){ HalDialogC::Show();}/*--------------------------------------------------------------- * Callback to toggle of case-sensitive and wildcard buttons. Only * one of the two can be selected. */voidRichSearchWinC::ToggleCase(Widget, RichSearchWinC *This, XtPointer data){ XmToggleButtonCallbackStruct *tb = (XmToggleButtonCallbackStruct*)data; if ( tb->set ) XmToggleButtonSetState(This->wildTB, False, False);}voidRichSearchWinC::ToggleWild(Widget, RichSearchWinC *This, XtPointer data){ XmToggleButtonCallbackStruct *tb = (XmToggleButtonCallbackStruct*)data; if ( tb->set ) XmToggleButtonSetState(This->caseTB, False, False);}/*--------------------------------------------------------------- * Callback to handle press of find button */voidRichSearchWinC::DoFind(Widget, RichSearchWinC *This, XtPointer){ This->ClearMessage();//// Get pattern// if ( XmTextFieldGetLastPosition(This->stringTF) <= 0 ) { set_invalid(This->stringTF, True, True); This->PopupMessage("Please enter a search string."); return; } char *searchStr = XmTextFieldGetString (This->stringTF); Boolean checkCase = XmToggleButtonGetState(This->caseTB); Boolean wildcard = XmToggleButtonGetState(This->wildTB); Boolean reverse = XmToggleButtonGetState(This->backTB); TextLineC *bline = This->rich->cursorPos.textLine; Boolean found = False; TextLineC *line;//// If they entered a wildcard pattern, use a regular expression// if ( wildcard ) { RegexC pat(searchStr);//// Look forward or backward from the current cursor position// if ( reverse ) {//// Check lines above cursor// line = bline; while ( !found && line ) { found = This->RevSearchLine(line, pat, False/*before cursor*/); line = line->prev; }//// Wrap to bottom of text and check lines below cursor// line = This->rich->botTextLine; while ( !found && line && line != bline ) { found = This->RevSearchLine(line, pat, True/*after cursor*/); line = line->prev; } } // End if looking backward else { // Looking forward//// Check lines below cursor// line = bline; while ( !found && line ) { found = This->SearchLine(line, pat, True/*after cursor*/); line = line->next; }//// Wrap to top of text and check lines above cursor// line = This->rich->topTextLine; while ( !found && line && line != bline ) { found = This->SearchLine(line, pat, False/*before cursor*/); line = line->next; } } // End if looking forward } // End if using a wildcard else { // Not using a wildcard CharC str = searchStr;//// Look forward or backward from the current cursor position// if ( reverse ) {//// Check lines above cursor// line = bline; while ( !found && line ) { found = This->RevSearchLine(line, str, False/*before cursor*/, checkCase); line = line->prev; }//// Wrap to bottom of text and check lines below cursor// line = This->rich->botTextLine; while ( !found && line && line != bline ) { found = This->RevSearchLine(line, str, True/*after cursor*/, checkCase); line = line->prev; } } // End if looking backward else { // Looking forward//// Check lines below cursor// line = bline; while ( !found && line ) { found = This->SearchLine(line, str, True/*after cursor*/, checkCase); line = line->next; }//// Wrap to top of text and check lines above cursor// line = This->rich->topTextLine; while ( !found && line && line != bline ) { found = This->SearchLine(line, str, False/*before cursor*/, checkCase); line = line->next; } } // End if looking forward } // End if not using a wildcard XtFree(searchStr); if ( !found ) { This->Message("No match"); XBell(halApp->display, 0); }} // End DoFind/*--------------------------------------------------------------- * Method to search forward in a line for the given regex */BooleanRichSearchWinC::SearchLine(TextLineC *line, RegexC& pat, Boolean afterCursor){ Boolean found = False; u_int cmdCount = line->cmdList.size(); for (int i=0; !found && i<cmdCount; i++) { RichCmdC *cmd = line->Cmd(i); if ( !cmd->IsText() ) continue; int startPos = 0; if ( line == rich->cursorPos.textLine ) {//// Ignore text to the left of the cursor// if ( afterCursor ) { if ( i < rich->cursorPos.cmdPos ) continue; else if ( i == rich->cursorPos.cmdPos ) startPos = rich->cursorPos.strPos; }//// Ignore text to the right of the cursor// else if ( i > rich->cursorPos.cmdPos ) continue; }//// Look for pattern in current text segment// if ( startPos < cmd->text->size() ) { int findPos = pat.search(*cmd->text, startPos); found = (findPos >= 0); if ( found ) { TextPosC begPos(line, i, findPos); TextPosC endPos(line, i, findPos + pat[0].length()); UpdateSelection(begPos, endPos, endPos); } } } // End for each text string in line return found;} // End SearchLine/*--------------------------------------------------------------- * Method to search backward in a line for the given regex */BooleanRichSearchWinC::RevSearchLine(TextLineC *line, RegexC& pat, Boolean afterCursor){ Boolean found = False; u_int cmdCount = line->cmdList.size(); for (int i=cmdCount-1; !found && i>=0; i--) { RichCmdC *cmd = line->Cmd(i); if ( !cmd->IsText() ) continue; int startPos = cmd->text->size()-1; if ( line == rich->cursorPos.textLine ) {//// Ignore text to the right of the cursor// if ( !afterCursor ) { if ( i > rich->cursorPos.cmdPos ) continue; else if ( i == rich->cursorPos.cmdPos ) startPos = rich->cursorPos.strPos - 1; }//// Ignore text to the right of the cursor// else if ( i < rich->cursorPos.cmdPos ) continue; }//// Look for pattern in current text segment// if ( startPos > 0 ) { int findPos = pat.search(*cmd->text, startPos, -startPos); found = (findPos >= 0); if ( found ) { TextPosC begPos(line, i, findPos); TextPosC endPos(line, i, findPos + pat[0].length()); UpdateSelection(begPos, endPos, begPos); } } } // End for each text string in line return found;} // End RevSearchLine/*--------------------------------------------------------------- * Method to search forward in a line for the given character string */BooleanRichSearchWinC::SearchLine(TextLineC *line, CharC& str, Boolean afterCursor, Boolean checkCase){ Boolean found = False; u_int cmdCount = line->cmdList.size(); for (int i=0; !found && i<cmdCount; i++) { RichCmdC *cmd = line->Cmd(i); if ( !cmd->IsText() ) continue; u_int startPos = 0; if ( line == rich->cursorPos.textLine ) {//// Ignore text to the left of the cursor// if ( afterCursor ) { if ( i < rich->cursorPos.cmdPos ) continue; else if ( i == rich->cursorPos.cmdPos ) startPos = rich->cursorPos.strPos; }//// Ignore text to the right of the cursor// else if ( i > rich->cursorPos.cmdPos ) continue; }//// Look for string in current text segment// if ( startPos < cmd->text->size() ) { int findPos = cmd->text->PosOf(str, startPos, checkCase); found = (findPos >= 0); if ( found ) { TextPosC begPos(line, i, findPos); TextPosC endPos(line, i, findPos + str.Length()); UpdateSelection(begPos, endPos, endPos); } } } // End for each text string in line return found;} // End SearchLine/*--------------------------------------------------------------- * Method to search backward in a line for the given character string */BooleanRichSearchWinC::RevSearchLine(TextLineC *line, CharC& str, Boolean afterCursor, Boolean checkCase){ Boolean found = False; u_int cmdCount = line->cmdList.size(); for (int i=cmdCount-1; !found && i>=0; i--) { RichCmdC *cmd = line->Cmd(i); if ( !cmd->IsText() ) continue; u_int startPos = cmd->text->size(); if ( line == rich->cursorPos.textLine ) {//// Ignore text to the right of the cursor// if ( !afterCursor ) { if ( i > rich->cursorPos.cmdPos ) continue; else if ( i == rich->cursorPos.cmdPos ) startPos = rich->cursorPos.strPos; }//// Ignore text to the right of the cursor// else if ( i < rich->cursorPos.cmdPos ) continue; }//// Look for string in current text segment// if ( startPos > 0 ) { int findPos = cmd->text->RevPosOf(str, startPos, checkCase); found = (findPos >= 0); if ( found ) { TextPosC begPos(line, i, findPos); TextPosC endPos(line, i, findPos + str.Length()); UpdateSelection(begPos, endPos, begPos); } } } // End for each text string in line return found;} // End RevSearchLine/*--------------------------------------------------------------- * Method to update the selection in the rich text widget */voidRichSearchWinC::UpdateSelection(TextPosC& begPos, TextPosC& endPos, TextPosC& newCursorPos){ ScreenPosC spos = begPos; rich->HideCursor(); if ( rich->selectOn ) { rich->DrawSelection(); rich->selectOn = False; } rich->selectBegPos = begPos; rich->selectEndPos = endPos; rich->cursorPos = newCursorPos; rich->desiredCursorX = spos.x; rich->ScrollToCursor(); rich->DrawSelection(); rich->selectOn = True; rich->ShowCursor();}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?