/*! 指定された行の始点終点ドット位置の区間の文字の選択状態をON/OFFする @param[in] dBgnDot 開始ドット位置・マイナスなら0 @param[in] dEndDot 終了ドット位置・マイナスなら行末端 @param[in] rdLine 対象の行番号・ドキュメントの0インデックス @param[in] dForce 0斗愚留 +選択状態 ー選択解除 @return 該当文字のドット数 */ INT DocRangeSelStateToggle( INT dBgnDot, INT dEndDot, INT rdLine, INT dForce ) { UINT_PTR iLines; INT dLtrDot = 0, dMaxDots, dDot; RECT rect; iLines = DocNowFilePageLineCount( ); if( (INT)iLines <= rdLine ) return 0; dMaxDots = DocLineParamGet( rdLine, NULL, NULL ); // 範囲調整 if( 0 > dBgnDot ) dBgnDot = 0; if( 0 > dEndDot ) dEndDot = dMaxDots; for( dDot = dBgnDot; dEndDot > dDot; ) { dDot += DocLetterSelStateToggle( dDot, rdLine, dForce ); } //操作済のアレの計算がヘン・フラグの兼ね合いとか dLtrDot = dDot - dBgnDot; rect.left = dBgnDot; rect.top = rdLine * LINE_HEIGHT; rect.right = dEndDot; rect.bottom = rect.top + LINE_HEIGHT; // ViewRedrawSetLine( rdLine ); ViewRedrawSetRect( &rect ); DocSelectedByteStatus( ); return dLtrDot; // ドット数戻してOK }
/*! 行末空白削除の面倒見る・選択行とか @param[in] pXdot 今のドット位置を受けて戻す・削除に巻き込まれた対応 @param[in] dLine 今の行数 @return HRESULT 終了状態コード */ HRESULT DocLastSpaceErase( PINT pXdot, INT dLine ) { UINT_PTR iLines; INT iTop, iBottom, i, xDelDot, xMotoDot; BOOLEAN bFirst = TRUE; LPTSTR ptBuffer = NULL; RECT rect; LINE_ITR itLine; TRACE( TEXT("行末空白削除") ); // 範囲確認 iLines = DocNowFilePageLineCount( ); iTop = (*gitFileIt).vcCont.at( gixFocusPage ).dSelLineTop; iBottom = (*gitFileIt).vcCont.at( gixFocusPage ).dSelLineBottom; if( 0 > iTop ) iTop = 0; if( 0 > iBottom ) iBottom = iLines - 1; ViewSelPageAll( -1 ); // 選択範囲無くなる itLine = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.begin(); std::advance( itLine, iTop ); // 位置合わせ for( i = iTop; iBottom >= i; i++, itLine++ ) { xMotoDot = itLine->iDotCnt; ptBuffer = DocLastSpDel( &(itLine->vcLine) ); xDelDot = DocLineParamGet( i, NULL, NULL ); // サクった後の行末端すなわち削除位置 if( ptBuffer ) { SqnAppendString( &((*gitFileIt).vcCont.at( gixFocusPage ).stUndoLog), DO_DELETE, ptBuffer, xDelDot, i , bFirst ); bFirst = FALSE; } FREE( ptBuffer ); DocBadSpaceCheck( i ); // 状態をリセット・中で行書換でいいか? rect.top = i * LINE_HEIGHT; rect.bottom = rect.top + LINE_HEIGHT; rect.left = xDelDot; // 削ったら左側になる rect.right = xMotoDot + 20; // 元長さ+改行マーク ViewRedrawSetRect( &rect ); // ViewRedrawSetLine( i ); // 再描画COMMANDO } // キャレット位置ずれてたら適当に調整 DocLetterPosGetAdjust( pXdot, dLine, 0 ); // キャレット位置適当に調整 ViewDrawCaret( *pXdot, dLine, 1 ); DocPageInfoRenew( -1, 1 ); return S_OK; }
/*! 指定された行の改行の選択状態をON/OFFする @param[in] rdLine 対象の行番号・ドキュメントの0インデックス @param[in] dForce 0斗愚留 +選択状態 ー選択解除 @return HRESULT 終了状態コード */ HRESULT DocReturnSelStateToggle( INT rdLine, INT dForce ) { UINT_PTR iLines; UINT dStyle, maeSty; INT iLnDot, dByte; RECT rect; LINE_ITR itLine; iLines = DocNowFilePageLineCount( ); if( (INT)iLines <= rdLine ) return E_OUTOFMEMORY; iLnDot = DocLineParamGet( rdLine, NULL, NULL ); // フラグ操作 itLine = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.begin(); std::advance( itLine, rdLine ); dStyle = itLine->dStyle; maeSty = dStyle; if( 0 == dForce ){ dStyle ^= CT_SELRTN; } else if( 0 < dForce ){ dStyle |= CT_SELRTN; } else if( 0 > dForce ){ dStyle &= ~CT_SELRTN; } itLine->dStyle = dStyle; if( maeSty != dStyle ) // フラグ操作されてたら { if( gbCrLfCode ) dByte = YY2_CRLF; else dByte = STRB_CRLF; if( CT_SELRTN & dStyle ) gdSelByte += dByte; else gdSelByte -= dByte; if( 0 > gdSelByte ) gdSelByte = 0; // 0未満になったら本当はおかしい DocSelectedByteStatus( ); } rect.left = iLnDot; rect.top = rdLine * LINE_HEIGHT; rect.right = iLnDot + 20; // たぶんこれくらい rect.bottom = rect.top + LINE_HEIGHT; // ViewRedrawSetLine( rdLine ); ViewRedrawSetRect( &rect ); return S_OK; }
/*! 行末文字を削除する。ただし空白だったら削除しない @param[in] pXdot 今のドット位置を受けて戻す・削除に巻き込まれた対応 @param[in] dLine 今の行数 @return HRESULT 終了状態コード */ HRESULT DocLastLetterErase( PINT pXdot, INT dLine ) { UINT_PTR iLines; INT iTop, iBottom, i, xDot = 0; TCHAR ch; BOOLEAN bFirst = TRUE, bSeled = FALSE; RECT rect; LETR_ITR vcLtrItr; LINE_ITR itLine; // 範囲確認 iLines = DocNowFilePageLineCount( ); iTop = (*gitFileIt).vcCont.at( gixFocusPage ).dSelLineTop; iBottom = (*gitFileIt).vcCont.at( gixFocusPage ).dSelLineBottom; if( 0 <= iTop && 0 <= iBottom ) bSeled = TRUE; if( 0 > iTop ) iTop = 0; if( 0 > iBottom ) iBottom = iLines - 1; TRACE( TEXT("行末文字削除") ); // 選択してる場合は、操作行を全選択状態にする itLine = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.begin(); std::advance( itLine, iTop ); // 位置合わせ for( i = iTop; iBottom >= i; i++, itLine++ ) // 範囲内の各行について { // 文字があるなら操作する if( 0 != itLine->vcLine.size( ) ) { vcLtrItr = itLine->vcLine.end( ); vcLtrItr--; // 終端の一個前が末端文字 ch = vcLtrItr->cchMozi; rect.top = i * LINE_HEIGHT; rect.bottom = rect.top + LINE_HEIGHT; if( !( iswspace( ch ) ) ) { xDot = DocLineParamGet( i, NULL, NULL ); xDot -= vcLtrItr->rdWidth; SqnAppendLetter( &((*gitFileIt).vcCont.at( gixFocusPage ).stUndoLog), DO_DELETE, ch, xDot, i, bFirst ); bFirst = FALSE; DocIterateDelete( vcLtrItr, i ); rect.left = xDot; rect.right = xDot + 40; // 壱文字+改行・適当でよろし ViewRedrawSetRect( &rect ); // 末端だけ書き換えればいい? DocBadSpaceCheck( i ); // 良くないスペースを調べておく } } if( bSeled ) { DocRangeSelStateToggle( -1, -1, i , 1 ); // 該当行全体を選択状態にする DocReturnSelStateToggle( i, 1 ); // 改行も選択で } } // キャレット位置適当に調整 *pXdot = 0; DocLetterPosGetAdjust( pXdot, dLine, 0 ); // キャレット位置適当に調整 ViewDrawCaret( *pXdot, dLine, 1 ); DocPageInfoRenew( -1, 1 ); return S_OK; }
/*! ページ全体の選択状態をON/OFFする @param[in] dForce 0无 +選択状態 ー選択解除 @return 全体文字数 */ INT DocPageSelStateToggle( INT dForce ) { UINT_PTR iLines, ln, iLetters, mz; UINT dStyle; INT iTotal, iDot, iWid; RECT inRect; LINE_ITR itLine; if( 0 == dForce ) return 0; // 0なら処理しない if( 0 > gixFocusPage ) return 0; // 特殊な状況下では処理しない iTotal = 0; iLines = DocNowFilePageLineCount( ); itLine = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.begin(); for( ln = 0; iLines > ln; ln++, itLine++ ) { iDot = 0; // そこまでのドット数をため込む inRect.top = ln * LINE_HEIGHT; inRect.bottom = inRect.top + LINE_HEIGHT; iLetters = itLine->vcLine.size( ); // この行の文字数確認して // 壱文字ずつ、全部をチェキっていく for( mz = 0; iLetters > mz; mz++ ) { // 直前の状態 dStyle = itLine->vcLine.at( mz ).mzStyle; iWid = itLine->vcLine.at( mz ).rdWidth; inRect.left = iDot; inRect.right = iDot + iWid; if( 0 < dForce ) { itLine->vcLine.at( mz ).mzStyle |= CT_SELECT; if( !(dStyle & CT_SELECT) ){ ViewRedrawSetRect( &inRect ); } } else { itLine->vcLine.at( mz ).mzStyle &= ~CT_SELECT; if( dStyle & CT_SELECT ){ ViewRedrawSetRect( &inRect ); } } iDot += iWid; iTotal++; } // 壱行終わったら末尾状況確認。改行・本文末端に改行はない・選択のときのみ dStyle = itLine->dStyle; inRect.left = iDot; inRect.right = iDot + 20; // 改行描画エリア・大体これくらい if( 0 < dForce ) { if( iLines > ln+1 ) { itLine->dStyle |= CT_SELRTN; if( !(dStyle & CT_SELRTN) ){ ViewRedrawSetRect( &inRect ); } } } else { itLine->dStyle &= ~CT_SELRTN; if( dStyle & CT_SELRTN ){ ViewRedrawSetRect( &inRect ); } } } if( 0 < dForce ) // 頁全体のバイト数そのものか、非選択なので0 { DocSelRangeSet( 0, iLines - 1 ); DocPageParamGet( NULL, &gdSelByte ); } else { DocSelRangeSet( -1, -1 ); gdSelByte = 0; } DocSelectedByteStatus( ); // ViewRedrawSetLine( -1 ); // 画面表示更新 return iTotal; }