📄 clayoutmgr.cpp
字号:
if( EOL_NONE == pCDocLine->m_cEol ){
pLayout->m_cEol.SetType( EOL_NONE );/* 改行コードの種類 */
}else{
if( pLayout->m_nOffset + pLayout->m_nLength >
pCDocLine->m_pLine->GetLength() - pCDocLine->m_cEol.GetLen()
){
pLayout->m_cEol = pCDocLine->m_cEol;/* 改行コードの種類 */
}else{
pLayout->m_cEol = EOL_NONE;/* 改行コードの種類 */
}
}
return pLayout;
}
/*
|| 指定された物理行のデータへのポインタとその長さを返す Ver0
@date 2002/2/10 aroka CMemory変更
*/
const char* CLayoutMgr::GetLineStr( int nLine, int* pnLineLen )
{
CLayout* pLayout;
if( NULL == ( pLayout = Search( nLine ) ) ){
return NULL;
}
*pnLineLen = pLayout->m_nLength;
return pLayout->m_pCDocLine->m_pLine->GetPtr() + pLayout->m_nOffset;
}
/*! 指定された物理行のデータへのポインタとその長さを返す Ver1
@date 2002/03/24 YAZAKI GetLineStr( int nLine, int* pnLineLen )と同じ動作に変更。
*/
const char* CLayoutMgr::GetLineStr( int nLine, int* pnLineLen, const CLayout** ppcLayoutDes )
{
#if 0
const CLayout* pLayout;
const char* pData;
int nDataLen;
if( NULL == ( pLayout = Search( nLine ) ) ){
*ppcLayoutDes = pLayout;
return NULL;
}
pData = m_pcDocLineMgr->GetLineStr( pLayout->m_nLinePhysical, &nDataLen );
*pnLineLen = pLayout->m_nLength;
*ppcLayoutDes = pLayout;
return pData + pLayout->m_nOffset;
#endif
if( NULL == ( (*ppcLayoutDes) = Search( nLine ) ) ){
return NULL;
}
*pnLineLen = (*ppcLayoutDes)->m_nLength;
return (*ppcLayoutDes)->m_pCDocLine->m_pLine->GetPtr() + (*ppcLayoutDes)->m_nOffset;
}
/*
|| 指定された位置がレイアウト行の途中の行末かどうか調べる
@date 2002/4/27 MIK
*/
bool CLayoutMgr::IsEndOfLine( int nLine, int nPos )
{
CLayout* pLayout;
if( NULL == ( pLayout = Search( nLine ) ) )
{
return false;
}
if( EOL_NONE == pLayout->m_cEol.GetType() )
{ /* この行に改行はない */
/* この行の最後か? */
if( nPos == pLayout->m_nLength ) return true;
}
return false;
}
/*! 行内文字削除
@date 2002/03/24 YAZAKI bUndo削除
*/
void CLayoutMgr::DeleteData_CLayoutMgr(
int nLineNum,
int nDelPos,
int nDelLen,
int *pnModifyLayoutLinesOld,
int *pnModifyLayoutLinesNew,
int *pnDeleteLayoutLines,
CMemory& cmemDeleted, /* 削除されたデータ */
BOOL bDispSSTRING, /* シングルクォーテーション文字列を表示する */
BOOL bDispWSTRING /* ダブルクォーテーション文字列を表示する */
// BOOL bUndo /* Undo操作かどうか */
)
{
#ifdef _DEBUG
CRunningTimer cRunningTimer( (const char*)"CLayoutMgr::DeleteData_CLayoutMgr" );
#endif
const char* pLine;
int nLineLen;
CLayout* pLayout;
CLayout* pLayoutPrev;
// CLayout* pLayoutNext;
CLayout* pLayoutWork;
int nModLineOldFrom; /* 影響のあった変更前の行(from) */
int nModLineOldTo; /* 影響のあった変更前の行(to) */
int nDelLineOldFrom; /* 削除された変更前論理行(from) */
int nDelLineOldNum; /* 削除された行数 */
int nRowNum;
int nAllLinesOld;
int nDelStartLogicalLine;
int nDelStartLogicalPos;
int nCurrentLineType;
int nAddInsLineNum;
int nLineWork;
/* 現在行のデータを取得 */
pLine = GetLineStr( nLineNum, &nLineLen );
if( NULL == pLine ){
return;
}
pLayout = m_pLayoutPrevRefer;
nDelStartLogicalLine = pLayout->m_nLinePhysical;
nDelStartLogicalPos = nDelPos + pLayout->m_nOffset;
// pLayoutWork = pLayout;
// do{
// pLayoutWork = pLayoutWork->m_pNext;
// }while( NULL != pLayoutWork && 0 != pLayoutWork->m_nOffset );
// pLayoutNext = pLayoutWork;
pLayoutWork = pLayout;
nLineWork = nLineNum;
while( 0 != pLayoutWork->m_nOffset ){
pLayoutWork = pLayoutWork->m_pPrev;
--nLineWork;
}
nCurrentLineType = pLayoutWork->m_nTypePrev;
/* テキストのデータを削除 */
m_pcDocLineMgr->DeleteData_CDocLineMgr(
nDelStartLogicalLine, nDelStartLogicalPos,
nDelLen, &nModLineOldFrom, &nModLineOldTo,
&nDelLineOldFrom, &nDelLineOldNum, cmemDeleted
);
// DUMP();
/*--- 変更された行のレイアウト情報を再生成 ---*/
/* 論理行の指定範囲に該当するレイアウト情報を削除して */
/* 削除した範囲の直前のレイアウト情報のポインタを返す */
nAllLinesOld = m_nLines;
pLayoutPrev = DeleteLayoutAsLogical(
pLayoutWork,
nLineWork,
nModLineOldFrom, nModLineOldTo,
nDelStartLogicalLine, nDelStartLogicalPos,
pnModifyLayoutLinesOld
);
/* 指定行より後の行のレイアウト情報について、論理行番号を指定行数だけシフトする */
/* 論理行が削除された場合は0より小さい行数 */
/* 論理行が挿入された場合は0より大きい行数 */
ShiftLogicalLineNum( pLayoutPrev, -1 * nDelLineOldNum );
/* 指定レイアウト行に対応する論理行の次の論理行から指定論理行数だけ再レイアウトする */
if( NULL == pLayoutPrev ){
if( NULL == m_pLayoutTop ){
nRowNum = m_pcDocLineMgr->GetLineCount();
}else{
nRowNum = m_pLayoutTop->m_nLinePhysical;
}
}else{
if( NULL == pLayoutPrev->m_pNext ){
nRowNum =
m_pcDocLineMgr->GetLineCount() -
pLayoutPrev->m_nLinePhysical - 1;
}else{
nRowNum =
pLayoutPrev->m_pNext->m_nLinePhysical -
pLayoutPrev->m_nLinePhysical - 1;
}
}
/* 指定レイアウト行に対応する論理行の次の論理行から指定論理行数だけ再レイアウトする */
*pnModifyLayoutLinesNew = DoLayout_Range(
pLayoutPrev,
nRowNum,
nDelStartLogicalLine, nDelStartLogicalPos,
nCurrentLineType,
&nAddInsLineNum,
bDispSSTRING, /* シングルクォーテーション文字列を表示する */
bDispWSTRING /* ダブルクォーテーション文字列を表示する */
);
*pnDeleteLayoutLines = nAllLinesOld - m_nLines + nAddInsLineNum;
return;
}
/*! 文字列挿入
@date 2002/03/24 YAZAKI bUndo削除
*/
void CLayoutMgr::InsertData_CLayoutMgr(
int nLineNum,
int nInsPos,
const char* pInsData,
int nInsDataLen,
int* pnModifyLayoutLinesOld,
int* pnInsLineNum, /* 挿入によって増えたレイアウト行の数 */
int* pnNewLine, /* 挿入された部分の次の位置の行 */
int* pnNewPos, /* 挿入された部分の次の位置のデータ位置 */
BOOL bDispSSTRING, /* シングルクォーテーション文字列を表示する */
BOOL bDispWSTRING /* ダブルクォーテーション文字列を表示する */
// BOOL bUndo /* Undo操作かどうか */
)
{
const char* pLine;
int nLineLen;
CLayout* pLayout;
CLayout* pLayoutPrev;
// CLayout* pLayoutNext;
// CLayout* pLayoutLast;
CLayout* pLayoutWork;
int nInsStartLogicalLine;
int nInsStartLogicalPos;
int nInsLineNum;
int nAllLinesOld;
int nRowNum;
int nNewLine; /* 挿入された部分の次の位置の行 */
int nNewPos; /* 挿入された部分の次の位置のデータ位置 */
int nCurrentLineType;
int nAddInsLineNum;
int nLineWork;
// MYTRACE( "CLayoutMgr::InsertData()\n" );
/* 現在行のデータを取得 */
pLine = GetLineStr( nLineNum, &nLineLen );
if( NULL == pLine ){
/*
2004.04.02 FILE / Moca カーソル位置不正のため、空テキストで
nLineNumが0でないときに落ちる対策.データが空であることを
カーソル位置ではなく総行数で判定することでより確実に.
*/
if( m_nLines == 0 )
{
/* 空のテキストの先頭に行を作る場合 */
pLayout = NULL;
nLineWork = 0;
nInsStartLogicalLine = m_pcDocLineMgr->GetLineCount();
nInsStartLogicalPos = 0;
nCurrentLineType = 0;
}else{
pLine = GetLineStr( m_nLines - 1, &nLineLen );
// pLayoutLast = m_pLayoutPrevRefer;
if( ( nLineLen > 0 && ( pLine[nLineLen - 1] == CR || pLine[nLineLen - 1] == LF )) ||
( nLineLen > 1 && ( pLine[nLineLen - 2] == CR || pLine[nLineLen - 2] == LF )) ){
/* 空でないテキストの最後に行を作る場合 */
pLayout = NULL;
nLineWork = 0;
nInsStartLogicalLine = m_pcDocLineMgr->GetLineCount();
nInsStartLogicalPos = 0;
nCurrentLineType = m_nLineTypeBot;
}else{
/* 空でないテキストの最後の行を変更する場合 */
nLineNum = m_nLines - 1;
nInsPos = nLineLen;
pLayout = m_pLayoutPrevRefer;
nLineWork = m_nPrevReferLine;
nInsStartLogicalLine = pLayout->m_nLinePhysical;
nInsStartLogicalPos = nInsPos + pLayout->m_nOffset;
nCurrentLineType = pLayout->m_nTypePrev;
}
}
}else{
pLayout = m_pLayoutPrevRefer;
nLineWork = m_nPrevReferLine;
nInsStartLogicalLine = pLayout->m_nLinePhysical;
nInsStartLogicalPos = nInsPos + pLayout->m_nOffset;
nCurrentLineType = pLayout->m_nTypePrev;
}
if( NULL != pLayout ){
pLayoutWork = pLayout;
while( pLayoutWork != NULL && 0 != pLayoutWork->m_nOffset ){
pLayoutWork = pLayoutWork->m_pPrev;
nLineWork--;
}
if( NULL != pLayoutWork ){
nCurrentLineType = pLayoutWork->m_nTypePrev;
}else{
nCurrentLineType = 0;
}
}
/* データの挿入 */
m_pcDocLineMgr->InsertData_CDocLineMgr(
nInsStartLogicalLine,
nInsStartLogicalPos,
pInsData,
nInsDataLen,
&nInsLineNum,
&nNewLine,
&nNewPos
);
// MYTRACE( "nNewLine=%d nNewPos=%d \n", nNewLine, nNewPos );
/*--- 変更された行のレイアウト情報を再生成 ---*/
/* 論理行の指定範囲に該当するレイアウト情報を削除して */
/* 削除した範囲の直前のレイアウト情報のポインタを返す */
nAllLinesOld = m_nLines;
if( NULL != pLayout ){
pLayoutPrev = DeleteLayoutAsLogical(
pLayoutWork,
nLineWork,
nInsStartLogicalLine, nInsStartLogicalLine,
nInsStartLogicalLine, nInsStartLogicalPos,
pnModifyLayoutLinesOld
);
}else{
pLayoutPrev = m_pLayoutBot;
}
/* 指定行より後の行のレイアウト情報について、論理行番号を指定行数だけシフトする */
/* 論理行が削除された場合は0より小さい行数 */
/* 論理行が挿入された場合は0より大きい行数 */
if( NULL != pLine ){
ShiftLogicalLineNum( pLayoutPrev, nInsLineNum );
}
/* 指定レイアウト行に対応する論理行の次の論理行から指定論理行数だけ再レイアウトする */
if( NULL == pLayoutPrev ){
if( NULL == m_pLayoutTop ){
nRowNum = m_pcDocLineMgr->GetLineCount();
}else{
nRowNum = m_pLayoutTop->m_nLinePhysical;
}
}else{
if( NULL == pLayoutPrev->m_pNext ){
nRowNum =
m_pcDocLineMgr->GetLineCount() -
pLayoutPrev->m_nLinePhysical - 1;
}else{
nRowNum =
pLayoutPrev->m_pNext->m_nLinePhysical -
pLayoutPrev->m_nLinePhysical - 1;
}
}
/* 指定レイアウト行に対応する論理行の次の論理行から指定論理行数だけ再レイアウトする */
DoLayout_Range(
pLayoutPrev,
nRowNum,
nInsStartLogicalLine, nInsStartLogicalPos,
nCurrentLineType,
&nAddInsLineNum,
bDispSSTRING, /* シングルクォーテーション文字列を表示する */
bDispWSTRING /* ダブルクォーテーション文字列を表示する */
);
*pnInsLineNum = m_nLines - nAllLinesOld + nAddInsLineNum;
/* 論理位置→レイアウト位置変換 */
pLayout = Search( nNewLine );
XYLogicalToLayout( pLayout, nNewLine, nNewLine, nNewPos, pnNewLine, pnNewPos );
return;
}
/* 論理行の指定範囲に該当するレイアウト情報を削除して */
/* 削除した範囲の直前のレイアウト情報のポインタを返す */
CLayout* CLayoutMgr::DeleteLayoutAsLogical(
CLayout* pLayoutInThisArea,
int nLineOf_pLayoutInThisArea,
int nLineFrom,
int nLineTo,
int nDelLogicalLineFrom,
int nDelLogicalColFrom,
int* pnDeleteLines
)
{
//#ifdef _DEBUG
// CRunningTimer cRunningTimer( (const char*)"CLayoutMgr::DeleteLayoutAsLogical" );
//#endif
CLayout* pLayout;
CLayout* pLayoutWork;
CLayout* pLayoutNext;
*pnDeleteLines = 0;
if( 0 == m_nLines){ /* 全物理行数 */
return NULL;
}
if( NULL == pLayoutInThisArea ){
return NULL;
}
// 1999.11.22
m_pLayoutPrevRefer = pLayoutInThisArea->m_pPrev;
m_nPrevReferLine = nLineOf_pLayoutInThisArea - 1;
// m_pLayoutPrevRefer = NULL;
// m_nPrevReferLine = 0;
/* 範囲内先頭に該当するレイアウト情報をサーチ */
pLayoutWork = pLayoutInThisArea->m_pPrev;
while( NULL != pLayoutWork && nLineFrom <= pLayoutWork->m_nLinePhysical){
pLayoutWork = pLayoutWork->m_pPrev;
}
// m_pLayoutPrevRefer = pLayout->m_pPrev;
// --m_nPrevReferLine;
if( NULL == pLayoutWork ){
pLayout = m_pLayoutTop;
}else{
pLayout = pLayoutWork->m_pNext;
}
while( NULL != pLayout ){
if( pLayout->m_nLinePhysical > nLineTo ){
break;
}
pLayoutNext = pLayout->m_pNext;
if( NULL == pLayoutWork ){
/* 先頭行の処理 */
m_pLayoutTop = pLayout->m_pNext;
if( NULL != pLayout->m_pNext ){
pLayout->m_pNext->m_pPrev = NULL;
}
}else{
pLayoutWork->m_pNext = pLayout->m_pNext;
if( NULL != pLayout->m_pNext ){
pLayout->m_pNext->m_pPrev = pLayoutWork;
}
}
// if( m_pLayoutPrevRefer == pLayout ){
// // 1999.12.22 前にずらすだけでよいのでは
// m_pLayoutPrevRefer = pLayout->m_pPrev;
// --m_nPrevReferLine;
// }
if( ( nDelLogicalLineFrom == pLayout->m_nLinePhysical &&
nDelLogicalColFrom < pLayout->m_nOffset + pLayout->m_nLength ) ||
( nDelLogicalLineFrom < pLayout->m_nLinePhysical )
){
(*pnDeleteLines)++;;
}
#ifdef _DEBUG
if( m_pLayoutPrevRefer == pLayout ){
MYTRACE( "バグバグ\n" );
}
#endif
delete pLayout;
m_nLines--; /* 全物理行数 */
if( NULL == pLayoutNext ){
m_pLayoutBot = pLayoutWork;
}
pLayout = pLayoutNext;
}
// MYTRACE( "(*pnDeleteLines)=%d\n", (*pnDeleteLines) );
return pLayoutWork;
}
/* 指定行より後の行のレイアウト情報について、論理行番号を指定行数だけシフトする */
/* 論理行が削除された場合は0より小さい行数 */
/* 論理行が挿入された場合は0より大きい行数 */
void CLayoutMgr::ShiftLogicalLineNum( CLayout* pLayoutPrev, int nShiftLines )
{
MY_RUNNINGTIMER( cRunningTimer, "CLayoutMgr::ShiftLogicalLineNum" );
CLayout* pLayout;
// CLayout* pLayoutNext;
if( 0 == nShiftLines ){
return;
}
if( NULL == pLayoutPrev ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -