/** Erlang アウトライン解析 @par 主な仮定と方針 関数宣言は1カラム目から記載されている. @par 解析アルゴリズム 1カラム目がアルファベットの場合: 関数らしいとして解析開始 / 関数名を保存 スペースは読み飛ばす ( を発見したら ) まで引数を数える.その場合入れ子の括弧と文字列を考慮 -> または when があれば関数定義と見なす(次の行にまたがっても良い) 途中 % (コメント) が現れたら行末まで読み飛ばす */ void CDocOutline::MakeFuncList_Erlang( CFuncInfoArr* pcFuncInfoArr ) { COutlineErlang erl_state_machine; CLogicInt nLineCount; for( nLineCount = CLogicInt(0); nLineCount < m_pcDocRef->m_cDocLineMgr.GetLineCount(); ++nLineCount ){ CLogicInt nLineLen; const wchar_t* pLine = m_pcDocRef->m_cDocLineMgr.GetLine(nLineCount)->GetDocLineStrWithEOL(&nLineLen); if( erl_state_machine.parse( pLine, nLineLen, nLineCount )){ /* カーソル位置変換 物理位置(行頭からのバイト数、折り返し無し行位置) → レイアウト位置(行頭からの表示桁位置、折り返しあり行位置) */ CLayoutPoint ptPosXY; m_pcDocRef->m_cLayoutMgr.LogicToLayout( CLogicPoint(CLogicInt(0), erl_state_machine.GetFuncLine()), &ptPosXY ); pcFuncInfoArr->AppendData( erl_state_machine.GetFuncLine() + CLogicInt(1), ptPosXY.GetY2() + CLayoutInt(1), erl_state_machine.GetFuncName(), 0, 0 ); } } }
void CMruListener::OnAfterLoad(const SLoadInfo& sLoadInfo) { CEditDoc* pcDoc = GetListeningDoc(); CMRUFile cMRU; EditInfo eiOld; bool bIsExistInMRU = cMRU.GetEditInfo(pcDoc->m_cDocFile.GetFilePath(),&eiOld); //キャレット位置の復元 if( bIsExistInMRU && GetDllShareData().m_Common.m_sFile.GetRestoreCurPosition() ){ //キャレット位置取得 CLayoutPoint ptCaretPos; pcDoc->m_cLayoutMgr.LogicToLayout(eiOld.m_ptCursor, &ptCaretPos); //ビュー取得 CEditView& cView = pcDoc->m_pcEditWnd->GetActiveView(); if( ptCaretPos.GetY2() >= pcDoc->m_cLayoutMgr.GetLineCount() ){ //ファイルの最後に移動 cView.GetCommander().HandleCommand( F_GOFILEEND, false, 0, 0, 0, 0 ); } else{ cView.GetTextArea().SetViewTopLine( eiOld.m_nViewTopLine ); // 2001/10/20 novice cView.GetTextArea().SetViewLeftCol( eiOld.m_nViewLeftCol ); // 2001/10/20 novice // From Here Mar. 28, 2003 MIK // 改行の真ん中にカーソルが来ないように。 const CDocLine *pTmpDocLine = pcDoc->m_cDocLineMgr.GetLine( eiOld.m_ptCursor.GetY2() ); // 2008.08.22 ryoji 改行単位の行番号を渡すように修正 if( pTmpDocLine ){ if( pTmpDocLine->GetLengthWithoutEOL() < eiOld.m_ptCursor.x ) ptCaretPos.x--; } // To Here Mar. 28, 2003 MIK cView.GetCaret().MoveCursor( ptCaretPos, true ); cView.GetCaret().m_nCaretPosX_Prev = cView.GetCaret().GetCaretLayoutPos().GetX2(); } } // ブックマーク復元 // 2002.01.16 hor if( bIsExistInMRU ){ if( GetDllShareData().m_Common.m_sFile.GetRestoreBookmarks() ){ CBookmarkManager(&pcDoc->m_cDocLineMgr).SetBookMarks(eiOld.m_szMarkLines); } } else{ eiOld.m_szMarkLines[0] = L'\0'; } // MRUリストへの登録 EditInfo eiNew; pcDoc->GetEditInfo(&eiNew); // 2014.07.04 ブックマークの保持(エディタが落ちたときブックマークが消えるため) if( bIsExistInMRU ){ if( GetDllShareData().m_Common.m_sFile.GetRestoreBookmarks() ){ // SetBookMarksでデータがNUL区切りに書き換わっているので再取得 cMRU.GetEditInfo(pcDoc->m_cDocFile.GetFilePath(),&eiOld); auto_strcpy(eiNew.m_szMarkLines, eiOld.m_szMarkLines); } } cMRU.Add( &eiNew ); }
//! 同一ファイルの再オープン void CDocFileOperation::ReloadCurrentFile( ECodeType nCharCode //!< [in] 文字コード種別 ) { //プラグイン:DocumentCloseイベント実行 CPlug::Array plugs; CWSHIfObj::List params; CJackManager::getInstance()->GetUsablePlug( PP_DOCUMENT_CLOSE, 0, &plugs ); for( CPlug::ArrayIter it = plugs.begin(); it != plugs.end(); it++ ){ (*it)->Invoke(&m_pcDocRef->m_pcEditWnd->GetActiveView(), params); } if( !fexist(m_pcDocRef->m_cDocFile.GetFilePath()) ){ /* ファイルが存在しない */ // Jul. 26, 2003 ryoji BOMを標準設定に // IsBomDefOn使用 2013/5/17 Uchi m_pcDocRef->m_cDocFile.SetCodeSet( nCharCode, CCodeTypeName( nCharCode ).IsBomDefOn() ); // カーソル位置表示を更新する // 2008.07.22 ryoji m_pcDocRef->m_pcEditWnd->GetActiveView().GetCaret().ShowCaretPosInfo(); return; } //カーソル位置保存 CLayoutInt nViewTopLine = m_pcDocRef->m_pcEditWnd->GetActiveView().GetTextArea().GetViewTopLine(); /* 表示域の一番上の行(0開始) */ CLayoutInt nViewLeftCol = m_pcDocRef->m_pcEditWnd->GetActiveView().GetTextArea().GetViewLeftCol(); /* 表示域の一番左の桁(0開始) */ CLayoutPoint ptCaretPosXY = m_pcDocRef->m_pcEditWnd->GetActiveView().GetCaret().GetCaretLayoutPos(); //ロード SLoadInfo sLoadInfo; sLoadInfo.cFilePath=m_pcDocRef->m_cDocFile.GetFilePath(); sLoadInfo.eCharCode=nCharCode; sLoadInfo.bViewMode=CAppMode::getInstance()->IsViewMode(); // 2014.06.13 IsEditable->IsViewModeに戻す。かわりに bForceNoMsgを追加 sLoadInfo.bWritableNoMsg = !m_pcDocRef->IsEditable(); // すでに編集できない状態ならファイルロックのメッセージを表示しない sLoadInfo.bRequestReload=true; bool bRet = this->DoLoadFlow(&sLoadInfo); // カーソル位置復元 (※ここではオプションのカーソル位置復元(=改行単位)が指定されていない場合でも復元する) // 2007.08.23 ryoji 表示領域復元 if( ptCaretPosXY.GetY2() < m_pcDocRef->m_cLayoutMgr.GetLineCount() ){ m_pcDocRef->m_pcEditWnd->GetActiveView().GetTextArea().SetViewTopLine(nViewTopLine); m_pcDocRef->m_pcEditWnd->GetActiveView().GetTextArea().SetViewLeftCol(nViewLeftCol); } m_pcDocRef->m_pcEditWnd->GetActiveView().GetCaret().MoveCursorProperly( ptCaretPosXY, true ); // 2007.08.23 ryoji MoveCursor()->MoveCursorProperly() m_pcDocRef->m_pcEditWnd->GetActiveView().GetCaret().m_nCaretPosX_Prev = m_pcDocRef->m_pcEditWnd->GetActiveView().GetCaret().GetCaretLayoutPos().GetX2(); // 2006.09.01 ryoji オープン後自動実行マクロを実行する if( bRet ){ m_pcDocRef->RunAutoMacro( GetDllShareData().m_Common.m_sMacro.m_nMacroOnOpened ); //プラグイン:DocumentOpenイベント実行 CPlug::Array plugs; CWSHIfObj::List params; CJackManager::getInstance()->GetUsablePlug( PP_DOCUMENT_OPEN, 0, &plugs ); for( CPlug::ArrayIter it = plugs.begin(); it != plugs.end(); it++ ){ (*it)->Invoke(&m_pcDocRef->m_pcEditWnd->GetActiveView(), params); } } }
/* 現在位置の単語選択 */ bool CViewCommander::Command_SELECTWORD( CLayoutPoint* pptCaretPos ) { CLayoutRange sRange; CLogicInt nIdx; if( m_pCommanderView->GetSelectionInfo().IsTextSelected() ){ /* テキストが選択されているか */ /* 現在の選択範囲を非選択状態に戻す */ m_pCommanderView->GetSelectionInfo().DisableSelectArea( true ); } CLayoutPoint ptCaretPos = (NULL == pptCaretPos ? GetCaret().GetCaretLayoutPos() : *pptCaretPos); const CLayout* pcLayout = GetDocument()->m_cLayoutMgr.SearchLineByLayoutY( ptCaretPos.GetY2() ); if( NULL == pcLayout ){ return false; // 単語選択に失敗 } /* 指定された桁に対応する行のデータ内の位置を調べる */ nIdx = m_pCommanderView->LineColumnToIndex( pcLayout, ptCaretPos.GetX2() ); /* 現在位置の単語の範囲を調べる */ if( GetDocument()->m_cLayoutMgr.WhereCurrentWord( ptCaretPos.GetY2(), nIdx, &sRange, NULL, NULL ) ){ // 指定された行のデータ内の位置に対応する桁の位置を調べる // 2007.10.15 kobake 既にレイアウト単位なので変換は不要 /* pcLayout = GetDocument()->m_cLayoutMgr.SearchLineByLayoutY( sRange.GetFrom().GetY2() ); sRange.SetFromX( m_pCommanderView->LineIndexToColumn( pcLayout, sRange.GetFrom().x ) ); pcLayout = GetDocument()->m_cLayoutMgr.SearchLineByLayoutY( sRange.GetTo().GetY2() ); sRange.SetToX( m_pCommanderView->LineIndexToColumn( pcLayout, sRange.GetTo().x ) ); */ /* 選択範囲の変更 */ // 2005.06.24 Moca m_pCommanderView->GetSelectionInfo().SetSelectArea( sRange ); /* 選択領域描画 */ m_pCommanderView->GetSelectionInfo().DrawSelectArea(); /* 単語の先頭にカーソルを移動 */ GetCaret().MoveCursor( sRange.GetTo(), true ); GetCaret().m_nCaretPosX_Prev = GetCaret().GetCaretLayoutPos().GetX2(); return true; // 単語選択に成功。 } else { return false; // 単語選択に失敗 } }
/*! 対括弧の強調表示 @date 2002/09/18 ai @date 2003/02/18 ai 再描画対応の為大改造 */ void CEditView::DrawBracketPair( bool bDraw ) { // 03/03/06 ai すべて置換、すべて置換後のUndo&Redoがかなり遅い問題に対応 if( m_bDoing_UndoRedo || !GetDrawSwitch() ){ return; } if( !m_pTypeData->m_ColorInfoArr[COLORIDX_BRACKET_PAIR].m_bDisp ){ return; } // 括弧の強調表示位置が未登録の場合は終了 if( m_ptBracketPairPos_PHY.HasNegative() || m_ptBracketCaretPos_PHY.HasNegative() ){ return; } // 描画指定(bDraw=true) かつ // ( テキストが選択されている 又は // 選択範囲を描画している 又は // フォーカスを持っていない 又は // アクティブなペインではない ) 場合は終了 if( bDraw &&( GetSelectionInfo().IsTextSelected() || GetSelectionInfo().m_bDrawSelectArea || !m_bDrawBracketPairFlag || ( m_pcEditWnd->GetActivePane() != m_nMyIndex ) ) ){ return; } CGraphics gr; gr.Init(::GetDC(GetHwnd())); bool bCaretChange = false; gr.SetTextBackTransparent(true); for( int i = 0; i < 2; i++ ) { // i=0:対括弧,i=1:カーソル位置の括弧 // 2011.11.23 ryoji 対括弧 -> カーソル位置の括弧 の順に処理順序を変更 // # { と } が異なる行にある場合に { を BS で消すと } の強調表示が解除されない問題(Wiki BugReport/89)の対策 // # この順序変更によりカーソル位置が括弧でなくなっていても対括弧があれば対括弧側の強調表示は解除される CLayoutPoint ptColLine; if( i == 0 ){ m_pcEditDoc->m_cLayoutMgr.LogicToLayout( m_ptBracketPairPos_PHY, &ptColLine ); }else{ m_pcEditDoc->m_cLayoutMgr.LogicToLayout( m_ptBracketCaretPos_PHY, &ptColLine ); } if ( ( ptColLine.x >= GetTextArea().GetViewLeftCol() ) && ( ptColLine.x <= GetTextArea().GetRightCol() ) && ( ptColLine.y >= GetTextArea().GetViewTopLine() ) && ( ptColLine.y <= GetTextArea().GetBottomLine() ) ) { // 表示領域内の場合 if( !bDraw && GetSelectionInfo().m_bDrawSelectArea && ( 0 == IsCurrentPositionSelected( ptColLine ) ) ) { // 選択範囲描画済みで消去対象の括弧が選択範囲内の場合 continue; } const CLayout* pcLayout; CLogicInt nLineLen; const wchar_t* pLine = m_pcEditDoc->m_cLayoutMgr.GetLineStr( ptColLine.GetY2(), &nLineLen, &pcLayout ); if( pLine ) { EColorIndexType nColorIndex; CLogicInt OutputX = LineColumnToIndex( pcLayout, ptColLine.GetX2() ); if( bDraw ) { nColorIndex = COLORIDX_BRACKET_PAIR; } else{ if( IsBracket( pLine, OutputX, CLogicInt(1) ) ){ DispPos _sPos(0,0); // 注意:この値はダミー。CheckChangeColorでの参照位置は不正確 SColorStrategyInfo _sInfo; SColorStrategyInfo* pInfo = &_sInfo; pInfo->m_pDispPos = &_sPos; pInfo->m_pcView = this; // 03/10/24 ai 折り返し行のColorIndexが正しく取得できない問題に対応 // 2009.02.07 ryoji GetColorIndex に渡すインデックスの仕様変更(元はこっちの仕様だった模様) CColor3Setting cColor = GetColorIndex( pcLayout, ptColLine.GetY2(), OutputX, pInfo ); nColorIndex = cColor.eColorIndex2; } else{ SetBracketPairPos( false ); break; } } CTypeSupport cCuretLineBg(this,COLORIDX_CARETLINEBG); EColorIndexType nColorIndexBg = (cCuretLineBg.IsDisp() && ptColLine.GetY2() == GetCaret().GetCaretLayoutPos().GetY2() ? COLORIDX_CARETLINEBG : CTypeSupport(this,COLORIDX_EVENLINEBG).IsDisp() && ptColLine.GetY2() % 2 == 1 ? COLORIDX_EVENLINEBG : COLORIDX_TEXT); // 03/03/03 ai カーソルの左に括弧があり括弧が強調表示されている状態でShift+←で選択開始すると // 選択範囲内に反転表示されない部分がある問題の修正 CLayoutInt caretX = GetCaret().GetCaretLayoutPos().GetX2(); bool bCaretHide = (!bCaretChange && (ptColLine.x == caretX || ptColLine.x + 1 == caretX) && GetCaret().GetCaretShowFlag()); if( bCaretHide ){ bCaretChange = true; GetCaret().HideCaret_( GetHwnd() ); // キャレットが一瞬消えるのを防止 } { int nWidth = GetTextMetrics().GetHankakuDx(); int nHeight = GetTextMetrics().GetHankakuDy(); int nLeft = (GetTextArea().GetDocumentLeftClientPointX()) + GetTextMetrics().GetCharPxWidth(ptColLine.x); int nTop = (Int)( ptColLine.GetY2() - GetTextArea().GetViewTopLine() ) * nHeight + GetTextArea().GetAreaTop(); CLayoutXInt charsWidth = m_pcEditDoc->m_cLayoutMgr.GetLayoutXOfChar(pLine, nLineLen, OutputX); //色設定 CTypeSupport cTextType(this,COLORIDX_TEXT); cTextType.SetGraphicsState_WhileThisObj(gr); // 2013.05.24 背景色がテキストの背景色と同じならカーソル行の背景色を適用 CTypeSupport cColorIndexType(this,nColorIndex); CTypeSupport cColorIndexBgType(this,nColorIndexBg); CTypeSupport* pcColorBack = &cColorIndexType; if( cColorIndexType.GetBackColor() == cTextType.GetBackColor() && nColorIndexBg != COLORIDX_TEXT ){ pcColorBack = &cColorIndexBgType; } SetCurrentColor( gr, nColorIndex, nColorIndex, nColorIndexBg ); bool bTrans = false; // DEBUG_TRACE( _T("DrawBracket %d %d ") , ptColLine.y, ptColLine.x ); if( IsBkBitmap() && cTextType.GetBackColor() == pcColorBack->GetBackColor() ){ bTrans = true; RECT rcChar; rcChar.left = nLeft; rcChar.top = nTop; rcChar.right = nLeft + GetTextMetrics().GetCharPxWidth(charsWidth); rcChar.bottom = nTop + nHeight; HDC hdcBgImg = ::CreateCompatibleDC(gr); HBITMAP hBmpOld = (HBITMAP)::SelectObject(hdcBgImg, m_pcEditDoc->m_hBackImg); DrawBackImage(gr, rcChar, hdcBgImg); ::SelectObject(hdcBgImg, hBmpOld); ::DeleteDC(hdcBgImg); } DispPos sPos(nWidth, nHeight); sPos.InitDrawPos(CMyPoint(nLeft, nTop)); GetTextDrawer().DispText(gr, &sPos, 0, &pLine[OutputX], 1, bTrans); GetTextDrawer().DispNoteLine(gr, nTop, nTop + nHeight, nLeft, nLeft + (Int)charsWidth * nWidth); // 2006.04.30 Moca 対括弧の縦線対応 GetTextDrawer().DispVerticalLines(gr, nTop, nTop + nHeight, ptColLine.x, ptColLine.x + charsWidth); //※括弧が全角幅である場合を考慮 cTextType.RewindGraphicsState(gr); } if( ( m_pcEditWnd->GetActivePane() == m_nMyIndex ) && ( ( ptColLine.y == GetCaret().GetCaretLayoutPos().GetY() ) || ( ptColLine.y - 1 == GetCaret().GetCaretLayoutPos().GetY() ) ) ){ // 03/02/27 ai 行の間隔が"0"の時にアンダーラインが欠ける事がある為修正 GetCaret().m_cUnderLine.CaretUnderLineON( true, false ); } } } } if( bCaretChange ){ GetCaret().ShowCaret_( GetHwnd() ); // キャレットが一瞬消えるのを防止 } ::ReleaseDC( GetHwnd(), gr ); }
/*! アセンブラ アウトライン解析 @author MIK @date 2004.04.12 作り直し */ void CDocOutline::MakeTopicList_asm( CFuncInfoArr* pcFuncInfoArr ) { CLogicInt nTotalLine; nTotalLine = m_pcDocRef->m_cDocLineMgr.GetLineCount(); for( CLogicInt nLineCount = CLogicInt(0); nLineCount < nTotalLine; nLineCount++ ){ const WCHAR* pLine; CLogicInt nLineLen; WCHAR* pTmpLine; int length; int offset; #define MAX_ASM_TOKEN 2 WCHAR* token[MAX_ASM_TOKEN]; int j; WCHAR* p; //1行取得する。 pLine = m_pcDocRef->m_cDocLineMgr.GetLine(nLineCount)->GetDocLineStrWithEOL(&nLineLen); if( pLine == NULL ) break; //作業用にコピーを作成する。バイナリがあったらその後ろは知らない。 pTmpLine = wcsdup( pLine ); if( pTmpLine == NULL ) break; if( wcslen( pTmpLine ) >= (unsigned int)nLineLen ){ //バイナリを含んでいたら短くなるので... pTmpLine[ nLineLen ] = L'\0'; //指定長で切り詰め } //行コメント削除 p = wcsstr( pTmpLine, L";" ); if( p ) *p = L'\0'; length = wcslen( pTmpLine ); offset = 0; //トークンに分割 for( j = 0; j < MAX_ASM_TOKEN; j++ ) token[ j ] = NULL; for( j = 0; j < MAX_ASM_TOKEN; j++ ){ token[ j ] = my_strtok<WCHAR>( pTmpLine, length, &offset, L" \t\r\n" ); if( token[ j ] == NULL ) break; //トークンに含まれるべき文字でないか? if( wcsstr( token[ j ], L"\"") != NULL || wcsstr( token[ j ], L"\\") != NULL || wcsstr( token[ j ], L"'" ) != NULL ){ token[ j ] = NULL; break; } } if( token[ 0 ] != NULL ){ //トークンが1個以上ある int nFuncId = -1; WCHAR* entry_token = NULL; length = wcslen( token[ 0 ] ); if( length >= 2 && token[ 0 ][ length - 1 ] == L':' ){ //ラベル token[ 0 ][ length - 1 ] = L'\0'; nFuncId = 51; entry_token = token[ 0 ]; } else if( token[ 1 ] != NULL ){ //トークンが2個以上ある if( wcsicmp( token[ 1 ], L"proc" ) == 0 ){ //関数 nFuncId = 50; entry_token = token[ 0 ]; }else if( wcsicmp( token[ 1 ], L"endp" ) == 0 ){ //関数終了 nFuncId = 52; entry_token = token[ 0 ]; //}else //if( my_stricmp( token[ 1 ], _T("macro") ) == 0 ){ //マクロ // nFuncId = -1; // entry_token = token[ 0 ]; //}else //if( my_stricmp( token[ 1 ], _T("struc") ) == 0 ){ //構造体 // nFuncId = -1; // entry_token = token[ 0 ]; } } if( nFuncId >= 0 ){ /* カーソル位置変換 物理位置(行頭からのバイト数、折り返し無し行位置) → レイアウト位置(行頭からの表示桁位置、折り返しあり行位置) */ CLayoutPoint ptPos; m_pcDocRef->m_cLayoutMgr.LogicToLayout( CLogicPoint(0, nLineCount), &ptPos ); pcFuncInfoArr->AppendData( nLineCount + CLogicInt(1), ptPos.GetY2() + CLayoutInt(1), entry_token, nFuncId ); } } free( pTmpLine ); } return; }
// トグル用のフラグに変更 20060201 aroka BOOL CViewCommander::Command_FUNCLIST( int nAction, int _nOutlineType = OUTLINE_DEFAULT ) { static bool bIsProcessing = false; //アウトライン解析処理中フラグ //アウトラインプラグイン内でのEditor.Outline呼び出しによる再入を禁止する if( bIsProcessing )return FALSE; bIsProcessing = true; // 自プロセスが前面にいるかどうか調べる DWORD dwPid1, dwPid2; dwPid1 = ::GetCurrentProcessId(); ::GetWindowThreadProcessId( ::GetForegroundWindow(), &dwPid2 ); bool bForeground = (dwPid1 == dwPid2); EOutlineType nOutlineType = (EOutlineType)_nOutlineType; //2007.11.29 kobake // if( bCheckOnly ){ // return TRUE; // } static CFuncInfoArr cFuncInfoArr; // int nLine; // int nListType; std::tstring sTitleOverride; //プラグインによるダイアログタイトル上書き // 2001.12.03 hor & 2002.3.13 YAZAKI if( nOutlineType == OUTLINE_DEFAULT ){ /* タイプ別に設定されたアウトライン解析方法 */ nOutlineType = m_pCommanderView->m_pTypeData->m_eDefaultOutline; if( nOutlineType == OUTLINE_CPP ){ if( CheckEXT( GetDocument()->m_cDocFile.GetFilePath(), _T("c") ) ){ nOutlineType = OUTLINE_C; /* これでC関数一覧リストビューになる */ } } } if( NULL != GetEditWindow()->m_cDlgFuncList.GetHwnd() && nAction != SHOW_RELOAD ){ switch(nAction ){ case SHOW_NORMAL: // アクティブにする // 開いているものと種別が同じならActiveにするだけ.異なれば再解析 GetEditWindow()->m_cDlgFuncList.SyncColor(); if( GetEditWindow()->m_cDlgFuncList.CheckListType( nOutlineType )){ if( bForeground ){ ::SetFocus( GetEditWindow()->m_cDlgFuncList.GetHwnd() ); } bIsProcessing = false; return TRUE; } break; case SHOW_TOGGLE: // 閉じる // 開いているものと種別が同じなら閉じる.異なれば再解析 if( GetEditWindow()->m_cDlgFuncList.CheckListType( nOutlineType )){ if( GetEditWindow()->m_cDlgFuncList.IsDocking() ) ::DestroyWindow( GetEditWindow()->m_cDlgFuncList.GetHwnd() ); else ::SendMessageAny( GetEditWindow()->m_cDlgFuncList.GetHwnd(), WM_CLOSE, 0, 0 ); bIsProcessing = false; return TRUE; } break; default: break; } } /* 解析結果データを空にする */ cFuncInfoArr.Empty(); int nListType = nOutlineType; //2011.06.25 syat switch( nOutlineType ){ case OUTLINE_C: // C/C++ は MakeFuncList_C case OUTLINE_CPP: GetDocument()->m_cDocOutline.MakeFuncList_C( &cFuncInfoArr );break; case OUTLINE_PLSQL: GetDocument()->m_cDocOutline.MakeFuncList_PLSQL( &cFuncInfoArr );break; case OUTLINE_JAVA: GetDocument()->m_cDocOutline.MakeFuncList_Java( &cFuncInfoArr );break; case OUTLINE_COBOL: GetDocument()->m_cDocOutline.MakeTopicList_cobol( &cFuncInfoArr );break; case OUTLINE_ASM: GetDocument()->m_cDocOutline.MakeTopicList_asm( &cFuncInfoArr );break; case OUTLINE_PERL: GetDocument()->m_cDocOutline.MakeFuncList_Perl( &cFuncInfoArr );break; // Sep. 8, 2000 genta case OUTLINE_VB: GetDocument()->m_cDocOutline.MakeFuncList_VisualBasic( &cFuncInfoArr );break; // June 23, 2001 N.Nakatani case OUTLINE_WZTXT: GetDocument()->m_cDocOutline.MakeTopicList_wztxt(&cFuncInfoArr);break; // 2003.05.20 zenryaku 階層付テキスト アウトライン解析 case OUTLINE_HTML: GetDocument()->m_cDocOutline.MakeTopicList_html(&cFuncInfoArr, false);break; // 2003.05.20 zenryaku HTML アウトライン解析 case OUTLINE_TEX: GetDocument()->m_cDocOutline.MakeTopicList_tex(&cFuncInfoArr);break; // 2003.07.20 naoh TeX アウトライン解析 case OUTLINE_BOOKMARK: GetDocument()->m_cDocOutline.MakeFuncList_BookMark( &cFuncInfoArr );break; // 2001.12.03 hor case OUTLINE_FILE: GetDocument()->m_cDocOutline.MakeFuncList_RuleFile( &cFuncInfoArr, sTitleOverride );break; // 2002.04.01 YAZAKI アウトライン解析にルールファイルを導入 // case OUTLINE_UNKNOWN: //Jul. 08, 2001 JEPRO 使わないように変更 case OUTLINE_PYTHON: GetDocument()->m_cDocOutline.MakeFuncList_python(&cFuncInfoArr);break; // 2007.02.08 genta case OUTLINE_ERLANG: GetDocument()->m_cDocOutline.MakeFuncList_Erlang(&cFuncInfoArr);break; // 2009.08.10 genta case OUTLINE_XML: GetDocument()->m_cDocOutline.MakeTopicList_html(&cFuncInfoArr, true);break; // 2014.12.25 Moca case OUTLINE_FILETREE: /* 特に何もしない*/ ;break; // 2013.12.08 Moca case OUTLINE_TEXT: // fall though // ここには何も入れてはいけない 2007.02.28 genta 注意書き default: //プラグインから検索する { CPlug::Array plugs; CJackManager::getInstance()->GetUsablePlug( PP_OUTLINE, nOutlineType, &plugs ); if( plugs.size() > 0 ){ assert_warning( 1 == plugs.size() ); //インタフェースオブジェクト準備 CWSHIfObj::List params; COutlineIfObj* objOutline = new COutlineIfObj( cFuncInfoArr ); objOutline->AddRef(); params.push_back( objOutline ); //プラグイン呼び出し ( *plugs.begin() )->Invoke( m_pCommanderView, params ); nListType = objOutline->m_nListType; //ダイアログの表示方法をを上書き sTitleOverride = objOutline->m_sOutlineTitle; //ダイアログタイトルを上書き objOutline->Release(); break; } } //それ以外 GetDocument()->m_cDocOutline.MakeTopicList_txt( &cFuncInfoArr ); break; } /* 解析対象ファイル名 */ _tcscpy( cFuncInfoArr.m_szFilePath, GetDocument()->m_cDocFile.GetFilePath() ); /* アウトライン ダイアログの表示 */ CLayoutPoint poCaret = GetCaret().GetCaretLayoutPos(); if( NULL == GetEditWindow()->m_cDlgFuncList.GetHwnd() ){ GetEditWindow()->m_cDlgFuncList.DoModeless( G_AppInstance(), m_pCommanderView->GetHwnd(), (LPARAM)m_pCommanderView, &cFuncInfoArr, poCaret.GetY2() + CLayoutInt(1), poCaret.GetX2() + CLayoutInt(1), nOutlineType, nListType, m_pCommanderView->m_pTypeData->m_bLineNumIsCRLF /* 行番号の表示 false=折り返し単位/true=改行単位 */ ); }else{ /* アクティブにする */ GetEditWindow()->m_cDlgFuncList.Redraw( nOutlineType, nListType, &cFuncInfoArr, poCaret.GetY2() + 1, poCaret.GetX2() + 1 ); if( bForeground ){ ::SetFocus( GetEditWindow()->m_cDlgFuncList.GetHwnd() ); } } // ダイアログタイトルを上書き if( ! sTitleOverride.empty() ){ GetEditWindow()->m_cDlgFuncList.SetWindowText( sTitleOverride.c_str() ); } // 解析結果を折りたたみに反映する if (m_pCommanderView->m_pTypeData->m_ColorInfoArr[COLORIDX_FOLDING].m_bDisp && nOutlineType != OUTLINE_BOOKMARK && nOutlineType != OUTLINE_FILETREE) { CDocFoldMgr::getInstance()->RefreshFromOutline(&cFuncInfoArr, m_pCommanderView->GetDocument()->m_cDocLineMgr); if (m_pCommanderView->m_pTypeData->m_ColorInfoArr[COLORIDX_FOLDING].m_bDisp) { m_pCommanderView->m_pcEditDoc->OnChangeSetting(); } } bIsProcessing = false; return TRUE; }
/*! テキスト・トピックリスト作成 @date 2002.04.01 YAZAKI CDlgFuncList::SetText()を使用するように改訂。 @date 2002.11.03 Moca 階層が最大値を超えるとバッファオーバーランするのを修正 最大値以上は追加せずに無視する @date 2007.8頃 kobake 機械的にUNICODE化 @date 2007.11.29 kobake UNICODE対応できてなかったので修正 */ void CDocOutline::MakeTopicList_txt( CFuncInfoArr* pcFuncInfoArr ) { using namespace WCODE; //見出し記号 const wchar_t* pszStarts = GetDllShareData().m_Common.m_sFormat.m_szMidashiKigou; int nStartsLen = wcslen( pszStarts ); /* ネストの深さは、nMaxStackレベルまで、ひとつのヘッダは、最長32文字まで区別 (32文字まで同じだったら同じものとして扱います) */ const int nMaxStack = 32; // ネストの最深 int nDepth = 0; // いまのアイテムの深さを表す数値。 wchar_t pszStack[nMaxStack][32]; wchar_t szTitle[32]; // 一時領域 CLogicInt nLineCount; bool b278a = false; for( nLineCount = CLogicInt(0); nLineCount < m_pcDocRef->m_cDocLineMgr.GetLineCount(); ++nLineCount ) { //行取得 CLogicInt nLineLen; const wchar_t* pLine = m_pcDocRef->m_cDocLineMgr.GetLine(nLineCount)->GetDocLineStrWithEOL(&nLineLen); if( NULL == pLine )break; //行頭の空白飛ばし int i; for( i = 0; i < nLineLen; ++i ){ if( WCODE::IsBlank(pLine[i]) ){ continue; } break; } if( i >= nLineLen ){ continue; } //先頭文字が見出し記号のいずれかであれば、次へ進む int j; int nCharChars; int nCharChars2; nCharChars = CNativeW::GetSizeOfChar( pLine, nLineLen, i ); for( j = 0; j < nStartsLen; j += nCharChars2 ){ // 2005-09-02 D.S.Koba GetSizeOfChar nCharChars2 = CNativeW::GetSizeOfChar( pszStarts, nStartsLen, j ); if( nCharChars == nCharChars2 ){ if( 0 == wmemcmp( &pLine[i], &pszStarts[j], nCharChars ) ){ break; } } } if( j >= nStartsLen ){ continue; } //見出し種類の判別 -> szTitle if( pLine[i] == L'(' ){ if ( IsInRange(pLine[i + 1], L'0', L'9') ) wcscpy( szTitle, L"(0)" ); //数字 else if ( IsInRange(pLine[i + 1], L'A', L'Z') ) wcscpy( szTitle, L"(A)" ); //英大文字 else if ( IsInRange(pLine[i + 1], L'a', L'z') ) wcscpy( szTitle, L"(a)" ); //英小文字 else continue; //※「(」の次が英数字で無い場合、見出しとみなさない } else if( IsInRange(pLine[i], L'0', L'9') ) wcscpy( szTitle, L"0" ); // 全角数字 else if( IsInRange(pLine[i], L'�@', L'�S') || pLine[i] == L'\u24ea' || IsInRange(pLine[i], L'\u3251', L'\u325f') || IsInRange(pLine[i], L'\u32b1', L'\u32bf') ) wcscpy( szTitle, L"�@" ); // �@〜�S ○0 ○21○35 ○36○50 else if( IsInRange(pLine[i], L'�T', L'\u216f') ) wcscpy( szTitle, L"�T" ); // �T〜�] XIXIILCDM else if( IsInRange(pLine[i], L'�@', L'\u217f') ) wcscpy( szTitle, L"�T" ); // �T〜�] xixiilcdm else if( IsInRange(pLine[i], L'\u2474', L'\u2487') ) wcscpy( szTitle, L"\u2474" ); // (1)-(20) else if( IsInRange(pLine[i], L'\u2488', L'\u249b') ) wcscpy( szTitle, L"\u2488" ); // 1.-20. else if( IsInRange(pLine[i], L'\u249c', L'\u24b5') ) wcscpy( szTitle, L"\u249c" ); // (a)-(z) else if( IsInRange(pLine[i], L'\u24b6', L'\u24cf') ) wcscpy( szTitle, L"\u24b6" ); // ○A-○Z else if( IsInRange(pLine[i], L'\u24d0', L'\u24e9') ) wcscpy( szTitle, L"\u24d0" ); // ○a-○z else if( IsInRange(pLine[i], L'\u24eb', L'\u24f4') ){ // ●11-●20 if(b278a){ wcscpy( szTitle, L"\u278a" ); } else{ wcscpy( szTitle, L"\u2776" ); } } else if( IsInRange(pLine[i], L'\u24f5', L'\u24fe') ) wcscpy( szTitle, L"\u24f5" ); // ◎1-◎10 else if( IsInRange(pLine[i], L'\u2776', L'\u277f') ) wcscpy( szTitle, L"\u2776" ); // ●1-●10 else if( IsInRange(pLine[i], L'\u2780', L'\u2789') ) wcscpy( szTitle, L"\u2780" ); // ○1-○10 else if( IsInRange(pLine[i], L'\u278a', L'\u2793') ){ wcscpy( szTitle, L"\u278a" ); b278a = true; } // ●1-●10(SANS-SERIF) else if( IsInRange(pLine[i], L'\u3220', L'\u3229') ) wcscpy( szTitle, L"\ua3220" ); // (一)-(十) else if( IsInRange(pLine[i], L'\u3280', L'\u3289') ) wcscpy( szTitle, L"\u3220" ); // ○一-○十 else if( IsInRange(pLine[i], L'\u32d0', L'\u32fe') ) wcscpy( szTitle, L"\u32d0" ); // ○ア-○ヲ else if( wcschr(L"〇一二三四五六七八九十百零壱弐参伍", pLine[i]) ) wcscpy( szTitle, L"一" ); //漢数字 else{ wcsncpy( szTitle, &pLine[i], nCharChars ); // 先頭文字をszTitleに保持。 szTitle[nCharChars] = L'\0'; } /* 「見出し記号」に含まれる文字で始まるか、 (0、(1、...(9、(A、(B、...(Z、(a、(b、...(z で始まる行は、アウトライン結果に表示する。 */ //行文字列から改行を取り除く pLine -> pszText const wchar_t* pszText = &pLine[i]; nLineLen -= i; const bool bExtEol = GetDllShareData().m_Common.m_sEdit.m_bEnableExtEol; for( i = 0; i < nLineLen; ++i ){ if( WCODE::IsLineDelimiter(pszText[i], bExtEol) ){ break; } } std::wstring strText( pszText, i ); pszText = strText.c_str(); /* カーソル位置変換 物理位置(行頭からのバイト数、折り返し無し行位置) → レイアウト位置(行頭からの表示桁位置、折り返しあり行位置) */ CLayoutPoint ptPos; m_pcDocRef->m_cLayoutMgr.LogicToLayout( CLogicPoint(0, nLineCount), &ptPos ); /* nDepthを計算 */ int k; bool bAppend = true; for ( k = 0; k < nDepth; k++ ){ int nResult = wcscmp( pszStack[k], szTitle ); if ( nResult == 0 ){ break; } } if ( k < nDepth ){ // ループ途中でbreak;してきた。=今までに同じ見出しが存在していた。 // ので、同じレベルに合わせてAppendData. nDepth = k; } else if( nMaxStack > k ){ // いままでに同じ見出しが存在しなかった。 // ので、pszStackにコピーしてAppendData. wcscpy(pszStack[nDepth], szTitle); } else{ // 2002.11.03 Moca 最大値を超えるとバッファオーバーラン // nDepth = nMaxStack; bAppend = false; } if( bAppend ){ pcFuncInfoArr->AppendData( nLineCount + CLogicInt(1), ptPos.GetY2() + CLayoutInt(1) , pszText, 0, nDepth ); nDepth++; } } return; }
/*! 階層付きテキスト アウトライン解析 @author zenryaku @date 2003.05.20 zenryaku 新規作成 @date 2003.05.25 genta 実装方法一部修正 @date 2003.06.21 Moca 階層が2段以上深くなる場合を考慮 */ void CDocOutline::MakeTopicList_wztxt(CFuncInfoArr* pcFuncInfoArr) { int levelPrev = 0; bool bExtEol = GetDllShareData().m_Common.m_sEdit.m_bEnableExtEol; for(CLogicInt nLineCount=CLogicInt(0);nLineCount<m_pcDocRef->m_cDocLineMgr.GetLineCount();nLineCount++) { const wchar_t* pLine; CLogicInt nLineLen; pLine = m_pcDocRef->m_cDocLineMgr.GetLine(nLineCount)->GetDocLineStrWithEOL(&nLineLen); if(!pLine) { break; } // May 25, 2003 genta 判定順序変更 if( *pLine == L'.' ) { const wchar_t* pPos; // May 25, 2003 genta int nLength; wchar_t szTitle[1024]; // ピリオドの数=階層の深さを数える for( pPos = pLine + 1 ; *pPos == L'.' ; ++pPos ) ; CLayoutPoint ptPos; m_pcDocRef->m_cLayoutMgr.LogicToLayout( CLogicPoint(0, nLineCount), &ptPos ); int level = pPos - pLine; // 2003.06.27 Moca 階層が2段位上深くなるときは、無題の要素を追加 if( levelPrev < level && level != levelPrev + 1 ){ int dummyLevel; // (無題)を挿入 // ただし,TAG一覧には出力されないように for( dummyLevel = levelPrev + 1; dummyLevel < level; dummyLevel++ ){ pcFuncInfoArr->AppendData( nLineCount+CLogicInt(1), ptPos.GetY2()+CLayoutInt(1), LSW(STR_NO_TITLE1), FUNCINFO_NOCLIPTEXT, dummyLevel - 1 ); } } levelPrev = level; nLength = auto_sprintf(szTitle,L"%d - ", level ); wchar_t *pDest = szTitle + nLength; // 書き込み先 wchar_t *pDestEnd = szTitle + _countof(szTitle) - 2; while( pDest < pDestEnd ) { if( WCODE::IsLineDelimiter(*pPos, bExtEol) || *pPos == L'\0') { break; } else { *pDest++ = *pPos++; } } *pDest = L'\0'; pcFuncInfoArr->AppendData(nLineCount+CLogicInt(1),ptPos.GetY2()+CLayoutInt(1),szTitle, 0, level - 1); } } }
/*! @brief 行桁指定によるカーソル移動 必要に応じて縦/横スクロールもする. 垂直スクロールをした場合はその行数を返す(正/負). @return 縦スクロール行数(負:上スクロール/正:下スクロール) @note 不正な位置が指定された場合には適切な座標値に 移動するため,引数で与えた座標と移動後の座標は 必ずしも一致しない. @note bScrollがfalseの場合にはカーソル位置のみ移動する. trueの場合にはスクロール位置があわせて変更される @note 同じ行の左右移動はアンダーラインを一度消す必要が無いので bUnderlineDoNotOFFを指定すると高速化できる. 同様に同じ桁の上下移動はbVertLineDoNotOFFを指定すると カーソル位置縦線の消去を省いて高速化できる. @date 2001.10.20 deleted by novice AdjustScrollBar()を呼ぶ位置を変更 @date 2004.04.02 Moca 行だけ有効な座標に修正するのを厳密に処理する @date 2004.09.11 genta bDrawスイッチは動作と名称が一致していないので 再描画スイッチ→画面位置調整スイッチと名称変更 @date 2009.08.28 nasukoji テキスト折り返しの「折り返さない」対応 @date 2010.11.27 syat アンダーライン、縦線を消去しないフラグを追加 */ CLayoutInt CCaret::MoveCursor( CLayoutPoint ptWk_CaretPos, //!< [in] 移動先レイアウト位置 bool bScroll, //!< [in] true: 画面位置調整有り false: 画面位置調整無し int nCaretMarginRate, //!< [in] 縦スクロール開始位置を決める値 bool bUnderLineDoNotOFF, //!< [in] アンダーラインを消去しない bool bVertLineDoNotOFF //!< [in] カーソル位置縦線を消去しない ) { CTextArea& area = m_pEditView->GetTextArea(); // スクロール処理 CLayoutInt nScrollRowNum = CLayoutInt(0); CLayoutInt nScrollColNum = CLayoutInt(0); int nCaretMarginY; CLayoutInt nScrollMarginRight; CLayoutInt nScrollMarginLeft; if( 0 >= m_pEditView->GetTextArea().m_nViewColNum ){ return CLayoutInt(0); } if( m_pEditView->GetSelectionInfo().IsMouseSelecting() ){ // 範囲選択中 nCaretMarginY = 0; } else{ // 2001/10/20 novice nCaretMarginY = (Int)m_pEditView->GetTextArea().m_nViewRowNum / nCaretMarginRate; if( 1 > nCaretMarginY ){ nCaretMarginY = 1; } } // 2004.04.02 Moca 行だけ有効な座標に修正するのを厳密に処理する GetAdjustCursorPos( &ptWk_CaretPos ); m_pEditDoc->m_cLayoutMgr.LayoutToLogic( ptWk_CaretPos, &m_ptCaretPos_Logic //カーソル位置。ロジック単位。 ); /* キャレット移動 */ SetCaretLayoutPos(ptWk_CaretPos); // カーソル行アンダーラインのOFF bool bDrawPaint = ptWk_CaretPos.GetY2() != m_pEditView->m_nOldUnderLineYBg; m_cUnderLine.SetUnderLineDoNotOFF( bUnderLineDoNotOFF ); m_cUnderLine.SetVertLineDoNotOFF( bVertLineDoNotOFF ); m_cUnderLine.CaretUnderLineOFF( bScroll, bDrawPaint ); // YAZAKI m_cUnderLine.SetUnderLineDoNotOFF( false ); m_cUnderLine.SetVertLineDoNotOFF( false ); // 水平スクロール量(文字数)の算出 nScrollColNum = CLayoutInt(0); nScrollMarginRight = m_pEditView->GetTextMetrics().GetLayoutXDefault(CKetaXInt(SCROLLMARGIN_RIGHT)); nScrollMarginLeft = m_pEditView->GetTextMetrics().GetLayoutXDefault(CKetaXInt(SCROLLMARGIN_LEFT)); // 2010.08.24 Moca 幅が狭い場合のマージンの調整 { // カーソルが真ん中にあるときに左右にぶれないように CLayoutInt nNoMove = m_pEditView->GetTextMetrics().GetLayoutXDefault(CKetaXInt(SCROLLMARGIN_NOMOVE)); CLayoutInt Keta2Width = m_pEditView->GetTextMetrics().GetLayoutXDefault(CKetaXInt(2)); CLayoutInt a = ((m_pEditView->GetTextArea().m_nViewColNum) - nNoMove) / 2; CLayoutInt nMin = (Keta2Width <= a ? a : CLayoutInt(0)); // 1だと全角移動に支障があるので2以上 nScrollMarginRight = t_min(nScrollMarginRight, nMin); nScrollMarginLeft = t_min(nScrollMarginLeft, nMin); } // Aug. 14, 2005 genta 折り返し幅をLayoutMgrから取得するように if( m_pEditDoc->m_cLayoutMgr.GetMaxLineLayout() > area.m_nViewColNum && ptWk_CaretPos.GetX() >area.GetViewLeftCol() + area.m_nViewColNum - nScrollMarginRight ){ nScrollColNum = ( area.GetViewLeftCol() + area.m_nViewColNum - nScrollMarginRight ) - ptWk_CaretPos.GetX2(); } else if( 0 < area.GetViewLeftCol() && ptWk_CaretPos.GetX() < area.GetViewLeftCol() + nScrollMarginLeft ){ nScrollColNum = area.GetViewLeftCol() + nScrollMarginLeft - ptWk_CaretPos.GetX2(); if( 0 > area.GetViewLeftCol() - nScrollColNum ){ nScrollColNum = area.GetViewLeftCol(); } } // 2013.12.30 bScrollがOFFのときは横スクロールしない if( bScroll ){ m_pEditView->GetTextArea().SetViewLeftCol(m_pEditView->GetTextArea().GetViewLeftCol() - nScrollColNum); }else{ nScrollColNum = 0; } // From Here 2007.07.28 じゅうじ : 表示行数が3行以下の場合の動作改善 /* 垂直スクロール量(行数)の算出 */ // 画面が3行以下 if( m_pEditView->GetTextArea().m_nViewRowNum <= 3 ){ // 移動先は、画面のスクロールラインより上か?(up キー) if( ptWk_CaretPos.y - m_pEditView->GetTextArea().GetViewTopLine() < nCaretMarginY ){ if( ptWk_CaretPos.y < nCaretMarginY ){ //1行目に移動 nScrollRowNum = m_pEditView->GetTextArea().GetViewTopLine(); } else if( m_pEditView->GetTextArea().m_nViewRowNum <= 1 ){ // 画面が1行 nScrollRowNum = m_pEditView->GetTextArea().GetViewTopLine() - ptWk_CaretPos.y; } #if !(0) // COMMENTにすると、上下の空きを死守しない為、縦移動はgoodだが、横移動の場合上下にぶれる else if( m_pEditView->GetTextArea().m_nViewRowNum <= 2 ){ // 画面が2行 nScrollRowNum = m_pEditView->GetTextArea().GetViewTopLine() - ptWk_CaretPos.y; } #endif else { // 画面が3行 nScrollRowNum = m_pEditView->GetTextArea().GetViewTopLine() - ptWk_CaretPos.y + 1; } }else // 移動先は、画面の最大行数-2より下か?(down キー) if( ptWk_CaretPos.y - m_pEditView->GetTextArea().GetViewTopLine() >= (m_pEditView->GetTextArea().m_nViewRowNum - nCaretMarginY - 2) ){ CLayoutInt ii = m_pEditDoc->m_cLayoutMgr.GetLineCount(); if( ii - ptWk_CaretPos.y < nCaretMarginY + 1 && ii - m_pEditView->GetTextArea().GetViewTopLine() < m_pEditView->GetTextArea().m_nViewRowNum ) { } else if( m_pEditView->GetTextArea().m_nViewRowNum <= 2 ){ // 画面が2行、1行 nScrollRowNum = m_pEditView->GetTextArea().GetViewTopLine() - ptWk_CaretPos.y; }else{ // 画面が3行 nScrollRowNum = m_pEditView->GetTextArea().GetViewTopLine() - ptWk_CaretPos.y + 1; } } } // 移動先は、画面のスクロールラインより上か?(up キー) else if( ptWk_CaretPos.y - m_pEditView->GetTextArea().GetViewTopLine() < nCaretMarginY ){ if( ptWk_CaretPos.y < nCaretMarginY ){ //1行目に移動 nScrollRowNum = m_pEditView->GetTextArea().GetViewTopLine(); }else{ nScrollRowNum = -(ptWk_CaretPos.y - m_pEditView->GetTextArea().GetViewTopLine()) + nCaretMarginY; } } // 移動先は、画面の最大行数-2より下か?(down キー) else if( ptWk_CaretPos.y - m_pEditView->GetTextArea().GetViewTopLine() >= m_pEditView->GetTextArea().m_nViewRowNum - nCaretMarginY - 2 ){ CLayoutInt ii = m_pEditDoc->m_cLayoutMgr.GetLineCount(); if( ii - ptWk_CaretPos.y < nCaretMarginY + 1 && ii - m_pEditView->GetTextArea().GetViewTopLine() < m_pEditView->GetTextArea().m_nViewRowNum ) { } else{ nScrollRowNum = -(ptWk_CaretPos.y - m_pEditView->GetTextArea().GetViewTopLine()) + (m_pEditView->GetTextArea().m_nViewRowNum - nCaretMarginY - 2); } } // To Here 2007.07.28 じゅうじ if( bScroll ){ /* スクロール */ if( t_abs( nScrollColNum ) >= m_pEditView->GetTextArea().m_nViewColNum || t_abs( nScrollRowNum ) >= m_pEditView->GetTextArea().m_nViewRowNum ){ m_pEditView->GetTextArea().OffsetViewTopLine(-nScrollRowNum); if( m_pEditView->GetDrawSwitch() ){ m_pEditView->InvalidateRect( NULL ); if( m_pEditView->m_pcEditWnd->GetMiniMap().GetHwnd() ){ m_pEditView->MiniMapRedraw(true); } } } else if( nScrollRowNum != 0 || nScrollColNum != 0 ){ RECT rcClip; RECT rcClip2; RECT rcScroll; m_pEditView->GetTextArea().GenerateTextAreaRect(&rcScroll); if( nScrollRowNum > 0 ){ rcScroll.bottom = m_pEditView->GetTextArea().GetAreaBottom() - (Int)nScrollRowNum * m_pEditView->GetTextMetrics().GetHankakuDy(); m_pEditView->GetTextArea().OffsetViewTopLine(-nScrollRowNum); m_pEditView->GetTextArea().GenerateTopRect(&rcClip,nScrollRowNum); } else if( nScrollRowNum < 0 ){ rcScroll.top = m_pEditView->GetTextArea().GetAreaTop() - (Int)nScrollRowNum * m_pEditView->GetTextMetrics().GetHankakuDy(); m_pEditView->GetTextArea().OffsetViewTopLine(-nScrollRowNum); m_pEditView->GetTextArea().GenerateBottomRect(&rcClip,-nScrollRowNum); } int nScrollColPx = m_pEditView->GetTextMetrics().GetCharPxWidth(nScrollColNum); if( nScrollColNum > 0 ){ rcScroll.left = m_pEditView->GetTextArea().GetAreaLeft(); rcScroll.right = m_pEditView->GetTextArea().GetAreaRight() - nScrollColPx; m_pEditView->GetTextArea().GenerateLeftRect(&rcClip2, nScrollColNum); } else if( nScrollColNum < 0 ){ rcScroll.left = m_pEditView->GetTextArea().GetAreaLeft() - nScrollColPx; m_pEditView->GetTextArea().GenerateRightRect(&rcClip2, -nScrollColNum); } if( m_pEditView->GetDrawSwitch() ){ m_pEditView->ScrollDraw(nScrollRowNum, nScrollColNum, rcScroll, rcClip, rcClip2); if( m_pEditView->m_pcEditWnd->GetMiniMap().GetHwnd() ){ m_pEditView->MiniMapRedraw(false); } } } /* スクロールバーの状態を更新する */ m_pEditView->AdjustScrollBars(); // 2001/10/20 novice } // 横スクロールが発生したら、ルーラー全体を再描画 2002.02.25 Add By KK if (nScrollColNum != 0 ){ //次回DispRuler呼び出し時に再描画。(bDraw=falseのケースを考慮した。) m_pEditView->GetRuler().SetRedrawFlag(); } /* カーソル行アンダーラインのON */ //CaretUnderLineON( bDraw ); //2002.02.27 Del By KK アンダーラインのちらつきを低減 if( bScroll ){ /* キャレットの表示・更新 */ ShowEditCaret(); /* ルーラの再描画 */ HDC hdc = m_pEditView->GetDC(); m_pEditView->GetRuler().DispRuler( hdc ); m_pEditView->ReleaseDC( hdc ); /* アンダーラインの再描画 */ m_cUnderLine.CaretUnderLineON(true, bDrawPaint); /* キャレットの行桁位置を表示する */ ShowCaretPosInfo(); // Sep. 11, 2004 genta 同期スクロールの関数化 // bScroll == FALSEの時にはスクロールしないので,実行しない m_pEditView->SyncScrollV( -nScrollRowNum ); // 方向が逆なので符号反転が必要 m_pEditView->SyncScrollH( -nScrollColNum ); // 方向が逆なので符号反転が必要 } // 02/09/18 対括弧の強調表示 ai Start 03/02/18 ai mod S m_pEditView->DrawBracketPair( false ); m_pEditView->SetBracketPairPos( true ); m_pEditView->DrawBracketPair( true ); // 02/09/18 対括弧の強調表示 ai End 03/02/18 ai mod E return nScrollRowNum; }
/*! 行桁指定によるカーソル移動(座標調整付き) @return 縦スクロール行数(負:上スクロール/正:下スクロール) @note マウス等による移動で不適切な位置に行かないよう座標調整してカーソル移動する @date 2007.08.23 ryoji 関数化(MoveCursorToPoint()から処理を抜き出し) @date 2007.09.26 ryoji 半角文字でも中央で左右にカーソルを振り分ける @date 2007.10.23 kobake 引数説明の誤りを修正 ([in,out]→[in]) @date 2009.02.17 ryoji レイアウト行末以後のカラム位置指定なら末尾文字の前ではなく末尾文字の後に移動する */ CLayoutInt CCaret::MoveCursorProperly( CLayoutPoint ptNewXY, //!< [in] カーソルのレイアウト座標X bool bScroll, //!< [in] true: 画面位置調整有り/ false: 画面位置調整有り無し bool test, //!< [in] true: カーソル移動はしない CLayoutPoint* ptNewXYNew, //!< [out] 新しいレイアウト座標 int nCaretMarginRate, //!< [in] 縦スクロール開始位置を決める値 int dx //!< [in] ptNewXY.xとマウスカーソル位置との誤差(カラム幅未満のドット数) ) { CLogicInt nLineLen; const CLayout* pcLayout; if( 0 > ptNewXY.y ){ ptNewXY.y = CLayoutInt(0); } // 2011.12.26 EOF以下の行だった場合で矩形のときは、最終レイアウト行へ移動する if( ptNewXY.y >= m_pEditDoc->m_cLayoutMgr.GetLineCount() && (m_pEditView->GetSelectionInfo().IsMouseSelecting() && m_pEditView->GetSelectionInfo().IsBoxSelecting()) ){ const CLayout* layoutEnd = m_pEditDoc->m_cLayoutMgr.GetBottomLayout(); bool bEofOnly = (layoutEnd && layoutEnd->GetLayoutEol() != EOL_NONE) || NULL == layoutEnd; // 2012.01.09 ぴったり[EOF]位置にある場合は位置を維持(1つ上の行にしない) if( bEofOnly && ptNewXY.y == m_pEditDoc->m_cLayoutMgr.GetLineCount() && ptNewXY.x == 0 ){ }else{ ptNewXY.y = t_max(CLayoutInt(0), m_pEditDoc->m_cLayoutMgr.GetLineCount() - 1); } } /* カーソルがテキスト最下端行にあるか */ if( ptNewXY.y >= m_pEditDoc->m_cLayoutMgr.GetLineCount() ){ // 2004.04.03 Moca EOFより後ろの座標調整は、MoveCursor内でやってもらうので、削除 } /* カーソルがテキスト最上端行にあるか */ else if( ptNewXY.y < 0 ){ ptNewXY.Set(CLayoutInt(0), CLayoutInt(0)); } else{ /* 移動先の行のデータを取得 */ m_pEditDoc->m_cLayoutMgr.GetLineStr( ptNewXY.GetY2(), &nLineLen, &pcLayout ); int nColWidth = m_pEditView->GetTextMetrics().GetCharPxWidth(); CLayoutInt nPosX = CLayoutInt(0); int i = 0; CMemoryIterator it = m_pEditDoc->m_cLayoutMgr.CreateCMemoryIterator(pcLayout); while( !it.end() ){ it.scanNext(); if ( it.getIndex() + it.getIndexDelta() > CLogicInt(pcLayout->GetLengthWithoutEOL()) ){ i = nLineLen; break; } if( it.getColumn() + it.getColumnDelta() > ptNewXY.GetX2() ){ if (ptNewXY.GetX2() >= (pcLayout ? pcLayout->GetIndent() : CLayoutInt(0)) && ((ptNewXY.GetX2() - it.getColumn()) * nColWidth + dx) * 2 >= it.getColumnDelta() * nColWidth){ //if (ptNewXY.GetX2() >= (pcLayout ? pcLayout->GetIndent() : CLayoutInt(0)) && (it.getColumnDelta() > CLayoutInt(1)) && ((it.getColumn() + it.getColumnDelta() - ptNewXY.GetX2()) <= it.getColumnDelta() / 2)){ nPosX += it.getColumnDelta(); } //} i = it.getIndex(); break; } it.addDelta(); } nPosX += it.getColumn(); if ( it.end() ){ i = it.getIndex(); //nPosX -= it.getColumnDelta(); // 2009.02.17 ryoji コメントアウト(末尾文字の後に移動する) } if( i >= nLineLen ){ // 2011.12.26 フリーカーソル/矩形でデータ付きEOFの右側へ移動できるように /* フリーカーソルモードか */ if( GetDllShareData().m_Common.m_sGeneral.m_bIsFreeCursorMode || ( m_pEditView->GetSelectionInfo().IsMouseSelecting() && m_pEditView->GetSelectionInfo().IsBoxSelecting() ) /* マウス範囲選択中 && 矩形範囲選択中 */ || ( m_pEditView->m_bDragMode && m_pEditView->m_bDragBoxData ) /* OLE DropTarget && 矩形データ */ ){ // 折り返し幅とレイアウト行桁数(ぶら下げを含む)のどちらか大きいほうまでカーソル移動可能 // Aug. 14, 2005 genta 折り返し幅をLayoutMgrから取得するように CLayoutInt nMaxX = t_max(nPosX, m_pEditDoc->m_cLayoutMgr.GetMaxLineLayout()); nPosX = ptNewXY.GetX2(); if( nPosX < CLayoutInt(0) ){ nPosX = CLayoutInt(0); } else if( nPosX > nMaxX ){ nPosX = nMaxX; } } } ptNewXY.SetX( nPosX ); } if( ptNewXYNew ){ *ptNewXYNew = ptNewXY; GetAdjustCursorPos( ptNewXYNew ); } if( test ){ return CLayoutInt(0); } return MoveCursor( ptNewXY, bScroll, nCaretMarginRate ); }
/*! 単純に /^\\s*sub\\s+(\\w+)/ に一致したら $1を取り出す動作を行う。 ネストとかは面倒くさいので考えない。 package{ }を使わなければこれで十分.無いよりはまし。 @par nModeの意味 @li 0: はじめ @li 2: subを見つけた後 @li 1: 単語読み出し中 @date 2005.06.18 genta パッケージ区切りを表す ::と'を考慮するように */ void CDocOutline::MakeFuncList_Perl( CFuncInfoArr* pcFuncInfoArr ) { const wchar_t* pLine; CLogicInt nLineLen; int i; int nCharChars; wchar_t szWord[100]; int nWordIdx = 0; int nMaxWordLeng = 70; int nMode; bool bExtEol = GetDllShareData().m_Common.m_sEdit.m_bEnableExtEol; CLogicInt nLineCount; for( nLineCount = CLogicInt(0); nLineCount < m_pcDocRef->m_cDocLineMgr.GetLineCount(); ++nLineCount ){ pLine = m_pcDocRef->m_cDocLineMgr.GetLine(nLineCount)->GetDocLineStrWithEOL(&nLineLen); nMode = 0; for( i = 0; i < nLineLen; ++i ){ /* 1バイト文字だけを処理する */ // 2005-09-02 D.S.Koba GetSizeOfChar nCharChars = CNativeW::GetSizeOfChar( pLine, nLineLen, i ); if( 1 < nCharChars ){ break; } /* 単語読み込み中 */ if( 0 == nMode ){ /* 空白やタブ記号等を飛ばす */ if( L'\t' == pLine[i] || L' ' == pLine[i] || WCODE::IsLineDelimiter(pLine[i], bExtEol) ){ continue; } if( 's' != pLine[i] ) break; // sub の一文字目かもしれない if( nLineLen - i < 4 ) break; if( wcsncmp_literal( pLine + i, L"sub" ) ) break; int c = pLine[ i + 3 ]; if( c == L' ' || c == L'\t' ){ nMode = 2; // 発見 i += 3; } else break; } else if( 2 == nMode ){ if( L'\t' == pLine[i] || L' ' == pLine[i] || WCODE::IsLineDelimiter(pLine[i], bExtEol) ){ continue; } if( L'_' == pLine[i] || (L'a' <= pLine[i] && pLine[i] <= L'z' )|| (L'A' <= pLine[i] && pLine[i] <= L'Z' )|| (L'0' <= pLine[i] && pLine[i] <= L'9' ) ){ // 関数名の始まり nWordIdx = 0; szWord[nWordIdx] = pLine[i]; szWord[nWordIdx + 1] = L'\0'; nMode = 1; continue; } else break; } else if( 1 == nMode ){ if( L'_' == pLine[i] || (L'a' <= pLine[i] && pLine[i] <= L'z' )|| (L'A' <= pLine[i] && pLine[i] <= L'Z' )|| (L'0' <= pLine[i] && pLine[i] <= L'9' )|| // Jun. 18, 2005 genta パッケージ修飾子を考慮 // コロンは2つ連続しないといけないのだが,そこは手抜き L':' == pLine[i] || L'\'' == pLine[i] ){ ++nWordIdx; if( nWordIdx >= nMaxWordLeng ){ break; }else{ szWord[nWordIdx] = pLine[i]; szWord[nWordIdx + 1] = L'\0'; } }else{ // 関数名取得 /* カーソル位置変換 物理位置(行頭からのバイト数、折り返し無し行位置) → レイアウト位置(行頭からの表示桁位置、折り返しあり行位置) */ CLayoutPoint ptPosXY; m_pcDocRef->m_cLayoutMgr.LogicToLayout( CLogicPoint(CLogicInt(0), nLineCount), &ptPosXY ); // Mar. 9, 2001 pcFuncInfoArr->AppendData( nLineCount + CLogicInt(1), ptPosXY.GetY2() + CLayoutInt(1), szWord, 0 ); break; } } } } #ifdef _DEBUG pcFuncInfoArr->DUMP(); #endif return; }