home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1999 March
/
VPR9903A.BIN
/
APUPDATE
/
VC
/
Wzgd300c
/
WZGD300C.LZH
/
edit.c
next >
Wrap
C/C++ Source or Header
|
1997-10-20
|
114KB
|
4,573 lines
// WZ EDITOR 標準機能 編集
// Copyright 1995-96 TY
// Thanks y.mikomeさん for complete.c/template.c/ms like select/seikei.c
// Thanks CM.(千葉誠)さん for tssel
//2.99D 970331 TXCMDBASE対応
// std.view_to_edit,exec,wzopenをここに移動
#include <windows.h>
#include <windowsx.h>
#include "dialog.h"
#define IDD_OPEN 800
#define IDD_LIST 801
#define IDD_JUMP 802
#define IDD_LOAD 803
#define IDD_DEL 804
#define IDD_NEWEST 805
#define IDD_COMMENT 806
#define IDD_CONFIRM 1002
#define IDD_INSERT 1003
#define IDD_PREVIEW 1004
//{###カット&ペースト}
//1.99C
static BOOL txSelectCopyEx(TX* text)
{
if (!text->fClip) {
// 範囲指定されてなければカレント論理行をCopyする
return txClipCopyEx(text,0,0,HCLIP_WIN,CLIP_COPYPARA1,0,0);
} else {
return txSelectCopy(text);
}
}
//1.00C {#MS}削除
//2.00E {#VZ} txClipboardCopyへ移動
//2.00E2 TXCMD削除
void TXAPI txSelectTsCbPushQuit(tx *text)
{
// コピー(テキストスタック連動)
// 範囲内をクリップボードにコピーして、
// テキストスタックへPUSHし、範囲指定中止
text->fCopyingWinTs++;//2.99C 970325
clipClear(HCLIP_WIN);//1.00C VZ.KEYで、クリップボードに他アプリでコピーしたデータが入っているときに、範囲選択しないで^KK、^KCしても^KKでコピーした内容が貼り付けられなかった
txSelectCopyEx(text);
txSelectTsPushQuit(text);
text->fCopyingWinTs--;//2.99C 970325
}
//1.00C {#MS}追加
//2.00E {#MS} txClipboardCopyへ移動
//2.00E2 TXCMD削除
BOOL TXAPI txSelectTsCbPush(tx *text)
{
// コピー(テキストスタック連動)
// 範囲内をクリップボードにコピーして、
// テキストスタックへPUSH
#if 1//2.99C 970325
BOOL ret;
text->fCopyingWinTs++;//2.99C 970325
clipClear(HCLIP_WIN);//1.00C
txSelectCopyEx(text);
if (text->fClip) text->fClipMouse = TRUE;// 1.00C y.mikome
ret = txSelectTsPush(text);
text->fCopyingWinTs--;//2.99C 970325
return ret;
#else
clipClear(HCLIP_WIN);//1.00C
txSelectCopyEx(text);
if (text->fClip) text->fClipMouse = TRUE;// 1.00C y.mikome
return txSelectTsPush(text);
#endif
}
//2.00E {#MS}{#VZ} txClipboardCutへ移動
//2.00E2 TXCMD削除
void TXAPI txSelectTsCbPushDelete(tx *text)
{
// 切り取り(テキストスタック連動)
// 範囲内をクリップボードにコピーして、
// テキストスタックへPUSHし、削除し、範囲指定中止
text->fCopyingWinTs++;//2.99C 970325
clipClear(HCLIP_WIN);//1.00C
txSelectCopyEx(text);
txSelectTsPushDelete(text);
text->fCopyingWinTs--;//2.99C 970325
}
static BOOL IsClipOther(tx *text)
{
#if 1//2.90 テキストスタックとクリップボード併用でペースト時に、
// マクロでtxSelectCopyした内容がペーストされず、HCLIP_TSの内容がコピーされることがあった
// txSelectCopy時に、HCLIP_TSにデータがあるときがだめだった。
if (clipGetKind(HCLIP_WIN) && !clipIsWz()) return TRUE;
if (text->share->hclipLastCopy == HCLIP_WIN) return TRUE;
return FALSE;
#else
if (clipGetKind(HCLIP_WIN) && !clipIsWz()) return TRUE;
return FALSE;
#endif
}
static void cutAtMouse(tx *text)
{
if (text->fClip && text->fClipMouse) {
txSelectDelete(text);
}
}
//2.00E2 TXCMD削除
BOOL TXAPI txTsCbPaste(tx *text)
{
// 貼り付け(クリップボード連携)
// WZ以外でペーストしたデータがクリップボードにあれば、そこからペースト
// テキストスタックからペースト
// カーソルを、ペーストしたバイト数、移動します。
cutAtMouse(text);
if (IsClipOther(text)) return txPaste(text);
if (txTsPaste(text)) return TRUE;
return txPaste(text);
}
static BOOL pop(tx *text)
{
int ret = txPaste(text);
clipClear(HCLIP_WIN);
return ret;
}
//2.00E2 TXCMD削除
BOOL TXAPI txTsCbPop(tx *text)
{
// 吐き出し(クリップボード連携)
// テキストスタックからPOP
// カーソルは移動しません
cutAtMouse(text);
if (IsClipOther(text)) return pop(text);
#if 1//1.00E 1.00DだとTsが空の時にtxCopyした内容が出なかった
if (txTsPop(text)) {
clipClear(HCLIP_WIN);
return TRUE;
}
return pop(text);
#else
#if 1//1.00D 一番最初にtxTsCbCopyした内容が重複した
clipClear(HCLIP_WIN);
return txTsPop(text);
#else
if (txTsPop(text)) return TRUE;
return pop(text);
#endif
#endif
}
static BOOL pastemodal(tx *text)
{
return txClipPaste(text,HCLIP_WIN,text->fJumpTxPasteEnd,0);
}
static BOOL _txTsCbPasteModal(tx *text,HCLIP* pHclip)
{
// 貼り付け(テキストスタック連携)
// テキストスタックからペースト
// text->fJumpTxPasteEndが真ならカーソルを移動します
cutAtMouse(text);
*pHclip = HCLIP_WIN;
if (IsClipOther(text)) {
return pastemodal(text);
}
if (txTsPasteModal(text)) {
*pHclip = HCLIP_TS;
return TRUE;
}
return pastemodal(text);
}
//2.00E {#MS},{#VZ} txClipboardPasteへ移動
//2.00E2 TXCMD削除
BOOL TXAPI txTsCbPasteModal(tx *text)
{
// 貼り付け(テキストスタック連携)
// テキストスタックからペースト
// text->fJumpTxPasteEndが真ならカーソルを移動します
HCLIP hclip;
return _txTsCbPasteModal(text,&hclip);
}
static BOOL popmodal(tx *text)
{
int ret = txClipPaste(text,HCLIP_WIN,text->fJumpTxPasteEnd,0);
clipClear(HCLIP_WIN);
return ret;
}
static BOOL _txTsCbPopModal(tx *text,HCLIP* pHclip)
{
// 吐き出し(テキストスタック連携)
// テキストスタックからPOP
// text->fJumpTxPasteEndが真ならカーソルを移動します
cutAtMouse(text);
*pHclip = HCLIP_WIN;
if (IsClipOther(text)) return popmodal(text);
#if 1//1.00E 1.00DだとTsが空の時にtxCopyした内容が出なかった
if (txTsPopModal(text)) {
clipClear(HCLIP_WIN);
*pHclip = HCLIP_TS;
return TRUE;
}
return popmodal(text);
#else
#if 1//1.00D 一番最初にtxTsCbCopyした内容が重複した
clipClear(HCLIP_WIN);
return txTsPopModal(text);
#else
if (txTsPopModal(text)) return TRUE;
return popmodal(text);
#endif
#endif
}
//2.00E {#MS},{#VZ} txClipboardPopへ移動
//2.00E2 TXCMD削除
BOOL TXAPI txTsCbPopModal(tx *text)
{
// 吐き出し(テキストスタック連携)
// テキストスタックからPOP
// text->fJumpTxPasteEndが真ならカーソルを移動します
HCLIP hclip;
return _txTsCbPopModal(text,&hclip);
}
//2.00E2 TXCMD削除
void TXAPI txTsCbClear(tx *text)
{
// テキストスタックのトップを消去します。
// クリップボードにWZがペーストしたデータがあるときは、これも消去します。
#if 0//1.00D
cutAtMouse(text);
#endif
if (IsClipOther(text)) {
clipClear(HCLIP_WIN);
} else {
clipClear(HCLIP_WIN);
txTsClear(text);
}
}
//2.00E カットアンドペースト系のコマンドが多かったので一本化。従来のコマンドはそのまま残っています。
LPVOID TXAPI plugatrRead(TX* text,TYP typ)
{
return (LPVOID)txOp(text,TXOP_PLUG_READ,typ,0);
}
static PLUGOLE* txIsCurOLE(TX* text)
{
#ifdef __FLAT__
if (text->editmode) {
CHARATR charatr;
charatrRead(text,txGetAddress(text),&charatr);
if (charatr.fLink) {
PLUGOLE* plug = plugatrRead(text,charatrGetPlug(charatr));
if (plug->head.modePlug == PLUG_OLE) {
return plug;
}
}
}
return NULL;
#else
return NULL;
#endif
}
BOOL TXAPI TXCMDBASE txClipboardCopy(TX* text)
{
// 範囲内をクリップボードへコピー
// [設定]-[編集]-[クリップボード]の設定に従ってWindowsクリップボード/テキストスタックを使用
//2.00Eで追加
//{#MS} ^C ^{Insert}
//{#VZ} ^KK +{F8} +%{Delete}
//{#EMACS} +{F8} +%{Delete}
#if 0///2.99D 970329 OLEオブジェクトのコピーはいらない。アクティベートしてアプリケーションの機能でコピーすればいい
#ifdef __FLAT__
PLUGOLE* plugole;
if (!text->fClip && (plugole = txIsCurOLE(text))) {
return txOp(text,TXOP_OBJECTCOPY,(LPARAM)plugole,0);
}
#endif
#endif
if (!text->fClip && !text->fClipboardNoSelect) return FALSE;//2.98 970307
//2.95 970125 CLIPMODE_XXX対応
BOOL ret = FALSE;
switch(txGetModeClipboard(text)) {
case CLIPBOARD_WIN_TS: ret = txSelectTsCbPush(text);break;
case CLIPBOARD_WIN: ret = txSelectCopy(text);break;
case CLIPBOARD_TS: ret = txSelectTsPush(text);break;
}
if (text->fClipboardWinBased == CLIPMODE_WZ) txSelectQuit(text);
return ret;
}
BOOL TXAPI TXCMDBASE txClipboardCut(TX* text)
{
// 範囲内をクリップボードへカット
// [設定]-[編集]-[クリップボード]の設定に従ってWindowsクリップボード/テキストスタックを使用
//2.00Eで追加
//{#MS} ^X +{Delete} +^{Delete}
//{#VZ} ^Y {F8} %{Delete}
//{#EMACS} {F8} %{Delete}
if (!text->fClip && !text->fClipboardNoSelect) return FALSE;//2.98 970307
switch(txGetModeClipboard(text)) {
case CLIPBOARD_WIN_TS: return txSelectTsCbPushDelete(text);
case CLIPBOARD_WIN: return txSelectCopyDelete(text);
case CLIPBOARD_TS: return txSelectTsPushDelete(text);
}
return FALSE;
}
static BOOL _txClipboardPaste(TX* text,BOOL fPop)
{
//2.95 970125 CLIPMODE_XXX対応
txSetUndisp(text);//2.00E4 選択中にペーストするとちらついた
if (text->fClip) {
if (text->fClipboardWinBased == CLIPMODE_WZ) {
txSelectQuit(text);
} else {
txSelectDelete(text);
}
}
BOOL ret = FALSE;
IFILE adr = txGetAddress(text);
int ly = text->ly;
BOOL fSelectPaste = (text->fClipboardWinBased == CLIPMODE_WINWZ);
if (fSelectPaste) {
txSetUndisp(text);
}
HCLIP hclip = HCLIP_WIN;
if (fPop) {
switch(txGetModeClipboard(text)) {
case CLIPBOARD_WIN_TS: ret = _txTsCbPopModal(text,&hclip);break;
case CLIPBOARD_WIN: {
ret = txPaste(text);
clipClear(HCLIP_WIN);
break;
}
case CLIPBOARD_TS: ret = txTsPopModal(text);hclip = HCLIP_TS;break;
}
} else {
switch(txGetModeClipboard(text)) {
case CLIPBOARD_WIN_TS: ret = _txTsCbPasteModal(text,&hclip);break;
case CLIPBOARD_WIN: ret = txPaste(text);break;
case CLIPBOARD_TS: ret = txTsPasteModal(text);hclip = HCLIP_TS;break;
}
}
if (fSelectPaste) {
if (ret) {
#if 1 //2.95 970125 行単位選択でコピーして、行の途中でペーストすると、
// ペーストした文の選択がズレた。
int lyClip = text->ly;
txSetUndisp(text);
if (text->fClipPasteJump) {
txJumpAddress(text,text->clippastetop);
txSelectEx(text,CLIP_CHAR);
txJumpAddress(text,text->clippasteend);
txSetLy(text,lyClip);
} else {
txJumpAddress(text,text->clippasteend);
txSelectEx(text,CLIP_CHAR);
txJumpAddress(text,text->clippastetop);
txSetLy(text,ly);
}
text->fClipMouse = TRUE;
txSetDisp(text);
#else
txSelectEx(text,CLIP_CHAR);
text->fClipMouse = TRUE;
txJumpAddress(text,adr);
txSetLy(text,ly);
#endif
}
txSetDisp(text);
}
txSetDisp(text);//2.00E4
return ret;
}
BOOL TXAPI TXCMDBASE txClipboardPaste(TX* text)
{
// クリップボードからペースト
// [設定]-[編集]-[クリップボード]の設定に従ってWindowsクリップボード/テキストスタックを使用
//2.00Eで追加
//{#MS} ^V +{Insert}
//{#VZ} ^KC +{F9} +%{Insert}
//{#EMACS} +{F9} +%{Insert} ^Y
return _txClipboardPaste(text,FALSE);
}
//3.00B1 970522 追加カット、追加コピーを追加
BOOL TXAPI TXCMDBASE txClipboardAddCopy(TX* text)
{
// 範囲内をクリップボードへ追加コピー
// [設定]-[編集]-[クリップボード]の設定に従ってWindowsクリップボード/テキストスタックを使用
//3.00B1 970522 new
TX* text0 = text;
BOOL ret = FALSE;
{
TX* text = textopen(NULL);
if (text) {
txClipboardPaste(text);
txPrivatePush(text0);
txPrivatePop(text);
txSelectAll(text);
ret = txClipboardCopy(text);
}
textclose(text);
}
return ret;
}
BOOL TXAPI TXCMDBASE txClipboardAddCut(TX* text)
{
// 範囲内をクリップボードへ追加カット
// [設定]-[編集]-[クリップボード]の設定に従ってWindowsクリップボード/テキストスタックを使用
//3.00B1 970522 new
TX* text0 = text;
BOOL ret = FALSE;
{
TX* text = textopen(NULL);
if (text) {
txClipboardPaste(text);
txPrivatePush(text0);
txSelectDelete(text0);
txPrivatePop(text);
txSelectAll(text);
ret = txClipboardCopy(text);
}
textclose(text);
}
return ret;
}
BOOL TXAPI TXCMD txClipboardPasteReplace(TX* text)
{
// クリップボードからペースト
// 範囲選択されてたら、それを削除してからtxClipboardPasteする。
//3.00A2 970507 new
if (text->fClip) txSelectDelete(text);
return txClipboardPaste(text);
}
BOOL TXAPI TXCMDBASE txClipboardPop(TX* text)
{
// クリップボードからポップ
// [設定]-[編集]-[クリップボード]の設定に従ってWindowsクリップボード/テキストスタックを使用
//2.00Eで追加
//{#MS} +^V +^{Insert}
//{#VZ} ^J {F9} %{Insert}
//{#EMACS} {F9} %{Insert}
return _txClipboardPaste(text,TRUE);
}
BOOL TXAPI TXCMD txClipboardPopReplace(TX* text)
{
// クリップボードからポップ
// 範囲選択されてたら、それを削除してからtxClipboardPopする。
//3.00A2 970507 new
if (text->fClip) txSelectDelete(text);
return txClipboardPop(text);
}
BOOL TXCMDBASE txClipboardCopyWord(TX* text)
{
// 単語を選択してクリップボードへコピー。
// 2.91で追加。
txSelectEx(text,CLIP_WORD);
txstr sz;
txGetWord(text,sz);
txClipboardCopy(text);
statprintf(sz);
return TRUE;
}
//{###編集}
// 以下の関数はもう不要であるが互換性の為、残しておく
tabtospace
{
// テキスト全体で、タブをスペースに変換します
txTabToSpace(text);
}
spacetotab
{
// テキスト全体で、行頭のスペースをタブに変換します
txSpaceToTab(text);
}
deletetailspace
{
// テキスト全体で、行末のタブ/スペース/全角空白を削除します。
txDeleteTailSpace(text);
}
//{###編集}
//2.96 970210 txDeleteCharMs廃止。edit.txkeyDeleteCharを使ってください。
//2.96 970210 txDeletePrevMs廃止。edit.txkeyDeletePrevを使ってください。
extern "word" BOOL TXAPI TXCMD txFormArticleClear(tx *text);
static int txGetPrevPlugmode(TX* text)
{
// カーソル位置の一つ手前の文字のplugmodeを返す
//2.99D 970329 new
if (text->editmode) {
IFILE adr = txGetAddress(text);
if (adr >= 1) {
CHARATR charatr;
charatrRead(text,adr-1,&charatr);
if (charatr.fLink) {
return plugatrGetModePlug(text,charatrGetPlug(charatr));
}
}
}
return 0;
}
//2.99D 970329 OLEオブジェクトをDeleteやBackspaceで削除するときは問い合わせをするようにした
static int questionOleDelete(void)
{
#ifdef __FLAT__//強制ACTIVE
wndtxSetActive(textf->hwndbase);
#endif
return MessageBox(
wndtxGetActive(textf->hwndbase),
"OLEオブジェクトは削除するとアンドゥできません\n本当に削除しても良いですか?",
"WZ",MB_ICONQUESTION|MB_YESNOCANCEL|MB_DEFBUTTON2
);
}
int TXAPI TXCMDBASE TXMODAL txkeyDeletePrev(TX* text)
{
// 1文字前方削除(バックスペース)
// カーソルがフリーカーソル域に居るときはtxkeyLeftを実行します。
// 上書きモードのときは、txkeyLeftを実行します。
//{#VZ} {Backspace} ^H
//{#MI} {Backspace} ^H
//{#MS} {Backspace}
//{#EMACS} {Backspace}
//2.96 970210 WZ.EXEから移動
#if 1///3.00A 970430 VZ.KEYで^Bによる範囲選択中にBSすると範囲部分が削除された
if (
text->fClipMouse ||
(text->fClip && text->modeEditor == ME_WIN)
) {
txSelectDelete(text);
return TRUE;
}
#else
if (text->fClip) {//2.96 970209
txSelectDelete(text);
return TRUE;
}
#endif
if (text->fHTML && !text->fDispTag) {
//2.99B 970322 タグを消しているときに{Backspace}でタグを削除しないようにした
#if 1//2.99D 970329
if (txGetPrevPlugmode(text) == PLUG_HTML_TAG) {
statprintf("タグの表示をオフにしているので、タグは削除しません");
return FALSE;
}
#else
IFILE adr = txGetAddress(text);
if (adr >= 1) {
CHARATR charatr;
charatrRead(text,adr-1,&charatr);
if (charatr.fLink && plugatrGetModePlug(text,charatrGetPlug(charatr)) == PLUG_HTML_TAG) {
statprintf("タグの表示をオフにしているので、タグは削除しません");
return FALSE;
}
}
#endif
}
if (!text->fClip && txGetPrevPlugmode(text) == PLUG_OLE) {
int ret = questionOleDelete();
if (ret != IDYES) return FALSE;
}
if (txIsCurFree(text)) {
txkeyLeft(text);
if (!txIsCurFree(text)) {
if (!txIsCurReturn(text)) txDeleteChar(text);
}
return FALSE;
}
if (text->fOverWrite) {
txkeyLeft(text);
return FALSE;
}
if (text->editmode && text->fAfArticleDisc && txIsCurParaTop(text)) {
//2.98 970309 fAfArticleDiscがONのとき行頭BSで箇条書きクリア
PARAATR paraatr;
paraatrRead(text,text->npara,¶atr);
if (paraatr.fArticle) {
//2.98A 970311 実際に箇条書きがあるときだけ実行しないと、行頭でBSが効かなくなる。
txFormArticleClear(text);
return TRUE;
}
}
return txDeletePrev(text);
}
static int _txkeyDeleteChar(TX* text,int modeEditor)
{
// 1文字削除
if (!text->fClip && text->fHTML) {
if (!text->fDispTag && txGetCurPlugmode(text) == PLUG_HTML_TAG) {
//2.99B 970322 タグを消しているときに{Delete}でタグを削除しないようにした
statprintf("タグの表示をオフにしているので、タグは削除しません");
return FALSE;
}
#if 0//2.99D 970331 HTMLテキストモードでタグ'<'で{Delete}したときタグを丸ごと削除するのは不自然なのでやめた
if (call("html.htmlDeleteTag")) return TRUE;
#endif
}
if (!text->fClip && txGetCurPlugmode(text) == PLUG_OLE) {
int ret = questionOleDelete();
if (ret != IDYES) return FALSE;
}
if (modeEditor == ME_WIN) {
if (text->fClip) {
txSelectDelete(text);
return TRUE;
} else {
if (text->modeAutoIndent && !txIsCurParaTop(text) && txIsCurReturn(text)) {
txDeleteChar(text);
if (txGetChar(text) == ' ' || txGetChar(text) == '\t') {
txDeleteWord(text);
}
} else {
txDeleteChar(text);
}
}
return TRUE;
} else {
if (text->fClipMouse) {//3.00A 970429 VZ.KEY,MI.KEY:マウスで選択してDeleteすると範囲内を削除するようにした
txSelectDelete(text);
return TRUE;
}
if (txIsCurFree(text)) return FALSE;
return txDeleteChar(text);
}
}
//2.99D 970402 new
int TXCMDBASE txkeyDeleteCharMs(TX* text)
{
// ユーザインターフェースの設定にかかわらず、Windows準拠な文字削除
return _txkeyDeleteChar(text,ME_WIN);
}
int TXAPI TXCMDBASE txkeyDeleteChar(TX* text)
{
// 1文字削除(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
//{#RET}削除できたか返す
//{#VZ} {Delete} ^G
//{#MI} {Delete} ^G
//{#MS} {Delete}
//{#EMACS} {Delete} ^D
return _txkeyDeleteChar(text,text->modeEditor);
}
int TXCMDBASE txkeyDeleteWord(TX* text)
{
// 単語削除(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
//2.99A 970321 {#MS} ^{Delete} new
//{#MS} ^{Delete}
if (text->modeEditor == ME_MI) return txDeleteWordMi(text);
return txDeleteWord(text);
}
int TXCMDBASE txkeyDeletePrevWord(TX* text)
{
// 前単語削除(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
//2.99A 970321 {#MS} ^{Backspace} new
//{#MS} ^{Backspace}
return txDeletePrevWord(text);
}
int TXCMDBASE txkeySelect(TX* text)
{
// 選択開始(ユーザインターフェース)
// ユーザインターフェースの設定によって動作が変わります
// 選択中なら、選択を中止
if (text->modeEditor == ME_MI) return txSelect(text);
if (text->modeEditor == ME_VZ) return txSelectVz(text);
return txSelectWz(text);
}
vzZenhan
{
// 全角/半角変換
// カーソル位置から1語を変換
// 範囲選択しているときは、その範囲を変換。範囲の先頭文字
// を見てどちらの変換をするか判断します。
//2.99A 970321 {#MS} ^{F3} ^%U -> {#MS} ^%U
//{#MS} ^%U
//{#VZ} ^KZ
#if 1///2.00E6 範囲選択を解除する動作を改良
txSetUndisp(text);
int fClip = text->fClip;
if (text->fClip) {
txJumpSelectTop(text);
} else {
txSelect(text);
if (isspace(txGetChar(text))){
txRightWord(text);
} else {
txJumpWordEnd(text);
}
txJumpSelectTop(text);
}
if (txchIsKanji(txGetChar(text))) {
txJankToAnk(text);
txJkataToKana(text);
} else {
txAnkToJank(text);
txKanaToJkata(text);
}
if (fClip) {
text->fClipMouse = TRUE;
} else {
// 範囲選択してないときは次の文字へ移動
txJumpSelectEnd(text);
txSelectQuit(text);
}
txSetDisp(text);
#else
setundisp;
if (text->fClip==0) {
select;
if (isspace(getchar)){
rightword;
} else {
#if 1//1.00C
jumpwordend;
#else
jumpwordendmi;
while (isspace(getchar)){
left;
}
right;
#endif
}
}
txstr buff;
getword(buff);
mchar c = buff[0];
// if (c>=' '&&c<='~'||c>='「'&&c<='゚') {
if (!iskanji(c)) {//1.00C
anktojank;
kanatojkata;
} else {
janktoank;
jkatatokana;
}
// selectjump;
select;
setdisp;
#endif
}
int uiIsCaseWordUpper(void)
{
HDIALOG hd = dialog("大文字/小文字変換");
int mode = 0;
dialogRadioID(hd,&mode,"大文字→小文字","小文字→大文字");
if (dialogOpen(hd)) {
if (mode == 1) return IDNO;
return IDYES;
}
return IDCANCEL;
}
//2.00E6 txCaseWord -> edit.txCaseWord
BOOL TXCMDBASE txCaseWord(TX* text)
{
// 大文字/小文字変換(半角文字のみ変換)
// カーソル位置から1語を変換
// カーソル位置の文字を見てどちらの変換をするか判断します。
// 範囲選択しているときは、その範囲を変換。
// 大文字に変換するか小文字に変換するか問い合わせます。
//{#MI} ^QK
if (text->fClip) {
int ret = uiIsCaseWordUpper();
if (ret == IDCANCEL) return;
if (ret == IDYES) {
txEditOp(text,TXEDITOP_TOLOWER,NULL);
} else {
txEditOp(text,TXEDITOP_TOUPPER,NULL);
}
} else {
txEditOp(text,TXEDITOP_TOUPPER,NULL);
}
return TRUE;
}
vzCaseWord
{
// 大文字/小文字変換(全角対応)
// カーソル位置から1語を変換
// 範囲選択しているときは、その範囲を変換。
// 範囲の先頭文字を見てどちらの変換をするか判断します。
//2.99A 970321 {#MS} +{F3} ^U +^U -> {#MS} +^U
//{#MS} +^U
//{#VZ} ^QU
#if 1///2.00E6 高速モードでvzCaseWordを実行すると支障があった
txSetUndisp(text);
int fClip = text->fClip;
if (text->fClip) {
txJumpSelectTop(text);
} else {
txSelect(text);
txJumpWordEndMi(text);
txJumpSelectTop(text);
}
TXCHAR c = txGetChar(text);
BOOL fKanji = txchIsKanji(c);
if (fKanji) {
txJankToAnk(text);
c = txGetChar(text);
}
txEditOp(text,islower(c)?TXEDITOP_TOUPPER:TXEDITOP_TOLOWER,NULL);
if (fKanji) {
txAnkToJank(text);
}
if (fClip) {
text->fClipMouse = TRUE;
} else {
txSelectQuit(text);
}
txSetDisp(text);
return TRUE;
#else
//2.00E6 buffに文字列をコピーして、あとでinsertする手法は、
// 図やCHARATRの兼ね合いのため、高速モードでは無効
setundispex;//1.00C 折り返しを含む単語を変換するとスクロールしていた
if (text->fClip==0) {
select;
jumpwordendmi;
// right;//1.00C
}
txstr buff;
getword(buff);
mchar c = buff[0];
BOOL f;
if ((c>='!'&&c<='~')||(c>='「'&&c<='゚')) {
f=FALSE;
} else {
f=TRUE;
janktoank;
jkatatokana;
}
getword(buff);
c=buff[0];
if (c>='A'&&c<='Z') { strlwr(buff); }
if (c>='a'&&c<='z') { strupr(buff); }
selectdelete;
IFILE ad = getaddress;
insert(buff);
select;
jumpaddress(ad);
if(f){
anktojank;
kanatojkata;
}
selectquit;
setdispex;//1.00C
#endif
}
vzuiInsertFind
{
// 選択文字列の複写
// 検索文字列ヒストリーの内容をダイアログで選択して
// カーソル位置へペースト。
//2.95 970131 uiInsertFindを新設しました。そちらを使ってください
txstr str1=histRead(HIST_SEARCH,histGetCount(HIST_SEARCH)-1);//1.00B 選択文字列の複写でファイルヒストリの内容がデフォルト表示された
HDIALOG hd = dialog("複写文字列");
dialogControlHist(hd,HIST_SEARCH);
dialogStr(hd,"",str1,4,30);
if(dialogOpen(hd)){
insertfind;
}
}
#define IDD_INSERTFIND 100
BOOL dlgprocInsertFind(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDIALOG hd = dialogFromHwnd(hwnd);
switch(message) {
case WM_INITDIALOG: {
HWND hctrl = GetDlgItem(hwnd,IDD_INSERTFIND);
HSTRBLK sb = sbFromHist(HIST_SEARCH);
int n = sbGetCount(sb);
while(n--) {
ListBox_AddString(hctrl,sbRead(sb,n));
}
ListBox_SetCurSel(hctrl,0);
break;
}
case WM_COMMAND: {
int id = WM_COMMAND_GetId(wParam);
int notify = WM_COMMAND_GetNotify(wParam,lParam);
if (id == IDOK) {
HWND hctrl = GetDlgItem(hwnd,IDD_INSERTFIND);
int isel = ListBox_GetCurSel(hctrl);
if (isel >= 0) {
txstr sz(ListBox_GetTextLen(hctrl,isel)+1);
if (sz) {
ListBox_GetText(hctrl,isel,sz);
txInsert(text,sz);
histAdd(HIST_SEARCH,sz);
}
}
}
break;
}
}
return FALSE;
}
BOOL TXCMDBASE uiInsertFind(TX* text)
{
// 過去に検索した文字列を挿入
// 検索文字列ヒストリの内容をダイアログで選択して
// カーソル位置へ挿入。
//{#MS} ^%I
//{#VZ} ^KA +{F7}
//{#EMACS} +{F7}
HDIALOG hd = dialog("過去に検索した文字列を挿入");
dialogSetHookEx(hd,"\m.dlgprocInsertFind");
DTRECT r;
dialogGetPos(hd,&r);
r.cx = DTCX * 30;
r.cy = DTCY * 10;
__dialogAddItem(hd,"LISTBOX",NULL,IDD_INSERTFIND,&r,LBS_NOTIFY|WS_BORDER|WS_VSCROLL|WS_HSCROLL|WS_CHILD|WS_VISIBLE|WS_TABSTOP);
return dialogOpen(hd);
}
static UINT _insertBrace(TX* text,UINT index)
{
static mchar szkakko[] = "[]「」〔〕『』【】《》";
txSetUndisp(text);
TXCHAR ch = txGetChar(text);
mchar *p = strchr(szkakko,ch);
if (p && (((p - szkakko) / 2) % 2 == 1)) {
txDeletePrev(text);
txDeleteChar(text);
// next
p += 2;
if (*p == 0) p = szkakko;
} else {
int n = strlen(szkakko) / 4;
if (index < n) {
p = szkakko + index * 4;
} else {
p = szkakko;
}
}
txInsert(text,strleft(p,4));
txLeft(text);
txSetDisp(text);
return (p - szkakko) / 4;
}
permanent p_iBrace;
insertBrace
{
// 全角括弧挿入(学習つき)
// 全角括弧のペアを挿入後、カーソルを括弧の中にセット
// 連続して実行すると、いくつかの種類の括弧をトグル切り替え
// 最後に挿入したペアを覚えていて、次挿入するときは、そのペアを挿入します。
//{#MS} +^K
//{#MI} +^K
//{#VZ} ^]
//3.00A3 970507 new
p_iBrace = _insertBrace(text,p_iBrace);
}
//3.00A2 970507 {#MS} ^%] -> +^K
//3.00A2 970507 {#MI} +^K に割り当て
//3.00A3 970507 vzInsertBrace:{#MS} +^K , {#MI} +^K , {#VZ} ^]キー 割り当て解除。代わりにinsertBraceに割り当て
vzInsertBrace
{
// 全角括弧挿入
// 全角括弧のペアを挿入後、カーソルを括弧の中にセット
// 連続して実行すると、いくつかの種類の括弧をトグル切り替え
#if 1///3.00A3 970507
_insertBrace(text,0);
#else
static mchar szkakko[] = "[]「」〔〕『』【】《》";
#if 1//1.01A
setundisp;
TXCHAR ch = getchar;
mchar *p = strchr(szkakko,ch);
if (p && (((p - szkakko) / 2) % 2 == 1)) {
deleteprev;
deletechar;
// next
p += 2;
if (*p == 0) p = szkakko;
} else {
p = szkakko;
}
insert(strleft(p,4));
left;
setdisp;
#else
setundisp;
mchar *c;
txstr c0;
c=strchr(szkakko,getchar);
if (c) {
deletechar; deleteprev;
c0=strrear(c,2);
if(strlen(c0)==0) c0=szkakko;
} else {
c0=szkakko;
}
insert(strleft(c0,4));
left;
setdisp;
#endif
#endif
}
//2.00E6 キー割り当てされてなかったので#WZKEY {Enter}を削除
WriteReturnC
{
// Cインデント展開改行
// '{'の直後で実行するとCインデントに展開します。その他の位置では
// 通常の改行として働きます。Enterキーに割り当てて利用します。
#if 1//2.99C 970325 Cインデント展開改行 改良
if (
!text->fOverWrite && // 上書き時は展開しない
txIsCurReturn(text) &&
txGetCharPrev(text) == '{'
) {
txWriteReturn(text);
txWriteReturn(text);
txInsert(text,"}");
txLeft(text);//2.00E6 タブの前に空白が入った
txUp(text);
txWriteTab(text);
} else {
txWriteReturn(text);
}
#else
if (
text->cur0 && text->buff[text->cur0 - 1] == '{' &&
!text->fOverWrite//2.00E6 上書き時は展開しない
) {
txWriteReturn(text);
txWriteReturn(text);
txInsert(text,"}");
txLeft(text);//2.00E6 タブの前に空白が入った
txUp(text);
txWriteTab(text);
} else {
txWriteReturn(text);
}
#endif
}
//{###カット&ペースト}
txDupePara
{
// 論理行の複写
// カーソル位置の論理行を二重化。
//{#VZ} ^KD
//{#MI} +{F10}
SelectTsPushQuit;
tspop;
}
clipCopyFilename
{
// テキストのファイル名をクリップボードへコピー
//3.00A2 970505 new VZ.KEY:^QNに割り当て
//{#VZ} ^QN
if (text->szfilename[0]) {
memClipCopy(text->szfilename,strlen(text->szfilename),HCLIP_WIN,CLIP_CHAR);
return TRUE;
}
return FALSE;
}
//{###編集}
insertFilename
{
// テキストのファイル名をフルパスで挿入
//3.00A2 970505 new
txInsert(text,text->szfilename);
}
BOOL TXCMDBASE OpenContextMenu(TX* text)
{
// 状況に応じた右クリックメニューを開く。
// {#MS} +{F10}
txstr szMenu;
if (text->fClip) {
szMenu = text->szMenuMouseRClip;
} else {
szMenu = text->szMenuMouseR;
}
//information(text->szMenu);
if (!strnicmp(szMenu,"macro:",6)) {//3.00A3 970507 右クリックメニューにマクロを指定できるようにした。"macro:test.main"の様に指定しておくと、"test.main"を呼び出す。
call(&szMenu[6]);
return TRUE;
}
call("menu." + szMenu);
return TRUE;
}
//旧:usermenu.umcMouseR
//あんまり多すぎると、VGAではみ出してしまう
//3.00A 970427 {#EMACS} {MouseR}追加
menuMouseR
{
#WZKEY
// 右クリックメニュー
//{#MS} {MouseR}
//{#VZ} {MouseR}
//{#MI} {MouseR}
//{#EMACS} {MouseR}
OpenContextMenu(text);//2.91
// call("menu." + text->szMenuMouseR);
}
//旧:usermenu.umcMouseRClip
//3.00A 970427 {#EMACS} {MouseRClip}追加
menuMouseRClip
{
#WZKEY
// 選択時の右クリックメニュー
//{#MS} {MouseRClip}
//{#VZ} {MouseRClip}
//{#MI} {MouseRClip}
//{#EMACS} {MouseRClip}
OpenContextMenu(text);//2.91
// call("menu." + text->szMenuMouseRClip);
}
err_undo
{
statprintf("これ以上やり直しできません");
if (text->fbeep) MessageBeep(MB_ICONEXCLAMATION);
}
ViewToEdit
{
txSwitchViewMode(text);
txKeyLoad(text);
}
//2.99 970320
extern "word" {
BOOL TXAPI TXCMD txInsertBeamtab(TX* text);
BOOL TXAPI TXCMD txFormIndentInc(tx *text);
BOOL TXAPI TXCMD txFormIndentDec(tx *text);
}
//1.99H
BOOL TXCMDBASE tab(TX* text)
{
// 文字範囲選択なら、選択範囲を消去してタブに置き換えます。
// 行範囲選択なら、インデントを増加します。
// 上書きモードなら、カーソルを次のタブ位置へ進めます。
// 挿入モードなら、タブを挿入します。
//{#MS} {Tab}
//{#VZ} {Tab} ^I
//{#MI} {Tab} ^I
//{#EMACS} {Tab}
if (text->fClip && txIsClipInPara(text)) {
// 文字範囲選択なら、選択範囲を消去してタブに置き換える。
txSelectDelete(text);
{
BOOL fOverWrite0 = text->fOverWrite;
text->fOverWrite = FALSE;
txWriteTab(text);
text->fOverWrite = fOverWrite0;
}
} else if (text->fClip) {
#if 1//2.99 970320
if (txIsWP(text)) {
txFormIndentInc(text);
} else {
txIndentInc(text);
}
#else
if (text->editmode == 0) {
txIndentInc(text);
} else {
call("word.txFormIndentDec");
}
#endif
} else if (txIsWP(text)) {
//2.99C 970327 表で{TAB}入力が変だった
PLUGTAB* plug = txIsCurParaIncludeTable(text);
if (plug && plug->modeTab == MODETAB_TABLE) {
txWriteTab(text);
} else {
//2.99 970320 体裁/詳細モードでは、タブで字下げ及び桁揃えを行う様にした
// <TX>文書では、行頭タブは字下げと見なされるので、通常のタブを挿入しても仕方がない
if (txIsCurParaTop(text)) {
txFormIndentInc(text);
} else {
txInsertBeamtab(text);
}
}
} else {
txWriteTab(text);
}
return TRUE;
}
//1.99H
BOOL TXCMDBASE tabPrev(TX* text)
{
// 文字範囲選択なら、選択範囲を消去します。
// 行範囲選択なら、インデントを減らします。
// 選択中でなければ行頭のタブを削除します。
//{#MS} +{Tab}
//{#VZ} +{Tab}
//{#MI} +{Tab}
//{#EMACS} +{Tab}
if (text->fClip && txIsClipInPara(text)) {
// 文字範囲選択なら、選択範囲を消去
txSelectDelete(text);
} else if (text->fClip) {
#if 1//2.99 970320
if (txIsWP(text)) {
txFormIndentDec(text);
} else {
txIndentDec(text);
}
#else
if (text->editmode == 0) {
txIndentDec(text);
} else {
call("word.txFormIndentDec");
}
#endif
} else if (txIsWP(text)) {
//2.99 970320 体裁/詳細モードでは、Shift+タブで字下げの解除を行う様にした
txFormIndentDec(text);
} else {
txJumpParaTop(text);
if (txGetChar(text) == CHAR_TAB) {
txDeleteChar(text);
}
}
return TRUE;
}
//2.99 970320
// Enter,Shift+Enterなどに割り付けるキーコマンドを用意した。
// HTMLやeditmodeでコマンド名が異なるが、キーコマンドを用意したことによって、
// コマンド名の差異を吸収した。
BOOL TXCMDBASE txkeyEnter(TX* text)
{
// {Enter}キー割り当て用コマンド
// 改行を挿入または上書き。
//{#MS} {Enter} ^M
//{#VZ} {Enter} ^M
//{#MI} {Enter} ^M
//{#EMACS} {Enter} ^J ^M
//2.99 970320 new
txWriteReturn(text);
return TRUE;
}
WORD at_cmdcheck(WZCMD wzcmd)
{
//3.00B1 970523 new
mchar* szcmd = wzcmdToSzcmd(wzcmd);
if (!szcmd) return 0;
if (!stricmp(szcmd,"\m.txkeyShiftEnter")) {
if (!text->fHTML && !text->fWztext) {
if (text->tszformat[SZFORMAT_BR][0] == 0) return MF_GRAYED;
}
}
return 0;
}
BOOL TXCMDBASE txkeyShiftEnter(TX* text)
{
// Shift+{Enter}キー割り当て用コマンド
//{#MS} +{Enter}
//{#VZ} +{Enter}
//{#MI} +{Enter}
//{#EMACS} +{Enter}
//2.99 970320 new
if (text->fHTML) {
call("html.insertBR");
} else {
call("word.txInsertBR");
}
return TRUE;
}
BOOL TXCMDBASE txkeyCtrlEnter(TX* text)
{
// Ctrl+{Enter}キー割り当て用コマンド
//{#MS} ^{Enter}
//{#VZ} ^{Enter}
//{#MI} ^{Enter}
//{#EMACS} ^{Enter}
//2.99 970320 new
if (text->fHTML) {
call("html.insertP");
} else {
call("word.txFormFeedModal");
}
return TRUE;
}
BOOL TXCMDBASE txkeyAltEnter(TX* text)
{
// Alt+{Enter}キー割り当て用コマンド
//{#MS} %{Enter}
//{#VZ} %{Enter}
//{#MI} %{Enter}
//{#EMACS} %{Enter}
//2.99 970320 new
if (text->fHTML) {
call("html.uiPropertyTag");
} else {
if (text->textParaform) {
call("paraform.config");
} else if (txIsWP(text)) {
call("word.txuiCharProperty");
} else {
call("paraform.form");
}
}
return TRUE;
}
//2.96 970210 WriteTabMs廃止 edit.tabを使用してください
//1.00B edit.ShiftTabを追加
BOOL TXCMDBASE ShiftTab(TX* text)
{
// 範囲選択中は逆インデント、
// 選択中でないときは、カーソル行を逆インデントします
if (text->fClip) {
txIndentDec(text);
} else {
txJumpParaTop(text);
if (txGetChar(text) == 0x09) {
txDeleteChar(text);
}
}
return TRUE;
}
insertlf
{
// 改行を挿入
// 上書きモードでも、改行が挿入されます
// 1.00Eで追加
txInsert(text,"\n");
}
insertff
{
// 改頁コードを挿入
// 1.00Fで追加
txInsertChar(text,'L'-0x40);
}
BOOL TXCMDBASE uiInsertControl(TX* text)
{
// コントロールコードを挿入
// 1.00Fで追加
//{#VZ} ^P
//{#MI} ^V
inittext2;
opentext2;
{
HDIALOG hd = dialog("制御文字の入力");
{
int i;
for (i = 0;i <= 0x1B;i++) {
if (i == 0x0A) continue;//0x0Aは入力できない
insertf2("%c:\tCtrl-%c\n",i+'@',i+'@');
}
text2->npara = 1;
}
dialogList(hd,NULL,text2,20,10);
if (dialogOpen(hd)) {
int code = text2->npara;
code--;
if (code >= 0x0A) code++;
txInsertChar(text,code);
}
}
close2;
return TRUE;
}
uiInsertTitle
{
// タイトル文字列を挿入
// 1.00Fで追加
HDIALOG hd = dialog("タイトル文字列の挿入");
BOOL data[SZTITLE_N];
int i;
memset(data,0,sizeof(data));
for (i = SZTITLE_N;i--;) {
if (text->tsztitle[i][0]) {
data[i] = TRUE;
break;
}
}
dialogRadioInit(hd);
for (i = 0;i < SZTITLE_N;i++) {
dialogRadio(hd,"タイトル&" + inttostr(i + 1) + ": " + text->tsztitle[i],&data[i]);
}
if (dialogOpen(hd)) {
for (i = 0;i < SZTITLE_N;i++) {
if (data[i]) {
jumpparatop;
insert(text->tsztitle[i]);
break;
}
}
}
}
BOOL TXCMDBASE OpenAutosaveBackup(TX* text)
{
// 自動保存によるバックアップファイルを開く
if (text->autosaveMode == AUTOSAVE_BACKUP) {
mchar szfilename[CCHPATHNAME];
if (autosaveGetFileName(text,szfilename)) {
if (fileIsExist(szfilename)) {
txOpenForkFast(text,szfilename);
return TRUE;
}
}
}
statprintf("バックアップファイルはありません");
return FALSE;
}
//2.90
//2.99 970315 ehPopup廃止
permanent txstr szQuote = ">\\s";
#define TXQUOTE_SELECT 1 // 範囲選択されてなかった時でも選択状態にする
BOOL TXAPI txQuoteEx(TX* text,int mode)
{
//2.00Bで追加
strfromesc(szQuote);
txSetUndisp(text);
{
int fClip = text->fClip;
IFILE adr0 = txGetAddress(text);
//
if (!text->fClip) {
IFILE adr = txGetAddress(text);
txClipPasteEx(text,HCLIP_WIN,0,0,TRUE,CLIP_CHAR);
txSelect(text);
text->fClipMouse = TRUE;
adr0 = txGetAddress(text);
txJumpAddress(text,adr);
}
{
txWalkStart(text);
while(txIsWalking(text)) {
txJumpParaTop(text);
txInsert(text,szQuote);
if (!txNextPara(text)) break;
}
txWalkEnd(text);
}
if (mode == TXQUOTE_SELECT) {
// 範囲選択されていなかった時は範囲選択する。
} else {
// 範囲選択されていなかった時は範囲選択を解除する。
// カーソル位置はペーストしたデータの末尾の次の文字とする。
if (!fClip) {
txSelectQuit(text);
txJumpAddress(text,adr0);
}
}
}
txSetDisp(text);
strtoesc(szQuote);
return TRUE;
}
quote
{
// 引用符の挿入
// 選択中なら、範囲内の各行に引用符を付けます
// 選択中でなければ、クリップボードから引用符を付けて貼り付けます
// 動作の確認ダイアログは出しません
//2.00Bで追加
return txQuoteEx(text,TXQUOTE_SELECT);
}
BOOL TXAPI TXCMD TXUI txQuote(TX* text)
{
// 引用符の挿入
// 選択中なら、範囲内の各行に引用符を付けます
// 選択中でなければ、クリップボードから引用符を付けて貼り付けます
// 動作の確認ダイアログを出します
HDIALOG hd = dialog("引用符の挿入");
if (text->fClip) {
dialogCaption(hd,"範囲内の各行に、引用符を付けます。");
} else {
dialogCaption(hd,"クリップボードから、引用符を付けて貼り付けます。");
}
dialogIndent(hd,4);
dialogStr(hd,"引用符(&Q):",szQuote,16,10);
dialogCaption(hd," (半角スペースは\"\\s\"で指定してください)");
if (dialogOpen(hd)) {
return txQuoteEx(text,TXQUOTE_SELECT);
}
return FALSE;
}
//##世代管理
//1.92 undo.cから移動
#define MAXGENELIST 200
typedef struct {
TIME tTime[MAXGENELIST];
mchar tszComment[MAXGENELIST][CCHWORD];
GENELIST gl;
} GENECONTEXT;
GENECONTEXT _genecontext;
BOOL dlgprocGeneList(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message) {
case WM_INITDIALOG: {
HWND hwndList = GetDlgItem(hwnd,IDD_LIST);
int i;
SendMessage(hwndList,LB_ADDSTRING,0,(LPARAM)"現在テキスト編集開始時点");
for (i = 1;i <= _genecontext.gl.nList;i++) {
mchar* szComment = _genecontext.tszComment[i];
mchar buff[100 + CCHWORD];
mchar* dst = buff;
TM tm;
timeGetLocal(&tm,&_genecontext.tTime[i]);
sprintf(dst,"%02d/%02d/%02d %02d:%02d:%02d - ",tm.tm_year,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec);
dst += strlen(dst);
if (szComment[0]) {
sprintf(dst,"%s",szComment);
} else {
sprintf(dst,"%d世代",i);
}
SendMessage(hwndList,LB_ADDSTRING,0,(LPARAM)buff);
}
SendMessage(hwndList,LB_SETCURSEL,_genecontext.gl.curgene,0);
SetFocus(hwndList);
return FALSE;
}
case WM_COMMAND: {
int id = LOWORD(wParam);
switch(id) {
case IDD_NEWEST: {
txUndoNewest(text);
EndDialog(hwnd,TRUE);
return TRUE;
}
case IDD_COMMENT: {
HDIALOG hd = dialog("世代コメント");
dialogStrC(hd,"コメント:",txGetFrameNow()->pGeneComment,10,CCHWORD,30);//2.99C 970324 text1->txGetFrameNow()
dialogCaption(hd," (次に上書き保存するとできる世代のコメントになります)");
if (dialogOpen(hd)) {
}
return TRUE;
}
case IDD_OPEN:
case IDD_JUMP:
case IDD_LOAD:
case IDD_DEL: {
HWND hwndList = GetDlgItem(hwnd,IDD_LIST);
int isel = SendMessage(hwndList,LB_GETCURSEL,0,0);
if (isel != LB_ERR) {
EndDialog(hwnd,TRUE);
switch(id) {
case IDD_JUMP: {
NPARA npara = text->npara;
txSetUndisp(text);//2.92 ちらつき低減
txGeneJump(text,isel);
txJumpPara(text,npara);//カーソル位置を復元したほうが使いやすい
txSetDisp(text);//2.92 ちらつき低減
break;
}
case IDD_OPEN: {
txGeneOpen(text,isel);
break;
}
case IDD_DEL: {
if (!txGeneDelete(text,isel)) {
attention("現在開いている世代が削除される場合、削除できません");
}
break;
}
default: {
txuiGeneLoad(text,isel);
break;
}
}
} else {
EndDialog(hwnd,FALSE);
}
return TRUE;
}
}
return FALSE;
}
}
return FALSE;
}
GeneOpen
{
txGeneOpen(text,1);
}
BOOL TXCMDBASE uiGeneList(TX* text)
{
_genecontext.gl.maxList = MAXGENELIST;
_genecontext.gl.tTime = _genecontext.tTime;
_genecontext.gl.tszComment = _genecontext.tszComment;
if (text->text2 && !text->fMultiChild && text->modeMulti == MM_GENE) {
SetFocus(text->text2->hwndtext);
}
txGeneMakeList(text,&_genecontext.gl);
if (_genecontext.gl.nList == _genecontext.gl.maxList) {
information("世代が多すぎます。%d世代より前は表示できません。",MAXGENELIST);
}
{
HDIALOG hd = dialog("世代管理");
dialogSetContexthelp(hd,TRUE);
PMACROFUNC pfunc;
if (macroGetFuncAddress("dlgprocGeneList",&pfunc)) {
dialogSetHook(hd,&pfunc);
}
dialogControlID(hd,IDD_LIST);
dialogControlHelp(hd,206);
_dialogList(hd,NULL,60,12);
_dialogAddControlInfo(hd,IDD_LIST);
dialogLFV(hd);
int lcx = 15;
if (text->fGene) {
dialogControlID(hd,IDD_JUMP);
dialogControlHelp(hd,207);
dialogCmdDefault(hd,"移動(&J)",lcx);
//ここでは「以前を削除」コマンドは無効である。保存できないので
} else {
dialogControlID(hd,IDD_OPEN);
dialogControlHelp(hd,208);
dialogCmdDefault(hd,"参照(&R)",lcx);
dialogControlID(hd,IDD_DEL);
dialogControlHelp(hd,209);
dialogCmd(hd,"以前を削除(&D)",lcx);
// dialogControlID(hd,IDD_LOAD);
// dialogCmd(hd,"読み込み(&L)",lcx);
// dialogSpaceV(hd);
// dialogControlID(hd,IDD_NEWEST);
// dialogCmd(hd,"最新へ移動(&N)",lcx);
dialogControlID(hd,IDD_COMMENT);
dialogControlHelp(hd,210);
dialogCmd(hd,"コメント(&C)...",lcx);
}
dialogCancel(hd,lcx);
dialogSpaceV(hd);
dialogHelpID(hd,lcx,"wz",IDH_GENMNGR);
dialogOpen(hd);
}
return TRUE;
}
//##ms.key範囲選択
//1.92 select.cから移動
//{###範囲選択}
// カーソル位置と選択開始位置が同じなら選択解除
static void SelectQuitEx(TX* text)
{
if (text->clipcur0 == txGetAddress(text)) {
txSelectQuit(text);
}
}
// 拡張選択モード
static void SelectExtend(TX* text,int d)
{
static int mode = 0;
if (!text->fClip) mode = 0;
mode += d;
if (mode > 5) mode = 0;
if (mode < 1) mode = 0;
switch(mode) {
case 0: {
txSelectQuit(text);
break;
}
case 1: {
SelectQuitEx(text);
txSelect(text);
break;
}
case 2: {
SelectQuitEx(text);
txSelectWord(text);
break;
}
case 3: {
SelectQuitEx(text);
txSelectSentence(text);
break;
}
case 4: {
SelectQuitEx(text);
txSelectParaCur(text);
break;
}
case 5: {
SelectQuitEx(text);
txSelectAll(text);
break;
}
}
}
BOOL TXCMDBASE selectExtend(TX* text)
{
#WZKEY {F8}
// 拡張選択モード
// 方向キーで長さの調節が可能な選択モード
// 続けてキーを押すことで選択範囲を自動調節する
// :1回目=選択開始 2回目=単語選択 3回目=一文選択
// :4回目=段落選択 5回目=全文選択
//{#MS} {F8}
SelectExtend(text,1);
return TRUE;
}
BOOL TXCMDBASE selectExtendPrev(TX* text)
{
#WZKEY +{F8}
// 拡張選択モード(逆順)
// 拡張選択モードの選択範囲トグルを戻す。
//{#MS} +{F8}
if (!text->fClip) return FALSE;
SelectExtend(text,-1);
return TRUE;
}
//3.00B1 970613 new
BOOL TXAPI TXCMDBASE txSelectRevival(TX* text)
{
// 範囲選択の再現
// 直前に指定した選択開始位置からカーソル位置までを文字単位で範囲選択します。
IFILE cliptop = text->cliptopnow;
IFILE clipend = txGetAddress(text);
int ly = text->ly;
txSetUndispSilent(text);
txJumpAddress(text,cliptop);
txSelectEx(text,CLIP_CHAR);
txJumpAddress(text,clipend);
txSetLy(text,ly);
txSetDispSilent(text);
return TRUE;
}
//{###ジャンプ}
//3.00B1 970613 new
//3.00B1 970613 VZ.KEY txSelectJump=^QB -> edit.txSelectJumpEx=^QB
BOOL TXAPI TXCMDBASE txSelectJumpEx(TX* text)
{
// 範囲の先頭/末尾へジャンプ
// 範囲選択中でないときでも、直前に指定した範囲でジャンプします。
//{#VZ} ^QB
if (text->fClip) {
return txSelectJump(text);
} else {
IFILE adr = txGetAddress(text);
int ly = text->ly;
//
txSetUndispSilent(text);
txJumpAddress(text,text->cliptopnow);
txSetLy(text,text->lyClip);
txSetDispSilent(text);
//
text->cliptopnow = adr;
text->lyClip = ly;
return TRUE;
}
}
//2.00B 整形etcのカテゴリが"範囲選択"だったのを修正
//{###編集}
//##整形
// センタリング、右寄せ、左寄せ、インデント、1字見出し(※,・◎)にも対応したい
#include <windows.h>
#include "dialog.h"
permanent txstr ftszParaTop = " 「|>≫|>";
permanent int ftWidth = 70;
permanent int ftMode = 0;
permanent int ftArea = 0;
// カレント行が段落の先頭か?
static BOOL IsLineParaTop(tx* text)
{
mchar*p = text->buff + text->cury;
if (text->cury == text->cur0) {
// カーソルが行頭に居る
p = text->buff + text->cur;
}
WORD c = *p;
if (c == CHAR_LF || c == CHAR_CR || c == CHAR_FF || c == CHAR_EOF) return TRUE;
#if 0//文中の大文字単語"WindowsNT"などにも引っかかってしまう
if (isupper(c)) return TRUE;
#endif
if (iskanji(c)) {
c = MAKEWORD(p[1],c);
}
if (strchr(ftszParaTop,c)) {
return TRUE;
}
return FALSE;
}
// カレント行が段落の末尾か?
static BOOL IsLineEnd(tx* text)
{
int cxWidth = ftWidth * text->cxChar;
BOOL ret = FALSE;
int x = text->x;
// 行の最後が折り返し桁に達しているか?
txJumpLineEnd(text);
if (text->x + text->cxChar * 4 < cxWidth) {
// 達してなければ...
ret = TRUE;
}
// カーソル位置を戻す
txJumpX(text,x);
return ret;
}
// 段落の先頭へ
static void JumpParaTop(tx *text)
{
BOOL fFirst = TRUE;
txJumpLineTop(text);
while(1) {
if (!fFirst && IsLineEnd(text)) {
txDown(text);
break;
}
if (IsLineParaTop(text)) break;
if (!txUp(text)) break;
fFirst = FALSE;
}
}
static int strGetSpaceTop(mchar* szline)
{
int lchIndent = 0;
if (szline[0] == ' ') {
mchar*p = szline;
while(*p == ' ') {
lchIndent++;
p++;
}
}
return lchIndent;
}
//2.00B 行頭の半角空白(インデント)を削除
static void txDeleteSpaceTop(TX* text)
{
txstr szline;
txGetLine(text,szline);
int lchIndent = strGetSpaceTop(szline);
if (lchIndent) {
txDeleteBytes(text,lchIndent);
}
}
#define FORMTEXT_FORM 0x0001
#define FORMTEXT_JOINT 0x0002
#define FORMTEXT_RIGHT 0x0004
#define FORMTEXT_CENTER 0x0008
#define FORMTEXT_LEFT 0x0010
#define FORMTEXT_PARA1 0x0020
#define FORMTEXT_SELECT 0x0040
#define FORMTEXT_ALLTEXT 0x0080
static int FormText(tx* text,int mode)
{
txstr szline;
int cxWidth = ftWidth * text->cxChar;
//
txSetUndisp(text);
if (mode & FORMTEXT_ALLTEXT) {
txJumpFileTop(text);
} else if (mode & FORMTEXT_SELECT) {
txJumpSelectTop(text);
}
//
while(1) {
JumpParaTop(text);
//information("!!!");
// 改行を削除して1行にする
if (IsLineEnd(text)) {
//2.00B いきなり行の最後なら、何もしない
if (!txDown(text)) break;
} else {
while(1) {
if (txIsLineLf(text)) {
if (!txDown(text)) break;
if (IsLineParaTop(text)) break;
// 行の最後か?
if (IsLineEnd(text)) {
txJumpLineTop(text);
txDeleteSpaceTop(text);
txDeletePrev(text);
txNextPara(text);
break;
}
//
txDeleteSpaceTop(text);
txDeletePrev(text);
txJumpLineTop(text);
} else {
if (!txDown(text)) break;
}
}
if (mode & FORMTEXT_JOINT) {
} else {
// 折り返して改行を入れる
txUp(text);
JumpParaTop(text);
if (1) {
int cxWidth0 = text->cxWidth;
int width0 = text->width;
text->width = ftWidth;
text->cxWidth = cxWidth;
txFlushCurysize(text);
//2.00B 整形で、行頭の半角スペースによるインデントに対応
mchar szspace[CCHLINE];
txGetLine(text,szline);
int lchIndent = strGetSpaceTop(szline);
if (lchIndent) {
memset(szspace,' ',lchIndent);
}
while(1) {
if (txIsLineLf(text)) {
txDown(text);
break;
}
if (!txDown(text)) break;//2.00B
txInsertReturn(text);
if (lchIndent) {//2.00B
txCurInsertBuff(text,szspace,lchIndent);
// 行が全て空白だと無限ループになるから。
int len = lchIndent;
while(len >= text->curysize) {
txDeleteChar(text);
len--;
}
}
}
//
text->width = width0;
text->cxWidth = cxWidth0;
txFlushCurysize(text);
// widthの変更をリセット
txJumpAddress(text,txGetAddress(text));
}
}
}
if (mode & FORMTEXT_ALLTEXT) {
if (txIsLineEof(text)) break;
} else if ((mode & FORMTEXT_SELECT) && text->fClip) {
if (
(txGetAddress(text) >= text->cliptop) ||
(txIsLineEof(text)) //1.99H 空でないEOF行の直前文字まで選択して実行すると飛んだ
) {
txSelectQuit(text);
break;
}
} else {
break;
}
}
//
txSetDisp(text);
return 0;
}
//2.00B MS/VZキーに割り当て
//2.90 キー割り当て廃止
//{#MS} +^{Enter}
//{#VZ} +^{Enter}
formtext
{
// カーソル行または選択範囲内を整形
if (text->fClip) {
FormText(text,FORMTEXT_FORM|FORMTEXT_SELECT);
} else {
FormText(text,FORMTEXT_FORM|FORMTEXT_PARA1);
}
}
formtextAll
{
// テキスト全体を整形
FormText(text,FORMTEXT_FORM|FORMTEXT_ALLTEXT);
}
formtextJointAll
{
// テキスト全体を連結整形
FormText(text,FORMTEXT_JOINT|FORMTEXT_ALLTEXT);
}
uiFormText
{
HDIALOG hd = dialog("テキスト整形");
dialogSetContexthelp(hd,TRUE);
int x = DTCX * 40;
dialogSetGroupRight(hd,x);
dialogGroup(hd,"整形内容");
dialogControlHelp(hd,-296);
dialogRadioID(hd,&ftMode,"整形(&F)","連結(&J)");
dialogGroupEnd(hd);
dialogGroup(hd,"整形範囲");
if (text->fClip) {
dialogControlHelp(hd,221);
dialogRadioID(hd,&ftArea,"範囲内(&S)","テキスト全体(&A)");
} else {
dialogControlHelp(hd,221);
dialogRadioID(hd,&ftArea,"1段落(&S)","テキスト全体(&A)");
}
dialogGroupEnd(hd);
dialogControlHelp(hd,222);
dialogInt(hd,"折り返し桁(&W):",&ftWidth,16,3);
dialogControlHelp(hd,223);
dialogStr(hd,"段落区切(&P):",ftszParaTop,16,14);
if (dialogOpen(hd)) {
int arg = 0;
if (ftMode == 0) arg |= FORMTEXT_FORM;
if (ftMode == 1) arg |= FORMTEXT_JOINT;
if (ftArea == 0) {
if (text->fClip) {
arg |= FORMTEXT_SELECT;
} else {
arg |= FORMTEXT_PARA1;
}
} else {
arg |= FORMTEXT_ALLTEXT;
}
FormText(text,arg);
}
}
//##日付の挿入
#define ITEM_N 6
#define IDD_YEAR 100
#define IDD_MONTH 101
#define IDD_DAY 102
#define IDD_DAYOFWEEK 103
#define IDD_HOUR 104
#define IDD_MINUTE 105
#define IDD_DATEINC 106 //2.92 日付を増減して挿入する機能を追加
//
#define IDD_FORMAT 200
static void _cdecl cprintf(HWND hctrl,mchar* szformat,...)
{
mchar buff[CCHWORD];
vsprintf(buff,szformat,(void*)(&szformat + 1));
SendMessage(hctrl,CB_ADDSTRING,0,(LPARAM)buff);
}
static void cprintStd(HWND hctrl,int data)
{
cprintf(hctrl,"%d",data);
cprintf(hctrl,"%2d",data);
cprintf(hctrl,"%02d",data);
}
#define FORMAT_DAYOFWEEK_N 5
static mchar* szFromDayofweek(mchar szdst[CCHWORD],int mode,int day)
{
static mchar* tsz[][7] = {
{"日","月","火","水","木","金","土"},
{"Sun","Mon","Tue","Wed","Thu","Fri","Sat"},
{"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"},
};
switch(mode) {
case 0: {
sprintf(szdst,"%s曜日",tsz[0][day]);
break;
}
case 1: {
sprintf(szdst,"(%s)",tsz[0][day]);
break;
}
case 2: {
sprintf(szdst,"%s",tsz[1][day]);
break;
}
case 3: {
sprintf(szdst,"%s.",tsz[1][day]);
break;
}
case 4: {
sprintf(szdst,"%s",tsz[2][day]);
break;
}
}
return szdst;
}
#define FORMAT_MONTH_N 5
static mchar* szFromMonth(mchar szdst[CCHWORD],int mode,int data)
{
static mchar* tsz[13] = {
"",
"January","February","March","April","May","June",
"July","August","September","October","November","December"
};
switch(mode) {
case 0: {
sprintf(szdst,"%d",data);
break;
}
case 1: {
sprintf(szdst,"%2d",data);
break;
}
case 2: {
sprintf(szdst,"%02d",data);
break;
}
case 3: {
sprintf(szdst,"%s",tsz[data]);
break;
}
case 4: {
sprintf(szdst,"%s",tsz[data]);
szdst[3] = 0;
break;
}
}
return szdst;
}
permanent int dt_format = 0;
permanent int dt_year = 0;
permanent int dt_month = 0;
permanent int dt_day = 0;
permanent int dt_dayofweek = 0;
permanent int dt_hour = 0;
permanent int dt_minute = 0;
static void insertdateGetTime(HWND hwnd,TIME* _itime)
{
long n = (int)(INT)GetDlgItemInt(hwnd,IDD_DATEINC,NULL,TRUE);
TIME itime;
itimeGetNow(&itime);
itime += n * 86400L;
*_itime = itime;
}
static void insertdateFlush(HWND hwnd)
{
//2.98 970309 「挿入|日付・時刻」:書式をwzhist.datでカスタマイズできるようにした
static mchar _szhistid[] = "uiInsertDate";
HSTRBLK sb = historyOpen(_szhistid,4096);
if (sb) {
HWND hctrl = GetDlgItem(hwnd,IDD_FORMAT);
int isel = SendMessage(hctrl,LB_GETCURSEL,0,0);
SendMessage(hctrl,LB_RESETCONTENT,0,0);
TIME itime;
insertdateGetTime(hwnd,&itime);
TM tm;
itimeToTm(&itime,&tm);
//
int n = sbGetCount(sb);
int i;
for (i = n;i--;) {
mchar* szformat = sbRead(sb,i);
mchar buff[CCHWORD];
mchar* dst = buff;
mchar* p = szformat;
while(*p) {
if (*p == '{') {
int id = 0;
int lch;
BOOL f = FALSE;
if (lch = strmatch(p,"{year}")) {
id = IDD_YEAR;
} else if (lch = strmatch(p,"{month}")) {
id = IDD_MONTH;
} else if (lch = strmatch(p,"{day}")) {
id = IDD_DAY;
} else if (lch = strmatch(p,"{02month}")) {
id = IDD_MONTH;
f = TRUE;
} else if (lch = strmatch(p,"{02day}")) {
id = IDD_DAY;
f = TRUE;
} else if (lch = strmatch(p,"{dayofweek}")) {
id = IDD_DAYOFWEEK;
} else if (lch = strmatch(p,"{hour}")) {
id = IDD_HOUR;
} else if (lch = strmatch(p,"{12hour}")) {
id = IDD_HOUR;
f = TRUE;
} else if (lch = strmatch(p,"{minute}")) {
id = IDD_MINUTE;
} else if (lch = strmatch(p,"{minute}")) {
id = IDD_HOUR;
} else if (lch = strmatch(p,"{ampm}")) {
id = 1;
f = TRUE;
} else if (lch = strmatch(p,"{jampm}")) {
id = 2;
f = TRUE;
}
if (lch) {
p += lch;
if (id) {
if (f) {
switch(id) {
case IDD_MONTH: {
sprintf(dst,"%02d",tm.tm_mon+1);
dst += strlen(dst);
break;
}
case IDD_DAY: {
sprintf(dst,"%02d",tm.tm_mday);
dst += strlen(dst);
break;
}
case IDD_HOUR: {
sprintf(dst,"%d",tm.tm_hour % 12);
dst += strlen(dst);
break;
}
case 1:
case 2: {
static mchar *tsz[2][2] = {
{"AM","PM"},
{"午前","午後"},
};
BOOL h = (tm.tm_hour >= 12);
sprintf(dst,"%s",tsz[(id-1)][h]);
dst += strlen(dst);
break;
}
}
} else {
GetDlgItemText(hwnd,id,dst,CCHWORD - (dst - buff));
dst += strlen(dst);
}
}
} else {
p = strchr(p,'}');
if (!p) break;
}
} else {
if (iskanji(*p)) {
*dst++ = *p++;
*dst++ = *p++;
} else {
*dst++ = *p++;
}
}
}
*dst = 0;
SendMessage(hctrl,LB_ADDSTRING,0,(LPARAM)buff);
}
if (isel == LB_ERR) isel = dt_format;
SendMessage(hctrl,LB_SETCURSEL,isel,0);
}
//
historyClose(_szhistid,sb);
}
static void dateFlush(HWND hwnd)
{
TIME itime;
insertdateGetTime(hwnd,&itime);
TM tm;
itimeToTm(&itime,&tm);
int i;
for (i = 0;i < ITEM_N;i++) {
int id = IDD_YEAR + i;
HWND hctrl = GetDlgItem(hwnd,id);
int isel = SendMessage(hctrl,CB_GETCURSEL,0,0);
SendMessage(hctrl,CB_RESETCONTENT,0,0);
int data;
switch(id) {
case IDD_YEAR: {
data = 1900 + tm.tm_year;
cprintf(hctrl,"%4d",data);
cprintf(hctrl,"%2d",data % 100);
{
mchar buff[CCHWORD];
sprintf(buff,"平成%d",data - 1988);
SendMessage(hctrl,CB_ADDSTRING,0,(LPARAM)buff);
}
if (isel == CB_ERR) isel = dt_year;
break;
}
case IDD_MONTH: {
data = tm.tm_mon+1;
int i;
for (i = 0;i < FORMAT_MONTH_N;i++) {
mchar buff[CCHWORD];
szFromMonth(buff,i,data);
SendMessage(hctrl,CB_ADDSTRING,0,(LPARAM)buff);
}
if (isel == CB_ERR) isel = dt_month;
break;
}
case IDD_DAY: {
data = tm.tm_mday;
cprintStd(hctrl,data);
if (isel == CB_ERR) isel = dt_day;
break;
}
case IDD_DAYOFWEEK: {
data = tm.tm_wday;
int i;
for (i = 0;i < FORMAT_DAYOFWEEK_N;i++) {
mchar buff[CCHWORD];
szFromDayofweek(buff,i,data);
SendMessage(hctrl,CB_ADDSTRING,0,(LPARAM)buff);
}
if (isel == CB_ERR) isel = dt_dayofweek;
break;
}
case IDD_HOUR: {
data = tm.tm_hour;
cprintStd(hctrl,data);
if (isel == CB_ERR) isel = dt_hour;
break;
}
case IDD_MINUTE: {
data = tm.tm_min;
cprintStd(hctrl,data);
if (isel == CB_ERR) isel = dt_minute;
break;
}
}
if (isel == CB_ERR) isel = 0;
SendMessage(hctrl,CB_SETCURSEL,isel,0);
}
insertdateFlush(hwnd);
}
BOOL dlgprocDate(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message) {
case WM_INITDIALOG: {
dateFlush(hwnd);
break;
}
case WM_COMMAND: {
HDIALOG hd = dialogFromHwnd(hwnd);
int id = WM_COMMAND_GetId(wParam);
int notify = WM_COMMAND_GetNotify(wParam,lParam);
if (notify == CBN_SELCHANGE) {
if (IDD_YEAR <= id && id < IDD_YEAR + ITEM_N) {
insertdateFlush(hwnd);
}
}
if (id == IDOK) {
dateFlush(hwnd); //現在の時刻にセット
//
HWND hctrl = GetDlgItem(hwnd,IDD_FORMAT);
int isel = SendMessage(hctrl,LB_GETCURSEL,0,0);
dt_format = isel;
mchar buff[CCHWORD];
SendMessage(hctrl,LB_GETTEXT,isel,(LPARAM)buff);
txInsert(text,buff);
//
int i;
for (i = 0;i < ITEM_N;i++) {
int id = IDD_YEAR + i;
HWND hctrl = GetDlgItem(hwnd,id);
int isel = SendMessage(hctrl,CB_GETCURSEL,0,0);
switch(id) {
case IDD_YEAR: dt_year = isel;break;
case IDD_MONTH: dt_month = isel;break;
case IDD_DAY: dt_day = isel;break;
case IDD_DAYOFWEEK: dt_dayofweek = isel;break;
case IDD_HOUR: dt_hour = isel;break;
case IDD_MINUTE: dt_minute = isel;break;
}
}
} else if (id == IDD_DATEINC) {
dateFlush(hwnd);
}
break;
}
}
return FALSE;
}
BOOL TXCMDBASE uiInsertDate(TX* text)
{
// 日付・時刻の挿入
HDIALOG hd = dialog("日付・時刻の挿入");
dialogSetHookEx(hd,"\m.dlgprocDate");
DTRECT r;
dialogSetH(hd);
dialogSetGroupBottom(hd,DTCY * 15);
dialogGroup(hd,"挿入する日付・時刻(&I)");
dialogGetPos(hd,&r);
r.cx = DTCX * 28;
r.cy = DTCY * 12;
__dialogAddItem(hd,"LISTBOX",NULL,IDD_FORMAT,&r,LBS_NOTIFY|WS_BORDER|WS_VSCROLL|WS_HSCROLL|WS_CHILD|WS_VISIBLE|WS_TABSTOP);
dialogGroupEnd(hd);
dialogGroup(hd,"詳細");
int i;
for (i = 0;i < ITEM_N;i++) {
mchar* tsz[] = {
"年(&Y):",
"月(&M):",
"日(&D):",
"曜日(&W):",
"時(&H):",
"分(&N):",
};
dialogCaption(hd,tsz[i]);
dialogSetPosLX(hd,10);
dialogGetPos(hd,&r);
r.cx = DTCX * 14;
r.cy = DTCY * 7;
__dialogAddItem(hd,"COMBOBOX",NULL,IDD_YEAR + i,&r,CBS_AUTOHSCROLL|CBS_DROPDOWNLIST|WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP|WS_GROUP);
dialogLF(hd);
dialogSetPosY(hd,r.y + DTCY * 2);
}
dialogGroupEnd(hd);
dialogLF(hd);
int n = 0;
dialogControlID(hd,IDD_DATEINC);
dialogInt(hd,"日付の増減(&A):",&n,20,6);
dialogOpen(hd);
return TRUE;
}
//##文字列の補完
//1.99B HIST_STRも補完辞書として活用するようにした
//2.96A 970214 HIST_COMPLETEに学習するようにした
static mchar _szCompleteHist[] = "HIST_COMPLETE";
#define SIZE_COMPLETEHIST 1024
#define IFIND_HIST_LAST 24999
#define IFIND_END_HISTCOMPLETE 24999
#define IFIND_TOP_HISTCOMPLETE 20000
#define IFIND_END_HISTSTR 19999
#define IFIND_TOP_HISTSTR 15000
#define IFIND_END_HISTSEARCH 14999
#define IFIND_TOP_HISTSEARCH 10000
#define IFIND_HIST_TOP 10000
#define IFIND_NONE -1
static int _completeSearchHist(HHIST h,int ifind,BOOL fPrev,mchar* szdst,mchar* szstr)
{
int top;
int end;
HSTRBLK sb;
if (h == HIST_STR) {
top = IFIND_TOP_HISTSTR;
end = IFIND_END_HISTSTR;
sb = sbFromHist(h);
} else if (h == HIST_SEARCH) {
top = IFIND_TOP_HISTSEARCH;
end = IFIND_END_HISTSEARCH;
sb = sbFromHist(h);
} else {
top = IFIND_TOP_HISTCOMPLETE;
end = IFIND_END_HISTCOMPLETE;
sb = h;
}
//
if (ifind == end) {
ifind = sbGetCount(sb);
} else {
ifind -= top;
}
//
if (fPrev) {
ifind = sbiSearchNext(sb,szstr,ifind);
} else {
ifind = sbiSearchPrev(sb,szstr,ifind);
}
//
if (ifind == -1) {
if (fPrev) {
ifind = IFIND_NONE;
} else {
ifind = 0;
}
} else {
strcpymax(szdst,sbRead(sb,ifind),CCHWORD);
ifind += top;
}
return ifind;
}
static int completeSearchHist(int ifind,BOOL fPrev,mchar* szdst,mchar* szstr,HSTRBLK sbComplete)
{
#if 1//2.96A 970214
if (IFIND_TOP_HISTCOMPLETE <= ifind && ifind <= IFIND_END_HISTCOMPLETE) {
ifind = _completeSearchHist(sbComplete,ifind,fPrev,szdst,szstr);
if (ifind != 0) return ifind;
ifind = IFIND_END_HISTSTR;
}
if (IFIND_TOP_HISTSTR <= ifind && ifind <= IFIND_END_HISTSTR) {
ifind = _completeSearchHist(HIST_STR,ifind,fPrev,szdst,szstr);
if (ifind != 0) return ifind;
ifind = IFIND_END_HISTSEARCH;
}
return _completeSearchHist(HIST_SEARCH,ifind,fPrev,szdst,szstr);
#else
if (IFIND_TOP_HISTSTR <= ifind && ifind <= IFIND_END_HISTSTR) {
ifind = _completeSearchHist(HIST_STR,ifind,fPrev,szdst,szstr);
if (ifind == 0) {
return _completeSearchHist(HIST_SEARCH,IFIND_END_HISTSEARCH,fPrev,szdst,szstr);
}
return ifind;
} else {
return _completeSearchHist(HIST_SEARCH,ifind,fPrev,szdst,szstr);
}
#endif
}
static int _completeSearch(mchar szdst[CCHWORD],mchar* szstr,int ifind,BOOL fPrev,HSTRBLK sbComplete)
{
szdst[0] = 0;
if (ifind == IFIND_NONE) {
} else if (ifind >= IFIND_HIST_TOP) {
ifind = completeSearchHist(ifind,fPrev,szdst,szstr,sbComplete);
} else {
tx _txcomplete;
tx *text = &_txcomplete;
mchar szfilename[CCHPATHNAME];
pathFullConfig(szfilename,"complete.dic");
if (txInit(text,szfilename)) {
if (fPrev) {
txJumpPara(text,ifind);
} else {
txJumpPara(text,ifind + 1);
}
if (
szstr[0] && //2.99D 970402 新規作成で開いた直後、文字列の補完を行うとハングした
txSearchEx(text,szstr,(fPrev ? SEARCH_PREV : SEARCH_CUR)|SEARCH_NOSENSECASE|SEARCH_NOSENSEZENHAN|SEARCH_PARATOP)
) {
txstr sz;
txGetLine(text,sz);
ifind = text->npara;
strcpymax(szdst,sz,CCHWORD);
} else {
if (fPrev) {
ifind = IFIND_HIST_TOP;
} else {
ifind = IFIND_NONE;
}
}
} else {
if (fPrev) {
ifind = IFIND_HIST_TOP;
} else {
ifind = IFIND_NONE;
}
}
txClose(text);
}
return ifind;
}
static int completeSearch(mchar szdst[CCHWORD],mchar* szstr,int i,BOOL fPrev,HSTRBLK sbComplete)
{
while(1) {
i = _completeSearch(szdst,szstr,i,fPrev,sbComplete);
if (i == IFIND_NONE) return i;
if (szdst[0]) return i;
}
}
static BOOL _complate(tx* text,BOOL fPrev,HSTRBLK sbComplete)
{
static txstr _szstr; // 前回検索をかけた文字列
static int _ifind; // 前回検索をかけたインデックス
static IFILE _adr = -1; // 前回検索をかけたアドレス
static int _lchInsert; // 前回挿入したバイト数
static BOOL _fPrev = -1; // 前回の方向
static mchar szbuff[CCHWORD];// 前回挿入した文字列
BOOL ret = FALSE;
txstr szstr;
IFILE adr = txGetAddress(text);
if (adr == _adr) {
if (_ifind == -1) {
if (_fPrev == fPrev) {
return FALSE;
} else {
if (fPrev) {
_ifind = IFIND_HIST_TOP - 1;
} else {
_ifind = IFIND_HIST_LAST;
}
}
}
} else {
if (szbuff[0]) sbAddHist(sbComplete,szbuff); //2.96A 970214 学習
txSelectEx(text,CLIP_CHAR);
txLeft(text);
txJumpWordTopMi(text);
txGetWord(text,szstr);
txSelectQuit(text);
//1.99A 補完できないときにカーソルが単語の先頭に飛んだ
txRightBytes(text,strlen(szstr));
//
_szstr = szstr;
_ifind = IFIND_HIST_LAST;
_lchInsert = 0;
}
{
int i = completeSearch(szbuff,_szstr,_ifind,fPrev,sbComplete);
if (i >= 0) {
_ifind = i;
if (_lchInsert) {
txLeftBytes(text,_lchInsert);
txDeleteBytes(text,_lchInsert);
} else {
int lchOld = strlen(_szstr);
txLeftBytes(text,lchOld);//1.99A
txDeleteBytes(text,lchOld);
}
_lchInsert = strlen(szbuff);
txInsert(text,szbuff);
ret = TRUE;
} else {
_ifind = -1;
}
}
_adr = txGetAddress(text);
_fPrev = fPrev;
return ret;
}
static BOOL complate(tx* text,BOOL fPrev)
{
HSTRBLK sb = historyOpen(_szCompleteHist,SIZE_COMPLETEHIST);
BOOL ret;
text->fUndispSelect++;
text->fUndispCursor++;
ret = _complate(text,fPrev,sb);
text->fUndispSelect--;
text->fUndispCursor--;
txDispCursor(text);
txDispLocate(text);
historyClose(_szCompleteHist,sb);
return ret;
}
//2.00B MS/VZキーに割り当て
BOOL TXCMDBASE completePrev(TX* text)
{
// 文字列補完の前候補
// 補完した文字列を前候補に戻します。
//2.99A 970321 {#MS} +^J -> {#MS} +^J +^{F4}
//{#MS} +^J +^{F4}
//{#VZ} +^{Tab}
//{#EMACS} +^{Tab}
return complate(text,TRUE);
}
//2.99A 970321 {#MS} ^J -> {#MS} ^J +{F4}
//2.99G 970405 ^{F4} -> +^{F3} (^{F4}はキー割り当てできないため)
//2.00B MS/VZキーに割り当て
BOOL TXCMDBASE completeNext(TX* text)
{
// 文字列の補完実行(次候補)
// 英単語を途中まで入力した後実行すると、カーソルの直前単語を補完
// して完成させます。
//{#MS} ^J +{F4}
//{#VZ} ^{Tab}
//{#EMACS} ^{Tab}
return complate(text,FALSE);
}
static BOOL completeAddDic(mchar* szstr)
{
if (szstr[0] == 0) return FALSE;
BOOL ret = FALSE;
TX _txcomplete;
TX* text = &_txcomplete;
mchar szfilename[CCHPATHNAME];
pathFullConfig(szfilename,"complete.dic");
if (txInit(text,szfilename)) {
BOOL f = FALSE;
while(1) {
if (txSearchEx(text,szstr,SEARCH_CUR|SEARCH_NOSENSECASE|SEARCH_NOSENSEZENHAN|SEARCH_PARATOP)) {
txstr sz;
txGetLine(text,sz);
if (!stricmp(sz,szstr)) {
f = TRUE;
informationex("%sは既に登録されています",szstr);
break;
}
if (!txNextPara(text)) break;
} else {
break;
}
}
if (!f) {
txJumpFileTop(text);
txInsert(text,szstr);
txInsertReturn(text);
txSave(text);
informationex("%sを登録しました",szstr);
ret = TRUE;
}
}
txClose(text);
return ret;
}
BOOL TXCMDBASE completeAdd(TX* text)
{
// 文字列補完辞書への単語登録...
// 検索文字列ヒストリーに記憶した単語はいずれ消えてしまいます。
// 恒久的に使用する単語は辞書ファイルに登録してください。
HDIALOG hd = dialog("文字列補完辞書への登録");
BOOL ret = FALSE;
txstr szstr;
dialogControlHist(hd,HIST_SEARCH);
txGetWord(text,szstr);//2.92 completeAddでtxGetWordするようにした
dialogStr(hd,"登録する文字列(&S):",szstr,20,30);
if (dialogOpen(hd)) {
ret = completeAddDic(szstr);
}
return ret;
}
//##入力支援
//3.00B1 970522 入力支援:テキストファイルを指定して、そのファイルを辞書として使って入力支援できるようにした
#include <windowsx.h>
#define HIST_COMPLETE HIST_USER2
#define IDD_TOP_PREV 100
#define IDD_TOP_NEXT 101
#define IDD_END_PREV 102
#define IDD_END_NEXT 103
#define IDD_TARGET 104
//#define IDD_LIST 105
#define IDD_LISTCAPTION 106
#define IDD_TEXT 107
#define IDD_TEXTPARA 108 // 109も使用
#define IDD_HISTSEARCH 110
#define IDD_GUIDE 111
#define IDD_WRING 112
#define IDD_ADDDIC 113
#define IDD_LIST_PREVIEW 114
#define IDD_SELECT 115
#define IDD_REFERTEXTFILE 116
#define IDD_ALL 117
permanent BOOL _fSearchText = TRUE;
permanent BOOL _fSearchHistSearch = TRUE;
permanent BOOL _fSearchTextPara = FALSE;
permanent BOOL _fCompleteWring = TRUE;
permanent txstr p_szCompleteFile;//3.00B1 970522
static mchar _szCompleteFileHist[] = "HIST_COMPLETE_FILE";//3.00B1 970522
#define IDTIMER_COMPLETE 100
typedef struct {
HSTRBLK sb;
BOOL fEdit;
BOOL fCanceled;//3.00B1 970522
TX* text;
NPARA npara;
mchar szTarget[CCHWORD];
} COMPLETECONTEXT;
static void myPostMessage(HWND hwnd,int message,WPARAM wParam,LPARAM lParam)
{
MSG msg;
if (PeekMessage(&msg,hwnd,message,message,PM_NOREMOVE)) {
// 既にポストされている場合は、ポストしない
} else {
PostMessage(hwnd,message,wParam,lParam);
}
}
static void FlushTarget(HWND hwnd)
{
txstr szWord;
txGetWord(text,szWord);
SetDlgItemText(hwnd,IDD_TARGET,szWord);
}
static void FlushSelect(TX* text,BOOL fLeft)
{
if (txFlushSelectNow(text)) {
if (text->clipendnow <= text->cliptopnow) {
if (fLeft) return;
txSelectJump(text);
}
if (!fLeft) return;
txSelectJump(text);
}
}
static BOOL txSearchParaComplete(TX* text,mchar* szFind)
{
// szFindと完全に一致する行をtextが含んでいるかどうか返す
txJumpFileTop(text);
while(1) {
int ret;
if (ret = txSearchEx(text,szFind,SEARCH_CUR|SEARCH_PARATOP)) {
txRightBytes(text,ret - 1);
if (txIsCurReturn(text)) return TRUE;
} else {
return FALSE;
}
}
}
static int SearchTextDic(TX* textDst,TX* text,mchar* szTarget,SEARCHMODE mode,BOOL fReferFile)
{
txstr szPara;
if (txSearchEx(text,szTarget,SEARCH_NOSENSECASE|mode)) {
if (_fSearchTextPara) {
txGetPara(text,szPara);
// 行頭のスペースを削除
mchar*p = szPara;
while(1) {
if (isspace(*p)) {
p++;
} else if (*p == '/' && p[1] == '/') {
p += 2;
} else {
break;
}
}
if (fReferFile) txInsertChar(textDst,'f');//3.00B1 970522 p_szCompleteFileからのデータであることを示す
txInsertf(textDst,"%5d:",text->npara);//2.98 970309
txInsertLine(textDst,p);
return TRUE;
} else {
int lch = strlen(szTarget);
IFILE adr = txGetAddress(text);
txJumpWordTopMi(text);
txSelectEx(text,CLIP_CHAR);
txJumpWordEndMi(text);
txGetWord(text,szPara);
txJumpAddress(text,adr);
if (_fCompleteWring && strnicmp(szPara,szTarget,lch)) {
// 絞り込みの場合で、単語頭が一致しない場合
} else {
if (!txSearchParaComplete(textDst,szPara)) {
txJumpFileEnd(textDst);
txInsertLine(textDst,szPara);
return TRUE;
}
}
}
return FALSE;
}
return -1;
}
static void GetTextDic(COMPLETECONTEXT* context,TX* text,HWND hwnd,TX* text0,txstr szTarget,BOOL fReferFile)
{
BOOL fSelect = text->fClip;
txFlushSelectNow(text);
IFILE cliptopnow = text->cliptopnow;
IFILE adr = txGetAddress(text);
int n = 0;
int ly = text->ly;
txSetUndisp(text);
if (!_fSearchTextPara) {
// 単語取得の場合は、2つ、カーソル位置の近くで補完をする
SearchTextDic(text0,text,szTarget,SEARCH_PREV,fReferFile);
SearchTextDic(text0,text,szTarget,SEARCH_PREV,fReferFile);
SearchTextDic(text0,text,szTarget,SEARCH_PREV,fReferFile);
}
txJumpFileTop(text);
{
while(1) {
int ret = SearchTextDic(text0,text,szTarget,0,fReferFile);
if (GetAsyncKeyState(VK_ESCAPE) < 0) {//3.00B1 970522 入力支援:検索に時間がかかるときは{Esc}で中止できるようにした
SetDlgItemText(hwnd,IDD_GUIDE,"(中止しました)");
context->fCanceled = TRUE;
break;
}
if (ret == TRUE) {
n++;
if (n > 20) {
//あまり多いときは途中でやめないと遅い
SetDlgItemText(hwnd,IDD_GUIDE,"(マッチ数が多いので省略しました)");
break;
}
} else if (ret == -1) {
break;
}
}
}
if (fSelect) {
txJumpAddress(text,cliptopnow);
txSetLy(text,ly);
txSelectEx(text,CLIP_CHAR);
text->fClipMouse = TRUE;
} else {
txSelectQuit(text);
txJumpAddress(text,adr);
txSetLy(text,ly);
}
txSetDispEx(text);
}
static void makeCompleteFormText(TX* textDst,TX* text,mchar* szTarget)
{
SEARCHMODE mode = _fCompleteWring ? SEARCH_PARATOP : 0;
txstr sz;
while(1) {
if (txSearchEx(text,szTarget,mode|SEARCH_NOSENSECASE|SEARCH_CUR)) {
txGetPara(text,sz);
if (!txSearchParaComplete(textDst,sz)) {
txJumpFileEnd(textDst);
txInsertLine(textDst,sz);
}
txNextPara(text);
} else {
break;
}
}
}
static void makeCompleteFormStrblk(TX* textDst,HSTRBLK sb,mchar* szTarget)
{
sbSetSenseCase(sb,FALSE);
int n = sbGetCount(sb);
for (;n--;) {
mchar* sz = sbRead(sb,n);
mchar* p;
if (p = stristr(sz,szTarget)) {
if (_fCompleteWring && p != sz) {
} else {
if (!txSearchParaComplete(textDst,sz)) {
txJumpFileEnd(textDst);
txInsertLine(textDst,sz);
}
}
}
}
}
static BOOL uiCompleteAddDic(mchar* _szStr)
{
HDIALOG hd = dialog("文字列補完辞書への登録");
BOOL ret = FALSE;
txstr szStr = _szStr;
dialogStr(hd,"登録する文字列(&S):",szStr,20,30);
if (dialogOpen(hd)) {
ret = completeAddDic(szStr);
}
return ret;
}
BOOL dlgprocComplete(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDIALOG hd = dialogFromHwnd(hwnd);
COMPLETECONTEXT* context = (LPVOID)dialogGetCustdata(hd);
switch(message) {
case WM_INITDIALOG: {
myPostMessage(hwnd,WM_TXUSER,0,0);
// フォーカス順序をリストボックスをテキストボックスの直後にする
SetWindowPos(GetDlgItem(hwnd,IDD_LISTCAPTION),GetDlgItem(hwnd,IDD_TARGET),0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
SetWindowPos(GetDlgItem(hwnd,IDD_LIST),GetDlgItem(hwnd,IDD_LISTCAPTION),0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
//
HWND hctrl = GetDlgItem(hwnd,IDD_LIST_PREVIEW);
TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
if (text) {
text->fScrollBarH = TRUE;
text->fScrollBarV = TRUE;
text->fDispLine = FALSE;
text->dlgcode = DLGC_WANTARROWS;
text->fNoCursor = TRUE;
txFlush(text);
}
break;
}
case WM_COMMAND: {
int id = WM_COMMAND_GetId(wParam);
int notify = WM_COMMAND_GetNotify(wParam,lParam);
if (id == IDD_LIST) {
if (notify == LBN_DBLCLK) {//2.98 970309
PostMessage(hwnd,WM_COMMAND,IDOK,0);
return FALSE;
} else if (notify == LBN_SELCHANGE) {
HWND hctrl = GetDlgItem(hwnd,IDD_LIST);
int isel = ListBox_GetCurSel(hctrl);
if (isel >= 0) {
txstr sz(ListBox_GetTextLen(hctrl,isel)+1);
if (sz) {
ListBox_GetText(hctrl,isel,sz);
//
HWND hctrl = GetDlgItem(hwnd,IDD_LIST_PREVIEW);
TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
if (text) {
txSetUndisp(text);
txDeleteText(text);
if (_fSearchTextPara) {
TX* textTarget = context->text;
mchar*p = strGetWordTop(sz);
if (*p == 'f') {//3.00B1 970522 p_szCompleteFileからのデータ
p += strGetWordLen(p);
p = strGetWordTop(p);
NPARA npara = atoi(p);
TX* text = textopen(p_szCompleteFile);
if (text) {
txJumpNpara(text,npara);
txGetPara(text,sz);
}
textclose(text);
} else {
NPARA npara = atoi(p);
textTarget->fNoCursor++;
txSetUndispEx(textTarget);
txJumpNpara(textTarget,npara);
txGetPara(textTarget,sz);
}
txInsert(text,sz);
txSetDispEx(textTarget);
textTarget->fNoCursor--;
//
txJumpFileTop(text);
txSearchEx(text,context->szTarget,SEARCH_CUR|SEARCH_SELECT|SEARCH_NOSENSECASE);
txJumpWordTop(text);
txSelectEx(text,CLIP_CHAR);
txJumpWordEnd(text);
} else {
txInsert(text,sz);
}
txSetDisp(text);
}
}
}
}
}
switch(id) {
case IDCANCEL: {//3.00B1 970522
if (context->fCanceled) {
context->fCanceled = FALSE;
return TRUE;
}
break;
}
case IDOK: {
HWND hctrl = GetDlgItem(hwnd,IDD_LIST);
int isel = ListBox_GetCurSel(hctrl);
if (isel >= 0) {
txstr sz(ListBox_GetTextLen(hctrl,isel)+1);
if (sz) {
ListBox_GetText(hctrl,isel,sz);
if (!context->fEdit) {
// 補完文字列が変化してなければ...
txSelectDelete(text);
}
if (_fSearchTextPara) {//2.98 970309
HWND hctrl = GetDlgItem(hwnd,IDD_LIST_PREVIEW);
TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
if (text) {
TX* textTarget = context->text;
if (text->fClip) {
txPrivatePush(text);
txPrivatePaste(textTarget);
txPrivateDeleteTop(text);
} else {
txInsertText(textTarget,text);
}
}
} else {
txInsert(text,sz);
// 補完ヒストリに追加
sbAddHist(context->sb,sz);
}
}
}
break;
}
case IDD_TARGET: {
if (notify == EN_UPDATE) {
context->fEdit = TRUE;
SetTimer(hwnd,IDTIMER_COMPLETE,500,NULL);
}
break;
}
#if 1//2.98 970309
case IDD_TOP_PREV: {
HWND hctrl = GetDlgItem(hwnd,IDD_LIST_PREVIEW);
TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
if (text) {
FlushSelect(text,TRUE);
txLeftWordMi(text);
}
break;
}
case IDD_TOP_NEXT: {
HWND hctrl = GetDlgItem(hwnd,IDD_LIST_PREVIEW);
TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
if (text) {
FlushSelect(text,TRUE);
txRightWordMi(text);
}
break;
}
case IDD_END_PREV: {
HWND hctrl = GetDlgItem(hwnd,IDD_LIST_PREVIEW);
TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
if (text) {
FlushSelect(text,FALSE);
txLeftWordMi(text);
}
break;
}
case IDD_END_NEXT: {
HWND hctrl = GetDlgItem(hwnd,IDD_LIST_PREVIEW);
TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
if (text) {
FlushSelect(text,FALSE);
txRightWordMi(text);
}
break;
}
case IDD_ALL: {//3.00B1 970522
HWND hctrl = GetDlgItem(hwnd,IDD_LIST_PREVIEW);
TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
if (text) txSelectAll(text);
break;
}
#else
case IDD_TOP_PREV: {
FlushSelect(text,TRUE);
txLeft(text);
FlushTarget(hwnd);
myPostMessage(hwnd,WM_TXUSER,id,0);
break;
}
case IDD_TOP_NEXT: {
FlushSelect(text,TRUE);
txRight(text);
FlushTarget(hwnd);
myPostMessage(hwnd,WM_TXUSER,id,0);
break;
}
case IDD_END_PREV: {
FlushSelect(text,FALSE);
txLeft(text);
FlushTarget(hwnd);
myPostMessage(hwnd,WM_TXUSER,id,0);
break;
}
case IDD_END_NEXT: {
FlushSelect(text,FALSE);
txRight(text);
FlushTarget(hwnd);
myPostMessage(hwnd,WM_TXUSER,id,0);
break;
}
#endif
case IDD_REFERTEXTFILE: {//3.00B1 970522
if (notify == EN_CHANGE) {
myPostMessage(hwnd,WM_TXUSER,id,0);
}
break;
}
case IDD_WRING:
case IDD_TEXT:
case IDD_TEXTPARA:
case IDD_TEXTPARA+1:
case IDD_HISTSEARCH: {
myPostMessage(hwnd,WM_TXUSER,id,0);
break;
}
case IDD_JUMP: {//2.98 970310
HWND hctrl = GetDlgItem(hwnd,IDD_LIST);
int isel = ListBox_GetCurSel(hctrl);
if (isel >= 0) {
txstr sz(ListBox_GetTextLen(hctrl,isel)+1);
if (sz) {
ListBox_GetText(hctrl,isel,sz);
txSetUndisp(text);
txSelectQuit(text);
txJumpNpara(text,atoi(strGetWordTop(sz)));
txSetDisp(text);
return FALSE;
}
}
return TRUE;
}
case IDD_ADDDIC: {
HWND hctrl = GetDlgItem(hwnd,IDD_LIST);
int isel = ListBox_GetCurSel(hctrl);
if (isel >= 0) {
txstr sz(ListBox_GetTextLen(hctrl,isel)+1);
if (sz) {
ListBox_GetText(hctrl,isel,sz);
uiCompleteAddDic(sz);
}
} else {
mchar buff[CCHWORD];
GetDlgItemText(hwnd,IDD_TARGET,buff,cchof(buff));
uiCompleteAddDic(buff);
}
return TRUE;
}
}
return FALSE;
}
case WM_DESTROY: {
KillTimer(hwnd,IDTIMER_COMPLETE);
break;
}
case WM_TIMER: {
KillTimer(hwnd,IDTIMER_COMPLETE);
myPostMessage(hwnd,WM_TXUSER,IDD_TARGET,0);
break;
}
case WM_TXUSER: {
if (wParam == 0) {
// 初めのダイアログデータのセットによるEDITBOXのダーティー処理は無効化
context->fEdit = FALSE;
KillTimer(hwnd,IDTIMER_COMPLETE);
}
// WM_COMMANDが残っている場合は処理しない。高速化
MSG msg;
if (PeekMessage(&msg,hwnd,WM_COMMAND,WM_COMMAND,PM_NOREMOVE)) {
myPostMessage(hwnd,WM_TXUSER,wParam,0);
return FALSE;
}
//
dialogRead(hd);
//2.98 970309
EnableWindow(GetDlgItem(hwnd,IDD_TEXTPARA),(_fSearchText||p_szCompleteFile[0]));
EnableWindow(GetDlgItem(hwnd,IDD_HISTSEARCH),!_fSearchTextPara);
EnableWindow(GetDlgItem(hwnd,IDD_WRING),!_fSearchTextPara);
EnableWindow(GetDlgItem(hwnd,IDD_TOP_PREV),_fSearchTextPara);
EnableWindow(GetDlgItem(hwnd,IDD_TOP_NEXT),_fSearchTextPara);
EnableWindow(GetDlgItem(hwnd,IDD_END_PREV),_fSearchTextPara);
EnableWindow(GetDlgItem(hwnd,IDD_END_NEXT),_fSearchTextPara);
EnableWindow(GetDlgItem(hwnd,IDD_JUMP),_fSearchTextPara && _fSearchTextPara);
//
switch(wParam) {
case IDD_LIST: break;
default: {
TX _text0;
TX* text0 = &_text0;
if (txInit(text0,NULL)) {
txstr szTarget;
GetDlgItemText(hwnd,IDD_TARGET,szTarget,cchtxstr(szTarget));
{// タブ等は除く
mchar* dst = szTarget;
mchar* src = szTarget;
while(1) {
mchar c = *src++;
if (c == 0) break;
if (iskanji(c) && *src) {
*dst++ = c;
*dst++ = *src++;
} else if (c > ' ') {
*dst++ = c;
}
}
*dst = 0;
}
sstrcpy(context->szTarget,szTarget);
if (szTarget[0]) {
SetDlgItemText(hwnd,IDD_GUIDE,"");
if (!_fSearchTextPara) {
// [1]補完ヒストリから検索
makeCompleteFormStrblk(text0,context->sb,szTarget);
// [2]キーワードから検索
if (text->txKeyword) {
makeCompleteFormText(text0,text->txKeyword,szTarget);
}
// [3]complete.dicから検索
{
mchar szfilename[CCHPATHNAME];
pathFullConfig(szfilename,"complete.dic");
TX _txcomplete;
TX* text = &_txcomplete;
if (txInit(text,szfilename)) {
makeCompleteFormText(text0,text,szTarget);
txClose(text);
}
}
// [4]検索ヒストリから検索
if (_fSearchHistSearch) {
makeCompleteFormStrblk(text0,sbFromHist(HIST_SEARCH),szTarget);
}
}
// [5]テキストから検索
if (_fSearchText) {
GetTextDic(context,context->text,hwnd,text0,szTarget,FALSE);
}
if (p_szCompleteFile[0]) {//3.00B1 970522
TX* text = textopen(p_szCompleteFile);
if (text) {
GetTextDic(context,text,hwnd,text0,szTarget,TRUE);
}
textclose(text);
}
}
listboxFromText(GetDlgItem(hwnd,IDD_LIST),text0);
txClose(text0);
//
HWND hctrl = GetDlgItem(hwnd,IDD_LIST);
int isel = ListBox_GetCurSel(hctrl);
if (isel < 0) ListBox_SetCurSel(hctrl,0);
FORWARD_WM_COMMAND(hwnd,IDD_LIST,NULL,LBN_SELCHANGE,SendMessage);//2.98 970309
if (wParam != IDD_TARGET && szTarget[0]) {
SetFocus(hctrl);
}
}
break;
}
}
break;
}
}
return FALSE;
}
BOOL TXCMDBASE uiComplete(TX* text)
{
// 入力支援
//2.95 970131 新コマンド
//2.99A 970321 MS:F4割り当て
//{#MS} {F4}
HSTRBLK sb = historyOpen(_szCompleteHist,SIZE_COMPLETEHIST);
HSTRBLK sbFile = historyOpen(_szCompleteFileHist,2048);//3.00B1 970522
if (!sb) return FALSE;
COMPLETECONTEXT context;
structClear(context);
context.sb = sb;
context.text = text;
//
txstr szTarget;
if (text->fClip) {
txGetWord(text,szTarget);
text->fClipMouse = TRUE;
} else {
if (!txIsCurParaTop(text)) {
txSelectEx(text,CLIP_CHAR);
text->fClipMouse = TRUE;
txLeftWordMi(text);
txGetWord(text,szTarget);
}
}
if (szTarget[0] <= ' ') {
// 空白や改行なら、補完対象文字列はなしとする
szTarget[0] = 0;
context.fEdit = TRUE;
txSelectQuit(text);
}
HDIALOG hd = dialog("入力支援");
dialogSetHookEx(hd,"\m.dlgprocComplete");
dialogSetCustdata(hd,(DWORD)&context);
int lxg = 16;
int lx = 20;
dialogControlID(hd,IDD_TARGET);
dialogControlHelp(hd,406);
dialogStr(hd,"補完対象(&S):",szTarget,lxg,lx);
#if 0 // 要らん
dialogSetH(hd);
dialogSetPosLX(hd,lxg + 1);
dialogControlID(hd,IDD_TOP_PREV);
dialogButton(hd,"&<",NULL,2);
dialogControlID(hd,IDD_TOP_NEXT);
dialogButton(hd,"&>",NULL,2);
dialogSetPosLX(hd,lxg + lx - 8);
dialogControlID(hd,IDD_END_PREV);
dialogButton(hd,"< &B",NULL,4);
dialogControlID(hd,IDD_END_NEXT);
dialogButton(hd,"> &N",NULL,4);
dialogSetV(hd);
dialogLF(hd);
#endif
dialogControlID(hd,IDD_LISTCAPTION);
dialogCaptionDynamic(hd,"補完候補(&I):",20);
dialogControlID(hd,IDD_LIST);
dialogList(hd,NULL,NULL,40,_fwin40 ? 13 : 10);//2.99C 970326 WZ32で小さかった
dialogControlID(hd,IDD_GUIDE);
dialogCaptionDynamic(hd,NULL,40);
DTRECT rCmd;
dialogLFV(hd);
dialogGetPos(hd,&rCmd);
dialogLF(hd);
#if 1//2.98 970309
DTRECT r;
dialogGetPos(hd,&r);
r.cx = DTCX * 60;
r.cy = DTCY * 4;
__dialogAddItem(hd,TXWS_SZCLASS,"",IDD_LIST_PREVIEW,&r,TXWS_TEXT|TXWS_OPENTEXT|WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL|WS_HSCROLL);
r.y += r.cy + DTCYINT;
dialogSetPos(hd,&r);
dialogSetH(hd);
dialogControlID(hd,IDD_TOP_PREV);
dialogButton(hd,"&<",NULL,10);
dialogControlID(hd,IDD_TOP_NEXT);
dialogButton(hd,"> &K",NULL,10);
//3.00B1 970522
dialogIndent(hd,3);
dialogControlID(hd,IDD_ALL);
dialogButton(hd,"全て(&A)",NULL,10);
//
dialogSetPosLX(hd,60 - 21);
dialogControlID(hd,IDD_END_PREV);
dialogButton(hd,"< &L",NULL,10);
dialogControlID(hd,IDD_END_NEXT);
dialogButton(hd,"&>",NULL,10);
dialogSetV(hd);
#else
dialogControlID(hd,IDD_LIST_PREVIEW);
dialogControlStyle(hd,WS_GROUP|ES_MULTILINE|ES_WANTRETURN|ES_AUTOVSCROLL|ES_AUTOHSCROLL|WS_HSCROLL|WS_VSCROLL);
dialogEdit(hd,NULL,NULL,60,4);
dialogControlStyle(hd,0);
#endif
//3.00B1 970522
dialogLF(hd);
dialogSpaceV(hd);
dialogControlHist(hd,sbFile);
dialogControlRefer(hd,"-a");
dialogControlHelp(hd,511);
dialogControlID(hd,IDD_REFERTEXTFILE);
dialogStr(hd,"参照テキストファイル(&F):",p_szCompleteFile,17,33);
//
dialogLFV(hd);
dialogSetPos(hd,&rCmd);
dialogOK(hd,19);
dialogCancel(hd,19);
dialogSpaceV(hd);
//2.96 970201
dialogControlID(hd,IDD_ADDDIC);
dialogControlHelp(hd,407);
dialogCmd(hd,"辞書に追加(&D)...",19);//2.98 970309 UI化
dialogControlID(hd,IDD_JUMP);
dialogCmd(hd,"ジャンプ(&J)",19);//2.98 970310
dialogSpaceV(hd);
dialogControlID(hd,IDD_TEXT);
dialogControlHelp(hd,408);
dialogCheck(hd,"テキストも検索(&T)",&_fSearchText);
//2.98 970309 入力支援:「段落の取得」復活
// 常用はしないけど、さっき入力したところをもう一度という無計画なとこが、
// 元の入力支援のいいとこだったと思うんです(kitamakuraさん)。
dialogIndent(hd,2);
dialogControlRadioV(hd);
dialogControlID(hd,IDD_TEXTPARA);
dialogControlHelp(hd,411);
dialogCheck(hd,"段落取得(&P)",&_fSearchTextPara);
dialogIndent(hd,-2);
dialogControlID(hd,IDD_HISTSEARCH);
dialogControlHelp(hd,409);
dialogCheck(hd,"検索ヒストリも検索(&H)",&_fSearchHistSearch);
dialogControlID(hd,IDD_WRING);
dialogControlHelp(hd,410);
dialogCheck(hd,"絞り込み(&R)",&_fCompleteWring);
dialogOpen(hd);
historyClose(_szCompleteFileHist,sbFile);
historyClose(_szCompleteHist,sb);
}
//##慣用句挿入
#include <windows.h>
#include "dialog.h"
#include "outline.h"
#define IDD_ADD 101
#define IDD_EDIT 102
#define IDD_EDITBOX 103
//2.92
#define IDD_ADDCATEGORY 104
#define IDD_COPY 105
#define IDD_PASTE 106
//#define IDD_DEL 104
//3.00B1 970612
#define IDD_INSERTTAB 110
permanent int tmpl_isel = 0;
BOOL TXAPI txConvertDic(TX* text)
{
// .dicの形式をWZ2.0->WZ3.0へ自動変換
txJumpFileTop(text);
txstr szline;
txGetPara(text,szline);
if (szline[0] == '[') {
// WZ2.0形式
txInsertLine(text,"%sWZ2.0",text->tsztitle[0]);
while(1) {
txGetPara(text,szline);
int lch = strlen(szline);
if (szline[0] == '[' && szline[lch - 1] == ']') {
txDeleteChar(text);
txInsert(text,text->tsztitle[1]);
txJumpParaEnd(text);
txDeletePrev(text);
}
if (!txNextPara(text)) break;
}
txSave(text);
return TRUE;
}
return FALSE;
}
static void txSaveTemplate(TX* text)
{
// del EOF
txJumpFileEnd(text);
txPrevPara(text);
txDeletePara(text);
//
txSave(text);
}
BOOL dlgprocTemplateEdit(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
//3.00B1 970612 new
switch(message) {
case WM_COMMAND: {
int id = WM_COMMAND_GetId(wParam);
if (id == IDD_INSERTTAB) {
SendDlgItemMessage(hwnd,IDD_EDITBOX,EM_REPLACESEL,0,"\t");
return TRUE;
}
break;
}
}
return FALSE;
}
BOOL dlgprocTemplate(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message) {
case WM_INITDIALOG: {
EnableWindow(GetDlgItem(hwnd,IDD_PASTE),FALSE);
break;
}
case WM_COMMAND: {
int id = WM_COMMAND_GetId(wParam);
int notify = WM_COMMAND_GetNotify(wParam,lParam);
TX* text = outlineGetTx(hwnd);
long cur = outlineGetCursel(hwnd);
switch(id) {
case IDOK: {
if (text->fEdit) {
txSaveTemplate(text);
}
tmpl_isel = cur;
break;
}
case IDCANCEL: {
if (text->fEdit) {
int q = question("編集内容を保存しますか?");
if (q == IDYES) {
txSaveTemplate(text);
} else if (q == IDCANCEL) {
return TRUE;
}
}
break;
}
case IDD_COPY: {//2.92
outlineCopy(hwnd);
EnableWindow(GetDlgItem(hwnd,IDD_PASTE),TRUE);
break;
}
case IDD_PASTE: {//2.92
txPaste(text);
outlineFlush(hwnd);
outlineSetCursel(hwnd,cur);
break;
}
case IDD_ADD:
case IDD_ADDCATEGORY:
case IDD_EDIT: {
BOOL fEdit = (id == IDD_EDIT);
HEADLINE hl;
outlineGetCurheadline(hwnd,&hl);
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("慣用句の追加");
}
}
//
txstr szstr = hl.szstr;
if (fCategory) {
dialogStr(hd,"グループ名(&C):",szstr,12,20);
if (dialogOpen(hd) && szstr != "") {
if (hl.npara == 0) {
txJumpFileTop(text);
} else {
txJumpPara(text,hl.npara);
}
//
if (fCategory && fEdit) {
txDeletePara(text);
}
txInsertLine(text,"%s%s",text->tsztitle[0+!fCategory],szstr);
}
} else {
dialogStr(hd,"慣用句(&T):",szstr,12,20);
//
TX body;
tx* work = &body;
txInitText(work);
txOpenText(work);
if (fEdit) {
int fClip = clipGetKind(HCLIP_WIN); //★ymikome
int len = memClipPaste(NULL, HCLIP_WIN); //★ymikome
txstr szclip(len); //★ymikome
memClipPaste((mchar*)szclip, HCLIP_WIN); //★ymikome
outlineCopy(hwnd);
txPaste(work);
txJumpFileTop(work);
txDeletePara(work);
memClipCopy((mchar*)szclip, len, HCLIP_WIN, fClip); //★ymikome
} else if (id == IDD_ADD && textf->fClip) {
//2.97A 970228 テンプレート:選択中の時は内容を取り込む様にした。
txPrivatePush(textf);
txPrivatePaste(work);
txPrivateDeleteTop(work);
}
dialogControlID(hd,IDD_EDITBOX);
dialogEdit(hd,"内容(&C):",work,30,12);
if (fEdit) {//3.00B1 970612 慣用句の挿入:タブを挿入できるようにした
dialogCmdLFV(hd);
dialogOK(hd,14);
dialogCancel(hd,14);
dialogSpaceV(hd);
//
dialogSetHookEx(hd,"\m.dlgprocTemplateEdit");
dialogControlID(hd,IDD_INSERTTAB);
dialogCmd(hd,"タブを挿入(&T)",14);
}
if (dialogOpen(hd) && szstr != "") {
if (fEdit) {
outlineClear(hwnd);
}
if (id == IDD_ADD) {
HEADLINE hl;
outlineGetHeadline(hwnd,&hl,cur+1);
if (hl.npara == 0) {
txJumpFileTop(text);
} else {
txJumpPara(text,hl.npara);
}
cur++;
} else {
if (hl.npara == 0) {
txJumpFileTop(text);
} else {
txJumpPara(text,hl.npara);
}
}
txInsertLine(text,"%s%s",text->tsztitle[1],szstr);
txSelectAll(work);
txSelectCopy(work);
txPaste(text);
// 最終行が改行で終っていない場合に対応
txInsertReturn(text);
txUp(text);
txstr szline;
if (txGetLine(text,szline) == 0) {
txDeletePara(text);
} else {
txDown(text);
}
}
txClose(work);
}
outlineFlush(hwnd);
outlineSetCursel(hwnd,cur);
return TRUE;
}
case IDD_DEL: {
long cur = outlineGetCursel(hwnd);
outlineClear(hwnd);
outlineFlush(hwnd);
outlineSetCursel(hwnd,cur);
return TRUE;
}
}
break;
}
case CON_SELCHANGED: {
long cur = outlineGetCursel(hwnd);
HEADLINE hl;
BOOL fEof = !outlineGetHeadline(hwnd,&hl,cur+1);
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,IDOK),!fEof);
break;
}
}
return FALSE;
}
static void templateExec(TX* text)
{
#if 1//2.92
txSetUndisp(text);
{
TX _text;
TX* work = &_text;
txInit(work,NULL);
{
txClipPaste(work,HCLIP_WIN,FALSE,0);
txNextPara(work);
//
txJumpParaTop(text);
txstr szlinetop;
TXCHAR ch = txGetChar(text);
if (ch == ' ' || ch == '\t' || ch == ' ') {
// インデント対応
txSelectEx(text,CLIP_CHAR);
txRightWordMi(text);
txGetWord(text,szlinetop);
txSelectQuit(text);
}
IFILE adr = TXRECORD_ERROR;
txstr szline;
for (BOOL fFirst = TRUE;;fFirst = FALSE) {
if (txIsCurEof(work)) break;
txGetPara(work,szline);
//
if (!fFirst) txInsert(text,szlinetop);
{
mchar* p;
if (p = strstr(szline,"<>")) {
adr = txGetAddress(text) + p - szline;
}
}
txInsert(text,szline);
txInsertReturn(text);
//
if (!txNextPara(work)) break;
}
if (adr != TXRECORD_ERROR) {
txJumpAddress(text,adr);
txDeleteChar(text);
txDeleteChar(text);
}
}
txClose(work);
}
txSetDisp(text);
#else
txSetUndisp(text);//1.99I ゴミが残った
{
BOOL f;
txInitText(text2);
txOpenText(text2);
txClipPaste(text2,HCLIP_WIN,FALSE,0);
f = txSearchEx(text2,"<>",SEARCH_CUR);
txClose(text2);
//
txJumpParaTop(text);
IFILE cbClip = txClipOp(text,TXCLIPOP_GETSIZE,HCLIP_WIN,0);
txClipPaste(text,HCLIP_WIN,FALSE,0);
IFILE cbDel = txGetParaTail(text) - txGetParaTop(text);
txDeletePara(text);
if (f) {
if (txSearchEx(text,"<>",SEARCH_CUR)) {
txDeleteChar(text);
txDeleteChar(text);
}
} else {
txRightBytes(text,cbClip - cbDel);
}
}
txSetDisp(text);//1.99I
#endif
}
//2.00B キー割り当て
BOOL TXCMDBASE uiInsertTemplate(TX* text)
{
// 慣用句の挿入
//{#MS} +^T
//{#VZ} +^T
//{#MI} +^T
//{#EMACS} +^T
TX _txtemplate;
TX *text = &_txtemplate;
txInitText(text);
mchar szfilename[CCHPATHNAME];
pathFullConfig(szfilename,"template.dic");
txSetFileName(text,szfilename);
txOpenText(text);
//2.00E2 設定がなくても正常に動作するように
strcpy(text->tsztitle[0],"..");
strcpy(text->tsztitle[1],"...");
strcpy(text->tsztitle[2],"");
//2.92
txConvertDic(text);
// add EOF
txJumpFileEnd(text);
txInsertLine(text,"%s(end)",text->tsztitle[0]);
text->fEdit = FALSE;
//
HDIALOG hd = dialog("慣用句の挿入");
DTRECT r;
dialogGetPos(hd,&r);
r.cx = DTCX * 40;
r.cy = DTCY * 12;
#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
dialogSetPos(hd,&r);
int x = r.x + r.cx + DTCX * 2;
r.y += r.cy + DTCY;
r.cx = DTCX * 40;
r.cy = DTCY * 4;
__dialogAddItem(hd,"LISTBOX",NULL,IDD_TITLEVIEW,&r,LBS_NOTIFY|WS_BORDER|WS_VSCROLL|WS_HSCROLL|WS_CHILD|WS_VISIBLE|WS_TABSTOP);
//
int cx = 17;
dialogLFV(hd);
dialogSetPosX(hd,x);
dialogOK(hd,cx);
dialogCancel(hd,cx);
dialogSpaceV(hd);
dialogControlID(hd,IDD_ADD);
dialogButtonCmd(hd,"追加(&A)...",NULL,cx);
dialogControlID(hd,IDD_ADDCATEGORY);
dialogButtonCmd(hd,"グループの追加(&B)...",NULL,cx);//2.92
dialogControlID(hd,IDD_EDIT);
dialogButtonCmd(hd,"修正(&E)...",NULL,cx);
dialogControlID(hd,IDD_DEL);
dialogButtonCmd(hd,"削除(&D)",NULL,cx);
//2.92
dialogSpaceV(hd);
dialogControlID(hd,IDD_COPY);
dialogButtonCmd(hd,"コピー(&C)",NULL,cx);
dialogControlID(hd,IDD_PASTE);
dialogButtonCmd(hd,"貼り付け(&P)",NULL,cx);
//
CHOOSEOUTLINE co;
memset(&co,0,sizeof(CHOOSEOUTLINE));
co.text = text;
co.szhook = "\m.dlgprocTemplate";
co.iselFirst = tmpl_isel;
co.fNoTitleHead = TRUE;
BOOL ret = FALSE;
if (dialogSelectTitle(hd,&co)) {
templateExec(textf);
ret = TRUE;
}
txClose(text);
return ret;
}
//##tssel
typedef struct {
HCLIP hclip;
int istack; // マイナス値は無効を表す
int editmode;
} TSSELPREVIEWCONTEXT;
BOOL dlgprocTsselPreview(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message) {
case WM_INITDIALOG: {
HDIALOG hd = dialogFromHwnd(hwnd);
TSSELPREVIEWCONTEXT* context = (LPVOID)dialogGetCustdata(hd);
HWND hctrl = GetDlgItem(hwnd,IDD_PREVIEW);
{
TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
txSetUndisp(text);
text->width = 80;
text->fScrollBarH = TRUE;
text->fScrollBarV = TRUE;
txSetEditmode(text,context->editmode);
txClipPasteEx(text,context->hclip,context->istack,0,FALSE,CLIP_CHAR);
txFlush(text);
txSetDisp(text);
}
break;
}
}
return FALSE;
}
BOOL dlgprocTssel(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HCLIP hclip = HCLIP_TS;
switch(message) {
case WM_INITDIALOG: {
HWND hwndList = GetDlgItem(hwnd,IDD_LIST);
int n = txClipOp(text,TXCLIPOP_GETCOUNT,hclip,0);
if (n) {
TX textBody;
TX* text = &textBody;
txInitText(text);
txOpenText(text);
txstr szline;
for (int i = 0;i < n;i++) {
txDeleteText(text);
txClipPasteEx(text,hclip,i,0,FALSE,CLIP_CHAR);
txGetLine(text,szline);
SendMessage(hwndList,LB_ADDSTRING,0,(LPARAM)(mchar*)szline);
}
txClose(text);
} else {
SendMessage(hwndList,LB_ADDSTRING,0,(LPARAM)"テキストスタックは空です");
EnableWindow(GetDlgItem(hwnd,IDD_INSERT),FALSE);
EnableWindow(GetDlgItem(hwnd,IDD_CONFIRM),FALSE);
#if 0
EnableWindow(GetDlgItem(hwnd,IDD_DEL),FALSE);
#endif
}
ListBox_SetCurSel(GetDlgItem(hwnd,IDD_LIST),0);
break;
}
case WM_COMMAND: {
HDIALOG hd = dialogFromHwnd(hwnd);
int id = WM_COMMAND_GetId(wParam);
int notify = WM_COMMAND_GetNotify(wParam,lParam);
TSSELPREVIEWCONTEXT context;
context.hclip = hclip;
context.istack = ListBox_GetCurSel(GetDlgItem(hwnd,IDD_LIST));
context.editmode = text->editmode;
if (context.istack == LB_ERR) context.istack = -1;
switch(id) {
case IDD_INSERT: {
if (context.istack >= 0) {
IFILE adr = txGetAddress(text);
txSetUndisp(text);
txClipPasteEx(text,hclip,context.istack,0,TRUE,CLIP_CHAR);
txSelect(text);
text->fClipMouse = TRUE;
txJumpAddress(text,adr);
txSetDisp(text);
}
return FALSE;
}
case IDD_CONFIRM: {
HDIALOG hd = dialog("挿入されるデータの確認");
dialogSetHookEx(hd,"\m.dlgprocTsselPreview");
dialogSetCustdata(hd,(DWORD)&context);
DTRECT r;
dialogGetPos(hd,&r);
r.cx = DTCX * 80;
r.cy = DTCY * 10;
__dialogAddItem(hd,TXWS_SZCLASS,"",IDD_PREVIEW,&r,TXWS_TEXT|TXWS_OPENTEXT|WS_VSCROLL|WS_BORDER|WS_CHILD|WS_VISIBLE);
dialogLFV(hd);
dialogClose(hd,10);
dialogOpen(hd);
return TRUE;
}
}
break;
}
}
return FALSE;
}
// CM.(千葉誠)氏作"tssel"に敬意を表し、
// コマンド名を同じにさせていただきました。96.3 TY。
BOOL TXCMDBASE tssel(TX* text)
{
// テキストスタックから選んでペースト
HDIALOG hd = dialog("テキストスタックから挿入");
dialogSetHookEx(hd,"\m.dlgprocTssel");
dialogControlID(hd,IDD_LIST);
_dialogList(hd,NULL,60,12);
int lcx = 16;
dialogLFV(hd);
dialogControlID(hd,IDD_INSERT);
dialogCmdDefault(hd,"本文へ挿入",lcx);
#if 0
dialogControlID(hd,IDD_DEL);
dialogCmd(hd,"削除(&D)",lcx);
#endif
dialogControlID(hd,IDD_CONFIRM);
dialogCmd(hd,"内容確認(&C)...",lcx);
dialogControlID(hd,IDCANCEL);
dialogCmd(hd,"閉じる",lcx);
dialogOpen(hd);
return TRUE;
}
//##文字の変換
//2.99C 970324 文字の変換、オートコレクト ダイアログ デザイン改良
#if 1
#define IDD_CLEAR 100
#define IDD_KATA 110
#define IDD_HIRA 120
#define IDD_ALPHABET 130
#define IDD_NUMBER 140
#define IDD_SPACE 150
#define IDD_KIGOU 160
#define IDD_BRACE 170
static void CheckRadioButtonFirst(HWND hwnd,int idd)
{
CheckRadioButton(hwnd,idd,idd+9,idd);
}
BOOL dlgprocConvertChar(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message) {
case WM_COMMAND: {
int id = WM_COMMAND_GetId(wParam);
int notify = WM_COMMAND_GetNotify(wParam,lParam);
switch(id) {
case IDD_CLEAR: {
CheckRadioButtonFirst(hwnd,IDD_KATA);
CheckRadioButtonFirst(hwnd,IDD_HIRA);
CheckRadioButtonFirst(hwnd,IDD_ALPHABET);
CheckRadioButtonFirst(hwnd,IDD_NUMBER);
CheckRadioButtonFirst(hwnd,IDD_SPACE);
CheckRadioButtonFirst(hwnd,IDD_KIGOU);
CheckDlgButton(hwnd,IDD_BRACE,FALSE);
return TRUE;
}
}
break;
}
}
return FALSE;
}
BOOL TXAPI txuiConvertChar(TX* text,CHARCONVERT* cc,BOOL fAc)
{
//2.95 970128 TXAPI化
HDIALOG hd;
if (fAc) {
hd = dialogbig("オートコレクト");
} else {
hd = dialogbig("文字の変換");
}
dialogSetHookEx(hd,"\m.dlgprocConvertChar");
dialogSetContexthelp(hd,TRUE);
BOOL fAutoCollect = cc->fAc;
BOOL fJbraceToBrace = cc->fJbraceToBrace;
int modeKata = cc->fJkataToKana + cc->fKanaToJkata * 2 + cc->fKanaToJhira * 3;
int modeHira = cc->fJhiraToKana;
int modeAlphabet = cc->fJalphabetToAnk + cc->fAlphabetToJank * 2;
int modeNumber = cc->fJnumberToAnk + cc->fNumberToJank * 2;
int modeSpace = cc->fJspaceToAnk + cc->fSpaceToJank * 2;
int modeKigou = cc->fJkigouToAnk + cc->fKigouToJank * 2;
dialogSetGroupRight(hd,DTCX * 65);
if (fAc) {
dialogGroup(hd,"オートコレクト");
dialogControlHelp(hd,-308);
dialogSwitch(hd,&fAutoCollect,"する(&A)","しない(&N)");
dialogGroupEnd(hd);
}
dialogGroup(hd,"文字の変換");
dialogSetH(hd);
int lxg = 12;
dialogCaptionDynamic(hd,"カタカナ(&K):",lxg);
dialogControlID(hd,IDD_KATA);
dialogRadioID(hd,&modeKata,"そのまま","半角へ","全角へ","ひらがなへ");
dialogLF(hd);
dialogCaptionDynamic(hd,"ひらがな(&H):",lxg);
dialogControlID(hd,IDD_HIRA);
dialogRadioID(hd,&modeHira,"そのまま","半角カタカナへ");
dialogLF(hd);
dialogCaptionDynamic(hd,"アルファベット(&L):",lxg);
dialogControlID(hd,IDD_ALPHABET);
dialogRadioID(hd,&modeAlphabet,"そのまま","半角へ","全角へ");
dialogLF(hd);
dialogCaptionDynamic(hd,"数字(&U):",lxg);
dialogControlID(hd,IDD_NUMBER);
dialogRadioID(hd,&modeNumber,"そのまま","半角へ","全角へ");
dialogLF(hd);
dialogCaptionDynamic(hd,"記号(&I):",lxg);
dialogControlID(hd,IDD_KIGOU);
dialogRadioID(hd,&modeKigou,"そのまま","半角へ","全角へ");
dialogLF(hd);
dialogCaptionDynamic(hd,"空白(&S):",lxg);
dialogControlID(hd,IDD_SPACE);
dialogRadioID(hd,&modeSpace,"そのまま","半角へ","全角へ");
dialogLF(hd);
dialogControlID(hd,IDD_BRACE);
dialogCheck(hd,"「」を[]へ(&B)",&fJbraceToBrace);
dialogLF(hd);
dialogSetV(hd);
dialogGroupEnd(hd);
dialogLFV(hd);
dialogOK(hd,12);
dialogCancel(hd,12);
dialogControlID(hd,IDD_CLEAR);
dialogCmd(hd,"クリア(&Z)",12);
if (dialogOpen(hd)) {
cc->fAc = fAutoCollect;
cc->fJbraceToBrace = fJbraceToBrace;
cc->fJkataToKana = (modeKata == 1);
cc->fKanaToJkata = (modeKata == 2);
cc->fKanaToJhira = (modeKata == 3);
cc->fJhiraToKana = modeHira;
cc->fJalphabetToAnk = (modeAlphabet == 1);
cc->fAlphabetToJank = (modeAlphabet == 2);
cc->fJnumberToAnk = (modeNumber == 1);
cc->fNumberToJank = (modeNumber == 2);
cc->fJspaceToAnk = (modeSpace == 1);
cc->fSpaceToJank = (modeSpace == 2);
cc->fJkigouToAnk = (modeKigou == 1);
cc->fKigouToJank = (modeKigou == 2);
return TRUE;
}
return FALSE;
}
#else
BOOL TXAPI txuiConvertChar(TX* text,CHARCONVERT* cc,BOOL fAc)
{
//2.95 970128 TXAPI化
HDIALOG hd;
if (fAc) {
hd = dialogbig("オートコレクト");
} else {
hd = dialogbig("文字の変換");
}
dialogSetContexthelp(hd,TRUE);
BOOL fJkataToKana = cc->fJkataToKana;
BOOL fJkanaToKana = cc->fJkanaToKana;
BOOL fJankToAnk = cc->fJankToAnk;
BOOL fJalphabetToAnk = cc->fJalphabetToAnk;
BOOL fJnumberToAnk = cc->fJnumberToAnk;
BOOL fJkigouToAnk = cc->fJkigouToAnk;
BOOL fJspaceToAnk = cc->fJspaceToAnk;
BOOL fKanaToJhira = cc->fKanaToJhira;
BOOL fKanaToJkata = cc->fKanaToJkata;
BOOL fAnkToJank = cc->fAnkToJank;
BOOL fAlphabetToJank = cc->fAlphabetToJank;
BOOL fNumberToJank = cc->fNumberToJank;
BOOL fKigouToJank = cc->fKigouToJank;
BOOL fSpaceToJank = cc->fSpaceToJank;
BOOL fJbraceToBrace = cc->fJbraceToBrace;
BOOL fAutoCollect = cc->fAc;
dialogSetGroupRight(hd,DTCX * 40);
if (fAc) {
dialogGroup(hd,"オートコレクト");
dialogControlHelp(hd,-308);
dialogSwitch(hd,&fAutoCollect,"する(&A)","しない(&N)");
dialogGroupEnd(hd);
}
dialogGroup(hd,"半角文字に変換");
int id = 310 + fAc;
dialogControlHelp(hd,id);
dialogCheck(hd,"カタカナ(&K)",&fJkataToKana);
dialogControlHelp(hd,id);
dialogCheck(hd,"ひらがなとカタカナ(&H)",&fJkanaToKana);
dialogControlHelp(hd,id);
dialogCheck(hd,"アルファベット(&L)",&fJalphabetToAnk);
dialogControlHelp(hd,id);
dialogCheck(hd,"数字(&U)",&fJnumberToAnk);
dialogControlHelp(hd,id);
dialogCheck(hd,"記号(&I)",&fJkigouToAnk);
dialogControlHelp(hd,id);
dialogCheck(hd,"空白(&S)",&fJspaceToAnk);
dialogControlHelp(hd,id);
dialogCheck(hd,"「」を[]へ(&B)",&fJbraceToBrace);
dialogGroupEnd(hd);
dialogGroup(hd,"全角文字に変換");
int id = 312 + fAc;
dialogControlHelp(hd,id);
dialogCheck(hd,"カタカナ(&1)",&fKanaToJkata);
dialogControlHelp(hd,id);
dialogCheck(hd,"カタカナをひらがなへ(&2)",&fKanaToJhira);
dialogControlHelp(hd,id);
dialogCheck(hd,"アルファベット(&3)",&fAlphabetToJank);
dialogControlHelp(hd,id);
dialogCheck(hd,"数字(&4)",&fNumberToJank);
dialogControlHelp(hd,id);
dialogCheck(hd,"記号(&5)",&fKigouToJank);
dialogControlHelp(hd,id);
dialogCheck(hd,"空白(&6)",&fSpaceToJank);
dialogGroupEnd(hd);
if (dialogOpen(hd)) {
cc->fAc = fAutoCollect;
cc->fJkataToKana = fJkataToKana;
cc->fJkanaToKana = fJkanaToKana;
cc->fJankToAnk = fJankToAnk;
cc->fJalphabetToAnk = fJalphabetToAnk;
cc->fJnumberToAnk = fJnumberToAnk;
cc->fJkigouToAnk = fJkigouToAnk;
cc->fJspaceToAnk = fJspaceToAnk;
cc->fKanaToJhira = fKanaToJhira;
cc->fKanaToJkata = fKanaToJkata;
cc->fAnkToJank = fAnkToJank;
cc->fAlphabetToJank = fAlphabetToJank;
cc->fNumberToJank = fNumberToJank;
cc->fKigouToJank = fKigouToJank;
cc->fSpaceToJank = fSpaceToJank;
cc->fJbraceToBrace = fJbraceToBrace;
return TRUE;
}
return FALSE;
}
#endif
// 123abc## あああ漢字アアア
// 123abc## アアア漢字
// "、'、“”、‘’
//2.99C 970324 半角文字と全角文字の変換 改良
permanent DWORD _cc;
BOOL TXCMDBASE uiConvertChar(TX* text)
{
// 半角文字と全角文字の変換
//2.00Cで追加
CHARCONVERT cc = *(CHARCONVERT*)&_cc;
if (txuiConvertChar(text,&cc,FALSE)) {
_cc = structToDWORD(cc);
txCharConvert(text,&cc);
return TRUE;
}
return FALSE;
}
BOOL TXCMDBASE uiAutocorrectConfig(TX* text)
{
// オートコレクトの設定を行います。
//2.00Bで追加
//2.00Cでコマンド名変更
if (txuiConvertChar(text,&text->charconvert,TRUE)) {
return TRUE;
}
return FALSE;
}
//##漢字コード変換
//2.00D
extern "tx" BOOL kcToSJIS(tx* text,int kc);
BOOL TXAPI TXCMD txFromEUC(TX* text)
{
// テキストをEUCコードとみなして、Shift-JISに変換
//2.00Dで追加
return kcToSJIS(text,KC_EUC);
}
BOOL TXAPI TXCMD txFromJIS(TX* text)
{
// テキストをJISコードとみなして、Shift-JISに変換
//2.00Dで追加
return kcToSJIS(text,KC_JIS);
}
BOOL TXAPI TXCMDBASE txuiFromEUC(TX* text)
{
// テキストをEUCコードとみなして、Shift-JISに変換
// 変換後に保存する文字コードもEUCにするか確認ダイアログを出す
//2.99A 970321 new
if (kcToSJIS(text,KC_EUC)) {
int ret = question("保存時の文字コードをEUCにしますか?");
if (ret == IDYES) {
text->kcSave = KC_EUC;
}
return TRUE;
}
return FALSE;
}
BOOL TXAPI TXCMDBASE txuiFromJIS(TX* text)
{
// テキストをJISコードとみなして、Shift-JISに変換
// 変換後に保存する文字コードもJISにするか確認ダイアログを出す
//2.99A 970321 new
if (kcToSJIS(text,KC_JIS)) {
int ret = question("保存時の文字コードをJISにしますか?");
if (ret == IDYES) {
text->kcSave = KC_JIS;
}
return TRUE;
}
return FALSE;
}
//2.90
BOOL txClipCopyAll(TX* text)
{
//information("%d",txGetTextSize(text));
txClipCopy(text,0,txGetTextSize(text),HCLIP_WIN,CLIP_CHAR);
return TRUE;
}
void txAdjustZenHanSpace(TX* text,BOOL fSet)
{
// fSet=TRUE : 全角文字と半角文字の間に空白を一つあけます。
// fSet=FALSE: 全角文字と半角文字の間の空白を削除します。
// 範囲選択されているときは範囲内、されていないときはテキスト全体で処理
if (text->fClip) {
txWalkStart(text);
} else {
txMarkCur(text);
txSetUndisp(text);
txJumpFileTop(text);
}
if (fSet) {
while(1) {
mchar* p = text->buff + text->cur;
mchar c = *p;
if (text->fClip && !txIsWalking(text)) break;
if (isalnum(c)) {
// 次の文字が漢字なら空白を挿入
if (!txRight(text)) break;
p = text->buff + text->cur;
if (iskanji(*p)) {
txInsertChar(text,' ');
}
} else if (iskanji(c)) {
TXCHAR ch = txGetChar(text);
if (strchr("。。.?・!」)…",ch)) {
//3.00A4 970509 英数字と全角文字の間に空白を空ける: 句読点と半角文字の間にも空白が入った
if (!txRight(text)) break;
} else {
// 次の文字がalnumなら空白を挿入
if (!txRight(text)) break;
p = text->buff + text->cur;
if (isalnum(*p)) {
txInsertChar(text,' ');
}
}
} else {
if (!txRight(text)) break;
}
}
} else {
while(1) {
mchar* p = text->buff + text->cur;
mchar c = *p;
if (text->fClip && !txIsWalking(text)) break;
if (isalnum(c)) {
// 次の文字が空白+漢字なら空白を削除
if (!txRight(text)) break;
p = text->buff + text->cur;
if (*p == ' ' && iskanji(p[1])) {
txDeleteChar(text);
}
} else if (iskanji(c)) {
// 次の文字が空白+alnumなら空白を削除
if (!txRight(text)) break;
p = text->buff + text->cur;
if (*p == ' ' && isalnum(p[1])) {
txDeleteChar(text);
}
} else {
if (!txRight(text)) break;
}
}
}
if (text->fClip) {
txWalkEnd(text);
} else {
txJumpMarkCur(text);
txSetDisp(text);
}
}
BOOL TXAPI TXCMDBASE txSetZenHanSpace(TX* text)
{
// 英数字と全角文字の間に空白を空ける
// 範囲選択されているときは範囲内、されてないときはテキスト全体が対象
//2.98 970309 new「編集|変換|...」
//3.00A2 970507 TXAPI化
txAdjustZenHanSpace(text,TRUE);
return TRUE;
}
BOOL TXAPI TXCMDBASE txClearZenHanSpace(TX* text)
{
// 英数字と全角文字の間の空白を削除
// 範囲選択されているときは範囲内、されてないときはテキスト全体が対象
//2.98 970309 new「編集|変換|...」
//3.00A2 970507 TXAPI化
txAdjustZenHanSpace(text,FALSE);
return TRUE;
}
//3.00B1 970610 罫線の変換が逆だった
static mchar _szNEC[] = "「」コカヨルスレケンイョホム、ニヌゼソ瘋オメアユ・ハヘツ艷ナ";
static mchar _szJIS[] = "─━┘└┴┷┛┸┗┻┐┌┬┯│┤┥├┼┝┿┓┰┏┳┃┨┫┠╂┣╋";
BOOL TXAPI TXCMD txConvertKeisenNecToJis(TX* text)
{
// ファイル内のNEC罫線をJISに変換
txSetUndispEx(text);
txJumpFileTop(text);
txSetHigh(text);
while(1) {
if (text->buff[text->cur] == 0x86) {//3.00C 971013 84->86 「罫線の変換」バグ対処
TXCHAR ch = txGetChar(text);
mchar* p;
if (p = strchr(_szNEC,ch)) {
txDeleteChar(text);
p = _szJIS + (p - _szNEC);
txInsertChar(text,MAKEWORD(p[1],*p));
}
} else {
if (!txRight(text)) break;
}
}
txJumpFileTop(text);
txResetHigh(text);
txSetDispEx(text);
return TRUE;
}
BOOL TXAPI TXCMD txConvertKeisenJisToNec(TX* text)
{
// ファイル内のJIS罫線をNECに変換
txSetUndispEx(text);
txJumpFileTop(text);
txSetHigh(text);
while(1) {
if (text->buff[text->cur] == 0x84) {//3.00C 971013 86->84 「罫線の変換」バグ対処
TXCHAR ch = txGetChar(text);
mchar* p;
if (p = strchr(_szJIS,ch)) {
txDeleteChar(text);
p = _szNEC + (p - _szJIS);
txInsertChar(text,MAKEWORD(p[1],*p));
}
} else {
if (!txRight(text)) break;
}
}
txJumpFileTop(text);
txResetHigh(text);
txSetDispEx(text);
return TRUE;
}
permanent int modeConvertKeisen;
BOOL TXCMDBASE uiConvertKeisen(TX* text)
{
// 罫線の変換
//2.99D 970329 new
HDIALOG hd = dialog("罫線の変換");
dialogControlRadioV(hd);
dialogRadioID(hd,&modeConvertKeisen,
"JIS罫線をNEC罫線に変換(&N)",
"NEC罫線をJIS罫線に変換(&J)"
);
if (dialogOpen(hd)) {
switch(modeConvertKeisen) {
case 0:return txConvertKeisenJisToNec(text);
case 1:return txConvertKeisenNecToJis(text);
}
}
return FALSE;
}