📄 ceditview_command_new.cpp
字号:
// $Id: CEditView_Command_New.cpp,v 1.43 2005/01/29 10:21:27 Administrator Exp $
/*! @file
@brief CEditViewクラスのコマンド処理系関数群
@author Norio Nakatani
$Revision: 1.43 $
*/
/*
Copyright (C) 1998-2001, Norio Nakatani
Copyright (C) 2001, genta, asa-o, hor
Copyright (C) 2002, YAZAKI, hor, genta. aroka, MIK
Copyright (C) 2003, MIK
This source code is designed for sakura editor.
Please contact the copyright holder to use this code for other purpose.
*/
#include "CEditView.h"
#include "CWaitCursor.h"
#include "charcode.h"
#include "CRunningTimer.h"
#include <algorithm> // 2001.12.11 hor for VC++
#include "COpe.h" /// 2002/2/3 aroka from here
#include "COpeBlk.h" ///
#include "CLayout.h"///
#include "CDocLine.h"///
#include "mymessage.h"///
#include "debug.h"///
#include "etc_uty.h"///
#include <string>///
#include <vector> /// 2002/2/3 aroka to here
#include "COsVersionInfo.h" // 2002.04.09 minfu
#include "CEditDoc.h" // 2002/5/13 YAZAKI ヘッダ整理
#include "CEditWnd.h"
#include "CDlgCtrlCode.h" //コントロールコードの入力(ダイアログ)
#include "CDlgFavorite.h" //お気に入り //@@@ 2003.04.08 MIK
using namespace std; // 2002/2/3 aroka to here
#ifndef FID_RECONVERT_VERSION // 2002.04.10 minfu
#define FID_RECONVERT_VERSION 0x10000000
#endif
/*! 現在位置にデータを挿入 Ver0
@date 2002/03/24 YAZAKI bUndo削除
*/
void CEditView::InsertData_CEditView(
int nX,
int nY,
const char* pData,
int nDataLen,
int* pnNewLine, /* 挿入された部分の次の位置の行 */
int* pnNewPos, /* 挿入された部分の次の位置のデータ位置 */
COpe* pcOpe, /* 編集操作要素 COpe */
BOOL bRedraw
// BOOL bUndo /* Undo操作かどうか */
)
{
#ifdef _DEBUG
gm_ProfileOutput = 1;
MY_RUNNINGTIMER( cRunningTimer, "CEditView::InsertData_CEditView" );
#endif
const char* pLine;
int nLineLen;
const char* pLine2;
int nLineLen2;
int nIdxFrom;
int nModifyLayoutLinesOld;
int nInsLineNum; /* 挿入によって増えたレイアウト行の数 */
PAINTSTRUCT ps;
HDC hdc;
int nLineAllColLen;
CMemory cMem;
int i;
const CLayout* pcLayout;
*pnNewLine = 0; /* 挿入された部分の次の位置の行 */
*pnNewPos = 0; /* 挿入された部分の次の位置のデータ位置 */
/* テキストが選択されているか */
if( IsTextSelected() ){
DeleteData( bRedraw );
nX = m_nCaretPosX;
nY = m_nCaretPosY;
}
pLine = m_pcEditDoc->m_cLayoutMgr.GetLineStr( nY, &nLineLen, &pcLayout );
nIdxFrom = 0;
// cMem.SetData( "", lstrlen( "" ) );
cMem.SetDataSz( "" );
if( NULL != pLine ){
/* 指定された桁に対応する行のデータ内の位置を調べる */
nIdxFrom = LineColmnToIndex2( pcLayout, nX, nLineAllColLen );
/* 行終端より右に挿入しようとした */
if( nLineAllColLen > 0 ){
/* 終端直前から挿入位置まで空白を埋める為の処理 */
/* 行終端が何らかの改行コードか? */
if( EOL_NONE != pcLayout->m_cEol ){
nIdxFrom = nLineLen - 1;
for( i = 0; i < nX - nLineAllColLen + 1; ++i ){
cMem += ' ';
}
cMem.Append( pData, nDataLen );
}else{
nIdxFrom = nLineLen;
for( i = 0; i < nX - nLineAllColLen; ++i ){
cMem += ' ';
}
cMem.Append( pData, nDataLen );
}
}else{
cMem.Append( pData, nDataLen );
}
}else{
nLineAllColLen = nX;
for( i = 0; i < nX - nIdxFrom; ++i ){
cMem += ' ';
}
cMem.Append( pData, nDataLen );
}
// MYTRACE( "nY=%d nIdxFrom=%d nLineAllColLen=%d \n", nY, nIdxFrom, nLineAllColLen );
if( !m_bDoing_UndoRedo && NULL != pcOpe ){ /* アンドゥ?リドゥの実行中か */
if( NULL != pLine ){
m_pcEditDoc->m_cLayoutMgr.CaretPos_Log2Phys(
LineIndexToColmn( pcLayout, nIdxFrom ),
nY,
&pcOpe->m_nCaretPosX_PHY_Before,
&pcOpe->m_nCaretPosY_PHY_Before
);
}else{
m_pcEditDoc->m_cLayoutMgr.CaretPos_Log2Phys(
0,
nY,
&pcOpe->m_nCaretPosX_PHY_Before,
&pcOpe->m_nCaretPosY_PHY_Before
);
}
}
/* 文字列挿入 */
m_pcEditDoc->m_cLayoutMgr.InsertData_CLayoutMgr(
nY,
nIdxFrom,
cMem.GetPtr(),
cMem.GetLength(),
&nModifyLayoutLinesOld,
&nInsLineNum,
pnNewLine, /* 挿入された部分の次の位置の行 */
pnNewPos, /* 挿入された部分の次の位置のデータ位置 */
m_pcEditDoc->GetDocumentAttribute().m_ColorInfoArr[COLORIDX_SSTRING].m_bDisp, /* シングルクォーテーション文字列を表示する */
m_pcEditDoc->GetDocumentAttribute().m_ColorInfoArr[COLORIDX_WSTRING].m_bDisp /* ダブルクォーテーション文字列を表示する */
);
/* メモリが再確保されてアドレスが無効になるので、再度、行データを求める */
pLine = m_pcEditDoc->m_cLayoutMgr.GetLineStr( nY, &nLineLen );
/* 指定された行のデータ内の位置に対応する桁の位置を調べる */
pLine2 = m_pcEditDoc->m_cLayoutMgr.GetLineStr( *pnNewLine, &nLineLen2, &pcLayout );
if( pLine2 != NULL ){
*pnNewPos = LineIndexToColmn( pcLayout, *pnNewPos );
}
if( *pnNewPos >= m_pcEditDoc->GetDocumentAttribute().m_nMaxLineSize ){
if( m_pcEditDoc->GetDocumentAttribute().m_bKinsokuRet
|| m_pcEditDoc->GetDocumentAttribute().m_bKinsokuKuto ) //@@@ 2002.04.16 MIK
{
if( m_pcEditDoc->m_cLayoutMgr.IsEndOfLine( *pnNewLine, *pnNewPos ) ) //@@@ 2002.04.18
{
*pnNewPos = 0;
(*pnNewLine)++;
}
}
else
{
// Oct. 7, 2002 YAZAKI
*pnNewPos = pcLayout->m_pNext ? pcLayout->m_pNext->GetIndent() : 0;
(*pnNewLine)++;
}
}
// MYTRACE( "nModifyLayoutLinesOld=%d nInsLineNum=%d *pnNewLine=%d *pnNewPos=%d\n", nModifyLayoutLinesOld, nInsLineNum, *pnNewLine, *pnNewPos );
/* 状態遷移 */
if( FALSE == m_bDoing_UndoRedo ){ /* アンドゥ?リドゥの実行中か */
m_pcEditDoc->SetModified(true,bRedraw); // Jan. 22, 2002 genta
}
/* 再描画 */
/* 行番号表示に必要な幅を設定 */
if( m_pcEditDoc->DetectWidthOfLineNumberAreaAllPane( bRedraw ) ){
/* キャレットの表示?更新 */
ShowEditCaret();
}else{
if( bRedraw ){
if( 0 < nInsLineNum ){
/* スクロールバーの状態を更新する */
AdjustScrollBars();
ps.rcPaint.left = 0;
ps.rcPaint.right = m_nViewAlignLeft + m_nViewCx;
ps.rcPaint.top = m_nViewAlignTop + (m_nCharHeight + m_pcEditDoc->GetDocumentAttribute().m_nLineSpace) * (nY - m_nViewTopLine);
ps.rcPaint.bottom = m_nViewAlignTop + m_nViewCy;
}else{
if( nModifyLayoutLinesOld < 1 ){
nModifyLayoutLinesOld = 1;
}
// ps.rcPaint.left = m_nViewAlignLeft;
ps.rcPaint.left = 0;
ps.rcPaint.right = m_nViewAlignLeft + m_nViewCx;
// 2002.02.25 Mod By KK 次行 (nY - m_nViewTopLine - 1); => (nY - m_nViewTopLine);
//ps.rcPaint.top = m_nViewAlignTop + (m_nCharHeight + m_pcEditDoc->GetDocumentAttribute().m_nLineSpace) * (nY - m_nViewTopLine - 1);
ps.rcPaint.top = m_nViewAlignTop + (m_nCharHeight + m_pcEditDoc->GetDocumentAttribute().m_nLineSpace) * (nY - m_nViewTopLine);
//禁則がある場合は1行前から再描画を行う @@@ 2002.04.19 MIK
if( m_pcEditDoc->GetDocumentAttribute().m_bWordWrap
|| m_pcEditDoc->GetDocumentAttribute().m_bKinsokuHead //@@@ 2002.04.19 MIK
|| m_pcEditDoc->GetDocumentAttribute().m_bKinsokuTail //@@@ 2002.04.19 MIK
|| m_pcEditDoc->GetDocumentAttribute().m_bKinsokuRet //@@@ 2002.04.19 MIK
|| m_pcEditDoc->GetDocumentAttribute().m_bKinsokuKuto ) //@@@ 2002.04.19 MIK
{
ps.rcPaint.top -= (m_nCharHeight + m_pcEditDoc->GetDocumentAttribute().m_nLineSpace);
}
if( ps.rcPaint.top < 0 ){
ps.rcPaint.top = 0;
}
ps.rcPaint.bottom = ps.rcPaint.top + (m_nCharHeight + m_pcEditDoc->GetDocumentAttribute().m_nLineSpace) * ( nModifyLayoutLinesOld + 1);
if( m_nViewAlignTop + m_nViewCy < ps.rcPaint.bottom ){
ps.rcPaint.bottom = m_nViewAlignTop + m_nViewCy;
}
}
hdc = ::GetDC( m_hWnd );
// OnKillFocus();
OnPaint( hdc, &ps, TRUE ); /* メモリDCを使用してちらつきのない再描画 */
// OnSetFocus();
::ReleaseDC( m_hWnd, hdc );
}
}
if( !m_bDoing_UndoRedo && NULL != pcOpe ){ /* アンドゥ?リドゥの実行中か */
pcOpe->m_nOpe = OPE_INSERT; /* 操作種別 */
m_pcEditDoc->m_cLayoutMgr.CaretPos_Log2Phys(
*pnNewPos,
*pnNewLine,
&pcOpe->m_nCaretPosX_PHY_To,
&pcOpe->m_nCaretPosY_PHY_To
);
pcOpe->m_nDataLen = cMem.GetLength(); /* 操作に関連するデータのサイズ */
pcOpe->m_pcmemData = NULL; /* 操作に関連するデータ */
}
#ifdef _DEBUG
gm_ProfileOutput = 0;
#endif
return;
}
/*! 指定位置の指定長データ削除
@date 2002/03/24 YAZAKI bUndo削除
@date 2002/05/12 YAZAKI bRedraw, bRedraw2削除(常にFALSEだから)
*/
void CEditView::DeleteData2(
int nCaretX,
int nCaretY,
int nDelLen,
CMemory* pcMem,
COpe* pcOpe /* 編集操作要素 COpe */
)
{
#ifdef _DEBUG
gm_ProfileOutput = 1;
MY_RUNNINGTIMER( cRunningTimer, "CEditView::DeleteData(1)" );
#endif
const char* pLine;
int nLineLen;
int nIdxFrom;
int nModifyLayoutLinesOld;
int nModifyLayoutLinesNew;
int nDeleteLayoutLines;
int bLastLine;
/* 最後の行にカーソルがあるかどうか */
if( nCaretY == m_pcEditDoc->m_cLayoutMgr.GetLineCount() - 1 ){
bLastLine = 1;
}else{
bLastLine = 0;
}
const CLayout* pcLayout;
pLine = m_pcEditDoc->m_cLayoutMgr.GetLineStr( nCaretY, &nLineLen, &pcLayout );
if( NULL == pLine ){
goto end_of_func;
}
nIdxFrom = LineColmnToIndex( pcLayout, nCaretX );
if( !m_bDoing_UndoRedo && NULL != pcOpe ){ /* アンドゥ?リドゥの実行中か */
pcOpe->m_nOpe = OPE_DELETE; /* 操作種別 */
// pcOpe->m_nCaretPosX_To = LineIndexToColmn( pLine, nLineLen, nIdxFrom + nDelLen );/* 操作前のキャレット位置X */
// pcOpe->m_nCaretPosY_To = nCaretY; /* 操作前のキャレット位置Y */
// m_pcEditDoc->m_cLayoutMgr.CaretPos_Log2Phys(
// pcOpe->m_nCaretPosX_To,
// pcOpe->m_nCaretPosY_To,
// &pcOpe->m_nCaretPosX_PHY_To,
// &pcOpe->m_nCaretPosY_PHY_To
// );
m_pcEditDoc->m_cLayoutMgr.CaretPos_Log2Phys(
LineIndexToColmn( pcLayout, nIdxFrom + nDelLen ),
nCaretY,
&pcOpe->m_nCaretPosX_PHY_To,
&pcOpe->m_nCaretPosY_PHY_To
);
}
/* データ削除 */
m_pcEditDoc->m_cLayoutMgr.DeleteData_CLayoutMgr(
nCaretY, nIdxFrom, nDelLen,
&nModifyLayoutLinesOld,
&nModifyLayoutLinesNew,
&nDeleteLayoutLines,
*pcMem,
m_pcEditDoc->GetDocumentAttribute().m_ColorInfoArr[COLORIDX_SSTRING].m_bDisp, /* シングルクォーテーション文字列を表示する */
m_pcEditDoc->GetDocumentAttribute().m_ColorInfoArr[COLORIDX_WSTRING].m_bDisp /* ダブルクォーテーション文字列を表示する */
);
if( !m_bDoing_UndoRedo && NULL != pcOpe ){ /* アンドゥ?リドゥの実行中か */
pcOpe->m_nDataLen = pcMem->GetLength(); /* 操作に関連するデータのサイズ */
pcOpe->m_pcmemData = pcMem; /* 操作に関連するデータ */
}
/* 選択エリアの先頭へカーソルを移動 */
MoveCursor( nCaretX, nCaretY, FALSE );
m_nCaretPosX_Prev = m_nCaretPosX;
end_of_func:;
#ifdef _DEBUG
gm_ProfileOutput = 0;
#endif
return;
}
/*! カーソル位置または選択エリアを削除
@date 2002/03/24 YAZAKI bUndo削除
*/
void CEditView::DeleteData(
BOOL bRedraw
// BOOL bUndo /* Undo操作かどうか */
)
{
#ifdef _DEBUG
gm_ProfileOutput = 1;
MY_RUNNINGTIMER( cRunningTimer, "CEditView::DeleteData(2)" );
#endif
const char* pLine;
int nLineLen;
const char* pLine2;
int nLineLen2;
int nLineNum;
int nCurIdx;
int nNxtIdx;
int nNxtPos;
PAINTSTRUCT ps;
HDC hdc;
int nIdxFrom;
int nIdxTo;
int nDelPos;
int nDelLen;
int nDelPosNext;
int nDelLenNext;
// CMemory cmemBuf;
RECT rcSel;
int bLastLine;
CMemory* pcMemDeleted;
COpe* pcOpe = NULL;
int nCaretPosXOld;
int nCaretPosYOld;
int i;
const CLayout* pcLayout;
int nSelectColmFrom_Old;
int nSelectLineFrom_Old;
// hor IsTextSelected内に移動
// CWaitCursor cWaitCursor( m_hWnd ); // 2002.01.25 hor
nCaretPosXOld = m_nCaretPosX;
nCaretPosYOld = m_nCaretPosY;
/* テキストが選択されているか */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -