/** * CFootyDoc::ReturnLine * @brief InsertStringのサブルーチンで、改行処理を行います。 */ void CFootyDoc::ReturnLine(LinePt *pNowLine,const wchar_t **pString,const wchar_t *pWork, size_t nPos,std::wstring *pRestStr,int n,bool bFirst) { // 宣言 LinePt pLine = *pNowLine; CFootyLine cInsertLine; // データ挿入 if (!bFirst) // 最初でないときはコピーする pLine->m_strLineData = std::wstring(*pString,(size_t)(pWork - *pString)); else // 最初の位置の時はバックアップ { if (nPos == pLine->GetLineLength()) { *pRestStr = L""; } else { *pRestStr = pLine->m_strLineData.substr(nPos); pLine->m_strLineData.erase(nPos,pLine->GetLineLength()-nPos); } pLine->m_strLineData += std::wstring(*pString,(size_t)(pWork - *pString)); } //次の行を生成する pLine++; m_lsLines.insert(pLine,cInsertLine); // ポインタ操作 *pString = pWork + n; (*pNowLine)++; }
/** * @brief 現在のキャレット位置の一行上に空行を挿入します。 * @param bIndentMode [in] オートインデント処理を行うかどうか */ CFootyDoc::RedrawType CFootyDoc::InsertReturnUp( bool bIndentMode ) { if ( IsReadOnly() ) return REDRAW_FAILED; // 選択状態の解除 m_nSelectType = SELECT_NONE; // 状況によって処理を分ける if (m_cCaretPos.GetLineNum() == 0) { // 一番上の行の時は、その位置の先頭で改行したことにする m_cCaretPos.SetPosition(m_cCaretPos.GetLinePointer(),0); InsertReturn( bIndentMode ); m_cCaretPos.SetPosition(m_lsLines.begin(),0); } else { // それ以外の時は、その位置の一つ上で改行したことにする LinePt pLine = m_cCaretPos.GetLinePointer(); pLine--; m_cCaretPos.SetPosition(pLine,pLine->GetLineLength()); InsertReturn( bIndentMode ); } return REDRAW_ALL; }
/** * CFootyDoc::InsertChar * @brief ワイド文字一つを挿入します * @param wChar 挿入する文字 * @return 描画範囲 */ CFootyDoc::RedrawType CFootyDoc::InsertChar(wchar_t wChar) { // 宣言 LinePt pLine; size_t nPos; CUndoBuffer cUndo; CEditPosition cEditPosition = m_cCaretPos; RedrawType nRetRedraw = REDRAW_LINE; if ( IsReadOnly() ) return REDRAW_FAILED; // 選択文字列を削除、アンドゥ情報を格納 if ( IsSelecting() ) { DeleteSelected(&cUndo); cUndo.m_nUndoType = CUndoBuffer::UNDOTYPE_REPLACE; nRetRedraw = REDRAW_ALL; } else if (m_bInsertMode || m_cCaretPos.GetPosition() == m_cCaretPos.GetLinePointer()->GetLineLength()) { cUndo.m_nUndoType = CUndoBuffer::UNDOTYPE_INSERT; } else { // 上書きされるときは、アンドゥ情報を書き換える必要がある cUndo.m_cBeforeStart = cEditPosition; cEditPosition.MoveColumnForward(&m_lsLines,1); cUndo.m_cBeforeEnd = cEditPosition; cUndo.m_strBefore += m_cCaretPos.GetLinePointer()->GetLineData() [m_cCaretPos.GetPosition()]; cUndo.m_nUndoType = CUndoBuffer::UNDOTYPE_REPLACE; } cUndo.m_strAfter += wChar; // 文字を入れる pLine = m_cCaretPos.GetLinePointer(); nPos = m_cCaretPos.GetPosition(); if (m_bInsertMode || nPos == pLine->GetLineLength()) pLine->m_strLineData.insert(nPos,1,wChar); else pLine->m_strLineData[nPos] = wChar; // 倫理行何行になるかチェック size_t nBeforeEthic = pLine->GetEthicLine(); if (SetLineInfo(pLine, false/*改行を含むか by Tetr@pod*/)) nRetRedraw = REDRAW_ALL; if (nBeforeEthic != pLine->GetEthicLine()) nRetRedraw = REDRAW_ALL; // 桁を増加させる cUndo.m_cAfterStart = m_cCaretPos; m_cCaretPos.MoveColumnForward(&m_lsLines,1); cUndo.m_cAfterEnd = m_cCaretPos; // アンドゥ情報を挿入 PushBackUndo(&cUndo); SendMoveCaretCallBack(); return nRetRedraw; }
/** * @brief キャレット位置を単語すっ飛ばして前に */ void CFootyDoc::MoveWordForward() { LinePt pLine = m_cCaretPos.GetLinePointer(); size_t nPos = m_cCaretPos.GetPosition(); if (m_cCaretPos.GetPosition() != pLine->GetLineLength()) { CFootyLine::WordInfo wiWord = pLine->GetWordInfo(nPos,false); m_cCaretPos.MoveColumnForward(&m_lsLines,wiWord.m_nEndPos - nPos); } else m_cCaretPos.MoveColumnForward(&m_lsLines,1); SendMoveCaretCallBack(); }
/** * CFootyView::CaretMove * @brief キャレットの位置とIMEポジションの位置を設定する */ void CFootyView::CaretMove(){ /*宣言*/ const LinePt pLine = m_pDocuments->GetCaretPosition()->GetLinePointer(); const size_t nPosition = m_pDocuments->GetCaretPosition()->GetPosition(); CEthicLine cFirstVisible = *m_pDocuments->GetFirstVisible(m_nViewID); CFootyLine::EthicInfo stEthicInfo; int nCaretX,nCaretY; /*キャレット位置を計算する*/ int nOffset = (int)pLine->GetOffset(); stEthicInfo = pLine->CalcEthicLine (nPosition,m_pDocuments->GetLapelColumn(), m_pDocuments->GetTabLen(),m_pDocuments->GetLapelMode()); nCaretX = GetTextPosX((int)stEthicInfo.m_nEthicColumn); nCaretY = m_nRulerHeight + (int)(nOffset - cFirstVisible.GetLinePointer()->GetOffset() - cFirstVisible.GetEthicNum() + stEthicInfo.m_nEthicLine) * (m_pFonts->GetHeight() + m_nHeightMargin); /*キャレットの太さを決定する*/ if (!m_pDocuments->IsInsertMode()){ if (nPosition == pLine->GetLineLength()) m_nCaretWidth = 2; else{ stEthicInfo = pLine->CalcEthicLine (nPosition + 1,m_pDocuments->GetLapelColumn(), m_pDocuments->GetTabLen(),m_pDocuments->GetLapelMode()); m_nCaretWidth = GetTextPosX((int)stEthicInfo.m_nEthicColumn) - nCaretX; } } else m_nCaretWidth = 2; /*キャレットを再構築*/ if (m_bIsFocused){ m_cCaret.ReCreate(m_nCaretWidth,m_pFonts->GetHeight()); m_cCaret.Move(nCaretX,nCaretY); } int nHeightScroll = GetSystemMetrics(SM_CYHSCROLL); int nWidthScroll = GetSystemMetrics(SM_CXVSCROLL); if (nCaretX < m_nLineCountWidth || m_nWidth - nWidthScroll < nCaretX || nCaretY < m_nRulerHeight || m_nHeight - nHeightScroll < nCaretY){ nCaretX = 0; nCaretY = 0; m_cCaret.Hide(); } else{ if (m_bIsFocused)m_cCaret.Show(); } // IMEを設定する if (m_bIsFocused) { LOGFONT lFont; COMPOSITIONFORM cf; HIMC hImc=ImmGetContext(m_hWnd); if (hImc) { // フォントを設定する GetObject(m_pFonts->GetKanjiFont(),sizeof(LOGFONT),&lFont); ImmSetCompositionFont(hImc,&lFont); // IME表示領域を設定する cf.dwStyle = CFS_POINT; cf.ptCurrentPos.x = (long)nCaretX; cf.ptCurrentPos.y = (long)nCaretY; cf.rcArea.left = cf.ptCurrentPos.x; cf.rcArea.top = cf.ptCurrentPos.y; cf.rcArea.right = m_nWidth; cf.rcArea.bottom = m_nHeight; ImmSetCompositionWindow(hImc, &cf); // ハンドルの解放 ImmReleaseContext(m_hWnd,hImc); } } }