📄 clayoutmgr.cpp
字号:
pLayout = m_pLayoutTop;
}else{
pLayout = pLayoutPrev->m_pNext;
}
/* レイアウト情報全体を更新する(なな、なんと!!!) */
while( NULL != pLayout ){
// pLayoutNext = pLayout->m_pNext;
pLayout->m_nLinePhysical += nShiftLines; /* 対応する論理行番号 */
// pLayout = pLayoutNext;
pLayout = pLayout->m_pNext;
}
return;
}
/* 現在位置の単語の範囲を調べる */
int CLayoutMgr::WhereCurrentWord(
int nLineNum,
int nIdx,
int* pnLineFrom,
int* pnIdxFrom,
int* pnLineTo,
int* pnIdxTo,
CMemory* pcmcmWord,
CMemory* pcmcmWordLeft
)
{
int nRetCode;
CLayout* pLayout;
pLayout = Search( nLineNum );
if( NULL == pLayout ){
return FALSE;
}
/* 現在位置の単語の範囲を調べる */
nRetCode = m_pcDocLineMgr->WhereCurrentWord(
pLayout->m_nLinePhysical,
pLayout->m_nOffset + nIdx,
pnIdxFrom,
pnIdxTo,
pcmcmWord,
pcmcmWordLeft
);
if( nRetCode ){
/* 論理位置→レイアウト位置変換 */
XYLogicalToLayout( pLayout, nLineNum, pLayout->m_nLinePhysical, *pnIdxFrom, pnLineFrom, pnIdxFrom );
XYLogicalToLayout( pLayout, nLineNum, pLayout->m_nLinePhysical, *pnIdxTo, pnLineTo, pnIdxTo );
}
return nRetCode;
}
/* 現在位置の左右の単語の先頭位置を調べる */
int CLayoutMgr::PrevOrNextWord(
int nLineNum,
int nIdx,
int* pnLineNew,
int* pnColmNew,
BOOL bLEFT,
BOOL bStopsBothEnds
)
{
int nRetCode;
CLayout* pLayout;
pLayout = Search( nLineNum );
if( NULL == pLayout ){
return FALSE;
}
/* 現在位置の左右の単語の先頭位置を調べる */
nRetCode = m_pcDocLineMgr->PrevOrNextWord(
pLayout->m_nLinePhysical,
pLayout->m_nOffset + nIdx,
pnColmNew,
bLEFT,
bStopsBothEnds
);
if( nRetCode ){
/* 論理位置→レイアウト位置変換 */
XYLogicalToLayout( pLayout, nLineNum, pLayout->m_nLinePhysical, *pnColmNew, pnLineNew, pnColmNew );
}
return nRetCode;
}
//! 単語検索
/*
@retval 0 見つからない
*/
int CLayoutMgr::SearchWord(
int nLineNum, /* 検索開始行 */
int nIdx, /* 検索開始位置 */
const char* pszPattern, /* 検索条件 */
int bPrevOrNext, /* 0==前方検索 1==後方検索 */
int bRegularExp, /* 1==正規表現 */
int bLoHiCase, /* 1==大文字小文字の区別 */
int bWordOnly, /* 1==単語のみ検索 */
int* pnLineFrom, /* マッチレイアウト行from */
int* pnIdxFrom, /* マッチレイアウト位置from */
int* pnLineTo, /* マッチレイアウト行to */
int* pnIdxTo, /* マッチレイアウト位置to */
//! [in] 正規表現コンパイルデータ
CBregexp* pRegexp // Jun. 26, 2001 genta
)
{
int nRetCode;
int nLogLine;
CLayout* pLayout;
pLayout = Search( nLineNum );
if( NULL == pLayout ){
return FALSE;
}
/* 単語検索 */
nRetCode = m_pcDocLineMgr->SearchWord(
pLayout->m_nLinePhysical,
pLayout->m_nOffset + nIdx,
pszPattern,
bPrevOrNext,
bRegularExp,
bLoHiCase,
bWordOnly,
pnLineFrom,
pnIdxFrom,
pnIdxTo,
pRegexp /* 正規表現コンパイルデータ */
);
if( nRetCode ){
/* 論理位置→レイアウト位置変換 */
nLogLine = *pnLineFrom;
CaretPos_Phys2Log(
*pnIdxFrom,
nLogLine,
pnIdxFrom,
pnLineFrom
);
CaretPos_Phys2Log(
*pnIdxTo,
nLogLine,
pnIdxTo,
pnLineTo
);
}
return nRetCode;
}
/* 論理位置→レイアウト位置変換 */
void CLayoutMgr::XYLogicalToLayout(
CLayout* pLayoutInThisArea,
int nLayoutLineOfThisArea,
int nLogLine,
int nLogIdx,
int* pnLayLine,
int* pnLayIdx
)
{
CLayout* pLayout;
int nCurLayLine;
*pnLayLine = 0;
*pnLayIdx = 0;
if( pLayoutInThisArea == NULL ){
pLayoutInThisArea = m_pLayoutBot;
nLayoutLineOfThisArea = m_nLines - 1;
}
if( pLayoutInThisArea == NULL ){
*pnLayLine = m_nLines;
*pnLayIdx = 0;
return;
}
/* 範囲内先頭に該当するレイアウト情報をサーチ */
if( (pLayoutInThisArea->m_nLinePhysical > nLogLine) ||
(pLayoutInThisArea->m_nLinePhysical == nLogLine &&
pLayoutInThisArea->m_nOffset > nLogIdx)
){
/* 現在位置より前方に向かってサーチ */
pLayout = pLayoutInThisArea->m_pPrev;
nCurLayLine = nLayoutLineOfThisArea - 1;
while( pLayout != NULL ){
if( pLayout->m_nLinePhysical == nLogLine &&
pLayout->m_nOffset <= nLogIdx &&
nLogIdx <= pLayout->m_nOffset + pLayout->m_nLength
){
*pnLayLine = nCurLayLine;
*pnLayIdx = nLogIdx - pLayout->m_nOffset;
return;
}
if( NULL == pLayout->m_pPrev ){
*pnLayLine = nCurLayLine;
*pnLayIdx = 0;
return;
}
pLayout = pLayout->m_pPrev;
nCurLayLine--;
}
}else{
/* 現在位置を含む後方に向かってサーチ */
pLayout = pLayoutInThisArea;
nCurLayLine = nLayoutLineOfThisArea;
while( pLayout != NULL ){
if( pLayout->m_nLinePhysical == nLogLine &&
pLayout->m_nOffset <= nLogIdx &&
nLogIdx <= pLayout->m_nOffset + pLayout->m_nLength
){
*pnLayLine = nCurLayLine;
*pnLayIdx = nLogIdx - pLayout->m_nOffset;
return;
}
if( NULL == pLayout->m_pNext ){
// if( nCurLayLine == nLogLine ){
// *pnLayLine = nCurLayLine;
// *pnLayIdx = pLayout->m_nLength;
// }else{
*pnLayLine = nCurLayLine + 1;
*pnLayIdx = 0;
// }
return;
}else
if( pLayout->m_pNext->m_nLinePhysical > nLogLine ){
*pnLayLine = nCurLayLine;
*pnLayIdx = nLogIdx - pLayout->m_nOffset;
return;
}
pLayout = pLayout->m_pNext;
nCurLayLine++;
}
}
return;
}
/*! @brief カーソル位置変換 物理→レイアウト
物理位置(行頭からのバイト数、折り返し無し行位置)
→レイアウト位置(行頭からの表示桁位置、折り返しあり行位置)
@param nX [in] 物理位置X
@param nY [in] 物理位置Y
@param pnCaretPosX [out] 論理位置X
@param pnCaretPosY [out] 論理位置Y
@date 2004.06.16 Moca インデント表示の際のTABを含む行の座標ずれ修正
*/
void CLayoutMgr::CaretPos_Phys2Log(
int nX,
int nY,
int* pnCaretPosX,
int* pnCaretPosY
// BOOL bFreeCaret
)
{
//#ifdef _DEBUG
// CRunningTimer cRunningTimer( (const char*)"CLayoutMgr::CaretPos_Phys2Log" );
//#endif
const CLayout* pLayout;
// CLayout* pLayoutNext;
int nCaretPosX;
int nCaretPosY;
const char* pData;
int nDataLen;
int i;
int nCharChars;
*pnCaretPosX = 0;
*pnCaretPosY = 0;
//1999.12.11
// サーチ開始地点は先頭から
// pLayout = m_pLayoutTop;
// nCaretPosY = 0;
/* 改行単位行 <= 折り返し単位行 が成り立つから、
サーチ開始地点をできるだけ目的地へ近づける */
// pLayout = GetLineData( nY );
pLayout = Search( nY );
if( NULL == pLayout ){
if( 0 < m_nLines ){
*pnCaretPosY = m_nLines;
}
return;
}
nCaretPosY = nY;
// Layoutを1つずつ先に進めながらnYが物理行に一致するLayoutを探す
nCaretPosX = 0;
do{
if( nY == pLayout->m_nLinePhysical ){
// 2004.06.16 Moca インデント表示の際に位置がずれる(TAB位置ずれによる)
// TAB幅を正確に計算するには当初からインデント分を加えておく必要がある.
nCaretPosX = pLayout->GetIndent();
// pData = GetLineStr( nCaretPosY, &nDataLen );
// pData = pLayout->m_pLine + pLayout->m_nOffset;
pData = pLayout->m_pCDocLine->m_pLine->GetPtr() + pLayout->m_nOffset; // 2002/2/10 aroka CMemory変更
nDataLen = pLayout->m_nLength;
for( i = 0; i < nDataLen; ++i ){
if( pLayout->m_nOffset + i >= nX ){
break;
}
if( pData[i] == TAB ){
// Sep. 23, 2002 genta メンバー関数を使うように
nCharChars = GetActualTabSpace( nCaretPosX );
}else{
nCharChars = CMemory::MemCharNext( pData, nDataLen, &pData[i] ) - &pData[i];
}
if( nCharChars == 0 ){
nCharChars = 1;
}
nCaretPosX += nCharChars;
if( pData[i] == TAB ){
nCharChars = 1;
}
i += nCharChars - 1;
}
if( i < nDataLen ){
// nX, nYがこの行の中に見つかったらループ打ち切り
break;
}
if( NULL == pLayout->m_pNext ){
// 当該位置に達していなくても,レイアウト末尾ならデータ末尾を返す.
nCaretPosX += ( nDataLen - i );
// nCaretPosX = 0;
break;
}
if( nY < pLayout->m_pNext->m_nLinePhysical ){
// 次のLayoutが当該物理行を過ぎてしまう場合はデータ末尾を返す.
nCaretPosX += ( nDataLen - i );
break;
}
}
if( nY < pLayout->m_nLinePhysical ){
// ふつうはここには来ないと思うが... (genta)
// Layoutの指す物理行が探している行より先を指していたら打ち切り
break;
}
// 次の行へ進む
nCaretPosY++;
pLayout = pLayout->m_pNext;
}while( NULL != pLayout );
// 2004.06.16 Moca インデント表示の際の位置ずれ修正
*pnCaretPosX = pLayout ? nCaretPosX : 0;
*pnCaretPosY = nCaretPosY;
//#ifdef _DEBUG
// MYTRACE( "\t\tnCaretPosY - nY = %d\n", nCaretPosY - nY );
//#endif
return;
}
/*
カーソル位置変換
レイアウト位置(行頭からの表示桁位置、折り返しあり行位置)
→
物理位置(行頭からのバイト数、折り返し無し行位置)
*/
void CLayoutMgr::CaretPos_Log2Phys(
int nCaretPosX,
int nCaretPosY,
int* pnX,
int* pnY
)
{
//#ifdef _DEBUG
// CRunningTimer cRunningTimer( (const char*)"CLayoutMgr::CaretPos_Log2Phys" );
//#endif
int nX;
// int nY;
const CLayout* pcLayout;
int i;
const char* pData;
int nDataLen;
int nCharChars;
BOOL bEOF;
bEOF = FALSE;
*pnX = 0;
*pnY = 0;
if( nCaretPosY > m_nLines ){
*pnX = 0;
*pnY = m_nLines;
return;
}
pcLayout = Search( nCaretPosY );
if( NULL == pcLayout ){
if( 0 < nCaretPosY ){
pcLayout = Search( nCaretPosY - 1 );
if( NULL == pcLayout ){
*pnX = 0;
*pnY = m_pcDocLineMgr->GetLineCount(); // 2002/2/10 aroka CDocLineMgr変更
return;
}else{
pData = GetLineStr( nCaretPosY - 1, &nDataLen );
if( pData[nDataLen - 1] == '\r' || pData[nDataLen - 1] == '\n' ){
*pnX = 0;
*pnY = m_pcDocLineMgr->GetLineCount(); // 2002/2/10 aroka CDocLineMgr変更
return;
}else{
*pnY = m_pcDocLineMgr->GetLineCount() - 1; // 2002/2/10 aroka CDocLineMgr変更
bEOF = TRUE;
nX = 999999;
goto checkloop;
}
}
}
*pnX = 0;
*pnY = m_nLines;
return;
}else{
*pnY = pcLayout->m_nLinePhysical;
}
pData = GetLineStr( nCaretPosY, &nDataLen );
nX = pcLayout ? pcLayout->GetIndent() : 0;
checkloop:;
// enumEOLType nEOLType;
for( i = 0; i < nDataLen; ++i ){
if( pData[i] == TAB ){
// Sep. 23, 2002 genta メンバー関数を使うように
nCharChars = GetActualTabSpace( nX );
// }else
// if( pData[i] == '\r' || pData[i] == '\n' ){
// /* 行終端子の種類を調べる */
// nEOLType = GetEOLType( &pData[i], nDataLen - i );
// nCharChars = 1;
}else{
nCharChars = CMemory::MemCharNext( pData, nDataLen, &pData[i] ) - &pData[i];
}
if( nCharChars == 0 ){
nCharChars = 1;
}
nX += nCharChars;
if( nX > nCaretPosX && !bEOF ){
break;
}
if( pData[i] == TAB ){
nCharChars = 1;
}
// if( pData[i] == '\r' || pData[i] == '\n' ){
// nCharChars = gm_pnEolLenArr[nEOLType];
// }
i += nCharChars - 1;
}
i += pcLayout->m_nOffset;
*pnX = i;
return;
}
/* テスト用にレイアウト情報をダンプ */
void CLayoutMgr::DUMP( void )
{
#ifdef _DEBUG
const char* pData;
int nDataLen;
MYTRACE( "------------------------\n" );
MYTRACE( "m_nLines=%d\n", m_nLines );
MYTRACE( "m_pLayoutTop=%08lxh\n", m_pLayoutTop );
MYTRACE( "m_pLayoutBot=%08lxh\n", m_pLayoutBot );
MYTRACE( "m_nMaxLineSize=%d\n", m_nMaxLineSize );
MYTRACE( "m_nTabSpace=%d\n", m_nTabSpace );
CLayout* pLayout;
CLayout* pLayoutNext;
pLayout = m_pLayoutTop;
while( NULL != pLayout ){
pLayoutNext = pLayout->m_pNext;
MYTRACE( "\t-------\n" );
MYTRACE( "\tthis=%08lxh\n", pLayout );
MYTRACE( "\tm_pPrev =%08lxh\n", pLayout->m_pPrev );
MYTRACE( "\tm_pNext =%08lxh\n", pLayout->m_pNext );
MYTRACE( "\tm_nLinePhysical=%d\n", pLayout->m_nLinePhysical );
MYTRACE( "\tm_nOffset=%d\n", pLayout->m_nOffset );
MYTRACE( "\tm_nLength=%d\n", pLayout->m_nLength );
MYTRACE( "\tm_enumEOLType =%s\n", pLayout->m_cEol.GetName() );
MYTRACE( "\tm_nEOLLen =%d\n", pLayout->m_cEol.GetLen() );
MYTRACE( "\tm_nTypePrev=%d\n", pLayout->m_nTypePrev );
pData = m_pcDocLineMgr->GetLineStr( pLayout->m_nLinePhysical, &nDataLen );
MYTRACE( "\t[%s]\n", pData );
pLayout = pLayoutNext;
}
MYTRACE( "------------------------\n" );
#endif
return;
}
/*[EOF]*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -