home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1998 March
/
VPR9803B.ISO
/
APUPDATE
/
VC
/
Tx300b
/
TX300B.LZH
/
SEARCH.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-06-13
|
127KB
|
4,856 lines
// WZ EDITOR 標準機能 検索
// Copyright 1995-96 TY
// WZ2.0新型検索ダイアログ: thanks y.mikomeさん
//{###検索・置換}
//2.92 検索置換リストを拡張し、複数の文字列の検索・置換を一度に行えるようにした
//2.92 通常の検索・置換操作の延長で、複数文字列検索置換を行えるようにした
//2.92 Grepでも使用できる
//2.99C 970324 wndtxCallNext -> wndtxCallNextEx
//2.99C 970324 wndtxCallBoth -> wndtxCallBothEx
//2.99D 970331 TXCMDBASE対応
//1.00D search.tllを利用する場合、
// 予め#include "dialog.h"しておかなければならなかったが不要にした
#export
#include "dialog.h"
#endexport
#include <windows.h>
#include <windowsx.h>
#define IDD_PREV 2001
#define IDD_NEXT 2002
#define IDD_ALL 2003
#define IDD_AREA 2004
#define IDD_TOREPLACE 2005
#define IDD_SEARCH 2006
#define IDD_CASE 2007
#define IDD_ZENHAN 2008
#define IDD_WORD 2009
#define IDD_RE 2010
#define IDD_NOESC 2011
#define IDD_ALLTEXT 2012
#define IDD_MODETOP 2013
#define IDD_MODEEND 2016
#define IDD_OPTION 2017
#define IDD_REPLACE 2019
#define IDD_ADD 2020
#define IDD_EDIT 2021
#define IDD_DEL 2022
#define IDD_ADDCATEGORY 2023
#define IDD_COPY 2024
#define IDD_PASTE 2025
#define IDD_SEARCHLOOK 2026 //2.95 970130
#define IDD_SEARCHSPECIAL 2027 //2.97 970225
#define IDD_TARGET 2028 //2.97 970225
#define IDD_NOSYMBOL 2029 //2.98 970309
#define IDD_TITLENAME 2030 //3.00A2 970506
// grep.cと共通値
#define IDD_SZFIND 3000
#define IDD_SZREPLACE 3001
#define IDD_REFERSEARCHLIST 3002
//
#define IDD_MODEREPLACETOP 3100
#define IDD_MODEREPLACEEND 3109
#define bitequ(dst,flag,bit) if (flag) {(dst) |= (bit);} else {(dst) &= ~(bit);}
static mchar _szIdSearchlist[] = "\\検索リスト:";
static BYTE _lchIdSearchlist = 9;
//次だと、うまくいかない。TX-Cの仕様
//static BYTE _lchIdSearchlist = sizeof(_szIdSearchlist) - 1;
extern "tx" {
//1.00F キーボードマクロに検索ダイアログを開いた検索を記録できるようにした
// 入力された検索文字列自体は記録せず、"txSearchContinue"のように記録します。
BOOL TXAPI keymacroDoing(void);
BOOL TXAPI keymacroPop(void);
BOOL TXAPI keymacroAdd(WZCMD wzcmd);
}
typedef struct {
BYTE modeDirection;
#define DIR_PREV 0
#define DIR_NEXT 1
BYTE modeReplace;
#define REPLACE_1 0
#define REPLACE_ALL 1
#define REPLACE_AREA 2
} SEARCHCONTEXT;
static SEARCHCONTEXT _context;
static SEARCHOPT _searchopt;
BOOL TXAPI txuiSearchSetForEx(tx *text,mchar *szcaption,txstr _szfind,DWORD* searchmode);
void uiJumpAddress(TX* text);
SEARCHMODE TXAPI searchmodeFromSearchopt(SEARCHOPT* opt)
{
// text->fSearchWordなどの検索オプション指定をsearchmode書式に変換して返します
//1.00H2 で追加
DWORD searchmode = 0;
searchmode |= SEARCH_NOSENSECASE * (!opt->fSearchSenseCase);
searchmode |= SEARCH_NOSENSEZENHAN * (!opt->fSearchSenseZenhan);
searchmode |= SEARCH_WORD * (opt->fSearchWord != 0);
searchmode |= SEARCH_AREA * (opt->fSearchArea != 0);
searchmode |= SEARCH_CUR * (opt->fSearchCur != 0);
searchmode |= SEARCH_NOESC * (opt->fSearchEscapeNo != 0);
searchmode |= SEARCH_NOSYMBOL * (opt->fSearchNoSymbol != 0);//2.98 970309
searchmode |= SEARCH_RE * (opt->fSearchRE != 0);
searchmode |= SEARCH_ALLTEXT * (opt->fSearchAllText != 0);//1.01A
searchmode |= REPLACE_CONFIRM * (opt->fReplaceConfirm != 0);//2.92
if (opt->fCategory) {
switch(opt->category) {
case SEARCHCATEGORY_NORMAL: {
bitequ(searchmode,FALSE,SEARCH_NOSENSEZENHAN);
bitequ(searchmode,FALSE,SEARCH_WORD);
bitequ(searchmode,FALSE,SEARCH_RE);
break;
}
case SEARCHCATEGORY_WORD: {
bitequ(searchmode,FALSE,SEARCH_NOSENSEZENHAN);
bitequ(searchmode,TRUE,SEARCH_WORD);
bitequ(searchmode,FALSE,SEARCH_RE);
break;
}
case SEARCHCATEGORY_RE: {
bitequ(searchmode,FALSE,SEARCH_NOSENSEZENHAN);
bitequ(searchmode,FALSE,SEARCH_WORD);
bitequ(searchmode,TRUE,SEARCH_RE);
break;
}
case SEARCHCATEGORY_FUZZY: {
bitequ(searchmode,TRUE,SEARCH_NOSENSEZENHAN);
bitequ(searchmode,FALSE,SEARCH_WORD);
bitequ(searchmode,FALSE,SEARCH_RE);
bitequ(searchmode,TRUE,SEARCH_NOSENSECASE);
break;
}
}
}
return searchmode;
}
//1.01A
// optを全クリアするので注意してください
void TXAPI searchmodeToSearchopt(SEARCHMODE searchmode,SEARCHOPT* opt)
{
//1.96 clear
memset(opt,0,sizeof(SEARCHOPT));
//
opt->fSearchSenseCase = !((searchmode & SEARCH_NOSENSECASE) != 0);
opt->fSearchSenseZenhan = !((searchmode & SEARCH_NOSENSEZENHAN) != 0);
opt->fSearchWord = ((searchmode & SEARCH_WORD) != 0);
opt->fSearchArea = ((searchmode & SEARCH_AREA) != 0);
opt->fSearchCur = ((searchmode & SEARCH_CUR) != 0);
opt->fSearchEscapeNo = ((searchmode & SEARCH_NOESC) != 0);
opt->fSearchNoSymbol = ((searchmode & SEARCH_NOSYMBOL) != 0);//2.98 970310
opt->fSearchRE = ((searchmode & SEARCH_RE) != 0);
opt->fSearchAllText = ((searchmode & SEARCH_ALLTEXT) != 0);
opt->fReplaceConfirm = ((searchmode & REPLACE_CONFIRM) != 0);//2.92
//1.96
opt->category = SEARCHCATEGORY_NORMAL;
if (searchmode & SEARCH_WORD) opt->category = SEARCHCATEGORY_WORD;
if (searchmode & SEARCH_RE) opt->category = SEARCHCATEGORY_RE;
if (searchmode & SEARCH_NOSENSEZENHAN) opt->category = SEARCHCATEGORY_FUZZY;
}
static mchar _szNormal[] = "通常";
static mchar _szWord[] = "単語";
static mchar _szRe[] = "正規";
static mchar _szFuzzy[] = "曖昧";
static mchar _szNoSenseCase[] = "大小文字同一視";
static mchar _szNoEsc[] = \"'\'は通常文字";
static mchar _szNoSymbol[] = "空白と記号をスキップ";//2.98 970309
SEARCHMODE TXAPI searchmodeFromSzstr(mchar* szstr)
{
//1.96 文字列をSEARCHMODEに変換
SEARCHOPT opt;
memset(&opt,0,sizeof(SEARCHOPT));
opt.fCategory = TRUE;
opt.fSearchSenseCase = TRUE;
//
opt.category = SEARCHCATEGORY_NORMAL;
if (strstr(szstr,_szWord)) {
opt.category = SEARCHCATEGORY_WORD;
} else if (strstr(szstr,_szRe)) {
opt.category = SEARCHCATEGORY_RE;
} else if (strstr(szstr,_szFuzzy)) {
opt.category = SEARCHCATEGORY_FUZZY;
}
//
if (strstr(szstr,_szNoSenseCase)) opt.fSearchSenseCase = FALSE;
if (strstr(szstr,_szNoEsc)) opt.fSearchEscapeNo = TRUE;
if (strstr(szstr,_szNoSymbol)) opt.fSearchNoSymbol = TRUE;//2.98 970309
//
return searchmodeFromSearchopt(&opt);
}
void TXAPI searchmodeToSzstr(SEARCHMODE searchmode,txstr szstr)
{
//1.96 searchmodeを文字列に変換
SEARCHOPT opt;
searchmodeToSearchopt(searchmode,&opt);
//
szstr = "";
switch(opt.category) {
case SEARCHCATEGORY_NORMAL: szstr += _szNormal + " ";break;
case SEARCHCATEGORY_WORD: szstr += _szWord + " ";break;
case SEARCHCATEGORY_RE: szstr += _szRe + " ";break;
case SEARCHCATEGORY_FUZZY: szstr += _szFuzzy + " ";break;
}
if (!opt.fSearchSenseCase) szstr += _szNoSenseCase + " ";
if (opt.fSearchEscapeNo) szstr += _szNoEsc + " ";
if (opt.fSearchNoSymbol) szstr += _szNoSymbol + " ";//2.98 970309
}
//##エラー
err_title
{
statprintf("見出しが見つかりません");
if (text->fbeep) MessageBeep(MB_ICONEXCLAMATION);
}
err
{
SHARE* sh = text->share;
if (text->fClipSearch && !text->fClipMouse) {
//2.99 970314 再検索でtxSelectQuitしなくなったため
txSelectQuit(text);
}
if (sh->argSearchAll.szFind[0]) {
//2.96 970201 全WZで検索中
} else if (sh->fResultSearchAlltext) {
if (sh->fResultSearchAlltext == 2) {
statprintf("全WZ検索:一周しました");
} else {
statprintf("全WZ検索:ファイルが閉じられたので、中止しました");
}
sh->fResultSearchAlltext = 0;
if (text->fbeep) MessageBeep(MB_ICONEXCLAMATION);
} else {
statprintf("文字列が見つかりません");
if (text->fbeep) MessageBeep(MB_ICONEXCLAMATION);
}
}
err_clear
{
statprintf("");
}
// from search/replace
static txstr szfind;
static txstr szreplace;
static HDIALOG _hdreplace;
static BOOL _fReplace; //1.01A 前回の置換・検索は置換だったか?
//##検索/置換ダイアログ
static void histsearchAdd(mchar* szfind,DWORD searchmode,BOOL fNoSearchmode)
{
if (szfind[0]) {
wzlock(LOCK_HIST);
HSTRBLK sb = histToStrblk(HIST_SEARCH);
sbAddHist(sb,szfind);
if (!fNoSearchmode) {
//2.00C3 余計な検索モードが記憶されないようにした。
// 記憶されると、誤動作することがある。
searchmode &= (SEARCH_FORWARD|SEARCH_PREV|SEARCH_NOESC|SEARCH_NOSENSECASE|SEARCH_NOSENSEZENHAN|SEARCH_WORD|SEARCH_RE|SEARCH_ALLTEXT|SEARCH_NOSYMBOL);
//
sbWriteCustdata(sb,sbGetCount(sb) - 1,searchmode);
}
wzunlock(LOCK_HIST);
}
}
static void _dialogSearchOption(HDIALOG hd,tx *text,SEARCHOPT* searchopt,SEARCHMODE exmode)
{
BOOL fCompact = ((exmode & SEARCH_DIALOGCOMPACT) != 0);
if (exmode & SEARCH_OLDDIALOG) {
dialogGroup(hd,"文字の区別");
dialogControlID(hd,IDD_CASE);
dialogCheck(hd,"大文字と小文字を区別(&C)",&searchopt->fSearchSenseCase);
dialogControlID(hd,IDD_ZENHAN);
dialogCheck(hd,"全角と半角文字を区別(&Z)",&searchopt->fSearchSenseZenhan);
dialogGroupEnd(hd);
dialogGroup(hd,"検索モード");
dialogControlID(hd,IDD_WORD);
dialogCheck(hd,"ワードサーチ(&W)",&searchopt->fSearchWord);
dialogControlID(hd,IDD_RE);
dialogCheck(hd,"正規表現(&E)",&searchopt->fSearchRE);
dialogControlID(hd,IDD_NOESC);
dialogCheck(hd,\"\を通常文字とみなす(&Y)",&searchopt->fSearchEscapeNo);
if (exmode & SEARCH_ALLTEXT) {
dialogControlID(hd,IDD_ALLTEXT);
dialogCheck(hd,"全WZを対象(&T)",&searchopt->fSearchAllText);//1.01A
}
dialogGroupEnd(hd);
} else {
searchopt->fCategory = TRUE;
int xRight= dialogGetGroupRight(hd);
dialogSetGroupRight(hd,0);
DTRECT r;
if (fCompact) {//2.97 970225
dialogSetIntXY(hd,0,0);
dialogGetPos(hd,&r);
dialogCaption(hd,"モード:");
r.x += DTCX * 6;
dialogSetPos(hd,&r);
} else {
dialogGroup(hd,"モード");
}
dialogControlRadioV(hd);
dialogControlID(hd,IDD_MODETOP);
dialogControlHelp(hd,-292);
dialogRadioIDI(hd,&searchopt->category,"通常(&M)","単語(&W)","正規(&E)","曖昧(&X)");
if (fCompact) {
r.x += DTCX * 14;
dialogSetPos(hd,&r);
} else {
dialogGroupEndGetRect(hd,&r);
dialogGroupLFV(hd);
dialogSetGroupRight(hd,xRight);
}
//
if (fCompact) {//2.97 970225
} else {
dialogSetGroupBottom(hd,r.y + r.cy);//1.99C
dialogGroup(hd,"オプション");
}
dialogControlReverseBool(hd);
dialogControlID(hd,IDD_CASE);
dialogControlHelp(hd,186);
dialogCheck(hd,"大小文字同一視(&C)",&searchopt->fSearchSenseCase);
//
dialogControlID(hd,IDD_NOESC);
dialogControlHelp(hd,187);
dialogCheck(hd,\"\を通常文字(&Y)",&searchopt->fSearchEscapeNo);
//2.98 970309 テキスト中の改行や空白・記号を無視して、純粋な文字(英数時、ひらがなカタカナ漢字)の検索を行うオプションを追加
dialogControlID(hd,IDD_NOSYMBOL);
dialogControlHelp(hd,413);
dialogCheck(hd,"空白と記号をスキップ(&O)",&searchopt->fSearchNoSymbol);
//
if (exmode & SEARCH_ALLTEXT) {
//1.01A
dialogControlID(hd,IDD_ALLTEXT);
dialogControlHelp(hd,188);
dialogCheck(hd,"全WZを対象(&T)",&searchopt->fSearchAllText);
}
if (exmode & REPLACE_CONFIRM) {//1.99A "確認"をつけるか制御可能にした
dialogControlEnable(hd,((exmode & SEARCH_REPLACE)!= 0));
dialogControlHelp(hd,189);
dialogCheck(hd,"確認(&K)",&searchopt->fReplaceConfirm);
}
if (fCompact) {
dialogResetInt(hd);
if (exmode & SEARCH_DIALOGSLIST) {//2.97 970225
r.x += DTCX * 21;
dialogSetPos(hd,&r);
//
dialogControlID(hd,IDD_REFERSEARCHLIST);
dialogControlHelp(hd,203);
dialogButton(hd,"リスト(&L)...",NULL,9);
}
} else {
dialogGroupEnd(hd);
dialogSetGroupBottom(hd,0);//1.99C
}
dialogLF(hd);
}
}
void TXAPI dialogSearchOption(HDIALOG hd,SEARCHOPT* searchopt,SEARCHMODE exmode)
{
// ダイアログハンドルhdに検索オプションコントロールを追加します。
// 置換用のときはexmodeにSEARCH_REPLACEを指定してください。
//1.96仕様変更
if (textf->modeSearchDialog == 0) {//2.99C 970324 text1->textf
exmode |= SEARCH_OLDDIALOG;
}
_dialogSearchOption(hd,textf,searchopt,exmode);//2.99C 970324 text1->textf
}
#define MODEOPTION_NONE 0
#define MODEOPTION_WITH 1
#define MODEOPTION_ONLY 2
//1.96 モードレスダイアログ
static HWND _hwndSearch;
static TX* _txSearch; //2.90 text1以外がモードレス検索できなかった、
//プログラムも各種変更した
static BOOL _hwndSearchIsReplace;//2.97 970225
#if 0//2.99D 970402
static int _fFocusSub;//2.99C 970325
#endif
//1.99G 位置記憶
//2.97 970225 検索と置換別々に記憶
static BOOL _fWindowPos[3];
static int _x[3];
static int _y[3];
//1.99G ネスティング
static int _modeSearch;
static void mtSetContext(TX* text,BOOL fSub)
{
//2.99D 970402 new
txOp(text,TXOP_MTSETCONTEXT,fSub,0);
}
static void mtReadContext(TX* text,BOOL fSub)
{
//2.99D 970402 new
txOp(text,TXOP_MTREADCONTEXT,fSub,0);
}
static void dialogSearch(HDIALOG hd,tx *text,BOOL modeOption,SEARCHMODE exmode)
{
BOOL fCompact = ((exmode & SEARCH_DIALOGCOMPACT) != 0); //2.97 970225
if (exmode & SEARCH_REPLACE) {
dialogSetGroupRight(hd,DTCX * 42);
if (fCompact) {//2.97 970225
dialogSetH(hd);
dialogControlHelp(hd,190);
dialogControlHistRead(hd,HIST_SEARCH);
dialogControlID(hd,IDD_SZFIND);
dialogStr(hd,"検索(&S):",szfind,10,35);
dialogLFSetV(hd);
dialogControlHelp(hd,191);
dialogControlHistRead(hd,HIST_SEARCH);
dialogControlID(hd,IDD_SZREPLACE);
dialogStr(hd,"置換(&I):",szreplace,10,35);
} else {
dialogGroup(hd,"置換(&S)");
dialogControlHelp(hd,190);
dialogControlGuide(hd,"を",3);
dialogControlHistRead(hd,HIST_SEARCH);
dialogControlID(hd,IDD_SZFIND);
dialogStr(hd,NULL,szfind,0,35);
dialogControlHelp(hd,191);
dialogControlGuide(hd,"へ",3);
dialogControlHistRead(hd,HIST_SEARCH);
dialogControlID(hd,IDD_SZREPLACE);//2.00B
dialogStr(hd,NULL,szreplace,0,35);
dialogSpace(hd);
if (!text->modeSearchDialog) {//拡張オプション
dialogCheck(hd,"確認(&K)",&_searchopt.fReplaceConfirm);
}
dialogGroupEnd(hd);
}
} else {
dialogSetGroupRight(hd,DTCX * 40);
if (modeOption == MODEOPTION_ONLY) {
} else if (modeOption == MODEOPTION_WITH || text->modeSearchDialog) {//拡張オプション
if (fCompact) {//2.97 970225
dialogSetH(hd);
dialogControlHelp(hd,190);
dialogControlHistRead(hd,HIST_SEARCH);
dialogControlID(hd,IDD_SZFIND);
dialogStr(hd,"検索(&S):",szfind,10,35);
dialogLFSetV(hd);
} else {
dialogGroup(hd,"検索(&S)");//1.99C
dialogControlHelp(hd,190);
dialogControlHistRead(hd,HIST_SEARCH);
dialogControlID(hd,IDD_SZFIND);
dialogStr(hd,NULL,szfind,0,37);
dialogGroupEnd(hd);
}
} else {
if (fCompact) {//2.97 970225
dialogControlHelp(hd,190);
dialogControlHistRead(hd,HIST_SEARCH);
dialogControlID(hd,IDD_SZFIND);
dialogStr(hd,"検索(&S):",szfind,10,35);
} else {
dialogGroup(hd,"検索(&S)");
dialogSetH(hd);
dialogControlHelp(hd,190);
dialogControlHistRead(hd,HIST_SEARCH);
dialogControlID(hd,IDD_SZFIND);
dialogStr(hd,NULL,szfind,0,35);
dialogLF(hd);
dialogSetV(hd);
dialogGroupEnd(hd);
}
}
}
if (modeOption != MODEOPTION_NONE) {
searchmodeToSearchopt(text->searchmode,&_searchopt);
if (text->modeSearchDialog == 0) exmode |= SEARCH_OLDDIALOG;
if (!(exmode & SEARCH_ALLTEXT)) {
//1.99A SEARCH_ALLTEXTが無効の場合は、
// text->searchmodeでのSEARCH_ALLTEXTが有効な場合があるので、
// クリアしてやる
_searchopt.fSearchAllText = FALSE;
}
_dialogSearchOption(hd,text,&_searchopt,exmode);
}
}
static mchar *_szcaption;
#if 1 //2.99D 970330 for DEBUGWIN err
static void _searchClose(BOOL fDestroyWindow)
{
if (_hwndSearch) {
HWND hwnd = _hwndSearch;
_hwndSearch = NULL;
{//1.99G 入力されていた検索文字列などの状態をとっておく
HDIALOG hd = dialogFromHwnd(hwnd);
dialogRead(hd);
//
SEARCHMODE searchmode = searchmodeFromSearchopt(&_searchopt);
histsearchAdd(szfind,searchmode,FALSE);
}
//2.99A 970320 モードレス検索ダイアログでもIMEの状態を変更したら、テキストウィンドウにもその状態を引き継ぐ
text->fImeWasOn = imeGetOpen();
//
if (fDestroyWindow) {
dialogFree(hwnd); // dialogFreeでDestroyWindowもされる。
} else {
dialogUnlink(hwnd);
}
_txSearch = NULL;
}
}
static void searchClosed(void)
{
_searchClose(FALSE);
}
static void searchClose(void)
{
_searchClose(TRUE);
}
#else
static void searchClose(void)
{
if (_hwndSearch) {
HWND hwnd = _hwndSearch;
_hwndSearch = NULL;
{//1.99G 入力されていた検索文字列などの状態をとっておく
HDIALOG hd = dialogFromHwnd(hwnd);
dialogRead(hd);
//
SEARCHMODE searchmode = searchmodeFromSearchopt(&_searchopt);
histsearchAdd(szfind,searchmode,FALSE);
}
//2.99A 970320 モードレス検索ダイアログでもIMEの状態を変更したら、テキストウィンドウにもその状態を引き継ぐ
text->fImeWasOn = imeGetOpen();
//
#if 0//2.99D 970330 dialogFreeでDestroyWindowもされる。
DestroyWindow(hwnd);
#endif
dialogFree(hwnd);
_txSearch = NULL;
}
}
#endif
static BOOL searchExec(TX* text,int id,int *pRet,int mode)
{
int ret = 0;
*pRet = 0;
if (id) {
if (mode & SEARCHDLG_MODELESS) {
err_clear();
}
text->searchmode = searchmodeFromSearchopt(&_searchopt);
//information("%d %d",_searchopt.fSearchcategory,_searchopt.searchcategory);
if ((text->searchmode & SEARCH_WORD) && (text->searchmode & SEARCH_NOSENSEZENHAN)) {
attention("[全角と半角文字を区別]がOFFのときは、ワードサーチできません");
return FALSE;
}
//
SEARCHMODE searchmode = text->searchmode;
if (mode & SEARCHDLG_REPLACE) {
BOOL fSearchlist = !strncmp(szfind,_szIdSearchlist,_lchIdSearchlist);
if (szfind == "") {
attention("検索文字列を指定してください");
return FALSE;
}
if (!szreplace[0] && !fSearchlist) {
HDIALOG hd = dialog("置換 - 確認");
mchar buff[CCHLINE];
dialogCaption(hd,"置換文字列が指定されていません。");
sprintf(buff,"見つけた\"%s\"を全て削除します。",szfind);
dialogCaption(hd,buff);
dialogCaption(hd,"よろしいですか?");
if (!dialogOpen(hd)) return FALSE;
}
if (id == IDD_AREA) {
searchmode |= SEARCH_AREA;
} else {
searchmode &= ~SEARCH_AREA;
}
searchmode |= REPLACE_CONFIRM * (_searchopt.fReplaceConfirm);
searchmode |= SEARCH_ALL * (id == IDD_ALL);
searchmode |= SEARCH_PREV * (id == IDD_PREV);
// for return FALSE
wzlock(LOCK_SEARCHALL);
text->share->replace.searchmode = searchmode;
strcpy(text->share->replace.szFind,szfind);
strcpy(text->share->replace.szReplace,szreplace);
wzunlock(LOCK_SEARCHALL);
//1.99G 置換がヒストリに記憶されなかった
histsearchAdd(szfind,searchmode,FALSE);
histsearchAdd(szreplace,0,TRUE);// 置換文字列はsearchmodeを記録しない
//1.99G SEARCH_SELECTを追加
ret = txReplaceEx(text,szfind,szreplace,searchmode|SEARCH_SELECT);
/// ret = txReplaceEx(text,szfind,szreplace,searchmode|SEARCH_SELECT|REPLACE_CONFIRMMODAL);
} else {
histsearchAdd(szfind,searchmode,FALSE);
if (mode & SEARCHDLG_VZ) {
if (mode & SEARCHDLG_CAPTION) {
ret = !(szfind == "");
} else {
text->pagingmode = 'S';
if (szfind == "") {
// 検索モードから抜ける
txSwitchPagingMode(text);
} else {
SendMessage(text->hwndbase,WM_TXSB_SETUPTEXT,HSL_PAGE,0);
ret = TRUE;
}
}
} else {
BOOL fPrev = FALSE;
txMarkCur(text);
if (mode & SEARCHDLG_MINI) {
if (mode & SEARCHDLG_PREV) {
fPrev = TRUE;
}
} else {
if (id == IDD_PREV) {
fPrev = TRUE;
}
}
if (fPrev) {
ret = txSearchEx(text,szfind,searchmode|SEARCH_PREV);
if (keymacroDoing()) keymacroAdd(wzcmdFromSzcmd("txSearchContinuePrev"));//1.00F
} else {
ret = txSearchEx(text,szfind,searchmode);
if (keymacroDoing()) keymacroAdd(wzcmdFromSzcmd("txSearchContinue"));//1.00F
}
}
if (!ret) {
err();
}
}
}
*pRet = ret;
return TRUE;
}
#if 1//3.00B1 970613 汎用化
//2.00B [欧文]表示では、検索ダイアログの検索文字列と置換文字列のフォントをテキストのフォントと同じにした
// wndSetFontAsText()でTRUEが返ったら、hctrlをDestroyする前に必ずこれを実行すること
BOOL TXAPI wndSetFontAsText(HWND hctrl,TX* text)
{
BOOL ret = FALSE;
if (text->fCurWestern || text->share->config.fSearchSetFont) {
if (hctrl) {
LOGFONT lf;
structClear(lf);
FONTSTYLE* fs = &text->tfonttx[FONTTX_TEXT].fs;
{
HFONT hfont0 = (HFONT)SendMessage(hctrl,WM_GETFONT,0,0);
if (hfont0 && GetObject(hfont0,sizeof(lf),&lf)) {
// OK
}
}
if (text->fCurWestern) {
strcpy(lf.lfFaceName,fs->tlfFaceName[IFONT_ANK]);
if (lf.lfFaceName[0] == 0) strcpy(lf.lfFaceName,"Arial");
} else {
strcpy(lf.lfFaceName,fs->tlfFaceName[IFONT_STD]);
}
// for WZ32 : 通常は、FixedSysの高さよりもエディトボックスの高さの方が小さい
if (!stricmp(lf.lfFaceName,"FixedSys")) strcpy(lf.lfFaceName,"MS ゴシック");
#if 0 // これだとWindows3.1で文字の下が切れるので、GetObjectするようにした
RECT r;
GetClientRect(hctrl,&r);
lf.lfHeight = rectCy(&r) - 1;// -2するとWZ32+欧文TimesNewRomanで小さ過ぎ
// -1しないとWZ16+FixedSysで'_'が見えない
#endif
//
lf.lfWeight = FW_NORMAL;
lf.lfPitchAndFamily = DEFAULT_PITCH;
if (text->fCurWestern) {
lf.lfCharSet = DEFAULT_CHARSET;
} else {
lf.lfCharSet = SHIFTJIS_CHARSET;
}
HFONT hfont;
if (hfont = CreateFontIndirect(&lf)) {
ret = TRUE;
SendMessage(hctrl,WM_SETFONT,(WPARAM)hfont,0);
}
}
}
return ret;
}
//2.00B
// wndSetFontAsText()でTRUEが返ったら、hctrlをDestroyする前に必ずこれを実行すること
void TXAPI wndSetFontAsTextDelete(HWND hctrl)
{
if (hctrl) {
HFONT hfont = (HFONT)SendMessage(hctrl,WM_GETFONT,0,0);
if (hfont) {
//beep();wait(500);
DeleteObject(hfont);
}
}
}
#else
//2.00B [欧文]表示では、検索ダイアログの検索文字列と置換文字列のフォントをテキストのフォントと同じにした
static void SetFont(HWND hwnd,int id)
{
if (text->fCurWestern || text->share->config.fSearchSetFont) {
HWND hctrl = GetDlgItem(hwnd,id);
if (hctrl) {
#if 1//3.00A2 970504 「欧文+日本語」で「検索ダイアログをテキストフォントと同じ」にしても欧文フォントでの検索ができなかった
LOGFONT lf;
structClear(lf);
FONTSTYLE* fs = &text->tfonttx[FONTTX_TEXT].fs;
{
HFONT hfont0 = (HFONT)SendMessage(hctrl,WM_GETFONT,0,0);
if (hfont0 && GetObject(hfont0,sizeof(lf),&lf)) {
// OK
}
}
if (text->fCurWestern) {
strcpy(lf.lfFaceName,fs->tlfFaceName[IFONT_ANK]);
if (lf.lfFaceName[0] == 0) strcpy(lf.lfFaceName,"Arial");
} else {
strcpy(lf.lfFaceName,fs->tlfFaceName[IFONT_STD]);
}
// for WZ32 : 通常は、FixedSysの高さよりもエディトボックスの高さの方が小さい
if (!stricmp(lf.lfFaceName,"FixedSys")) strcpy(lf.lfFaceName,"MS ゴシック");
#if 0 // これだとWindows3.1で文字の下が切れるので、GetObjectするようにした
RECT r;
GetClientRect(hctrl,&r);
lf.lfHeight = rectCy(&r) - 1;// -2するとWZ32+欧文TimesNewRomanで小さ過ぎ
// -1しないとWZ16+FixedSysで'_'が見えない
#endif
//
lf.lfWeight = FW_NORMAL;
lf.lfPitchAndFamily = DEFAULT_PITCH;
if (text->fCurWestern) {
lf.lfCharSet = DEFAULT_CHARSET;
} else {
lf.lfCharSet = SHIFTJIS_CHARSET;
}
HFONT hfont;
if (hfont = CreateFontIndirect(&lf)) {
text->fSearchSetFont = TRUE;
SendMessage(hctrl,WM_SETFONT,(WPARAM)hfont,0);
}
#else
HFONT hfont = (HFONT)SendMessage(hctrl,WM_GETFONT,0,0);
LOGFONT lf;
if (hfont == NULL) {
hfont = GetStockObject(GetSystemFontNo());
}
//information("%d",hfont);
if (GetObject(hfont,sizeof(lf),&lf)) {
FONTSTYLE* fs = &text->tfonttx[FONTTX_TEXT].fs;
strcpy(lf.lfFaceName,fs->tlfFaceName[IFONT_STD]);
lf.lfWeight = FW_NORMAL;
lf.lfPitchAndFamily = DEFAULT_PITCH;
if (text->fCurWestern) {
lf.lfCharSet = DEFAULT_CHARSET;
} else {
lf.lfCharSet = SHIFTJIS_CHARSET;
}
if (hfont = CreateFontIndirect(&lf)) {
text->fSearchSetFont = TRUE;
SendMessage(hctrl,WM_SETFONT,(WPARAM)hfont,0);
}
}
#endif
}
}
}
//2.00B
static void ResetFont(HWND hwnd,int id)
{
HWND hctrl = GetDlgItem(hwnd,id);
if (hctrl) {
HFONT hfont = (HFONT)SendMessage(hctrl,WM_GETFONT,0,0);
if (hfont) {
DeleteObject(hfont);
}
}
}
#endif
static int searchlistOpen(BOOL fRefer,txstr szSelected);
#define IDD_LIST 100
extern "edit" BOOL TXAPI TXCMDBASE txClipboardCopy(TX* text);
static BOOL searchdlgGetID(void)
{
// 検索ダイアログのモードを返す
// 0:検索,1:置換,2:検索閲覧
if (_hwndSearch) {
return _hwndSearchIsReplace;
}
return 2;
}
#if 0
static void varSetXY(TX* text,int index,int x,int y)
{
txVarSet(text,"\m.x"+numtostr(index),x);
txVarSet(text,"\m.y"+numtostr(index),y);
}
static int varGetX(TX* text,int index)
{
return txVarGet(text,"\m.x"+numtostr(index));
}
static int varGetY(TX* text,int index)
{
return txVarGet(text,"\m.y"+numtostr(index));
}
#endif
static void wndMoveUncursor(HWND hwnd)
{
//2.00E3 モードレス検索ダイアログの初期位置が邪魔にならないようにした
int im = searchdlgGetID();
RECT rSearch;
GetWindowRect(hwnd,&rSearch);
RECT rText;
GetWindowRect(text->hwndtext,&rText);
_x[im] = rText.right - rectCx(&rSearch);
_y[im] = rText.bottom - rectCy(&rSearch);
SetWindowPos(hwnd,NULL,_x[im],_y[im],0,0,SWP_NOSIZE);
}
BOOL dlgprocSearchlook(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDIALOG hd = dialogFromHwnd(hwnd);
switch(message) {
case WM_INITDIALOG: {
wndMoveUncursor(hwnd);
PostMessage(hwnd,WM_TXUSER,0,0);
break;
}
case WM_COMMAND: {
int id = WM_COMMAND_GetId(wParam);
int notify = WM_COMMAND_GetNotify(wParam,lParam);
switch(id) {
case IDD_LIST: {
if (notify == LBN_SELCHANGE) {
HWND hctrl = GetDlgItem(hwnd,IDD_LIST);
int isel = ListBox_GetCurSel(hctrl);
if (isel != LB_ERR) {
txstr sz(ListBox_GetTextLen(hctrl,isel)+1);
if (sz) {
ListBox_GetText(hctrl,isel,sz);
if (atoi(sz)) {
txJumpPara(text,atoi(sz));
}
}
}
} else if (notify == LBN_DBLCLK) {
FORWARD_WM_COMMAND(hwnd,IDOK,NULL,NULL,PostMessage);
break;
}
break;
}
case IDD_COPY: {
txClipboardCopy(text);
break;
}
case IDD_SEARCH: {
txstr szFind;
SEARCHMODE searchmode;
HSTRBLK sb = sbFromHist(HIST_SEARCH);
int n = sbGetCount(sb);
if (n) {
szFind = sbRead(sb,n-1);
searchmode = sbReadCustdata(sb,n-1);
}
if (txuiSearchSetForEx(text,"検索文字列",szFind,&searchmode)) {
histsearchAdd(szFind,searchmode,FALSE);
PostMessage(hwnd,WM_TXUSER,0,0);
}
return TRUE;
}
}
break;
}
case WM_TXUSER: {
HSTRBLK sb = sbFromHist(HIST_SEARCH);
int n = sbGetCount(sb);
if (!n) break;
mchar* szFind = sbRead(sb,n-1);
DWORD searchmode = sbReadCustdata(sb,n-1);
//
TX _text0;
TX* text0 = &_text0;
if (txInit(text0,NULL)) {
int n = 0;
txstr szPara;
txSetUndispEx(text);
txJumpFileTop(text);
while(1) {
if (txSearchEx(text,szFind,searchmode)) {
n++;
txGetPara(text,szPara);
txInsertf(text0,"%5d: ",text->npara);
txInsert(text0,strGetWordTop(szPara));
txInsertReturn(text0);
if (!txNextPara(text)) break;
} else {
break;
}
}
if (n == 0) {
txInsertLine(text0,"%s は見つかりません",szFind);
}
txSetDispEx(text);
{//2.99 970319 検索閲覧:検索文字列と件数を表示
txstr buff;
buff += "検索閲覧 - ";
buff += szFind;
buff += " : ";
buff += inttostr(n);
buff += "件";
SetWindowText(hwnd,buff);
}
//
HWND hctrl = GetDlgItem(hwnd,IDD_LIST);
listboxFromText(hctrl,text0);
//
// int isel = ListBox_GetCurSel(hctrl);
// if (isel < 0) ListBox_SetCurSel(hctrl,0);
// SetFocus(hctrl);
//
txClose(text0);
}
break;
}
}
return FALSE;
}
BOOL TXCMDBASE searchLook(TX* text)
{
// 検索閲覧
// 前回指定した検索文字列でテキスト全体を検索し、結果を一覧で表示する
//2.95 970130 新コマンド
txMarkCur(text);
text->fNoMarkCur++;
{
//2.99D 970331 検索閲覧では下線、検索文字列の表示を強制ON
BOOL fDispUnder0 = text->fDispUnder;
BOOL fDispFindEnable0 = text->fDispFindEnable;
BOOL fDispFind0 = text->fDispFind;
text->fDispUnder = TRUE;
text->fDispFindEnable = TRUE;
if (!text->fDispFind) text->fDispFind = COLORING_COLOR_UNDER;
txFlush(text);
//
IFILE adr = txGetAddress(text);
HDIALOG hd = dialog("検索閲覧");
dialogSetHookEx(hd,"\m.dlgprocSearchlook");
dialogControlID(hd,IDD_LIST);
dialogList(hd,NULL,NULL,60,10);
//
dialogLFV(hd);
//
dialogControlID(hd,IDOK);
dialogCmdDefault(hd,"ジャンプ(&J)",16);
dialogControlID(hd,IDD_COPY);
dialogCmd(hd,"コピー(&C)",16);
dialogControlID(hd,IDD_SEARCH);
dialogCmd(hd,"検索文字列(&S)...",16);
dialogCancel(hd,16);
//
if (dialogOpen(hd) != IDOK) {
txJumpAddress(text,adr);
}
//2.99D 970331
text->fDispUnder = fDispUnder0;
text->fDispFindEnable = fDispFindEnable0;
text->fDispFind = fDispFind0;
txFlush(text);
}
text->fNoMarkCur--;
return TRUE;
}
BOOL dlgprocSearch(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDIALOG hd = dialogFromHwnd(hwnd);
int mode = dialogGetCustdata(hd);
switch(message) {
case WM_INITDIALOG: {
#if 1//2.99C 970323
EnableDlgItem(hwnd,IDD_MODEREPLACETOP + 2,textf->fClip);
#else
HWND hctrl = GetDlgItem(hwnd,IDD_MODEREPLACETOP + 2);
if (hctrl) EnableWindow(hctrl,textf->fClip);
#endif
#if 1//3.00B1 970613
text->fSearchSetFont = wndSetFontAsText(GetDlgItem(hwnd,IDD_SZFIND),textf);
text->fReplaceSetFont = wndSetFontAsText(GetDlgItem(hwnd,IDD_SZREPLACE),textf);
#else
SetFont(hwnd,IDD_SZFIND);
SetFont(hwnd,IDD_SZREPLACE);
#endif
if (_hwndSearch) {
int im = searchdlgGetID();
if (_fWindowPos[im]) {
SetWindowPos(hwnd,NULL,_x[im],_y[im],0,0,SWP_NOSIZE);
} else {
wndMoveUncursor(hwnd);
}
}
break;
}
case WM_DESTROY: {
#if 1//3.00B1 970613
if (text->fSearchSetFont) {
text->fSearchSetFont = FALSE;
wndSetFontAsTextDelete(GetDlgItem(hwnd,IDD_SZFIND));
}
if (text->fReplaceSetFont) {
text->fReplaceSetFont = FALSE;
wndSetFontAsTextDelete(GetDlgItem(hwnd,IDD_SZREPLACE));
}
#else
if (text->fSearchSetFont) {//2.99D 970330 検索ダイアログでフォントをセットしてないときも解放していた
text->fSearchSetFont = FALSE;
ResetFont(hwnd,IDD_SZFIND);
ResetFont(hwnd,IDD_SZREPLACE);
}
#endif
break;
}
case WM_COMMAND: {
int id = WM_COMMAND_GetId(wParam);
int notify = WM_COMMAND_GetNotify(wParam,lParam);
switch(id) {
case IDD_SZFIND: {
if (text->fVzTextBoxHist && notify == EN_CHANGE) {
PostMessage(hwnd,WM_TXUSER,0,0);
} else if (!text->fVzTextBoxHist &&
(notify == CBN_EDITCHANGE||notify == CBN_SELCHANGE)
) {
PostMessage(hwnd,WM_TXUSER,0,0);
}
break;
}
case IDD_OPTION: {
// flush _searchopt
SendMessage(hwnd,WM_TXUSER,0,0);
//
HDIALOG hd = dialog("検索オプション");
#if 1//1.99A
{
//1.99A モードレス版ではSEARCH_ALLTEXTできない仕様
DWORD exmode = 0;
if (!_hwndSearch) {
exmode |= SEARCH_ALLTEXT | REPLACE_CONFIRM;
}
dialogSearch(hd,text,MODEOPTION_ONLY,exmode);
}
#else
dialogSearch(hd,text,FALSE,2);
#endif
dialogOpen(hd);
return TRUE;
}
case IDD_REFERSEARCHLIST: {
#if 1//2.92
txstr szSearchlist;
if (searchlistOpen(TRUE,szSearchlist)) {
szSearchlist = _szIdSearchlist + szSearchlist;
SetDlgItemText(hwnd,IDD_SZFIND,szSearchlist);
}
#else
PostMessage(hwnd,WM_COMMAND,IDCANCEL,0);
PostMessage(text->hwndbase,WM_COMMAND,IDM_WZCMDTOP + wzcmdRegister("\m.uiSearchList"),0);
#endif
return TRUE;
}
case IDD_NOESC: {
PostMessage(hwnd,WM_TXUSER,id,0);
break;
}
case IDD_SEARCHLOOK: {
dialogRead(hd);
//
SEARCHMODE searchmode = searchmodeFromSearchopt(&_searchopt);
histsearchAdd(szfind,searchmode,FALSE);
//
callPost("\m.searchLook");
return FALSE;
}
case IDD_SEARCHSPECIAL: {
callPost("\m.uiJumpEx");
PostMessage(hwnd,WM_COMMAND,IDCANCEL,0);
return FALSE;
}
}
if (_hwndSearch) {
switch(id) {
case IDCANCEL: {
#if 1//2.99D 970330 for DEBUGWIN err
searchClosed();
#else
searchClose();
#endif
return FALSE;
}
case IDOK:
//2.00B case IDD_PREV:
//2.00B case IDD_NEXT:
case IDD_ALL:
case IDD_AREA: {
dialogRead(hd);
int ret;
searchExec(_txSearch,id,&ret,mode);
return TRUE;
}
case IDD_PREV: //2.00B
case IDD_NEXT: //2.00B
case IDD_SEARCH:
case IDD_REPLACE: {
TX* text = _txSearch;//2.90
dialogRead(hd);
SEARCHMODE searchmode = searchmodeFromSearchopt(&_searchopt);
if (id == IDD_PREV) {
searchmode |= SEARCH_PREV;
_context.modeDirection = DIR_PREV;
id = IDD_SEARCH;
} else if (id == IDD_NEXT) {
_context.modeDirection = DIR_NEXT;
id = IDD_SEARCH;
} else if (_context.modeDirection == DIR_PREV) {
searchmode |= SEARCH_PREV;
}
#if 0//2.99D 970402
if (_fFocusSub == 1) SetFocus(text->hwndbase);//2.99C 970325 分割下側のウィンドウでモードレス検索できなかった
#endif
if (id == IDD_SEARCH) {
histsearchAdd(szfind,searchmode,FALSE);//1.99A 検索ヒストリに追加されてなかった
#if 1//1.99G 再検索で検索オプションが受け継がれなかった
text->searchmode = searchmode;
#endif
if (txSearchEx(text,szfind,searchmode|SEARCH_SELECT)) {
//1.99A 見つけた文字列を表示させるためSEARCH_SELECTする
err_clear();
if (_hwndSearch) {
//2.97 970225 モードレス検索ダイアログで検索結果がダイアログで隠れるのを改良
POINT p;
p.y = txOp(text,TXOP_LYTOY,text->ly + 1,0);
ClientToScreen(text->hwndtext,&p);
RECT r;
GetWindowRect(hwnd,&r);
if (p.y > r.top) {
txSetLyCenter(text);
}
}
} else {
err();
}
} else {
#if 1//2.99C 970324 ファイル全体に対してモードレス置換すると確認ダイアログが出ることがあった
searchmode &= ~REPLACE_CONFIRM;
#endif
searchmode |= SEARCH_CUR;
switch(_context.modeReplace) {
case REPLACE_ALL: searchmode |= SEARCH_ALL;break;
case REPLACE_AREA: searchmode |= SEARCH_AREA;break;
default: searchmode |= REPLACE_ONCE;break;
}
if (searchmode & REPLACE_ONCE) {
// カーソル位置を置換箇所に移動する
txSearchEx(text,szfind,searchmode);
}
int n = txReplaceEx(text,szfind,szreplace,searchmode);
if (searchmode & REPLACE_ONCE) {
// 次を検索
if (txSearchEx(text,szfind,searchmode|SEARCH_SELECT)) {
err_clear();
} else {
err();
}
}
}
#if 0//2.99D 970402
if (_fFocusSub == 1) SetFocus(hwnd);//2.99C 970325 分割下側のウィンドウでモードレス検索できなかった
#endif
return TRUE;
}
case IDD_TOREPLACE: {
dialogRead(hd);
searchClose();
PostMessage(text->hwndbase,
WM_COMMAND,
IDM_WZCMDTOP + wzcmdRegister("\m.uiReplaceModeless"),
0
);
return TRUE;
}
}
}
break;
}
case WM_CLOSE: {
#if 1//2.99F 970404 2.99Dでモードレス検索・置換ダイアログで×でダイアログを閉じれなかった
// ダイアログプロシジャーはWM_CLOSEを処理しない
searchClose();
break;
#else
#if 1//2.99D 970330 for DEBUGWIN err
searchClosed();
break;
#else
searchClose();
break;
#endif
#endif
}
case WM_TXUSER: {
HSTRBLK sb = histToStrblk(HIST_SEARCH);
mchar buff[CCHWORD];
GetDlgItemText(hwnd,IDD_SZFIND,buff,CCHWORD);
//
BOOL f = sbGetSenseCase(sb);
sbSetSenseCase(sb,TRUE);// 大文字 小文字を区別
int i = sbiSearch(sb,buff);
if (
i != -1 && !text->share->config.fNoMemorySearchOption &&
wParam != IDD_NOESC //3.00A3 970508 「\を通常文字」が変更できないことがあった
) {
dialogRead(hd);
DWORD searchmode = sbReadCustdata(sb,i);
//
BOOL fCategory = _searchopt.fCategory;
searchmodeToSearchopt(searchmode,&_searchopt);
_searchopt.fCategory = fCategory;
//
dialogWriteItem(hd,IDD_CASE);
dialogWriteItem(hd,IDD_NOSYMBOL);
dialogWriteItem(hd,IDD_ZENHAN);
dialogWriteItem(hd,IDD_WORD);
dialogWriteItem(hd,IDD_RE);
dialogWriteItem(hd,IDD_NOESC);
dialogWriteItem(hd,IDD_ALLTEXT);
{
int id;
for (id = IDD_MODETOP;id <= IDD_MODEEND;id++) {
dialogWriteItem(hd,id);
}
}
}
sbSetSenseCase(sb,f);// 大文字 小文字を区別を元に戻す
//2.92
{
BOOL f = (strncmp(buff,_szIdSearchlist,_lchIdSearchlist) != 0);
if (IsDlgButtonChecked(hwnd,IDD_NOESC)) f = TRUE;
#if 1//2.99D 970330
EnableDlgItem(hwnd,IDD_MODETOP,f);
EnableDlgItem(hwnd,IDD_MODETOP+1,f);
EnableDlgItem(hwnd,IDD_MODETOP+2,f);
EnableDlgItem(hwnd,IDD_MODETOP+3,f);
EnableDlgItem(hwnd,IDD_CASE,f);
EnableDlgItem(hwnd,IDD_NOSYMBOL,f);
EnableDlgItem(hwnd,IDD_SZREPLACE,f);
#else
EnableWindow(GetDlgItem(hwnd,IDD_MODETOP),f);
EnableWindow(GetDlgItem(hwnd,IDD_MODETOP+1),f);
EnableWindow(GetDlgItem(hwnd,IDD_MODETOP+2),f);
EnableWindow(GetDlgItem(hwnd,IDD_MODETOP+3),f);
EnableWindow(GetDlgItem(hwnd,IDD_CASE),f);
EnableWindow(GetDlgItem(hwnd,IDD_NOSYMBOL),f);
EnableWindow(GetDlgItem(hwnd,IDD_SZREPLACE),f);
#endif
}
break;
}
case WM_MOVE: {
// 位置を覚える
if (_hwndSearch) {
int im = searchdlgGetID();
_fWindowPos[im] = TRUE;
WINDOWPLACEMENT wplace;
wplace.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(hwnd,(LPWINDOWPLACEMENT)&wplace);
_x[im] = wplace.rcNormalPosition.left;
_y[im] = wplace.rcNormalPosition.top;
}
break;
}
case WM_ACTIVATE: {//2.99C 970323 置換ダイアログの"範囲内"改善
BOOL fActive = LOWORD(wParam);
if (fActive != WA_INACTIVE) {
EnableDlgButtonEx(hwnd,IDD_MODEREPLACETOP + 2,textf->fClip,IDD_MODEREPLACETOP);
}
break;
}
}
return FALSE;
}
//_search.cからも呼ばれる
//ネストは不可能
int search(int mode)
{
BOOL fReplace = ((mode & SEARCHDLG_REPLACE) != 0);
BOOL fModeless = ((mode & SEARCHDLG_MODELESS) != 0);
BOOL fButton = text->share->config.fSearchButton;
_fReplace = fReplace;//1.01A
if (text->fDispFindAtSearch) {//2.99C 970323
text->fDispFindEnable = TRUE;
}
#if 1
//1.99G 検索モードレスを開いてて置換が選択されたときに対応
// 現在ダイアログを開いているとき以前とモードが違えばダイアログを作り直す
if (_hwndSearch) {
if (_modeSearch == mode) {
SetActiveWindow(_hwndSearch);
SetFocus(_hwndSearch);
return 0;
} else {
searchClose();
}
}
_modeSearch = mode;
#else
if (_hwndSearch) {
SetActiveWindow(_hwndSearch);
SetFocus(_hwndSearch);
return 0;
}
#endif
#if 0//2.00E4
memset(&_context,0,sizeof(_context));
#endif
int ret = 0;
if (keymacroDoing()) {
keymacroPop();
}
if (text->modeSearchDialog == 2 && !fReplace) mode |= SEARCHDLG_MINI;
#if 1//1.00B 範囲選択時の検索文字列取得を改善
if (text->fClip == CLIP_BOX) {
attention("箱範囲指定中は検索/置換できません");
return 0;
}
if (!(mode & SEARCHDLG_SZFIND)) {
if (text->fBinedit) {
if (txIsClipInPara(text)) {
szfind = "\\xx";
txstr sz;
int cb = txGetWord(text,sz);
for (mchar*p = sz;cb--;p++) {
mchar buff[10];
sprintf(buff,"%02X",*p);
szfind += buff;
}
} else {
sprintf(szfind,"\\xx%02X",text->buff[text->cur]);
}
} else {
if (txIsClipInPara(text)) {
txGetWord(text,szfind);
} else {
if (text->share->config.fSearchGetText && !isspace(txGetChar(text))) {
txGetWord(text,szfind);
}
}
}
}
#else
if (!isspace(getchar)) txGetWord(text,szfind);
#endif
#if 1//2.92
if (mode & SEARCHDLG_CONFIRM) text->searchmode |= REPLACE_CONFIRM;
#else
_fReplaceConfirm = (mode & SEARCHDLG_CONFIRM);
#endif
while(1) {
int cx = 16;
int id;
HDIALOG hd;
//1.00C 検索/置換ダイアログはカーソル位置に出る様に改良
if (mode & SEARCHDLG_CAPTION) {
} else if (fReplace) {
_szcaption = "置換";
} else if (mode & SEARCHDLG_VZ) {
_szcaption = "検索 - VZ";
} else if ((mode & SEARCHDLG_MINI) && (mode & SEARCHDLG_PREV)) {
_szcaption = "検索 - カーソル以前";
} else {
_szcaption = "検索";
}
_hdreplace = hd = _dialog(
_szcaption,
EXDS_POSCURSOR|!(mode & SEARCHDLG_MINI) * EXDS_BIG,
NULL
);
dialogSetCustdata(hd,mode);
dialogSetHookEx(hd,"\m.dlgprocSearch");
dialogSetContexthelp(hd,TRUE);
{
//1.99A モードレス版ではSEARCH_ALLTEXTできない仕様
DWORD exmode = fModeless ? 0 : SEARCH_ALLTEXT;
if (fReplace) {
exmode |= SEARCH_REPLACE;
if (!fModeless) exmode |= REPLACE_CONFIRM;
}
dialogSearch(
hd,text,
(mode & SEARCHDLG_MINI) ? MODEOPTION_NONE : MODEOPTION_WITH,
exmode|SEARCH_DIALOGCOMPACT|SEARCH_DIALOGSLIST
);
}
if (mode & SEARCHDLG_MINI) {
dialogLFV(hd);
dialogOK(hd,6);
dialogLFV(hd);
dialogControlID(hd,IDD_OPTION);
dialogCmd(hd,"オプション(&O)...",cx);
dialogSetNoButton(hd);
} else if (mode & SEARCHDLG_VZ) {
if (fReplace) {
dialogLFV(hd);
dialogOK(hd,cx);
dialogCancel(hd,cx);
dialogSpaceV(hd);
}
} else {
dialogLFV(hd);
dialogIndent(hd,2);
if (fModeless) {
#if 0//2.00E4 モードレス検索ダイアログでカーソル以前/以降を覚える様にした
_context.modeDirection = DIR_NEXT;
#endif
dialogSetIntXY(hd,0,0);
if (!fButton) {
dialogControlRadioV(hd);
dialogControlHelp(hd,-303);
dialogRadioIDB(hd,&_context.modeDirection,"上へ(&P)","下へ(&N)");
if (fReplace) {
dialogHeadline(hd,NULL,12);
} else {
dialogLFV(hd);
}
}
if (fReplace) {
if (!text->fClip && _context.modeReplace == REPLACE_AREA) {
_context.modeReplace = REPLACE_1;
}
dialogControlRadioV(hd);
dialogControlID(hd,IDD_MODEREPLACETOP);
dialogControlHelp(hd,-305);
dialogRadioIDB(hd,&_context.modeReplace,"1つ置換(&1)","全て(&2)","範囲内(&3)");
dialogLFV(hd);
}
dialogResetInt(hd);
//
if (fButton) {
dialogControlID(hd,IDD_PREV);
dialogControlHelp(hd,192);
dialogCmd(hd,"上へ(&P)",cx);
dialogControlID(hd,IDD_NEXT);
dialogControlHelp(hd,193);
dialogCmdDefault(hd,"下へ(&N)",cx);
} else {
dialogControlID(hd,IDD_SEARCH);
dialogControlHelp(hd,195);
dialogCmdDefault(hd,"次を検索",cx);
}
dialogControlID(hd,IDCANCEL);
dialogCancel(hd,cx);
if (fReplace) {
dialogSpaceV(hd);
dialogControlID(hd,IDD_REPLACE);
dialogControlHelp(hd,197);
dialogCmd(hd,"置換(&R)",cx);
}
#if 0//2.97 970225
dialogHelpID(hd,cx,"wz",fReplace ? IDH_REPLACE : IDH_SEARCH);
//
dialogSpace(hd);
dialogControlID(hd,IDD_REFERSEARCHLIST);
dialogControlHelp(hd,203);
dialogCmd(hd,"検索リスト(&L)...",cx);
//
if (!fReplace) {
dialogControlID(hd,IDD_TOREPLACE);
dialogControlHelp(hd,198);
dialogCmd(hd,"置換(&R) >>",cx);
}
#endif
} else {
if (mode & SEARCHDLG_PREV) {
dialogControlID(hd,IDD_PREV);
dialogControlHelp(hd,192);
dialogCmdDefault(hd,"上へ(&P)",cx);
dialogControlID(hd,IDD_NEXT);
dialogControlHelp(hd,193);
dialogCmd(hd,"下へ(&N)",cx);
} else {
if (fReplace) {
dialogControlEnable(hd,!text->fClip || txIsClipInPara(text));
dialogControlHelp(hd,199);
} else {
dialogControlHelp(hd,192);
}
dialogControlID(hd,IDD_PREV);
dialogCmd(hd,"上へ(&P)",cx);
if (fReplace) {
dialogControlEnable(hd,!text->fClip || txIsClipInPara(text));
dialogControlHelp(hd,200);
} else {
dialogControlHelp(hd,193);
}
dialogControlID(hd,IDD_NEXT);
dialogCmdDefault(hd,"下へ(&N)",cx);
}
if (fReplace) {
dialogSpace(hd);
dialogControlEnable(hd,text->fClip);
if (text->fClip && !txIsClipInPara(text)) {
dialogControlID(hd,IDD_AREA);
dialogControlHelp(hd,202);
dialogCmdDefault(hd,"範囲内(&B)",cx);
} else {
dialogControlID(hd,IDD_AREA);
dialogControlHelp(hd,202);
dialogCmd(hd,"範囲内(&B)",cx);
}
dialogControlEnable(hd,!text->fClip || txIsClipInPara(text));
dialogControlID(hd,IDD_ALL);
dialogControlHelp(hd,201);
dialogCmd(hd,"全て(&A)",cx);
}
dialogCancel(hd,cx);
#if 0//2.97 970225
dialogHelpID(hd,cx,"wz",fReplace ? IDH_REPLACE : IDH_SEARCH);
dialogSpaceV(hd);
dialogControlID(hd,IDD_REFERSEARCHLIST);
dialogControlHelp(hd,203);
dialogCmd(hd,"検索リスト(&L)...",cx);
#endif
}
#if 0
//2.95 970130
dialogControlID(hd,IDD_SEARCHLOOK);
dialogCmd(hd,"検索閲覧(&O) >>",cx);
#endif
//2.97 970225
if (!fReplace) {
dialogControlID(hd,IDD_SEARCHSPECIAL);
dialogCmd(hd,"ジャンプ(&U) >>",cx);
}
}
//2.99 970320 検索ダイアログではIMEの制御をしないようにした。
// つかいにくかった
if (fModeless) {
text->fNoImeControl++;//2.99 970320
//1.99G for Window Pos 記憶に必要である。
// dialogCreate中に呼び出されるWM_INITDIALOGでは
// まだdialogCreateの結果が_hwndSearchに代入されていないため
#if 0 //2.99D 970402 これだけではだめで、根本的に直した
_fFocusSub = txIsFocusSub(text);//2.99C 970325
#endif
_hwndSearch = TRUE;
txMarkCur(text);//2.99 970320 モードレス検索で検索開始地点がマーク0に記憶されなかった
_txSearch = text;//2.90
_hwndSearchIsReplace = fReplace;//2.97 970225
//
_hwndSearch = dialogCreate(hd);
text->fNoImeControl--;//2.99 970320
return TRUE;
} else {
text->fNoImeControl++;//2.99 970320
id = dialogOpen(hd);
text->fNoImeControl--;//2.99 970320
if (id == IDD_SEARCHLOOK) id = 0;
if (id == IDD_SEARCHSPECIAL) id = 0;
if (id) {
if (!searchExec(text,id,&ret,mode)) continue;
} else {
if (text->pagingmode == 'S') txSwitchPagingMode(text);
}
_hdreplace = NULL;
return ret;
}
}
}
// thanks y.mikomeさん
static int _txkeySearchContinue(TX* text,BOOL fPrev)
{
if (text->fDispFindAtSearch) {//2.99C 970323
text->fDispFindEnable = TRUE;
}
if (text->fClipMouse && !text->fClipSearch && txIsClipInPara(text)) {
// 選択されているときは、その文字列で再検索する。
txstr szStr;
txGetWord(text,szStr);
histsearchAdd(szStr,0,TRUE);
if (fPrev) txJumpSelectTop(text);
txSelectQuit(text);
txMarkCur(text);
}
if (fPrev) {
return txSearchContinuePrev(text);
} else {
return txSearchContinue(text);
}
}
//2.99 970314 txkeyプレフィックスを追加
BOOL TXCMDBASE txkeySearchContinuePrev(TX* text)
{
// 上方向への再検索
//2.97 970225 new
//2.99A 970321 {#MS} +{F4} ^%Y -> {#MS} +{F3} ^{PageUp}
//{#MS} +{F3} ^%Y ^{PageUp}
//{#MI} +{F5}
return _txkeySearchContinue(text,TRUE);
}
//2.99 970314 txkeyプレフィックスを追加
//2.99I 970405 MS.KEY +{F4}を外した。このキーには文字列の補完を割り当てた
BOOL TXCMDBASE txkeySearchContinue(TX* text)
{
// 下方向への再検索
//2.97 970225 new
//2.99A 970321 {#MS} {F4} +^Y -> {#MS} {F3} +{F4} +^Y ^{PageDown}
//{#MS} {F3} +^Y ^{PageDown}
//{#MI} {F5}
return _txkeySearchContinue(text,FALSE);
}
BOOL TXAPI txuiSearchSetFor(tx *text,mchar *szcaption,txstr _szfind)
{
//検索ダイアログボックスを出す
//文字列が入力されたかどうか返す
//_szfindに入力された文字列をセットします。
//1.00Cで追加
_szcaption = szcaption;
BOOL ret = search(SEARCHDLG_VZ|SEARCHDLG_CAPTION);
if (ret) {
_szfind = szfind;
}
return ret;
}
BOOL TXAPI txuiSearchSetForEx(tx *text,mchar *szcaption,txstr _szfind,DWORD* searchmode)
{
//検索ダイアログボックスを出す
//文字列が入力されたかどうか返す
//_szfindに入力された文字列をセットします。
//*searchmodeに指定された検索オプションをセットします。
//1.91A で追加
#if 1//1.92
SEARCHMODE searchmode0 = text->searchmode;
_szcaption = szcaption;
szfind = _szfind;//2.90 _szfindをデフォルトで表示するようにした
text->searchmode = *searchmode;
BOOL ret = search(SEARCHDLG_VZ|SEARCHDLG_CAPTION|SEARCHDLG_SZFIND);
if (ret) {
_szfind = szfind;
*searchmode = text->searchmode;
}
text->searchmode = searchmode0;
return ret;
#else
DWORD searchmodeTemp = searchmodeFromText(text);
_szcaption = szcaption;
searchmodeToText(text,*searchmode);
BOOL ret = search(SEARCHDLG_VZ|SEARCHDLG_CAPTION|SEARCHDLG_SZFIND);
if (ret) {
_szfind = szfind;
*searchmode = searchmodeFromText(text);
}
searchmodeToText(text,searchmodeTemp);
return ret;
#endif
}
vzuiSearch
{
// VZ互換検索ダイアログ
//1.00Cで追加
search(SEARCHDLG_VZ|SEARCHDLG_MINI);
}
uiSearchModeless
{
// モードレス検索ダイアログ
//1.96で追加
#if 1//1.99G
#if 1//2.00B モードレス検索/置換ダイアログで、選択された単語やカーソル位置の単語を検索文字列の初期値にセットするようにした
search(SEARCHDLG_MODELESS);
#else
search(SEARCHDLG_MODELESS|SEARCHDLG_SZFIND);
#endif
#else
search(SEARCHDLG_MODELESS);
#endif
}
uiReplaceModeless
{
// モードレス置換ダイアログ
//1.96で追加
#if 1//2.00B
search(SEARCHDLG_REPLACE|SEARCHDLG_CONFIRM|SEARCHDLG_MODELESS);
#else
search(SEARCHDLG_REPLACE|SEARCHDLG_CONFIRM|SEARCHDLG_MODELESS|SEARCHDLG_SZFIND);
#endif
}
BOOL TXAPI TXCMD txuiSearchMini(tx *text)
{
// 検索(小さいダイアログ版)
//1.00Cで追加
return search(SEARCHDLG_MINI);
}
BOOL TXAPI TXCMD txuiSearchPrevMini(tx *text)
{
// 前方検索(小さいダイアログ版)
//1.00Cで追加
return search(SEARCHDLG_MINI|SEARCHDLG_PREV);
}
BOOL TXCMDBASE txkeySearch(TX* text)
{
// モーダル/モードレス切り替え可能な検索ダイアログ
//2.99A 970320 new
//2.99A 970321 {#MS} ^F new
//{#MS} ^F
if (text->share->config.fSearchModeless) {
return uiSearchModeless();
} else {
return txuiSearch(text);
}
}
BOOL TXCMDBASE txkeyReplace(TX* text)
{
// モーダル/モードレス切り替え可能な置換ダイアログ
//2.99A 970320 new
//2.99A 970321 {#MS} ^H ^R new
//{#MS} ^H ^R
if (text->share->config.fSearchModeless) {
return uiReplaceModeless();
} else {
return txuiReplace(text);
}
}
//## grep
BOOL TXCMDBASE grep(TX* text)
{
// WZ Grepを起動します
// 1.00Fで追加
//{#EMACS} +{F6}
txstr szfind;
if (txIsClipInPara(text)) txGetWord(text,szfind);
#if 1//2.99D 970330 sw
if (szfind == "") {
macroFork("grep /i-");
} else {
macroFork("grep /i- -s\x0C" + szfind + "\x0C");
}
#else
//2.94 970121 "/I"追加
if (szfind == "") {
macroFork("grep /I");
} else {
macroFork("grep /I -s\x0C" + szfind + "\x0C");
}
#endif
return TRUE;
}
//## 特殊文字の検索
static BOOL _txSearchPlug(TX* text,int idplug,IFILE adr)
{
CHARATR charatr;
charatrRead(text,adr,&charatr);
if (charatr.fLink) {
if (plugatrGetModePlug(text,charatrGetPlug(charatr)) == idplug) {
return TRUE;
}
}
return FALSE;
}
static BOOL txSearchPlug(TX* text,int idplug,SEARCHMODE searchmode,mchar* szArg1,mchar* szArg2)
{
// szArg1,szArg2が""でなければ次の絞り込み検索を行う。
// idplug szArg1 szArg2
// PLUG_IMG: 図のファイル名
// PLUG_FOOTNOTE 脚注の内容
// PLUG_RUBY ルビの漢字 ルビのよみがな
// PLUG_LINK リンク先のファイル名 キャプション
// PLUG_PROOF 校正の内容 校正者
// PLUG_HTML_TAG タグの内容
//2.99 970313 改良
IFILE adr = txGetAddress(text);
IFILE adrCurscreen = txGetAddressCurscreen(text);
//information("%d",idplug);
if (idplug == PLUG_TAB) {
//2.99 970313 選択するようにした
BOOL fNow = (txIsCurParaIncludeTable(text) != NULL);//カーソル位置がTRUEなら、次の表を検索
BOOL ret = FALSE;
txSetUndisp(text);
if (searchmode & SEARCH_PREV) {
while(1) {
if (!txPrevPara(text)) break;
if (txIsCurParaIncludeTable(text)) {
if (!fNow) {
ret = TRUE;
break;
}
} else {
fNow = FALSE;
}
}
} else {
while(1) {
if (!txNextPara(text)) break;
if (txIsCurParaIncludeTable(text)) {
if (!fNow) {
ret = TRUE;
break;
}
} else {
fNow = FALSE;
}
}
}
if (ret) {
// 表の末尾行へ
while(1) {
if (!txIsCurParaIncludeTable(text)) {
break;
}
if (!txNextPara(text)) break;
}
txSelectEx(text,CLIP_SEARCH);
// 表の先頭行へ
while(1) {
if (!txPrevPara(text)) break;
if (!txIsCurParaIncludeTable(text)) {
txNextPara(text);
break;
}
}
if (text->fJumpCursorCenter) txSetLyCenter(text);
} else {
txSelectQuit(text);
txJumpAddress(text,adr);
txSetLyCurscreen(text,adrCurscreen);
}
txSetDisp(text);
return ret;
} else {
mchar szFind[2] = {CHAR_PLUG,0};
BOOL ret = FALSE;
txSetUndisp(text);
while(1) {
if (txSearchEx(text,szFind,searchmode)) {
if (_txSearchPlug(text,idplug,txGetAddress(text))) {
LPVOID ph = txGetCurPlug(text);
BOOL f = TRUE;
switch(idplug) {
case PLUG_IMG: {
PLUGIMG* plug = ph;
if (szArg1 && szArg1[0]) {
f = (stristr(plug->szfilename,szArg1) != NULL);
}
break;
}
case PLUG_HTML_TAG: {
PLUGHTMLTAG* plug = ph;
if (szArg1 && szArg1[0]) {
f = (stristr(plug->szTag,szArg1) != NULL);
}
break;
}
case PLUG_FOOTNOTE: {
PLUGFOOTNOTE* plug = ph;
if (szArg1 && szArg1[0]) {
f = (stristr(plug->szFootnote,szArg1) != NULL);
}
break;
}
case PLUG_RUBY: {
PLUGRUBY* plug = ph;
if (szArg1 && szArg1[0]) {
f = (stristr(plug->szTarget,szArg1) != NULL);
}
if (szArg2 && szArg2[0] && f) {
f = (stristr(plug->szRuby,szArg2) != NULL);
}
break;
}
case PLUG_LINK: {
PLUGLINK* plug = ph;
if (szArg1 && szArg1[0]) {
f = (stristr(plug->szfilename,szArg1) != NULL);
}
if (szArg2 && szArg2[0] && f) {
f = (stristr(plug->szCaption,szArg2) != NULL);
}
break;
}
case PLUG_PROOF: {
PLUGPROOF* plug = ph;
if (szArg1 && szArg1[0]) {
f = (stristr(plug->szTarget_szProof,szArg1) != NULL);
if (!f) f = (stristr(plug->szTarget_szProof + plug->ichProof,szArg1) != NULL);
}
if (szArg2 && szArg2[0] && f) {
f = (stristr(plug->szReader,szArg2) != NULL);
}
break;
}
}
if (f) {
ret = TRUE;
txRight(text);
txSelectEx(text,CLIP_SEARCH);
txLeft(text);
if (text->fJumpCursorCenter) txSetLyCenter(text);
break;
}
}
searchmode &= ~SEARCH_CUR;
} else {
break;
}
}
if (!ret) {
txSelectQuit(text);
txJumpAddress(text,adr);
txSetLyCurscreen(text,adrCurscreen);
}
txSetDisp(text);
return ret;
}
return FALSE;
}
static BOOL _txSearchCharatr(TX* text,int tag,IFILE adr)
{
CHARATR charatr;
charatrRead(text,adr,&charatr);
switch(tag) {
case TAG_B: return charatr.fBold;
case TAG_I: return charatr.fItalic;
case TAG_U: return charatr.fUnderline;
}
return FALSE;
}
static BOOL txSearchCharatr(TX* text,int tag,SEARCHMODE searchmode,LPARAM arg)
{
//2.99 970313 選択するようにした
IFILE adr = txGetAddress(text);
IFILE adr0 = adr;
IFILE adrCurscreen = txGetAddressCurscreen(text);
BOOL fNow = _txSearchCharatr(text,tag,adr);//カーソル位置がTRUEなら、次の文字列を検索
BOOL ret = FALSE;
txSetUndisp(text);
if (searchmode & SEARCH_PREV) {
for (;adr--;) {
if (_txSearchCharatr(text,tag,adr)) {
if (!fNow) {
txJumpAddress(text,adr + 1);
txSelectEx(text,CLIP_SEARCH);
// 文字列の先頭へ
for (;;) {
if (adr == 0) break;
adr--;
if (!_txSearchCharatr(text,tag,adr)) {
adr++;
break;
}
}
txJumpAddress(text,adr);
ret = TRUE;
break;
}
} else {
fNow = FALSE;
}
}
} else {
IFILE size = txGetTextSize(text);
for (adr++;adr < size;adr++) {
if (_txSearchCharatr(text,tag,adr)) {
if (!fNow) {
IFILE adrTop = adr;
// 文字列の末尾+1へ
for (;adr < size;adr++) {
if (!_txSearchCharatr(text,tag,adr)) {
break;
}
}
txJumpAddress(text,adr);
txSelectEx(text,CLIP_SEARCH);
//
txJumpAddress(text,adrTop);
ret = TRUE;
break;
}
} else {
fNow = FALSE;
}
}
}
if (ret) {
if (text->fJumpCursorCenter) txSetLyCenter(text);
txSetDisp(text);
return TRUE;
} else {
txSelectQuit(text);
txJumpAddress(text,adr0);
txSetLyCurscreen(text,adrCurscreen);
txSetDisp(text);
return FALSE;
}
}
#define IDD_PREV 2001
#define IDD_NEXT 2002
#define IDD_CAPTION1 2500
#define IDD_CONTENT1 2501
#define IDD_CAPTION2 2502
#define IDD_CONTENT2 2503
#define IDD_MOVEWINDOW 2504 //2.99 970312
#define JUMPID_LINE 0
#define JUMPID_PAGE 1
#define JUMPID_EDITED 2 //3.00B1 970521
#define JUMPID_IMG 3
#define JUMPID_TAB 4
#define JUMPID_FOOTNOTE 5
#define JUMPID_BOLD 6
#define JUMPID_UNDERLINE 7
#define JUMPID_ITALIC 8
#define JUMPID_TITLE 9
#define JUMPID_OLE 10
#define JUMPID_RUBY 11
#define JUMPID_LINK 12
#define JUMPID_HR 13
#define JUMPID_PROOF 14
#define JUMPID_FONT 15
#define JUMPID_TAG 16
#define JUMPID_PAIRTAG 17
static int _modeFindSpecial = 0;
static txstr _szFindSpecial1;
static txstr _szFindSpecial2;
static mchar _szCaptionNext[] = "次へ(&N)";
static void initContent(void)
{
_szFindSpecial1 = "";
_szFindSpecial2 = "";
if (_modeFindSpecial == JUMPID_LINE) {
int nline = txVarGet(text,"\m.nline");
if (nline == 0) nline = 1;
sprintf(_szFindSpecial1,"%d",nline);
} else if (_modeFindSpecial == JUMPID_PAGE) {
// 詳細モードでは頁指定ジャンプ
// 簡易頁表示では、頁・行複合指定ジャンプ
NPAGE npage = 0;
if (text->editmode == 2) {
npage = txNpageFromNpageclm(text,text->npage);
} else if (text->fLineD && text->height) {
npage = (text->nline / text->height) + 1;
}
if (npage) sprintf(_szFindSpecial1,"%d",npage);
//
int npageline = txVarGet(text,"\m.npageline");
if (npageline == 0) npageline = 1;
sprintf(_szFindSpecial2,"%d",npageline);
}
}
BOOL paraatrtextReadFedited(TX* text,NPARA npara)
{
//3.00B1 970521 new
if (text->editmode) {
PARAATR paraatr;
paraatrRead(text,npara,¶atr);
return paraatr.fEdited;
} else {
PARAATR_TEXT_CONTEXT* ptc = text->paraatrtextcontext;
BOOL fEdited = FALSE;
if (ptc && ptc->buff) {
if (npara < ptc->cur0) {
fEdited = ptc->buff[npara].fEdited;
} else {
npara += ptc->cur - ptc->cur0;
if (npara < ptc->size) {
fEdited = ptc->buff[npara].fEdited;
}
}
}
return fEdited;
}
}
BOOL TXAPI TXCMD txSearchEditedPrev(TX* text)
{
// 前の変更行へジャンプ
//{#RET}ジャンプしたかどうかを返す
//3.00B1 970522 new
NPARA npara = text->npara - 1;
for (;npara >= 1;npara--) {
if (paraatrtextReadFedited(text,npara)) {
txJumpNpara(text,npara);
return TRUE;
}
}
return FALSE;
}
BOOL TXAPI TXCMD txSearchEdited(TX* text)
{
// 次の変更行へジャンプ
//{#RET}ジャンプしたかどうかを返す
//3.00B1 970522 new
NPARA nparaSize = 0;
if (text->editmode) {
nparaSize = txRecordGetCount(text->txparaatr);
} else {
PARAATR_TEXT_CONTEXT* ptc = text->paraatrtextcontext;
if (ptc) {
nparaSize = ptc->size;
}
}
{
NPARA npara = text->npara + 1;
for (;npara < nparaSize;npara++) {
if (paraatrtextReadFedited(text,npara)) {
txJumpNpara(text,npara);
return TRUE;
}
}
}
return FALSE;
}
BOOL dlgprocSearchSpecial(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDIALOG hd = dialogFromHwnd(hwnd);
switch(message) {
case WM_INITDIALOG: {
PostMessage(hwnd,WM_TXUSER,TRUE,0);
break;
}
case WM_COMMAND: {
int id = WM_COMMAND_GetId(wParam);
int notify = WM_COMMAND_GetNotify(wParam,lParam);
switch(id) {
case IDD_TARGET: {
if (notify == LBN_SELCHANGE) PostMessage(hwnd,WM_TXUSER,0,0);
break;
}
case IDD_MOVEWINDOW: {
wndMoveUncursor(hwnd);
return TRUE;
}
case IDD_NEXT:
case IDD_PREV: {
SEARCHMODE mode = (id == IDD_PREV) ? SEARCH_PREV : 0;
BOOL ret = FALSE;
dialogRead(hd);
switch(_modeFindSpecial) {
case JUMPID_LINE:
case JUMPID_PAGE:
case JUMPID_PAIRTAG: PostMessage(hwnd,WM_COMMAND,IDOK,0);return TRUE;
case JUMPID_EDITED: { //3.00B1 970521
if (mode & SEARCH_PREV) {
ret = txSearchEditedPrev(text);
} else {
ret = txSearchEdited(text);
}
break;
}
case JUMPID_IMG:ret = txSearchPlug(text,PLUG_IMG,mode,_szFindSpecial1,_szFindSpecial2);break;
case JUMPID_TAB:ret = txSearchPlug(text,PLUG_TAB,mode,_szFindSpecial1,_szFindSpecial2);break;
case JUMPID_FOOTNOTE:ret = txSearchPlug(text,PLUG_FOOTNOTE,mode,_szFindSpecial1,_szFindSpecial2);break;
case JUMPID_BOLD:ret = txSearchCharatr(text,TAG_B,mode,0);break;
case JUMPID_UNDERLINE:ret = txSearchCharatr(text,TAG_U,mode,0);break;
case JUMPID_ITALIC:ret = txSearchCharatr(text,TAG_I,mode,0);break;
case JUMPID_TITLE: {
IFILE adr = txGetAddress(text);
IFILE adrCurscreen = txGetAddressCurscreen(text);
txSetUndisp(text);
if (mode & SEARCH_PREV) {
ret = txSearchTitlePrev(text);
} else {
ret = txSearchTitle(text);
}
if (ret) {
txJumpParaEnd(text);
txSelectEx(text,CLIP_SEARCH);
txJumpParaTop(text);
} else {
txSelectQuit(text);
txJumpAddress(text,adr);
txSetLyCurscreen(text,adrCurscreen);
}
txSetDisp(text);
break;
}
case JUMPID_OLE:ret = txSearchPlug(text,PLUG_OLE,mode,_szFindSpecial1,_szFindSpecial2);break;
case JUMPID_RUBY:ret = txSearchPlug(text,PLUG_RUBY,mode,_szFindSpecial1,_szFindSpecial2);break;
case JUMPID_LINK:ret = txSearchPlug(text,PLUG_LINK,mode,_szFindSpecial1,_szFindSpecial2);break;
case JUMPID_HR:ret = txSearchPlug(text,PLUG_HR,mode,_szFindSpecial1,_szFindSpecial2);break;
case JUMPID_PROOF:ret = txSearchPlug(text,PLUG_PROOF,mode,_szFindSpecial1,_szFindSpecial2);break;//2.98 970305
case JUMPID_FONT:ret = txSearchPlug(text,PLUG_FONT,mode,_szFindSpecial1,_szFindSpecial2);break;//2.98 970305
case JUMPID_TAG:ret = txSearchPlug(text,PLUG_HTML_TAG,mode,_szFindSpecial1,_szFindSpecial2);break;//2.98 970305
}
statprintf(ret ? "" : "見つかりません");
return TRUE;
}
}
break;
}
case WM_TXUSER: {
HWND hcaption1 = GetDlgItem(hwnd,IDD_CAPTION1);
HWND hcaption2 = GetDlgItem(hwnd,IDD_CAPTION2);
HWND hctrl1 = GetDlgItem(hwnd,IDD_CONTENT1);
HWND hctrl2 = GetDlgItem(hwnd,IDD_CONTENT2);
BOOL fEnableButton1 = TRUE;
BOOL fEnableButton2 = TRUE;
mchar* szCaption1 = "";
mchar* szCaption2 = "";
//
dialogRead(hd);
// button caption
switch(_modeFindSpecial) {
case JUMPID_LINE:
case JUMPID_PAGE:
case JUMPID_PAIRTAG: {
SetDlgItemText(hwnd,IDD_NEXT,"ジャンプ(&N)");
fEnableButton2 = FALSE;
break;
}
default: {
SetDlgItemText(hwnd,IDD_NEXT,_szCaptionNext);
break;
}
}
// textmode enable item
switch(_modeFindSpecial) {
case JUMPID_LINE: {
szCaption1 = text->fLineD ? "表示行番号(&C):" : "段落行番号(&C):";
break;
}
case JUMPID_PAGE: {
szCaption1 = "ページ(&C):";
szCaption2 = "行(&D):";
break;
}
case JUMPID_EDITED: {//3.00B1 970521
if (!text->fDispLineEdit) {
fEnableButton1 = FALSE;
fEnableButton2 = FALSE;
}
break;
}
default: {
if (text->editmode == 0) {// 不可
szCaption1 = "テキストモードでは実行できません";
fEnableButton1 = FALSE;
fEnableButton2 = FALSE;
}
break;
}
}
// textmode disable item
if (text->editmode) {
switch(_modeFindSpecial) {
case JUMPID_IMG: {
szCaption1 = "図のファイル名(&C):";
break;
}
case JUMPID_FOOTNOTE: {
szCaption1 = "脚注の内容(&C):";
break;
}
case JUMPID_RUBY: {
szCaption1 = "ルビの漢字(&C):";
szCaption2 = "ルビのよみがな(&D):";
break;
}
case JUMPID_LINK: {
szCaption1 = "リンク先のファイル名(&C):";
szCaption2 = "キャプション(&D):";
break;
}
case JUMPID_PROOF: {//2.98 970305
szCaption1 = "校正の内容(&C):";
szCaption2 = "校正者(&D):";
break;
}
case JUMPID_TAG: {//2.98 970305
if (text->fHTML) {
szCaption1 = "タグの内容(&C):";
} else {
fEnableButton1 = FALSE;
fEnableButton2 = FALSE;
}
break;
}
case JUMPID_PAIRTAG: {//2.99 970313
if (!text->fHTML) {
fEnableButton1 = FALSE;
}
break;
}
}
}
initContent();
SetWindowText(hcaption1,szCaption1);
SetWindowText(hcaption2,szCaption2);
SetWindowText(hctrl1,_szFindSpecial1);
SetWindowText(hctrl2,_szFindSpecial2);
#if 1//2.99D 970330
EnableDlgItem(hwnd,IDD_NEXT,fEnableButton1);
EnableDlgItem(hwnd,IDD_PREV,fEnableButton2);
#else
EnableWindow(GetDlgItem(hwnd,IDD_NEXT),fEnableButton1);
EnableWindow(GetDlgItem(hwnd,IDD_PREV),fEnableButton2);
#endif
//
if (_modeFindSpecial == JUMPID_PAGE) {
EnableWindow(hctrl1,(_szFindSpecial1[0] != 0));
EnableWindow(hctrl2,(text->editmode < 2));
} else {
EnableWindow(hctrl1,(szCaption1[0] != 0));
EnableWindow(hctrl2,(szCaption2[0] != 0));
}
//
if (wParam) {
// at WM_INITDIALOG
if (IsWindowEnabled(hctrl1)) {
SetFocus(hctrl1);
Edit_SetSel(hctrl1,0,-1);
}
}
}
}
return FALSE;
}
extern "html" BOOL TXCMD TXAPI txHtmlJumpPairTag(TX* text);
BOOL TXCMDBASE uiJumpEx(TX* text)
{
// ジャンプ
// 行、ページへのジャンプ、図や表、脚注、太字などを検索します。
//2.99 970312 特殊検索から変更し、行/ページジャンプを統合
//2.99A 970321 {#MS} {F5} new
//{#MS} {F5}
if (text->fBinedit) {
uiJumpAddress(text);
} else {
HDIALOG hd = dialogbig("ジャンプ"); //2.99D 970330 dialogbig化
dialogSetHookEx(hd,"\m.dlgprocSearchSpecial");
//
dialogControlID(hd,IDD_TARGET);
dialogControlListbox(hd,_fwin40 ? 7 : 6);//2.99C 970326 WZ32で小さすぎた
dialogSelectID(
hd,"移動先(&O):",&_modeFindSpecial,16,16,
"行","ページ","変更行", //3.00B1 970521 ジャンプの移動先に"変更行"を追加
"図","表","脚注","太字","下線","斜体","見出し","オブジェクト",
"ルビ","ハイパーリンク","水平線","校正","特殊文字",
"HTMLタグ","HTMLペアタグ"
);
if (text->editmode == 0) {
#if 1//3.00B1 970521
switch(_modeFindSpecial) {
case JUMPID_LINE:
case JUMPID_PAGE:
case JUMPID_EDITED: break;
default: _modeFindSpecial = JUMPID_LINE;
}
#else
if (_modeFindSpecial != JUMPID_LINE && _modeFindSpecial != JUMPID_PAGE) {
_modeFindSpecial = JUMPID_LINE;
}
#endif
}
dialogCmdLFV(hd);
//
dialogSpaceV(hd);
dialogSpaceV(hd);
dialogSetIntXY(hd,0,1);
dialogControlID(hd,IDD_CAPTION1);
dialogCaptionDynamic(hd,NULL,32);
dialogControlID(hd,IDD_CONTENT1);
dialogStr(hd,NULL,_szFindSpecial1,0,32);
dialogSpaceV(hd);
dialogSpaceV(hd);
dialogControlID(hd,IDD_CAPTION2);
dialogCaptionDynamic(hd,NULL,32);
dialogControlID(hd,IDD_CONTENT2);
dialogStr(hd,NULL,_szFindSpecial2,0,32);
dialogResetInt(hd);
//
int lxg = 16;
dialogLFV(hd);
dialogControlID(hd,IDD_NEXT);
dialogCmdDefault(hd,"次へ(&N)",lxg);
dialogControlID(hd,IDD_PREV);
dialogCmd(hd,"前へ(&P)",lxg);
dialogControlID(hd,IDCANCEL);
dialogCmd(hd,"閉じる",lxg);
dialogControlID(hd,IDD_MOVEWINDOW);
dialogCmd(hd,"ウィンドウ移動(&M)",lxg);
if (dialogOpen(hd) == IDOK) {
switch(_modeFindSpecial) {
case JUMPID_LINE: {
int nline = atoi(_szFindSpecial1);
txJumpModal(text,nline);
txVarSet(text,"\m.nline",nline);
break;
}
case JUMPID_PAGE: {
int npage = atoi(_szFindSpecial1);
int npageline = atoi(_szFindSpecial2);
if (npage) {
if (text->editmode == 2) {
txJumpPage(text,npage);
} else {
txJumpModal(text,(npage - 1) * text->height + npageline);
}
} else {
txJumpModal(text,npageline);
}
txVarSet(text,"\m.npageline",npageline);
break;
}
case JUMPID_PAIRTAG: {
txHtmlJumpPairTag(text);
break;
}
}
}
}
return TRUE;
}
//##検索リスト
#include "outline.h"
typedef struct {
mchar szFind[CCHWORD];
mchar szReplace[CCHWORD];
mchar szMode[CCHWORD];
SEARCHMODE searchmode;
IFILE adrFind;
WORD fFind:1; //3.00A2 970506
SIGNED_WORD lchFind; //3.00A2 970506 int->SIGNED_WORD
SIGNED_WORD ly; //3.00A2 970506 int->SIGNED_WORD
} SEARCHSET;
static BOOL txGetSearchset(TX* text,SEARCHSET* ss,BOOL _fFirst)
{
// 一回で終わる場合は2を返す
BOOL ret = FALSE;
BOOL fOnce = FALSE;
BOOL fFirst = TRUE;
structClear(*ss);
while(1) {
txstr szline;
txGetPara(text,szline);
if (strmatch(szline,text->tsztitle[1])) {
// "..."を仮定
if (!fFirst) break;
if (_fFirst && !fOnce) fOnce = TRUE;
} else if (strmatch(szline,text->tsztitle[0])) {
// ".."を仮定
if (!fFirst) break;
if (!_fFirst) break;
fOnce = 2;
} else {
fFirst = FALSE;
int lch;
if (lch = strmatch(szline,"find=")) {
ret = TRUE;
strcpymax(ss->szFind,&szline[lch],cchof(ss->szFind));
} else if (lch = strmatch(szline,"to=")) {
ret = TRUE;
strcpymax(ss->szReplace,&szline[lch],cchof(ss->szReplace));
} else if (lch = strmatch(szline,"mode=")) {
ret = TRUE;
strcpymax(ss->szMode,&szline[lch],cchof(ss->szMode));
ss->searchmode = searchmodeFromSzstr(ss->szMode);
}
}
if (!txNextPara(text)) break;
}
if (fOnce == TRUE && ret) {
//information("!!!");
return 2;
}
return ret;
}
static int SearchMulti(TX* text,TX* txArg,SEARCHMODE searchmode,TXSEARCHLISTARG* arg)
{
txSetUndisp(text);
IFILE adr = txGetAddress(text);
int ly = text->ly;
//
BOOL fPrev = ((searchmode & SEARCH_PREV) != 0);
#define MAX_SSN 50
SEARCHSET tss[MAX_SSN];
memset(tss,0,sizeof(tss));
int n = 0;
int i;
BOOL fFirst = TRUE;
//txstr sz;txGetPara(txArg,sz);information(sz);
for (i = 0;i < MAX_SSN;i++,fFirst = FALSE) {
SEARCHSET *ss = tss + i;
n = i + 1;
int ret = txGetSearchset(txArg,ss,fFirst);
if (!ret) break;
//information("%s %lX",ss->szFind,ss->searchmode|searchmode);
if (ss->lchFind = txSearchEx(text,ss->szFind,ss->searchmode|searchmode)) {
ss->fFind = TRUE;//3.00A2 970506
ss->adrFind = txGetAddress(text);
ss->lchFind--;
ss->ly = text->ly;
//information("ret:%d n:%d lchFind:%d adrFind:%ld %s %lX",ret,n,ss->lchFind,ss->adrFind,ss->szFind,ss->searchmode|searchmode);
}
txJumpAddress(text,adr);
txSetLy(text,ly);
if (ret == 2) break;
}
IFILE adrFind = 0;
int iFind = -1;
#if 1//3.00A2 970506 検索リスト:テキスト先頭でマッチするときに、NOT FOUNDになることがあった
if (fPrev) {
for (i = 0;i < n;i++) {
SEARCHSET *ss = tss + i;
if (ss->fFind && (adrFind == 0 || ss->adrFind > adrFind)) {
adrFind = ss->adrFind;
iFind = i;
}
}
} else {
for (i = 0;i < n;i++) {
SEARCHSET *ss = tss + i;
if (ss->fFind && (adrFind == 0 || ss->adrFind < adrFind)) {
adrFind = ss->adrFind;
iFind = i;
}
}
}
#else
if (fPrev) {
for (i = 0;i < n;i++) {
SEARCHSET *ss = tss + i;
if (ss->adrFind && (adrFind == 0 || ss->adrFind > adrFind)) {
adrFind = ss->adrFind;
iFind = i;
}
}
} else {
for (i = 0;i < n;i++) {
SEARCHSET *ss = tss + i;
if (ss->adrFind && (adrFind == 0 || ss->adrFind < adrFind)) {
adrFind = ss->adrFind;
iFind = i;
}
}
}
#endif
if (iFind == -1) {
} else {
SEARCHSET *ss = tss + iFind;
if (arg) {
arg->searchmode = ss->searchmode;
if (arg->szReplace) strcpymax(arg->szReplace,ss->szReplace,arg->cchReplace);
//information("%s %lX",arg->szReplace,arg->searchmode);
}
if (ss->searchmode & SEARCH_RE) {
// vwxwのタグや、マッチ長をセットする
txJumpAddress(text,ss->adrFind);
SEARCHMODE mode = ss->searchmode;
mode &= ~SEARCH_PREV;
mode |= SEARCH_CUR;
//information("%s %lX",ss->szFind,mode);
txSearchEx(text,ss->szFind,mode);
}
txJumpAddress(text,ss->adrFind);
txSetLy(text,ss->ly);
txSetDisp(text);
//information("%d",ss->lchFind);
return ss->lchFind + 1;
}
txSetDisp(text);
return 0;
}
extern "edit" BOOL TXAPI txConvertDic(TX* text);
static void txInitSearchDic(TX* text)
{
txInitText(text);
mchar szfilename[CCHPATHNAME];
pathFullConfig(szfilename,"search.dic");
txSetFileName(text,szfilename);
txOpenText(text);
//2.00E2 設定がなくても正常に動作するように
strcpy(text->tsztitle[0],"..");
strcpy(text->tsztitle[1],"...");
strcpy(text->tsztitle[2],"");
//2.92
txConvertDic(text);
}
int TXAPI txSearchlistEx(TX* _text,mchar* szFind,TXSEARCHLISTARG* arg)
{
//2.92 検索リストのszFindエントリの内容の検索を実行
int ret = 0;
TX _txdic;
TX *text = &_txdic;
txInitSearchDic(text);
txstr sz = text->tsztitle[0];
sz += szFind;
if (txSearchEx(text,sz,SEARCH_CUR|SEARCH_PARATOP)) {
//txstr sz;txGetPara(text,sz);information(sz);
ret = SearchMulti(_text,text,arg->searchmode,arg);
} else {
txJumpFileTop(text);
txstr sz = text->tsztitle[1];
sz += szFind;
if (txSearchEx(text,sz,SEARCH_CUR|SEARCH_PARATOP)) {
//txstr sz;txGetPara(text,sz);information(sz);
ret = SearchMulti(_text,text,arg->searchmode,arg);
}
}
txClose(text);//3.00B1 970613 置換リストで大量に置換するとメモリ不足になった
return ret;
}
static mchar* getSzfind(TX* text,txstr szstr)
{
txGetPara(text,szstr);
if (strmatch(szstr,text->tsztitle[1])) {
// "..."を仮定
return &szstr[strlen(text->tsztitle[1])];
} else if (strmatch(szstr,text->tsztitle[0])) {
// ".."を仮定
return &szstr[strlen(text->tsztitle[0])];
}
return "";
}
BOOL dlgprocListAdd(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
//3.00A2 970506 new
switch(message) {
case WM_COMMAND: {
int id = WM_COMMAND_GetId(wParam);
int notify = WM_COMMAND_GetNotify(wParam,lParam);
if (id == IDOK) {
mchar buff[CCHWORD];
GetDlgItemText(hwnd,IDD_TITLENAME,buff,cchof(buff));
if (strchr(buff,'\\')) {
//3.00A2 970506 置換リストの「グループ名」・「タイトル」に \ が使えないので、\が使われた時はエラーメッセージを出す様にした。
information("グループ名およびタイトルに \\ は使えません。\n全角 ¥ を使うか、別の文字を使ってください");
return TRUE;
}
}
break;
}
}
return FALSE;
}
static void listOp(HWND hwnd,int id)
{
//2.92 マルチ検索/置換対応
TX* text = outlineGetTx(hwnd);
dialogRead(dialogFromHwnd(hwnd));
TX body;
TX* work = &body;
txInitText(work);
txCopyConfig(work,text);
txOpenText(work);
if (id != IDD_PASTE) {
outlineCopy(hwnd);
#if 1//2.99D 970330
EnableDlgItem(hwnd,IDD_PASTE,TRUE);
#else
EnableWindow(GetDlgItem(hwnd,IDD_PASTE),TRUE);
#endif
txPaste(work);
txJumpFileTop(work);
}
//
txstr szstr;
HEADLINE hl;
outlineGetCurheadline(hwnd,&hl);
szstr = hl.szstr;
//
switch(id) {
case IDD_PASTE: {
{
long cur = outlineGetCursel(hwnd);
if (hl.npara == 0) {
txJumpFileTop(text);
} else {
txJumpPara(text,hl.npara);
}
txPaste(text);
outlineFlush(hwnd);
outlineSetCursel(hwnd,cur);
}
break;
}
case IDD_EDIT:
case IDD_ADD:
case IDD_ADDCATEGORY: {
SEARCHSET ss;
txGetSearchset(work,&ss,TRUE);
SEARCHOPT searchopt;
//
if (!(hl.nest == 1 || hl.nest == 2)) break;
//
BOOL fEdit = (id == IDD_EDIT);
BOOL fCategory = (id == IDD_ADDCATEGORY || (fEdit && hl.nest == 1));
HDIALOG hd;
if (fEdit) {
if (fCategory) {
hd = dialog("グループ名の変更");
} else {
hd = dialog("検索リストの編集");
}
} else {
if (fCategory) {
hd = dialog("グループの追加");
} else {
hd = dialog("検索リストに追加");
}
}
dialogSetHookEx(hd,"\m.dlgprocListAdd");//3.00A2 970506
dialogSetContexthelp(hd,TRUE);
dialogControlHelp(hd,185);
dialogControlID(hd,IDD_TITLENAME);//3.00A2 970506
if (fCategory) {
dialogStr(hd,"グループ名(&T):",szstr,12,32);
} else {
dialogStr(hd,"タイトル(&T):",szstr,8,32);
}
dialogSpaceV(hd);
if (!fCategory) {
dialogSetGroupRight(hd,DTCX * 42);
dialogGroup(hd,"検索文字列と置換文字列(&S)");
dialogControlHelp(hd,190);
dialogControlHistRead(hd,HIST_SEARCH);
dialogStrC(hd,"検索:",ss.szFind,7,cchof(ss.szFind),30);
dialogControlHelp(hd,191);
dialogControlHistRead(hd,HIST_SEARCH);
dialogStrC(hd,"置換:",ss.szReplace,7,cchof(ss.szReplace),30);
dialogGroupEnd(hd);
//
searchmodeToSearchopt(ss.searchmode,&searchopt);
//
dialogSearchOption(hd,&searchopt,0);
}
if (dialogOpen(hd)) {
if (!fCategory) {
SEARCHMODE searchmode = searchmodeFromSearchopt(&searchopt);
{
txstr szmode;
searchmodeToSzstr(searchmode,szmode);
strcpymax(ss.szMode,szmode,cchof(ss.szMode));
}
}
//
long cur = outlineGetCursel(hwnd);
if (fEdit && !fCategory) {
outlineClear(hwnd);
}
if (hl.npara == 0) {
txJumpFileTop(text);
} else {
txJumpPara(text,hl.npara);
}
if (fCategory) {
if (fEdit) {
txDeletePara(text);
}
} else {
if (id == IDD_ADD) {
HEADLINE hl;
outlineGetHeadline(hwnd,&hl,cur+1);
hl.npara == 0 ? txJumpFileTop(text) : txJumpPara(text,hl.npara);
cur++;
}
}
txInsertLine(text,"%s%s",text->tsztitle[0+!fCategory],szstr);
if (!fCategory) {
txInsertLine(text,"find=%s",ss.szFind);
txInsertLine(text,"to=%s",ss.szReplace);
txInsertLine(text,"mode=%s",ss.szMode);
}
//
outlineFlush(hwnd);
outlineSetCursel(hwnd,cur);
}
break;
}
case IDD_DEL: {
int ret = MessageBox(
hwnd,
szstr + "\nを削除します。よろしいですか?",
"検索リストから削除",
MB_ICONQUESTION|MB_YESNOCANCEL
);
if (ret == IDYES) {
long cur = outlineGetCursel(hwnd);
outlineClear(hwnd);
outlineFlush(hwnd);
outlineSetCursel(hwnd,cur);
}
break;
}
case IDD_SEARCH: {
SEARCHMODE searchmode = 0;
if (_context.modeDirection == DIR_PREV) searchmode |= SEARCH_PREV;
txstr szstr;
if (txSearchEx(textf,_szIdSearchlist+getSzfind(work,szstr),searchmode)) {
err_clear();
} else {
err();
}
break;
}
case IDD_REPLACE: {
SEARCHMODE searchmode = 0;
if (_context.modeDirection == DIR_PREV) searchmode |= SEARCH_PREV;
switch(_context.modeReplace) {
case REPLACE_ALL: searchmode |= SEARCH_ALL;break;
case REPLACE_AREA: searchmode |= SEARCH_AREA;break;
default: searchmode |= REPLACE_ONCE;break;
}
int n;
txstr szstr;
if (n = txReplaceEx(textf,_szIdSearchlist+getSzfind(work,szstr),NULL,searchmode)) {
// OK
} else {
err();
}
break;
}
}
txClose(work);
}
typedef struct {
mchar szstr[CCHWORD];
} SEARCHLISTCONTEXT;
SEARCHLISTCONTEXT _contextsl;
BOOL dlgprocList(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message) {
case WM_INITDIALOG: {
#if 1//2.99C 970323
EnableDlgItem(hwnd,IDD_MODEREPLACETOP + 2,textf->fClip);
EnableDlgItem(hwnd,IDD_PASTE,FALSE);
#else
EnableWindow(GetDlgItem(hwnd,IDD_MODEREPLACETOP + 2),textf->fClip);
EnableWindow(GetDlgItem(hwnd,IDD_PASTE),FALSE);
#endif
break;
}
case WM_COMMAND: {
int id = WM_COMMAND_GetId(wParam);
int notify = WM_COMMAND_GetNotify(wParam,lParam);
switch(id) {
case IDOK: {
HEADLINE hl;
outlineGetCurheadline(hwnd,&hl);
strcpymax(_contextsl.szstr,hl.szstr,cchof(_contextsl.szstr));
break;
}
case IDD_COPY:
case IDD_PASTE:
case IDD_ADD:
case IDD_ADDCATEGORY:
case IDD_DEL:
case IDD_EDIT:
case IDD_REPLACE:
case IDD_SEARCH: {
listOp(hwnd,id);
return TRUE;
}
}
break;
}
case CON_SELCHANGED: {
long cur = outlineGetCursel(hwnd);
HEADLINE hl;
BOOL fEof = !outlineGetHeadline(hwnd,&hl,cur+1);
#if 1//2.99D 970330
EnableDlgItem(hwnd,IDD_ADD,!fEof);
EnableDlgItem(hwnd,IDD_DEL,!fEof);
EnableDlgItem(hwnd,IDD_EDIT,!fEof);
EnableDlgItem(hwnd,IDD_COPY,!fEof);
EnableDlgItem(hwnd,IDD_SEARCH,!fEof);
EnableDlgItem(hwnd,IDD_REPLACE,!fEof);
#else
EnableWindow(GetDlgItem(hwnd,IDD_ADD),!fEof);
EnableWindow(GetDlgItem(hwnd,IDD_DEL),!fEof);
EnableWindow(GetDlgItem(hwnd,IDD_EDIT),!fEof);
EnableWindow(GetDlgItem(hwnd,IDD_COPY),!fEof);
EnableWindow(GetDlgItem(hwnd,IDD_SEARCH),!fEof);
EnableWindow(GetDlgItem(hwnd,IDD_REPLACE),!fEof);
#endif
break;
}
case WM_ACTIVATE: {//2.99C 970323
BOOL fActive = LOWORD(wParam);
if (fActive != WA_INACTIVE) {
EnableDlgButtonEx(hwnd,IDD_MODEREPLACETOP + 2,textf->fClip,IDD_MODEREPLACETOP);
}
break;
}
}
return FALSE;
}
static int searchlistOpen(BOOL fRefer,txstr szSelected)
{
BOOL ret = FALSE;
TX _txdic;
TX *text = &_txdic;
txInitSearchDic(text);
// add EOF
txJumpFileEnd(text);
txInsertLine(text,"%s(end)",text->tsztitle[0]);
text->fEdit = FALSE;
//
HDIALOG hd = _dialog("検索リスト",EXDS_POSCURSOR|EXDS_BIG,NULL);
dialogSetContexthelp(hd,TRUE);
int cx = 16;
dialogCaption(hd,"一覧(&L):");
DTRECT r;
dialogGetPos(hd,&r);
r.cx = DTCX * 30;
r.cy = DTCY * 12;
dialogControlHelp(hd,204);
#if 1//2.92
dialogAddTitle(hd,&r);
#else
__dialogAddItem(hd,"LISTBOX",NULL,IDD_TITLELIST,&r,LBS_NOTIFY|WS_BORDER|WS_VSCROLL|WS_HSCROLL|WS_CHILD|WS_VISIBLE|WS_TABSTOP);
#endif
_dialogAddControlInfo(hd,IDD_TITLELIST);
dialogLFV(hd);
dialogCaption(hd,NULL);
cx = 17;
dialogControlID(hd,IDD_ADD);
dialogControlHelp(hd,204);
dialogCmd(hd,"追加(&A)...",cx);
dialogControlID(hd,IDD_ADDCATEGORY);
dialogControlHelp(hd,204);
dialogCmd(hd,"グループの追加(&B)...",cx);
dialogControlID(hd,IDD_EDIT);
dialogControlHelp(hd,204);
dialogCmd(hd,"修正(&E)...",cx);
dialogControlID(hd,IDD_DEL);
dialogControlHelp(hd,204);
dialogCmd(hd,"削除(&D)...",cx);
dialogSpaceV(hd);
dialogControlID(hd,IDD_COPY);
dialogControlHelp(hd,204);
dialogCmd(hd,"コピー(&C)",cx);
dialogControlID(hd,IDD_PASTE);
dialogControlHelp(hd,204);
dialogCmd(hd,"貼り付け(&T)",cx);
dialogLF(hd);
dialogCaption(hd,"内容:");
dialogGetPos(hd,&r);
r.cx = DTCX * 40;
r.cy = DTCY * 4;
dialogControlHelp(hd,205);
__dialogAddItem(hd,"LISTBOX",NULL,IDD_TITLEVIEW,&r,LBS_NOTIFY|WS_BORDER|WS_VSCROLL|WS_HSCROLL|WS_CHILD|WS_VISIBLE|WS_TABSTOP);
_dialogAddControlInfo(hd,IDD_TITLEVIEW);
if (fRefer) {
dialogLFV(hd);
dialogSpaceH(hd);
dialogSpaceH(hd);
dialogSpaceH(hd);
dialogOK(hd,cx);
dialogCancel(hd,cx);
dialogSpaceV(hd);
} else {
dialogLFV(hd);
dialogSpaceH(hd);
dialogSpaceH(hd);
dialogSpaceH(hd);
cx = 16;
// dialogControlRadioV(hd);
_context.modeDirection = DIR_NEXT;
dialogControlHelp(hd,-303);
dialogRadioIDB(hd,&_context.modeDirection,"上へ(&P)","下へ(&N)");
//
dialogControlID(hd,IDD_SEARCH);
dialogControlHelp(hd,195);
dialogCmdDefault(hd,"次を検索(&S)",cx);
dialogSpaceV(hd);
dialogControlRadioV(hd);
_context.modeReplace = textf->fClip ? REPLACE_AREA : REPLACE_1;
dialogControlID(hd,IDD_MODEREPLACETOP);
dialogControlHelp(hd,-305);
dialogRadioIDB(hd,&_context.modeReplace,"1つ置換(&1)","全て(&2)","範囲内(&3)");
//
dialogControlID(hd,IDD_REPLACE);
dialogControlHelp(hd,197);
dialogCmd(hd,"置換(&R)",cx);
dialogSpaceV(hd);
dialogControlID(hd,IDCANCEL);
dialogCancel(hd,cx);
}
CHOOSEOUTLINE co;
memset(&co,0,sizeof(CHOOSEOUTLINE));
co.text = text;
co.szhook = "\m.dlgprocList";
co.iselFirst = 0;
co.fNoTitleHead = TRUE;
if (dialogSelectTitle(hd,&co)) {
ret = TRUE;
if (fRefer) {
szSelected = _contextsl.szstr;
}
}
if (text->fEdit) {
// del EOF
txJumpFileEnd(text);
txPrevPara(text);
txDeletePara(text);
//
txSave(text);
}
txClose(text);
return ret;
}
uiSearchList
{
// 検索リスト
// 決まった置換や検索をリストで選んで実行します
//1.96で追加
return searchlistOpen(FALSE,NULL);
}
//##複数テキストの検索・置換
vzuiSearchMulti
{
// VZの[複数テキストで検索・置換]ライクなコマンド
//1.01A で追加
//{#VZ} +{F6}
if (_fReplace) {
wzlock(LOCK_SEARCHALL);
text->share->replace.searchmode |= SEARCH_ALLTEXT;
wzunlock(LOCK_SEARCHALL);
txReplaceContinue(text);
} else {
txSearchContinue(text);
}
}
uiSearchFunctionC
{
// 関数名を指定して、Cの関数定義を検索します
//2.90で追加
BOOL ret = FALSE;
HDIALOG hd = dialog("C関数定義の検索");
txstr szstr;
dialogControlHist(hd,HIST_SEARCH);
dialogStr(hd,"関数名(&N)",szstr,10,30);
if (dialogOpen(hd)) {
txSetUndispEx(text);
txJumpFileTop(text);
while(1) {
txSearchEx(text,"^[A-Za-z_][^/]*[^;]$",SEARCH_RE|SEARCH_NOSELECT);
txJumpParaTop(text);
NPARA npara = text->npara;
if (!txSearchEx(text,szstr,SEARCH_CUR|SEARCH_NOSELECT)) break;
if (text->npara == npara) {
ret = TRUE;
break;
}
txJumpNpara(text,npara);
if (!txNextPara(text)) break;
}
if (ret) {
txSetDisp(text);
} else {
txSetDispEx(text);
}
}
if (!ret) statprintf("見つかりませんでした");
return ret;
}
//2.96 970201 WZ.EXEから移動
// 旧API
int TXAPI TXHIGH txSearch(tx *text,mchar *find)
{
// findをカーソル位置の次から検索
// 検索ヒストリは変更しません
//1.00H2 検索オプションはtext->searchmodeを参照します
//{#RET}見つかればカーソルを移動し0以外の値、
// 見つからなければ0を返す
#if 1//2.96 970201
return txSearchEx(text,find,text->searchmode);
#else
#if 1//1.92
return SearchNext(text,find,text->searchmode);
#else
return SearchNext(text,find,searchmodeFromText(text));
#endif
#endif
}
int TXAPI TXHIGH txSearchPrev(tx *text,mchar *find)
{
// findをカーソル位置からテキスト先頭まで検索
// ※txSearchContinuePrevには影響しません。
//{#RET}見つかればカーソルを移動し0以外の値、
// 見つからなければ0を返す
#if 1//2.96 970201
return txSearchEx(text,find,text->searchmode|SEARCH_PREV);
#else
#if 1//1.92
return SearchPrev(text,find,text->searchmode|SEARCH_PREV);
#else
return SearchPrev(text,find,searchmodeFromText(text)|SEARCH_PREV);
#endif
#endif
}
//1.91A jump.cから移動
//{###ジャンプ}
#include "wintxx.h"
#include "dialog.h"
void uiJumpAddress(TX* text)
{
txstr str;
static int adr = 0;
HDIALOG hd = dialog("ジャンプ");
sprintf(str,"%08lX",adr);
dialogStr(hd,"アドレス(&A):",str,10,12);
if (dialogOpen(hd)) {
mchar*p = str;
adr = 0;
for (;*p;p++) {
mchar c = toupper(*p);
if (isdigit(c)) {
adr *= 16;
adr += c - '0';
} else if ('A' <= c && c <= 'F') {
adr *= 16;
adr += c - 'A' + 10;
} else {
break;
}
}
txJumpAddress(text,adr);
}
}
BOOL TXCMDBASE uiJump(TX* text)
{
// 指定行ジャンプ
// ジャンプダイアログを開いて、指定された行番号にジャンプします
if (text->fBinedit) {
uiJumpAddress(text);
} else {
int nline = txVarGet(text,"\m.nline");
if (nline == 0) nline = 1;
HDIALOG hd = dialog("ジャンプ");
dialogInt(hd,"行番号(&N):",&nline,10,7);
// dialogSetHelp(hd,"wz txuiJump");
if (dialogOpen(hd)) {
txJumpModal(text,nline);
txVarSet(text,"\m.nline",nline);
}
}
return TRUE;
}
//2.99 970312 uiJumpPageを元に戻した
//2.95 970131 改良 テキストモードでもheightを使ってページ数を計算
// thanks y.mikomeさん
BOOL TXCMDBASE uiJumpPage(TX* text)
{
// 指定頁,行ジャンプ
// 詳細モードでは頁指定ジャンプ
// 簡易頁表示では、頁・行複合指定ジャンプ
// それ以外では行指定ジャンプ
HDIALOG hd = dialog("ジャンプ");
NPAGE npage = 0;
if (text->editmode == 2) {
npage = txNpageFromNpageclm(text,text->npage);
} else if (text->fLineD && text->height) {
npage = (text->nline / text->height) + 1;
}
dialogControlEnable(hd,(npage != 0));
dialogIntW(hd,"ページ(&P):",&npage,10,7);
int line = txVarGet(text,"\m.npageline");
if (line == 0) line = 1;
dialogControlEnable(hd,(text->editmode < 2));
dialogInt(hd,"行番号(&N):",&line,10,7);
if (dialogOpen(hd)) {
if (npage) {
if (text->editmode == 2) {
txJumpPage(text,npage);
} else {
txJumpModal(text,(npage - 1) * text->height + line);
}
} else {
txJumpModal(text,line);
}
txVarSet(text,"\m.npageline",line);
}
return TRUE;
}
err_brace
{
statprintf("括弧が見つかりません");
if (text->fbeep) MessageBeep(MB_ICONEXCLAMATION);
}
BOOL TXCMDBASE vzSetLySwitch(TX* text)
{
// 表示位置変更
// カーソル位置を画面上端、中央、下端の順に切り替えます。
// 編集位置は変わりません。
//{#VZIBM} +{Home}
//{#VZ98} {Clr}
//{#EMACS} +{Home}
int y = text->lcywindow - 3;
y /= 2;
if (text->ly==y) {
txSetLy(text,text->lcywindow-2);
} else {
if (text->ly==1){
txSetLy(text,y);
} else {
txSetLy(text,1);
}
}
return TRUE;
}
otherJumpLineTop
{
// 次画面で行頭に移動します
//1.00Cで追加
return wndtxCallNextEx("txJumpLineTop");
}
otherJumpLineEnd
{
// 次画面で行末に移動します
//1.00Cで追加
return wndtxCallNextEx("txJumpLineEnd");
}
otherJumpFileTopLine
{
// 次画面でテキストの先頭表示行へジャンプ
//1.00Cで追加
return wndtxCallNextEx("txJumpFileTopLine");
}
otherJumpFileEndLine
{
// 次画面でテキストの末尾表示行へジャンプ
//1.00Cで追加
return wndtxCallNextEx("txJumpFileEndLine");
}
//{###カーソル移動}
//## 範囲選択してカーソル移動
//2.99D 970331 範囲選択してカーソル移動するコマンド追加
//2.99D 970331 new
static int _txkeySelect(TX* text,mchar* szBaseCmd)
{
// 選択して右へ
int modeEditor0 = text->modeEditor;
int fKeyVkShift0 = text->fKeyVkShift;
text->modeEditor = ME_WIN;
text->fKeyVkShift = 2;
int ret = txCall(text,szBaseCmd);
text->modeEditor = modeEditor0;
text->fKeyVkShift = fKeyVkShift0;
return ret;
}
//2.99D 970331 new
int TXCMD txkeySelectRight(TX* text)
{
// 選択して右へ
return _txkeySelect(text,"txkeyRight");
}
//2.99D 970331 new
int TXCMD txkeySelectLeft(TX* text)
{
// 選択して左へ
return _txkeySelect(text,"txkeyLeft");
}
//2.99D 970331 new
int TXCMD txkeySelectUp(TX* text)
{
// 選択して上へ
return _txkeySelect(text,"txkeyUp");
}
//2.99D 970331 new
int TXCMD txkeySelectDown(TX* text)
{
// 選択して下へ
return _txkeySelect(text,"txkeyDown");
}
otherUp
{
// 次画面のカーソルを1行上に移動します
//1.00Cで追加
return wndtxCallNextEx("txUp");
}
otherDown
{
// 次画面のカーソルを1行下に移動します
//1.00Cで追加
return wndtxCallNextEx("txDown");
}
otherPrevRoll
{
// 次画面を1行ロールアップします
//1.00Cで追加
return wndtxCallNextEx("txPrevRoll");
}
otherNextRoll
{
// 次画面を1行ロールダウンします
//1.00Cで追加
return wndtxCallNextEx("txNextRoll");
}
otherNextPage
{
// 次画面をページダウンします
//1.00Cで追加
return wndtxCallNextEx("txNextPage");
}
otherNextPageVz
{
// 次画面をページダウン(VZライク)します
//1.00Cで追加
return wndtxCallNextEx("txNextPageVz");
}
otherNextPageMi
{
// 次画面をページダウン(MIFESライク)します
//1.00Cで追加
return wndtxCallNextEx("txNextPageMi");
}
otherPrevPage
{
// 次画面をページアップします
//1.00Cで追加
return wndtxCallNextEx("txPrevPage");
}
otherPrevPageVz
{
// 次画面をページアップ(VZライク)します
//1.00Cで追加
return wndtxCallNextEx("txPrevPageVz");
}
otherPrevPageMi
{
// 次画面をページアップ(MIFESライク)します
//1.00Cで追加
return wndtxCallNextEx("txPrevPageMi");
}
bothUp
{
// 次画面と同時にカーソル1行上に移動します
//1.00Cで追加
return wndtxCallBothEx("txUp");
}
bothDown
{
// 次画面と同時にカーソルを1行下に移動します
//1.00Cで追加
return wndtxCallBothEx("txDown");
}
bothPrevRoll
{
// 次画面と同時に1行ロールアップします
//1.00Cで追加
return wndtxCallBothEx("txPrevRoll");
}
bothNextRoll
{
// 次画面と同時に1行ロールダウンします
//1.00Cで追加
return wndtxCallBothEx("txNextRoll");
}
bothNextPage
{
// 次画面と同時にページダウンします
//1.00Cで追加
return wndtxCallBothEx("txNextPage");
}
bothNextPageVz
{
// 次画面と同時にページダウン(VZライク)します
//1.00Cで追加
return wndtxCallBothEx("txNextPageVz");
}
bothNextPageMi
{
// 次画面と同時にページダウン(MIFESライク)します
//1.00Cで追加
return wndtxCallBothEx("txNextPageMi");
}
bothPrevPage
{
// 次画面と同時にページアップします
//1.00Cで追加
return wndtxCallBothEx("txPrevPage");
}
bothPrevPageVz
{
// 次画面と同時にページアップ(VZライク)します
//1.00Cで追加
return wndtxCallBothEx("txPrevPageVz");
}
bothPrevPageMi
{
// 次画面と同時にページアップ(MIFESライク)します
//1.00Cで追加
return wndtxCallBothEx("txPrevPageMi");
}
//{###ジャンプ}
//##しおり
#define IDD_UMLIST 100
#define IDD_JUMP 101
#define IDD_REGISTER 102
#define IDD_KILL 103
static void markFlush(TX* text,HWND hwnd)
{
//3.00A2 970506 引数にtext追加
HWND hctrl = GetDlgItem(hwnd,IDD_UMLIST);
SendMessage(hctrl,LB_RESETCONTENT,0,0);
#if 1
txSetUndispEx(text);
txstr szline;
int i;
for (i = 1;i < MAXMARK;i++) {
txJumpAddress(text,text->mark[i]);
txGetPara(text,szline);
mchar szbuff[CCHWORD];
reReplace(szbuff,CCHWORD,strGetWordTop(szline),"\t"," ",SEARCH_ALL);
mchar buff[40];
sprintf(buff,"%d) %d:\t",i,text->npara);
SendMessage(hctrl,LB_ADDSTRING,0,(LPARAM)(mchar*)(buff + szbuff));
}
txSetDispEx(text);
#else
#if 0 //3.00A3 970508 tszmark廃止
if (text->tszmark) {
int i;
for (i = 0;i < MAXMARK;i++) {
mchar szbuff[CCHMARK * 2];
strcpy(szbuff,text->tszmark + CCHMARK * i);
strtoesc(szbuff);
//
mchar szdst[CCHMARK * 2];
reReplace(szdst,CCHMARK * 2,szbuff,\"\\s"," ",SEARCH_ALL);
strcpy(szbuff,szdst);
reReplace(szdst,CCHMARK * 2,szbuff,\"\\t"," ",SEARCH_ALL);
//
SendMessage(hctrl,LB_ADDSTRING,0,(LPARAM)(mchar*)(inttostr(i) + ": " + szdst));
}
SendMessage(hctrl,LB_SETCURSEL,0,0);
}
#endif
#endif
}
BOOL dlgprocMark(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDIALOG hd = dialogFromHwnd(hwnd);//3.00A2 970506
TX* text = (TX*)dialogGetCustdata(hd);//3.00A2 970506
switch(message) {
case WM_INITDIALOG: {
markFlush(text,hwnd);
if (txVarIsExist(text,"\m.iMark")) {
ListBox_SetCurSel(GetDlgItem(hwnd,IDD_UMLIST),txVarGet(text,"\m.iMark"));
}
// SendDlgItemMessage(hwnd,IDD_UMLIST,LB_SETTABSTOPS,1,10);
break;
}
case WM_COMMAND: {
HDIALOG hd = dialogFromHwnd(hwnd);
int id = WM_COMMAND_GetId(wParam);
int notify = WM_COMMAND_GetNotify(wParam,lParam);
switch(id) {
case IDD_UMLIST: {
if (notify == LBN_DBLCLK) {
FORWARD_WM_COMMAND(hwnd,IDD_JUMP,NULL,NULL,PostMessage);
break;
}
#if 0
if (notify == LBN_SELCHANGE) {
HWND hctrl = GetDlgItem(hwnd,id);
int isel = ListBox_GetCurSel(hctrl);
if (isel != LB_ERR) {
txJumpAddress(text,text->mark[isel+1]);
}
break;
}
#endif
break;
}
case IDD_JUMP: {
HWND hctrl = GetDlgItem(hwnd,IDD_UMLIST);
int i = ListBox_GetCurSel(hctrl);
if (i != LB_ERR) {
txVarSet(text,"\m.iMark",i);
txJumpMarkN(text,i + 1);
}
break;
// return TRUE;
}
case IDD_REGISTER: {
HWND hctrl = GetDlgItem(hwnd,IDD_UMLIST);
int i = ListBox_GetCurSel(hctrl);
if (i != LB_ERR) {
txVarSet(text,"\m.iMark",i);
txMarkN(text,i + 1);
markFlush(text,hwnd);
SendMessage(hctrl,LB_SETCURSEL,i,0);
}
break;
// return TRUE;
}
}
break;
}
}
return FALSE;
}
//2.95 970130 しおり改良
//2.99G 970405 MS.KEY割り当て
BOOL TXCMDBASE uiMark(TX* text)
{
// しおり
//{#MS} ^{F5}
IFILE adr = txGetAddress(text);
txMarkCur(text);
text->fNoMarkCur++;
//
int cx = 12;
HDIALOG hd = dialog("しおり");
dialogSetContexthelp(hd,TRUE);
dialogSetHookEx(hd,"\m.dlgprocMark");
dialogSetCustdata(hd,text);//3.00A2 970506
DTRECT r;
dialogGetPos(hd,&r);
r.cx = DTCX * 60;
r.cy = DTCY * 6; //2.99C 970326 4->6 WZ32で小さすぎた
__dialogAddItem(hd,"LISTBOX",NULL,IDD_UMLIST,&r,LBS_NOTIFY|LBS_USETABSTOPS|WS_BORDER|WS_VSCROLL|WS_HSCROLL|WS_CHILD|WS_VISIBLE|WS_TABSTOP);
dialogControlHelp(hd,217);
_dialogAddControlInfo(hd,IDD_UMLIST);
dialogSetPosY(hd,r.y + r.cy);
dialogLFV(hd);
dialogControlID(hd,IDD_JUMP);
dialogControlHelp(hd,218);
dialogCmdDefault(hd,"ジャンプ(&J)",cx);
//
dialogControlID(hd,IDD_REGISTER);
dialogControlHelp(hd,219);
dialogCmd(hd,"はさむ(&R)",cx);
//
dialogSpaceV(hd);
dialogControlID(hd,IDCANCEL);
dialogButtonCmd(hd,"キャンセル",NULL,cx);
if (!dialogOpen(hd)) {
txJumpAddress(text,adr);
}
text->fNoMarkCur--;
return TRUE;
}
//旧:usermenu.umcMiJump
menuJumpMi
{
#WZKEY
// MiJumpメニュー
//{#MI} {F3}
call("menu.ジャンプ(MIFESライク)");
}
//旧:usermenu.umcMiSearch
menuSearchMi
{
#WZKEY
// MiSearchメニュー
//{#MI} +{F3}
call("menu.検索(MIFESライク)");
}
//旧:usermenu.umcMiMark
menuMarkMi
{
#WZKEY
// MiMarkメニュー
//{#MI} ^J
call("menu.マーク(MIFESライク)");
}
// testdata
// ください。下さいな。下さいだ。
//2.00E4
void __new(void)
{
_context.modeDirection = DIR_NEXT;
}
//{###カーソル移動}
//##キー割り当てコマンド(WIN,VZ,MI,WIN範囲選択 共通)
//2.90
int TXCMDBASE txkeyLeftWord(TX* text)
{
// 1つ前の単語へ(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
//{#MS} ^{Left} +^{Left}
//{#VZ} +{Left} ^A
//{#MI} ^A
txkeySelectWin(text);
if (text->fClip) {
//2.96 970210 txkeyLeftWord 選択時は単語を取得しやすい移動にした
IFILE adr = txGetAddress(text);
int ret = txJumpWordTopMi(text);
if (adr == txGetAddress(text)) {
return txLeftWordMi(text);
}
return ret;
}
#if 1//2.96 970210 MS.KEYの単語移動をMIFESライクにした
if (text->modeEditor == ME_VZ) return txLeftWord(text);
return txLeftWordMi(text);
#else
if (text->modeEditor == ME_MI) return txLeftWordMi(text);
return txLeftWord(text);
#endif
}
int TXCMDBASE txkeyRightWord(TX* text)
{
// 1つ後の単語へ(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
//{#MS} ^{Right} +^{Right}
//{#VZ} +{Right} ^F
//{#MI} ^F
txkeySelectWin(text);
if (text->fClip) {
//2.96 970210 txkeyRightWord 選択時は単語を取得しやすい移動にした
IFILE adr = txGetAddress(text);
int ret = txJumpWordEndMi(text);
if (adr == txGetAddress(text)) {
return txRightWordMi(text);
}
return ret;
}
#if 1//2.96 970210
if (text->modeEditor == ME_VZ) return txRightWord(text);
return txRightWordMi(text);
#else
if (text->modeEditor == ME_MI) return txRightWordMi(text);
return txRightWord(text);
#endif
}
int TXCMDBASE txkeyPrevPage(TX* text)
{
// ページアップ(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
// txPrevHalfPage
//{#MS} {PageUp} +{PageUp}
//{#VZ98} ^R +{Up}
//{#VZIBM} ^R {PageUp}
//{#MI} +{Up}
//{#EMACS} {PageUp}
txkeySelectWin(text);
#if 1//3.00A 970427 VZ.KEYでページング単位が半画面のとき、検索ジャンプができなかった
if (text->modeEditor == ME_VZ) return txPrevPageVz(text);
if (text->fHalfPage && !text->fPageTurn) return txPrevHalfPage(text);//2.99F 970404 txkeyNextPage:ハーフページで頁めくりオフならハーフページ移動するようにした
if (text->modeEditor == ME_MI) return txPrevPageMi(text);
return txPrevPage(text);
#else
if (text->fHalfPage && !text->fPageTurn) return txPrevHalfPage(text);//2.99F 970404 txkeyNextPage:ハーフページで頁めくりオフならハーフページ移動するようにした
if (text->modeEditor == ME_MI) return txPrevPageMi(text);
if (text->modeEditor == ME_VZ) return txPrevPageVz(text);
return txPrevPage(text);
#endif
}
int TXCMDBASE txkeyNextPage(TX* text)
{
// ページダウン(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
// txNextHalfPage
//{#MS} {PageDown} +{PageDown}
//{#VZ98} ^C +{Down}
//{#VZIBM} ^C {PageDown}
//{#MI} +{Down}
//{#EMACS} {PageDown} ^V
txkeySelectWin(text);
#if 1//3.00A 970427 VZ.KEYでページング単位が半画面のとき、検索ジャンプができなかった
if (text->modeEditor == ME_VZ) return txNextPageVz(text);
if (text->fHalfPage && !text->fPageTurn) return txNextHalfPage(text);//2.99F 970404 txkeyNextPage:ハーフページで頁めくりオフならハーフページ移動するようにした
if (text->modeEditor == ME_MI) return txNextPageMi(text);
return txNextPage(text);
#else
if (text->fHalfPage && !text->fPageTurn) return txNextHalfPage(text);//2.99F 970404 txkeyNextPage:ハーフページで頁めくりオフならハーフページ移動するようにした
if (text->modeEditor == ME_MI) return txNextPageMi(text);
if (text->modeEditor == ME_VZ) return txNextPageVz(text);
return txNextPage(text);
#endif
}
int TXCMDBASE txkeyPrevHalfPage(TX* text)
{
// ハーフページアップ(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
//{#MI} {PageUp} ^R
txkeySelectWin(text);
#if 0//2.99 970313
if (text->modeEditor == ME_MI) return txPrevPageMi(text);
if (text->modeEditor == ME_VZ) return txPrevPageVz(text);
#endif
return txPrevHalfPage(text);
}
int TXCMDBASE txkeyNextHalfPage(TX* text)
{
// ハーフページダウン(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
//{#MI} {PageDown} ^C
txkeySelectWin(text);
#if 0//2.99 970313
if (text->modeEditor == ME_MI) return txNextPageMi(text);
if (text->modeEditor == ME_VZ) return txNextPageVz(text);
#endif
return txNextHalfPage(text);
}
int TXCMDBASE txkeyJumpLineTop(TX* text)
{
// 表示行の先頭へジャンプ(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
//{#MS} {Home} +{Home}
//{#VZ98} ^Q[ %{Left}
//{#VZIBM} ^Q[ {Home}
//{#MI} ^QS +{Left}
//{#EMACS} {Home}
txkeySelectWin(text);
return txJumpLineTop(text);
}
int TXCMDBASE txkeyJumpLineTail(TX* text)
{
// 表示行の末尾文字の後ろへジャンプ(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
//{#MS} {End} +{End}
//{#VZ98} ^Q] %{Right}
//{#VZIBM} ^Q] {End}
//{#MI} ^QD +{Right}
//{#EMACS} {End}
txkeySelectWin(text);
return txJumpLineTail(text);
}
int TXCMDBASE txkeyJumpParaTop(TX* text)
{
// 段落の先頭へジャンプ(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
//{#VZ} ^QS ^{Left}
//{#EMACS} ^A ^{Left}
txkeySelectWin(text);
return txJumpParaTop(text);
}
int TXCMDBASE txkeyJumpParaEnd(TX* text)
{
// 段落の末尾へジャンプ(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
//{#VZ} ^QD ^{Right}
//{#EMACS} ^E ^{Right}
txkeySelectWin(text);
return txJumpParaEnd(text);
}
int TXCMDBASE txkeyJumpScreenTop(TX* text)
{
// 画面の上端へジャンプ(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
//2.99A 970321 {#MS} ^{PageUp} +^{PageUp} -> {#MS} +^{PageUp}
//{#MS} +^{PageUp}
//{#VZ98} ^{Up} ^QE
//{#VZIBM} ^{Up} ^QE ^{Home}
//{#MI} ^{PageUp}
txkeySelectWin(text);
return txJumpScreenTop(text);
}
int TXCMDBASE txkeyJumpScreenEnd(TX* text)
{
// 画面の下端へジャンプ(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
//2.99A 970321 {#MS} ^{PageDown} +^{PageDown} -> {#MS} +^{PageDown}
//{#MS} +^{PageDown}
//{#VZ98} ^{Down} ^QX
//{#VZIBM} ^{Down} ^QX ^{End}
//{#MI} ^{PageDown}
txkeySelectWin(text);
return txJumpScreenEnd(text);
}
int TXCMDBASE txkeyJumpWordTop(TX* text)
{
// 語の先頭へジャンプ(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
txkeySelectWin(text);
if (text->modeEditor == ME_VZ) return txJumpWordTop(text);
return txJumpWordTopMi(text);
}
int TXCMDBASE txkeyJumpWordTail(TX* text)
{
// 語の末尾の次の文字へジャンプ(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
txkeySelectWin(text);
if (text->modeEditor == ME_VZ) return txJumpWordEnd(text);
return txJumpWordEndMi(text);
}
//{###ジャンプ}
int TXCMDBASE txkeyJumpFileTop(TX* text)
{
// テキストの先頭へジャンプ(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
//{#MS} ^{Home} +^{Home}
txkeySelectWin(text);
return txJumpFileTop(text);
}
int TXCMDBASE txkeyJumpFileEnd(TX* text)
{
// テキストの末尾へジャンプ(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
//{#MS} ^{End} +^{End}
txkeySelectWin(text);
return txJumpFileEnd(text);
}
//{###ジャンプ}
//##タグジャンプ
//1.97で作り直した
//1.97 行番号指定なし、検索文字列指定に対応
//2.92 TX-C化、大改良
// テキストバッファポインタpから行末まで、存在するファイル名の記述があれば
// szfilenameに取得してファイル名の末尾の次の文字へのテキストバッファポインタを返す
// なければNULLを返す
static mchar* tagjumpGetFilename(mchar* p,mchar szfilename[CCHPATHNAME])
{
mchar path[CCHPATHNAME];
if (text->modeTagJump != TAGJUMP_VZ && strmatch(p,"・")) {
//2.92 grep形式。高速化のため直ぐに判別
p += 2;
while(isspace(*p)) p++;
if (isdigit(*p)) return NULL;
}
while(1) {
BOOL fdq = FALSE;
mchar *top;
// get top
while(1) {
mchar c = *p;
if (c == 0x0A || c == 0x1A || c == 0) {
return NULL;
} else if (c <= ' ' || c == '(' || c == ')' || c == ':') {
p++;
} else {
break;
}
}
top = p;
// get tail
while(1) {
mchar c = *p;
if (c == 0x0A || c == 0x1A || c == 0) {
#if 1//3.00A2 970504 「ファイル名+改行」でもタグジャンプするようにした(従来は「ファイル名+スペース+改行」でタグジャンプした)。
break;
#else
return NULL;
#endif
} else if (c == '"') {
fdq ^= 1;
p++;
} else if (c < ' ' || (c == ' ' && !fdq) || c == '(' || c == ')') {
break;
} else if (c == ':' && isdigit(p[1])) {
//2.00E "D:\WZ\TEST.C:256 void function()"の様な"ファイル名:行番号"形式のタグジャンプができなかった
break;
} else {
p++;
}
}
if (p > top && p[-1] == ':') p--;//1.00C タグジャンプを「ファイル名: 行番号」に対応させた
{
IBUFF len = p - top;
if (len < CCHPATHNAME) {
strcpylen(szfilename,top,len);
if (text->modeTagJump != TAGJUMP_VZ && iskanji(szfilename[0])) {
//2.92 標準では、漢字はファイル名としては認識しない
break;
}
pathFormLong(szfilename);//1.00H2 タグジャンプのロングファイル名対応
// wzpathAutoは若干時間がかかる
wzpathAuto(szfilename);//1.00F ジャンプ先ファイル名の指定がフルパスでないタグジャンプがうまくいかないことがあった
if (fileIsExist(szfilename)) {
return p;
}
}
}
if (text->modeTagJump != TAGJUMP_VZ) {
break;//2.92
}
}
return NULL;
}
static NLINE tagjumpGetNline(mchar* p,int* pLx,mchar szFind[CCHWORD])
{
int a = 0;
szFind[0] = 0;
while(1) {
mchar c = *p;
int a0 = a;
a = 0;
if (c == 0x0A || c == 0) {
return 0;
} else if (c == '"') {
strcpylenmax(szFind,p,strGetWordLen(p),CCHWORD);
pathFormLong(szFind);
{
mchar* p = strchrs(szFind," \t");
if (p) {
// 空白やタブは検索できない
*p = 0;
}
}
return 0;
} else if (!a0 && isdigit(c)) {
IFILE line = 0;
IBUFF lch = 0;
while(1) {
mchar c = *p;
if (isdigit(c)) {
line *= 10;
line += c - '0';
p++;
} else {
break;
}
}
if (*p == ',') {
lch = atoi(p + 1);
}
if (pLx) *pLx = lch;
return line;
} else if (iskanji(c)) {
p += 2;
} else {
if (isalpha(c)) {
a = 1;
}
p++;
}
}
}
BOOL TXAPI txJumpTagExec(TX* text,mchar* szfilename,NPARA nline,int lx,mchar* szFind)
{
// npara == 0 指定なし
// lx < 0 指定なし
// !szFind||!szFind[0] 指定なし
#if 1//2.94 970121
mchar sw[30];
if (szFind && szFind[0]) {
sprintf(sw,"/s%s",szFind);
forkstd(szfilename,sw);
} else if (nline) {
#if 1//2.99D 970330 sw
if (lx >= 0) {
sprintf(sw,"/k /J%ld,%d /Yc",nline,lx);
} else {
//3.00B1 970519 lx < 0に対応してなかった
sprintf(sw,"/k /J%ld /Yc",nline);
}
#else
if (lx >= 0) sprintf(sw,"/P /J%ld,%d /Yc",nline,lx);
#endif
//information("%s",sw);
forkstd(szfilename,sw);
} else {
forkstd(szfilename,NULL);
}
return TRUE;
#else
HWND hwnd = isopen(szfilename);
if (hwnd) {
if (szFind && szFind[0]) {
if (nline) SendMessageOther(hwnd,WM_TXJUMPPARA,0,nline);
{
REPLACEARGEX arg;
structClear(arg);
arg.searchmode = SEARCH_CUR;
strcpy(arg.szFind,szFind);
wndtxSendMem(hwnd,WM_TXSEARCHEX,0,&arg,sizeof(arg));
}
} else if (nline) {
SendMessageOther(hwnd,WM_TXJUMPPARA,0,nline);
wndtxCall(hwnd,"txJumpParaTop");
if (lx >= 0) SendMessageOther(hwnd,WM_TXRIGHTBYTES,lx,0);
wndtxCall(hwnd,"txSetLyCenter");
} else {
wndtxSetActive(hwnd);
}
} else {
mchar sw[30];
if (szFind && szFind[0]) {
sprintf(sw,"--s%s",szFind);
forkstd(szfilename,sw);
} else if (nline) {
#if 1//2.99D 970330 sw
if (lx >= 0) sprintf(sw,"/k --J%ld,%d --Yc",nline,lx);
#else
if (lx >= 0) sprintf(sw,"--P --J%ld,%d --Yc",nline,lx);
#endif
forkstd(szfilename,sw);
} else {
forkstd(szfilename,NULL);
}
}
return TRUE;
#endif
}
void tagjumpreturnAdd(mchar* szfilename,IFILE adr);
BOOL TXAPI TXCMDBASE txJumpTagEx(tx *text)
{
// タグジャンプ
//{#VZ} +{F10}
//{#MI} {F10}
//{#EMACS} +{F10}
if (txJumpLink(text)) return TRUE;//2.99 970320 タグジャンプでリンクのジャンプができなかった
tagjumpreturnAdd(text->szfilename,txGetAddress(text));//3.00B1 970612 「タグジャンプから戻る」対応
mchar szfilename[CCHPATHNAME];
txstr szpara(CCHLINE*4);
txGetPara(text,szpara);
{
mchar* p = szpara;
p = tagjumpGetFilename(p,szfilename);
if (!p) {
//2.92 grep結果のタグジャンプ及び"ファイル名"へのジャンプを標準タグジャンプでサポート
if (call("grep.Jump")) return TRUE;
return txJumpURL(text);
}
{
mchar szFind[CCHWORD];
int lx = -1;
NLINE nline = tagjumpGetNline(p,&lx,szFind);
return txJumpTagExec(text,szfilename,nline,lx,szFind);
}
}
return FALSE;
}
//{###ファイル}
//##その他
//2.98 970305 「検索|次画面と検索を開始」を追加
BOOL TXCMDBASE textCmpStart(TX* text)
{
// ファイルの比較を開始。
// 両画面の先頭にジャンプし、比較を開始する。
//2.98 970305 new
if (text->text2) {
txJumpFileTop(text->text2);
} else {
HWND next = wndtxGetNextEditor();
if (next) wndtxCall(next,"txJumpFileTop");
}
txJumpFileTop(text);
txCmp(text);
return TRUE;
}
//{###ジャンプ}
//3.00B1 970612 「ダイナミックタグジャンプ」を製品に標準装備
//970519 1.0 start
//970612 1.1 WZ3.00B 標準装備
#define SZTITLE "ダイナミックタグジャンプ"
#include "_filer.h"
//## Abort Window
#define IDD_SEARCHINFO 100
static BOOL _fUserAbort;
static HWND _hwndAbort;
static BOOL abortProc(void)
{
MSG msg;
while(!_fUserAbort && _hwndAbort && PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
if (!IsDialogMessage(_hwndAbort,&msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return !_fUserAbort;
}
BOOL dlgprocAbort(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message) {
case WM_INITDIALOG: {
_fUserAbort = FALSE;
break;
}
case WM_COMMAND: {
if (LOWORD(wParam) == IDCANCEL) {
_fUserAbort = TRUE;
return TRUE;
}
break;
}
}
return FALSE;
}
static void abortNew(HDIALOG hd)
{
if (!_hwndAbort) {
_hwndAbort = dialogCreate(hd);
}
_fUserAbort = FALSE;
}
static void abortDelete(void)
{
if (_hwndAbort) {
dialogFree(_hwndAbort);
_hwndAbort = NULL;
}
}
//## 汎用関数
static int _txInsertWithQuote(TX* text,mchar* szInsert)
{
int ret;
txInsertChar(text,'"');
ret = txInsert(text,szInsert);
txInsertChar(text,'"');
return ret;
}
static int _txInsertInt(TX* text,long data)
{
mchar buff[20];
sprintf(buff,"%ld",data);
return txInsert(text,buff);
}
static void _txLimitNpara(TX* text,NPARA nparaMax,NPARA nparaNew)
{
txJumpFileEnd(text);
if (text->npara > nparaMax) {
// overflow : delete old entry
txJumpNpara(text,nparaNew);
txSelectEx(text,CLIP_CHAR);
txJumpFileEnd(text);
txSelectDelete(text);
}
}
//## タグジャンプから戻る
static TX* tagjumpreturnOpen(void)
{
mchar szfilename[CCHPATHNAME];
pathFullConfig(szfilename,"tagjmpre.dic");
return textopen(szfilename);
}
void tagjumpreturnAdd(mchar* szfilename,IFILE adr)
{
TX* text = tagjumpreturnOpen();
if (text) {
_txInsertWithQuote(text,szfilename);
txInsertChar(text,' ');
_txInsertInt(text,adr);
txInsertReturn(text);
//
_txLimitNpara(text,20,16);
//
txSave(text);
}
textclose(text);
}
tagjumpreturn
{
// ダイナミックタグジャンプから戻る
TX* text = tagjumpreturnOpen();
if (text) {
txstr szline;
txGetPara(text,szline);
mchar* p = strGetWordTop(szline);
int len = strGetWordLen(p);
if (len) {
mchar szfilename[CCHPATHNAME];
sstrcpylen(szfilename,p,len);
pathFormLong(szfilename);
//
p += len;
p = strGetWordTop(p);
IFILE adr = atoi(p);
//
mchar sw[30];
sprintf(sw,"/k /Ja%ld /Yc",adr);
forkstd(szfilename,sw);
//
txDeletePara(text);
txSave(text);
}
}
textclose(text);
}
//## Dynamic Tag Jump
static mchar _szTitleCfuncRe[] = "^[A-Za-z_][^/]*[^;]$";
typedef struct {
TX* cache;
mchar szfind[CCHWORD];
// cache match
NPARA nparaCache;
} FJCONTEXT;
permanent BOOL p_fSearchSubDirectory = FALSE;
permanent txstr p_szmask = "*.c;*.cpp;*.h;*.hpp";
static void cacheAdd(FJCONTEXT* context,mchar* szfind,mchar* szfilename,NPARA npara)
{
TX* text = context->cache;
txJumpFileTop(text);
txInsertChar(text,'"');txInsert(text,szfilename);txInsert(text,"\" ");
txInsertf(text,"%ld ",npara);
txInsertChar(text,'"');txInsert(text,szfind);txInsertChar(text,'"');
txInsertReturn(text);
}
#define SEARCHFILE_CACHEMATCH 1 // context->szfindがcontext->nparaCacheにあるか調べる
#define SEARCHFILE_CACHEFLUSH 2 // context->szfindがszfilenameの何行にあるかをcontext->nparaCacheに返す
#define SEARCHFILE_STATIC 3 // context->szfindがtextの何行にあるかをcontext->nparaCacheに返す
static int searchtext(TX* text,FJCONTEXT* context,int mode)
{
int nFind = 0;
//
txstr szline;
if (_hwndAbort) {
SetDlgItemText(_hwndAbort,IDD_SEARCHINFO,pathGetFileName(text->szfilename));
}
if (mode == SEARCHFILE_CACHEMATCH) {
txJumpNpara(text,context->nparaCache);
}
//
for(int i = 0;i < 2;i++) {
IFILE adr0 = -1;
SEARCHMODE searchmode = 0;
searchmode |= SEARCH_CUR; // 最初は、カーソル位置(ファイル先頭)から検索
while(1) {
if (!abortProc()) break;
int find = 0;
if (i == 0) {
find = txSearchEx(text,_szTitleCfuncRe,searchmode|SEARCH_RE);
} else {
find = txSearchEx(text,"^[\t ]*#[\t ]*define[\t ]+[A-Za-z_0-9]+[\t ]*(",searchmode|SEARCH_RE);
}
if (find) {
{// 無限に同じ所にマッチしないように
IFILE adr = txGetAddress(text);
if (adr == adr0) break;
adr0 = adr;
}
searchmode &= ~SEARCH_CUR; // 次からは、カーソル位置の次の文字から検索
//
txGetPara(text,szline);
if (mode) {
// context->szfindとマッチするか調べる
mchar* p = stristr(szline,context->szfind);
if (p) {
mchar* pp = strprev(szline,p);
if (!isalpha(*pp)) {
mchar* pn = p + strlen(context->szfind);
if (!isalnum(*pn)) {
if (mode == SEARCHFILE_STATIC) {
context->nparaCache = text->npara;
nFind++;
break;
} else if (mode == SEARCHFILE_CACHEMATCH) {
if (text->npara == context->nparaCache) {
nFind++;
cacheAdd(context,context->szfind,text->szfilename,text->npara);
}
break;
} else {
context->nparaCache = text->npara;
cacheAdd(context,context->szfind,text->szfilename,text->npara);
nFind++;
break;
}
// findAdd(context,text->szfilename,text->npara,szline);
//information("%s %d : %s",szfilename,text->npara,szline);
}
}
}
} else {
// 関数定義を抜き出してデータを作成する
if (stristrword(szline,"static")) {
// static関数は含めない
} else {
mchar* p;
if (p = reSearch(szline,"[A-Za-z_][A-Za-z_0-9]* *([^/]*)",0)) {// "func(arg)"だけでなく"func (arg)"にも対応
int lch = strchr(p,'(') - p;
mchar szfunc[CCHWORD];
sstrcpylen(szfunc,p,lch);
// del tail space
lch = strGetWordLen(szfunc);
szfunc[lch] = 0;
//
cacheAdd(context,szfunc,text->szfilename,text->npara);
nFind++;
}
//printf("%s\n",szfunc);
}
}
} else {
break;
}
}
}
return nFind;
}
static int searchfile(mchar *szfilename,mchar *szfind,FJCONTEXT* context,int mode)
{
int nFind = 0;
// cache flush
// szfilenameと同じファイル名のファイルを除く
if (mode == 0) {
TX* text = context->cache;
txJumpFileTop(text);
//
txstr szfind = "\"";
szfind += szfilename;
szfind += "\" ";
//
SEARCHMODE searchmode = SEARCH_PARATOP|SEARCH_NOSENSECASE|SEARCH_NOESC|SEARCH_CUR;
while(1) {
if (txSearchEx(text,szfind,searchmode)) {
txDeletePara(text);
txJumpParaTop(text);
} else {
break;
}
}
}
// skip backup file
{
mchar* sz = pathGetFileName(szfilename);
if (sz[0] == '$' && sz[1] == '~') return 0;
sz = pathGetExt(szfilename);
if (sz[0] == '~') return 0;
}
//
TX textBody;
TX* text = &textBody;
txInitText(text);
txSetFileName(text,szfilename);
if (txIsBinary(text)) return 0; // 開く前にファイル名でチェック
text->fSilent = TRUE; // 不要なattentionを出さない
text->fLineD = FALSE; // 論理行モード
text->fViewMode = TRUE;
text->fNoCursor = TRUE;
text->fKcAuto = text->share->config.fKcAuto;
txOpenText(text);
//
if (!txIsBinary(text)) {
nFind = searchtext(text,context,mode);
}
txClose(text);
return nFind;
}
static void searchpath(mchar *szpath,mchar *szfind,SEARCHMODE searchmode,FJCONTEXT* context)
{
#ifdef __FLAT__
WIN32_FIND_DATA ffd;
#else
FILEFIND filefind;
#endif
mchar szfilename[CCHPATHNAME];
// 通常ファイル
strcpy(szfilename,szpath);
#ifdef __FLAT__
{
HANDLE hfind = FindFirstFile(szpath,&ffd);
if (hfind != INVALID_HANDLE_VALUE) {
do {
if (!abortProc()) break;
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
pathSetFileName(szfilename,ffd.cFileName);
searchfile(szfilename,szfind,context,0);
} while(FindNextFile(hfind,&ffd));
FindClose(hfind);
}
}
#else
if (!fileFindFirst(szpath,FA_NORMAL,&filefind)) {
do {
if (!abortProc()) break;
pathSetFileName(szfilename,filefind.name);
searchfile(szfilename,szfind,context,0);
} while (!fileFindNext(&filefind));
}
#endif
// サブディレクトリ
if (searchmode & GREP_DIRECTORY) {
strcpy(szfilename,szpath);
pathSetFileName(szfilename,"*.*");
#ifdef __FLAT__
{
HANDLE hfind = FindFirstFile(szfilename,&ffd);
if (hfind != INVALID_HANDLE_VALUE) {
do {
if (!abortProc()) break;
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (ffd.cFileName[0] != '.') {
txstr szsubpath(CCHPATHNAME);
szsubpath = szpath;
pathSetFileName(szsubpath,ffd.cFileName + "\\" + pathGetFileName(szsubpath));
// information("[%s]",szsubpath);
searchpath(szsubpath,szfind,searchmode,context);
}
}
} while(FindNextFile(hfind,&ffd));
FindClose(hfind);
}
}
#else
if (!fileFindFirst(szfilename,FA_DIREC,&filefind)) {
do {
if (!abortProc()) break;
if (filefind.attrib & FA_DIREC) {
if (filefind.name[0] != '.') {
txstr szsubpath(CCHPATHNAME);
szsubpath = szpath;
pathSetFileName(szsubpath,filefind.name + "\\" + pathGetFileName(szsubpath));
// information("[%s]",szsubpath);
searchpath(szsubpath,szfind,searchmode,context);
}
}
} while (!fileFindNext(&filefind));
}
#endif
}
}
static void dtagjumpDelete(FJCONTEXT* context)
{
// destructor
abortDelete();
if (context->cache) {
TX* text = context->cache;
if (text->fEdit) txSave(text);
textclose(text);
context->cache = NULL;
}
}
static BOOL dtagjumpExec(FJCONTEXT* context,txstr szline)
{
TX* text = context->cache;
mchar szfilename[CCHPATHNAME];
mchar* p = szline;
int len;
p = strGetWordTop(p);
len = strGetWordLen(p);
sstrcpylen(szfilename,p,len);
p += len;p = strGetWordTop(p);
NPARA npara = atoi(p);
pathFormLong(szfilename);
//information("%s %d",szfilename,npara);
// check cache
txDeletePara(text);// delete cache entry
//
context->nparaCache = npara;
if (searchfile(szfilename,context->szfind,context,SEARCHFILE_CACHEMATCH)) {
// OK
} else {
// Cacheミス
if (searchfile(szfilename,context->szfind,context,SEARCHFILE_CACHEFLUSH)) {
// ファイル内での位置が変わっただけ
npara = context->nparaCache;
} else {
// 別ファイルへ移動した
return FALSE;
}
}
// jump
tagjumpreturnAdd(textf->szfilename,txGetAddress(textf));
mchar sw[30];
sprintf(sw,"/k /J%ld /Yc",npara);
forkstd(szfilename,sw);
return TRUE;
}
static int dtagjumpCache(FJCONTEXT* context)
{
BOOL ret = IDNO;
txstr sz = " \"";
sz += context->szfind;
sz += "\"";
//information("[%s]",sz);
TX* text = textopen(NULL);
if (text) {
txstr szline(CCHPATHNAME + 100);
int nFind = 0;
txJumpFileTop(context->cache);
while(1) {
if (txSearchEx(context->cache,sz,0)) {
txGetPara(context->cache,szline);
txInsert(text,szline);txInsertReturn(text);
nFind++;
} else {
break;
}
}
if (nFind) {
if (nFind == 1) {
if (dtagjumpExec(context,szline)) {
ret = IDOK;
}
} else {
HDIALOG hd = dialog(SZTITLE + " - ジャンプ先選択");
txJumpFileTop(text);
dialogList(hd,NULL,text,60,10);
if (dialogOpen(hd)) {
txGetPara(text,szline);
//
int n = text->npara;
txJumpFileTop(context->cache);
while(n--) {
if (!txSearchEx(context->cache,sz,0)) {
break;
}
}
//
if (dtagjumpExec(context,szline)) {
ret = IDOK;
}
} else {
ret = IDCANCEL;
}
}
}
}
textclose(text);
return ret;
}
// "a:\wz\*.c;*.cpp"対応
static void searchpathMultiMask(FJCONTEXT* context,mchar* _szpath)
{
mchar szpath[CCHPATHNAME];
mchar *szfile = pathGetFileName(_szpath);
strcpy(szpath,_szpath);
while(1) {
mchar *p;
if (p = strchr(szfile,';')) {
*p = 0;
}
pathSetFileName(szpath,szfile);
searchpath(szpath,"",p_fSearchSubDirectory ? GREP_DIRECTORY : 0,context);
if (p) {
*p = ';';
szfile = p + 1;
} else {
break;
}
}
}
static BOOL dtagjumpSearch(FJCONTEXT* context)
{
HDIALOG hd = dialog(SZTITLE + " - 検索");
txstr szpath = text->szfilename;
pathForm(szpath);
dialogControlHelp(hd,240);
dialogControlRefer(hd,"-d *.*");
dialogStr(hd,"検索フォルダ(&F):",szpath,14,37);
//
dialogStr(hd,"検索マスク(&M):",p_szmask,14,16);
//
dialogCheck(hd,"サブフォルダも検索(&U)",&p_fSearchSubDirectory);
//
if (dialogOpen(hd)) {
HDIALOG hd = dialog(SZTITLE + " - 検索中");
dialogSetHookEx(hd,"\m.dlgprocAbort");
dialogControlStyle(hd,WS_CHILD|WS_VISIBLE|SS_CENTER);
dialogControlID(hd,IDD_SEARCHINFO);
dialogCaptionDynamic(hd,"",30);
dialogControlStyle(hd,0);
dialogSetPosLX(hd,10);
dialogCancel(hd,10);
abortNew(hd);
//
pathSetDir(szpath);
szpath += p_szmask;
searchpathMultiMask(context,szpath);
//
abortDelete();
return TRUE;
}
return FALSE;
}
dtagjump
{
// ダイナミックタグジャンプ
// C言語の関数定義部、マクロ関数定義部へダイレクトにジャンプすることができます。
// 関数定義を参照したい関数名にカーソルを合わせてこのコマンドを実行するとジャンプします。
// 同一ファイル内でも別ファイルでもジャンプできます。
// みつからない場合は検索ダイアログが出ますので検索してください。
// 関数定義部分が移動しても自動的に追随します。
// #defineによるマクロ関数定義にもジャンプできます。
FJCONTEXT contextBody;
structClear(contextBody);
FJCONTEXT* context = &contextBody;
// get find function name
{
txstr szfind;
txGetWordWhole(text,szfind);
sstrcpy(context->szfind,szfind);
// information(context->szfind);
}
// cache
{
mchar szfilename[CCHPATHNAME];
pathFullConfig(szfilename,"dtgcache.dic");
context->cache = textopen(szfilename);
if (!context->cache) {
dtagjumpDelete(context);
return FALSE;
}
}
if (dtagjumpCache(context) != IDNO) {
dtagjumpDelete(context);
return TRUE;
}
// static function
{
IFILE adr = txGetAddress(text);
txSetUndispEx(text);
txJumpFileTop(text);
if (searchtext(text,context,SEARCHFILE_STATIC)) {
tagjumpreturnAdd(text->szfilename,adr);
txJumpNpara(text,context->nparaCache);
txSetDisp(text);
dtagjumpDelete(context);
return TRUE;
} else {
txSetDispEx(text);
}
}
//
{
int q = question("関数定義 %s は見つかりませんでした\n検索しますか?",context->szfind);
if (q != IDYES) {
dtagjumpDelete(context);
return FALSE;
}
}
//
if (dtagjumpSearch(context)) {
if (dtagjumpCache(context) == IDNO) {
information("関数定義 %s は見つかりませんでした",context->szfind);
}
}
// destruct
dtagjumpDelete(context);
return TRUE;
}
void testFunction(void)
{
}
// testFunction();