/** * 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 エディタ上におけるポジションを割り出す関数です。 * @param x [in] マウスのx座標 * @param y [in] マウスのy座標 * @return 範囲を超えているときはfalseが返りますが、xがエディタ内にありかつ * yが最終行を超えているときはfalseを返しつつポジションも割り出されます。 */ bool CFootyView::CalcInfoFromMouse(int x,int y,CEditPosition *pPos) { FOOTY2_ASSERT( pPos ); // 宣言 size_t nEthicColumn = 0; size_t nPosition; size_t nLineFromTop; CEthicLine cMouseLine; // 適合範囲外 if (x < m_nLineCountWidth) return false; if (y < m_nRulerHeight) return false; // 計算する nLineFromTop = (size_t) (y - m_nRulerHeight) / (m_pFonts->GetHeight() + m_nHeightMargin); nEthicColumn = (size_t)m_nFirstVisibleColumn + (x - m_nLineCountWidth + (m_pFonts->GetWidth() + m_nWidthMargin) / 2) / (m_pFonts->GetWidth() + m_nWidthMargin); // そこからポジションの割り出し cMouseLine = *m_pDocuments->GetFirstVisible(m_nViewID); if (cMouseLine.MoveEthicNext(m_pDocuments->GetLineList(),nLineFromTop)) { nPosition = cMouseLine.GetLinePointer()->CalcRealPosition (cMouseLine.GetEthicNum(),nEthicColumn, m_pDocuments->GetLapelColumn(), m_pDocuments->GetTabLen(), m_pDocuments->GetLapelMode()); pPos->SetPosition(cMouseLine.GetLinePointer(),nPosition); return true; } else // 最終行超えてる { LinePt pLast = m_pDocuments->GetLastLine(); nPosition = pLast->CalcRealPosition (pLast->GetEthicLine() - 1,nEthicColumn, m_pDocuments->GetLapelColumn(), m_pDocuments->GetTabLen(), m_pDocuments->GetLapelMode()); pPos->SetPosition(pLast,nPosition); return false; } }
/** * CFootyDoc::OnBackSpace * @brief BackSpaceキーが押されたときの処理を行います。 * @return どのように再描画するのか * @note 適切な位置へキャレットが移動します。 */ CFootyDoc::RedrawType CFootyDoc::OnBackSpace() { // 宣言 LinePt pLine = m_cCaretPos.GetLinePointer(); size_t nPos = m_cCaretPos.GetPosition(); CUndoBuffer cUndo; RedrawType nType; if ( IsReadOnly() ) return REDRAW_FAILED; // 場合分け if (IsSelecting()) { nType = DeleteSelected(&cUndo); PushBackUndo(&cUndo); return nType; } else // 選択していないとき { if (nPos != 0) // 文字を削除 { bool bIsSurrogatePair = CFootyLine::IsSurrogateTail(pLine->GetLineData()[nPos-1]); RedrawType nNeedRedraw = REDRAW_LINE; // アンドゥ情報を代入する cUndo.m_nUndoType = CUndoBuffer::UNDOTYPE_DELETE; if (bIsSurrogatePair) cUndo.m_strBefore = pLine->m_strLineData.substr(nPos-2,2); else cUndo.m_strBefore = pLine->m_strLineData.substr(nPos-1,1); cUndo.m_cBeforeEnd = m_cCaretPos; // 文字列を削除する if (bIsSurrogatePair) pLine->m_strLineData.erase(nPos-2,2); else pLine->m_strLineData.erase(nPos-1,1); size_t nBeforeEthic = pLine->GetEthicLine(); if (SetLineInfo(pLine, false/*改行を含むか by Tetr@pod*/)) nNeedRedraw = REDRAW_ALL; if (nBeforeEthic != pLine->GetEthicLine()) nNeedRedraw = REDRAW_ALL; // ポジションを移動して if (bIsSurrogatePair) m_cCaretPos.MoveColumnBackward(&m_lsLines,2); else m_cCaretPos.MoveColumnBackward(&m_lsLines,1); // アンドゥ情報を格納する cUndo.m_cBeforeStart = m_cCaretPos; PushBackUndo(&cUndo); SendMoveCaretCallBack(); return nNeedRedraw; } else // 改行を削除 { if (pLine != m_lsLines.begin()) { // 次の行ポインタ取得 LinePt pPrevLine = pLine; pPrevLine--; // アンドゥ情報を代入しつつキャレット位置を移動する cUndo.m_nUndoType = CUndoBuffer::UNDOTYPE_DELETE; cUndo.m_strBefore = L"\r\n"; cUndo.m_cBeforeEnd = m_cCaretPos; m_cCaretPos.MoveColumnBackward(&m_lsLines,1); cUndo.m_cBeforeStart = m_cCaretPos; PushBackUndo(&cUndo); // 行の結合 pPrevLine->m_strLineData += pLine->GetLineData(); // 現在の位置を削除する DeleteLine(pLine); // 情報を更新する LinePt pNextLine = pPrevLine; pNextLine++; SetLineInfo(pPrevLine,pNextLine, false); SendMoveCaretCallBack(); return REDRAW_ALL; } else return REDRAW_NONE; } } }