diff --git a/sakura_core/CGrepAgent.cpp b/sakura_core/CGrepAgent.cpp index 1e8e76931e..42942eed32 100644 --- a/sakura_core/CGrepAgent.cpp +++ b/sakura_core/CGrepAgent.cpp @@ -30,6 +30,9 @@ #include "CSearchAgent.h" #include "dlg/CDlgCancel.h" #include "_main/CAppMode.h" +#include "_main/CMutex.h" +#include "env/CShareData.h" +#include "env/CSakuraEnvironment.h" #include "COpeBlk.h" #include "window/CEditWnd.h" #include "charset/CCodeMediator.h" @@ -46,6 +49,7 @@ #include #include #include +#include "apiwrap/StdApi.h" #include "apiwrap/StdControl.h" #include "CSelectLang.h" #include "sakura_rc.h" @@ -105,6 +109,93 @@ std::wstring FormatPathList( const ContainerType& containter ) return strPatterns; } +class CFileLoadOrWnd{ + CFileLoad m_cfl; + HWND m_hWnd; + int m_nLineCurrent; + int m_nLineNum; +public: + CFileLoadOrWnd(const SEncodingConfig& encode, HWND hWnd) + : m_cfl(encode) + , m_hWnd(hWnd) + , m_nLineCurrent(0) + , m_nLineNum(0) + { + } + ~CFileLoadOrWnd(){ + } + ECodeType FileOpen(const WCHAR* pszFile, bool bBigFile, ECodeType charCode, int nFlag) + { + if( m_hWnd ){ + DWORD_PTR dwMsgResult = 0; + if( 0 == ::SendMessageTimeout(m_hWnd, MYWM_GETLINECOUNT, 0, 0, SMTO_NORMAL, 10000, &dwMsgResult) ){ + // エラーかタイムアウト + throw CError_FileOpen(); + } + m_nLineCurrent = 0; + m_nLineNum = (int)dwMsgResult; + ::SendMessageAny(m_hWnd, MYWM_GETFILEINFO, 0, 0); + const EditInfo* editInfo = &GetDllShareData().m_sWorkBuffer.m_EditInfo_MYWM_GETFILEINFO; + return editInfo->m_nCharCode; + } + return m_cfl.FileOpen(pszFile, bBigFile, charCode, nFlag); + } + EConvertResult ReadLine(CNativeW* buffer, CEol* pcEol){ + if( m_hWnd ){ + const int max_size = (int)GetDllShareData().m_sWorkBuffer.GetWorkBufferCount(); + const WCHAR* pLineData = GetDllShareData().m_sWorkBuffer.GetWorkBuffer(); + buffer->SetStringHoldBuffer(L"", 0); + if( m_nLineNum <= m_nLineCurrent ){ + return RESULT_FAILURE; + } + int nLineOffset = 0; + int nLineLen = 0; //初回用仮値 + do{ + // m_sWorkBuffer#m_Workの排他制御。外部コマンド出力/TraceOut/Diffが対象 + LockGuard guard( CShareData::GetMutexShareWork() ); + { + nLineLen = ::SendMessageAny(m_hWnd, MYWM_GETLINEDATA, m_nLineCurrent, nLineOffset); + if( nLineLen == 0 ){ return RESULT_FAILURE; } // EOF => 正常終了 + if( nLineLen < 0 ){ return RESULT_FAILURE; } // 何かエラー + buffer->AllocStringBuffer(max_size); + buffer->AppendString(pLineData, t_min(nLineLen, max_size)); + } + nLineOffset += max_size; + }while(max_size < nLineLen); + if( 0 < nLineLen ){ + if( 1 < nLineLen && (*buffer)[nLineLen - 2] == WCODE::CR && + (*buffer)[nLineLen - 1] == WCODE::LF){ + pcEol->SetType(EEolType::cr_and_lf); + }else{ + pcEol->SetTypeByString(buffer->GetStringPtr() + nLineLen - 1, 1); + } + } + m_nLineCurrent++; + return RESULT_COMPLETE; + } + return m_cfl.ReadLine(buffer, pcEol); + } + LONGLONG GetFileSize(){ + if( m_hWnd ){ + return 0; + } + return m_cfl.GetFileSize(); + } + int GetPercent(){ + if( m_hWnd ){ + return (int)(m_nLineCurrent * 100.0 / m_nLineNum); + } + return m_cfl.GetPercent(); + } + + void FileClose(){ + if( m_hWnd ){ + return; + } + m_cfl.FileClose(); + } +}; + CGrepAgent::CGrepAgent() : m_bGrepMode( false ) /* Grepモードか */ , m_bGrepRunning( false ) /* Grep処理中 */ @@ -207,6 +298,60 @@ void CGrepAgent::AddTail( CEditView* pcEditView, const CNativeW& cmem, bool bAdd } } +int GetHwndTitle(HWND& hWndTarget, CNativeW* pmemTitle, WCHAR* pszWindowName, WCHAR* pszWindowPath, const WCHAR* pszFile) +{ + if( 0 != wcsncmp(L":HWND:", pszFile, 6) ){ + return 0; // ハンドルGrepではない + } +#ifdef _WIN64 + _stscanf(pszFile + 6, L"%016I64x", &hWndTarget); +#else + _stscanf(pszFile + 6, L"%08x", &hWndTarget); +#endif + if( pmemTitle ){ + const wchar_t* p = L"Window:["; + pmemTitle->SetStringHoldBuffer(p, 8); + } + if( !IsSakuraMainWindow(hWndTarget) ){ + return -1; + } + ::SendMessageAny(hWndTarget, MYWM_GETFILEINFO, 0, 0); + EditInfo* editInfo = &(GetDllShareData().m_sWorkBuffer.m_EditInfo_MYWM_GETFILEINFO); + if( '\0' == editInfo->m_szPath[0] ){ + // Grepかアウトプットか無題 + WCHAR szTitle[_MAX_PATH]{}; + WCHAR szGrep[100]{}; + editInfo->m_bIsModified = false; + const EditNode* node = CAppNodeManager::getInstance()->GetEditNode(hWndTarget); + WCHAR* pszTagName = szTitle; + if( editInfo->m_bIsGrep ){ + // Grepは検索キーとタグがぶつかることがあるので単に(Grep)と表示 + pszTagName = szGrep; + wcsncpy_s(pszTagName, _countof(szGrep), L"(Grep)", _TRUNCATE); + } + CFileNameManager::getInstance()->GetMenuFullLabel_WinListNoEscape(szTitle, _countof(szTitle), editInfo, node->m_nId, -1, NULL ); +#ifdef _WIN64 + auto_sprintf(pszWindowName, L":HWND:[%016I64x]%s", hWndTarget, pszTagName); +#else + auto_sprintf(pszWindowName, L":HWND:[%08x]%s", hWndTarget, pszTagName); +#endif + if( pmemTitle ){ + pmemTitle->AppendString(szTitle); + } + pszWindowPath[0] = L'\0'; + }else{ + SplitPath_FolderAndFile(editInfo->m_szPath, pszWindowPath, pszWindowName); + if( pmemTitle ){ + pmemTitle->AppendString(pszWindowName); + } + } + if( pmemTitle ){ + pmemTitle->AppendString(L"]"); + } + return 1; +} + + /*! Grep実行 @param[in] pcmGrepKey 検索パターン @@ -458,13 +603,28 @@ DWORD CGrepAgent::DoGrep( } } - cmemMessage.AppendString( LS( STR_GREP_SEARCH_TARGET ) ); //L"検索対象 " + HWND hWndTarget = NULL; + WCHAR szWindowName[_MAX_PATH]; + WCHAR szWindowPath[_MAX_PATH]; { - // 解析済みのファイルパターン配列を取得する - const auto& vecSearchFileKeys = cGrepEnumKeys.m_vecSearchFileKeys; - std::wstring strPatterns = FormatPathList( vecSearchFileKeys ); - cmemMessage.AppendString( strPatterns.c_str(), strPatterns.length() ); + int nHwndRet = GetHwndTitle(hWndTarget, &cmemWork, szWindowName, szWindowPath, pcmGrepFile->GetStringPtr()); + if( -1 == nHwndRet ){ + cmemMessage.AppendString(L"HWND handle error.\n"); + if( sGrepOption.bGrepHeader ){ + AddTail(pcViewDst, cmemMessage, sGrepOption.bGrepStdout); + } + return 0; + }else if( 0 == nHwndRet ){ + { + // 解析済みのファイルパターン配列を取得する + const auto& vecSearchFileKeys = cGrepEnumKeys.m_vecSearchFileKeys; + std::wstring strPatterns = FormatPathList( vecSearchFileKeys ); + cmemWork.SetString( strPatterns.c_str(), strPatterns.length() ); + } + } } + cmemMessage.AppendString( LS( STR_GREP_SEARCH_TARGET ) ); //L"検索対象 " + cmemMessage += cmemWork; cmemMessage.AppendString( L"\r\n" ); cmemMessage.AppendString( LS( STR_GREP_SEARCH_FOLDER ) ); //L"フォルダ " @@ -586,38 +746,87 @@ DWORD CGrepAgent::DoGrep( int nGrepTreeResult = 0; - for( int nPath = 0; nPath < (int)vPaths.size(); nPath++ ){ - bool bOutputBaseFolder = false; - std::wstring sPath = ChopYen( vPaths[nPath] ); - int nTreeRet = DoGrepTree( - pcViewDst, - &cDlgCancel, - pcmGrepKey->GetStringPtr(), - cmemReplace, - cGrepEnumKeys, - cGrepExceptAbsFiles, - cGrepExceptAbsFolders, - sPath.c_str(), - sPath.c_str(), - sSearchOption, - sGrepOption, - pattern, - &cRegexp, - 0, - bOutputBaseFolder, - &nHitCount, - cmemMessage, - cUnicodeBuffer - ); - if( nTreeRet == -1 ){ - nGrepTreeResult = -1; - break; + if( hWndTarget ){ + for( HWND hwnd = hWndTarget; NULL != hwnd; hwnd = NULL ){ + bool bOutputBaseFolder = false; + bool bOutputFolderName = false; + // 複数ウィンドウループ予約 + auto nPathLen = wcsnlen_s(szWindowPath, _countof(szWindowPath)); + std::wstring currentFile = szWindowPath; + if( currentFile.size() ){ + currentFile += L'\\'; + nPathLen += 1; + } + currentFile += szWindowName; + int nHitCount = nGrepTreeResult; + int nTreeRet = DoGrepFile( + pcViewDst, + &cDlgCancel, + hwnd, + pcmGrepKey->GetStringPtr(), + szWindowName, + sSearchOption, + sGrepOption, + pattern, + &cRegexp, + &nHitCount, + currentFile.c_str(), + szWindowPath, + (sGrepOption.bGrepSeparateFolder && sGrepOption.bGrepOutputBaseFolder ? L"" : szWindowPath), + (sGrepOption.bGrepSeparateFolder ? szWindowName : currentFile.c_str() + nPathLen), + bOutputBaseFolder, + bOutputFolderName, + cmemMessage, + cUnicodeBuffer + ); + if( nTreeRet == -1 ){ + nGrepTreeResult = -1; + break; + } + nGrepTreeResult += nTreeRet; + } + if( 0 < cmemMessage.GetStringLength() ){ + AddTail( pcViewDst, cmemMessage, sGrepOption.bGrepStdout ); + pcViewDst->GetCommander().Command_GOFILEEND( false ); + if( !CEditWnd::getInstance()->UpdateTextWrap() ) + CEditWnd::getInstance()->RedrawAllViews( pcViewDst ); + cmemMessage.Clear(); + } + nHitCount = nGrepTreeResult; + }else{ + for( int nPath = 0; nPath < (int)vPaths.size(); nPath++ ){ + bool bOutputBaseFolder = false; + std::wstring sPath = ChopYen( vPaths[nPath] ); + int nTreeRet = DoGrepTree( + pcViewDst, + &cDlgCancel, + pcmGrepKey->GetStringPtr(), + cmemReplace, + cGrepEnumKeys, + cGrepExceptAbsFiles, + cGrepExceptAbsFolders, + sPath.c_str(), + sPath.c_str(), + sSearchOption, + sGrepOption, + pattern, + &cRegexp, + 0, + bOutputBaseFolder, + &nHitCount, + cmemMessage, + cUnicodeBuffer + ); + if( nTreeRet == -1 ){ + nGrepTreeResult = -1; + break; + } + nGrepTreeResult += nTreeRet; + } + if( 0 < cmemMessage.GetStringLength() ) { + AddTail( pcViewDst, cmemMessage, sGrepOption.bGrepStdout ); + cmemMessage._SetStringLength(0); } - nGrepTreeResult += nTreeRet; - } - if( 0 < cmemMessage.GetStringLength() ) { - AddTail( pcViewDst, cmemMessage, sGrepOption.bGrepStdout ); - cmemMessage._SetStringLength(0); } if( -1 == nGrepTreeResult && sGrepOption.bGrepHeader ){ const wchar_t* p = LS( STR_GREP_SUSPENDED ); //L"中断しました。\r\n" @@ -781,6 +990,7 @@ int CGrepAgent::DoGrepTree( nRet = DoGrepFile( pcViewDst, pcDlgCancel, + NULL, pszKey, lpFileName, sSearchOption, @@ -1101,6 +1311,7 @@ static void OutputPathInfo( int CGrepAgent::DoGrepFile( CEditView* pcViewDst, //!< CDlgCancel* pcDlgCancel, //!< [in] Cancelダイアログへのポインタ + HWND hWndTarget, //!< [in] 対象Windows(NULLでファイル) const wchar_t* pszKey, //!< [in] 検索パターン const WCHAR* pszFile, //!< [in] 処理対象ファイル名(表示用) const SSearchOption& sSearchOption, //!< [in] 検索オプション @@ -1132,7 +1343,7 @@ int CGrepAgent::DoGrepFile( if( !CDocTypeManager().GetTypeConfigMini( CDocTypeManager().GetDocumentTypeOfPath( pszFile ), &type ) ){ return -1; } - CFileLoad cfl( type->m_encoding ); // 2012/12/18 Uchi 検査するファイルのデフォルトの文字コードを取得する様に + CFileLoadOrWnd cfl( type->m_encoding, hWndTarget ); // 2012/12/18 Uchi 検査するファイルのデフォルトの文字コードを取得する様に int nOldPercent = 0; int nKeyLen = wcslen( pszKey ); diff --git a/sakura_core/CGrepAgent.h b/sakura_core/CGrepAgent.h index 84fd9ab0a9..10769c6a5c 100644 --- a/sakura_core/CGrepAgent.h +++ b/sakura_core/CGrepAgent.h @@ -129,6 +129,7 @@ class CGrepAgent : public CDocListenerEx{ int DoGrepFile( CEditView* pcViewDst, CDlgCancel* pcDlgCancel, + HWND hWndTarget, const wchar_t* pszKey, const WCHAR* pszFile, const SSearchOption& sSearchOption, diff --git a/sakura_core/String_define.h b/sakura_core/String_define.h index 53614215fc..63cabc315a 100644 --- a/sakura_core/String_define.h +++ b/sakura_core/String_define.h @@ -1323,5 +1323,7 @@ #define STR_FILEDIALOG_EOL 35039 #define STR_FILEDIALOG_MRU 35040 #define STR_FILEDIALOG_OPENFOLDER 35041 +#define STR_DLGGREP_THISDOC 35045 +#define STR_DLGGREP_THISDOC_ERROR 35046 // Now using max number 35044 by STR_STATUS_FONTZOOM_1 diff --git a/sakura_core/_main/CControlTray.cpp b/sakura_core/_main/CControlTray.cpp index 19786f4e2a..4f99a0e4fe 100644 --- a/sakura_core/_main/CControlTray.cpp +++ b/sakura_core/_main/CControlTray.cpp @@ -68,6 +68,8 @@ static LRESULT CALLBACK CControlTrayWndProc( HWND, UINT, WPARAM, LPARAM ); //Stonee, 2001/07/01 多重起動された場合は前回のダイアログを前面に出すようにした。 void CControlTray::DoGrep() { + m_cDlgGrep.m_bEnableThisText = false; + //Stonee, 2001/06/30 //前回のダイアログがあれば前面に (suggested by genta) if ( ::IsWindow(m_cDlgGrep.GetHwnd()) ){ diff --git a/sakura_core/cmd/CViewCommander_TagJump.cpp b/sakura_core/cmd/CViewCommander_TagJump.cpp index 78fb1921a5..129a140ee7 100644 --- a/sakura_core/cmd/CViewCommander_TagJump.cpp +++ b/sakura_core/cmd/CViewCommander_TagJump.cpp @@ -1,4 +1,4 @@ -/*! @file +/*! @file @brief CViewCommanderクラスのコマンド(タグジャンプ)関数群 2012/12/17 CViewCommander.cppから分離 @@ -71,6 +71,66 @@ static bool IsFileExists2( const wchar_t* pszFile ) return IsFileExists(pszFile, true); } +static bool IsHWNDTag( const wchar_t* pLine, std::wstring& str, int* pnLen = NULL ) +{ + if( 0 == wcsncmp(pLine, L":HWND:[", 7) ){ + const wchar_t* pFileEnd = wcsstr( pLine, L"]" ); + if( pFileEnd ){ + const int nLen = pFileEnd - pLine + 1; + int i = 7; + for( ; i < nLen; i++ ){ + if( !(WCODE::Is09(pLine[i]) || (L'a' <= pLine[i] && L'f' <= pLine[i])) ){ + break; + } + } + if( i != nLen && nLen <= 16 + 8 ){ + if( pnLen ){ + *pnLen = nLen; + return true; + } + str.assign(pLine, nLen); + return true; + } + } + } + return false; +} + +static int GetLineColumnPos(const wchar_t* pLine) +{ + // filename(1234,56): str + const wchar_t* pTagEnd = wcsstr( pLine, L"): " ); + if( !pTagEnd ){ + // filename(1234,56) [SJIS]: str + pTagEnd = wcsstr( pLine, L"]: " ); + if( pTagEnd ){ + int fileEnd = pTagEnd - pLine - 1; + for( ; 1 < fileEnd; fileEnd-- ){ + if( L'[' == pLine[fileEnd] ){ + fileEnd--; + break; + } + } + for( ; 1 < fileEnd && L' ' == pLine[fileEnd]; fileEnd-- ){} + if( ')' == pLine[fileEnd] ){ + pTagEnd = &pLine[fileEnd]; + }else{ + pTagEnd = NULL; + } + } + } + if( pTagEnd ){ + int fileEnd = pTagEnd - pLine - 1; + for( ; 1 < fileEnd && (L'0' <= pLine[fileEnd] && pLine[fileEnd] <= L'9'); fileEnd-- ){} + if( 1 < fileEnd && (L',' == pLine[fileEnd]) ){ fileEnd--; } + for( ; 1 < fileEnd && (L'0' <= pLine[fileEnd] && pLine[fileEnd] <= L'9'); fileEnd-- ){} + if( 1 < fileEnd && L'(' == pLine[fileEnd] ){ + return fileEnd; + } + } + return 0; +} + /*! タグジャンプ @param bClose [in] true:元ウィンドウを閉じる @@ -123,6 +183,8 @@ bool CViewCommander::Command_TagJumpNoMessage( bool bClose ) // ノーマル // C:\RootFolder\SubFolders\FileName.ext(5395,11): str + // :HWND:[01234567] 無題1(1234,56): str + // :HWND:[01234567] 無題1(1234,56) [SJIS]: str // ノーマル/ベースフォルダ/フォルダ毎 // ◎"C:\RootFolder" @@ -233,6 +295,8 @@ bool CViewCommander::Command_TagJumpNoMessage( bool bClose ) }else if( 0 == wmemcmp( pLine, L"◆\"", 2 ) ){ if (!GetQuoteFilePath(&pLine[2], strFile, MAX_TAG_PATH)) { break; + }else if( IsHWNDTag(&pLine[2], strJumpToFile) ){ + break; } searchMode = TAGLIST_SUBPATH; }else if( 0 == wmemcmp( pLine, L"・", 1 ) ){ @@ -241,46 +305,33 @@ bool CViewCommander::Command_TagJumpNoMessage( bool bClose ) if (!GetQuoteFilePath(&pLine[2], strFile, MAX_TAG_PATH)) { break; } + if( IsHWNDTag(&pLine[2], strJumpToFile) ){ + break; + } + searchMode = TAGLIST_SUBPATH; }else if( pLine[1] == L'(' ){ // ファイル毎(WZ風) + // ・( 12,34 ): str GetLineColumn( &pLine[1], &nJumpToLine, &nJumpToColumn ); searchMode = TAGLIST_FILEPATH; }else{ // ノーマル/ファイル相対パス - // ・FileName.ext(123,45): str - // ・FileName.ext(123,45) [SJIS]: str - const wchar_t* pTagEnd = wcsstr( pLine, L"): " ); - if( !pTagEnd ){ - pTagEnd = wcsstr( pLine, L"]: " ); - if( pTagEnd ){ - int fileEnd = pTagEnd - pLine - 1; - for( ; 1 < fileEnd; fileEnd-- ){ - if( L'[' == pLine[fileEnd] ){ - fileEnd--; - break; - } - } - for( ; 1 < fileEnd && L' ' == pLine[fileEnd]; fileEnd-- ){} - if( ')' == pLine[fileEnd] ){ - pTagEnd = &pLine[fileEnd]; - }else{ - pTagEnd = NULL; - } - } - } - if( pTagEnd ){ - int fileEnd = pTagEnd - pLine - 1; - for( ; 1 < fileEnd && (L'0' <= pLine[fileEnd] && pLine[fileEnd] <= L'9'); fileEnd-- ){} - if( 1 < fileEnd && (L',' == pLine[fileEnd]) ){ fileEnd--; } - for( ; 1 < fileEnd && (L'0' <= pLine[fileEnd] && pLine[fileEnd] <= L'9'); fileEnd-- ){} - if( 1 < fileEnd && L'(' == pLine[fileEnd] && fileEnd - 1 < MAX_TAG_PATH ){ - strFile.assign(pLine + 1, fileEnd - 1); - GetLineColumn( &pLine[fileEnd + 1], &nJumpToLine, &nJumpToColumn ); - searchMode = TAGLIST_SUBPATH; - }else{ + // ・FileName.ext(123,45): str + // ・FileName.ext(123,45) [SJIS]: str + // ・subpath\FileName.ext(123,45): str + // ・:HWND:[01234567](無題)2(123,45): str + int fileEnd = GetLineColumnPos(pLine); + if (1 < fileEnd && L'(' == pLine[fileEnd] && fileEnd - 1 < MAX_TAG_PATH) { + strFile.assign(pLine + 1, fileEnd - 1); + GetLineColumn( &pLine[fileEnd + 1], &nJumpToLine, &nJumpToColumn ); + if( IsHWNDTag(pLine + 1, strJumpToFile) ){ break; } + searchMode = TAGLIST_SUBPATH; + }else{ + break; + } } }else{ @@ -299,6 +350,9 @@ bool CViewCommander::Command_TagJumpNoMessage( bool bClose ) if( searchMode == TAGLIST_SUBPATH || searchMode == TAGLIST_ROOT ){ continue; } + if( IsHWNDTag(&pLine[2], strJumpToFile) ){ + break; + } // フォルダ毎:ファイル名 if (GetQuoteFilePath(&pLine[2], strFile, MAX_TAG_PATH)) { searchMode = TAGLIST_SUBPATH; @@ -315,6 +369,9 @@ bool CViewCommander::Command_TagJumpNoMessage( bool bClose ) if( searchMode == TAGLIST_ROOT ){ continue; } + if( IsHWNDTag(&pLine[2], strJumpToFile) ){ + break; + } // ファイル毎(WZ風):フルパス if( IsFilePath( &pLine[2], &nBgn, &nPathLen ) && !_IS_REL_PATH( &pLine[2] ) ){ strJumpToFile.assign(&pLine[2 + nBgn], nPathLen); @@ -366,6 +423,17 @@ bool CViewCommander::Command_TagJumpNoMessage( bool bClose ) if( NULL == pLine ){ return false; } + int nLen = 0; + std::wstring test; + if (IsHWNDTag(pLine, test, &nLen)) { + int nFileEnd = GetLineColumnPos(pLine); + if( nFileEnd ){ + strJumpToFile.assign(pLine, nLen); + GetLineColumn(&pLine[nFileEnd + 1], &nJumpToLine, &nJumpToColumn); + } + } + } + if (strJumpToFile.empty()) { //@@@ 2001.12.31 YAZAKI const wchar_t *p = pLine; const wchar_t *p_end = p + nLineLen; @@ -401,7 +469,7 @@ bool CViewCommander::Command_TagJumpNoMessage( bool bClose ) // Apr. 21, 2003 genta bClose追加 if (strJumpToFile.empty() == false && - m_pCommanderView->TagJumpSub(strJumpToFile.c_str(), CMyPoint(nJumpToColumn, nJumpToLine), bClose ) ){ //@@@ 2003.04.13 + m_pCommanderView->TagJumpSub(strJumpToFile.c_str(), CMyPoint(nJumpToColumn, nJumpToLine), bClose)) { //@@@ 2003.04.13 return true; } @@ -767,7 +835,7 @@ bool CViewCommander::Sub_PreProcTagJumpByTagsFile( WCHAR* szCurrentPath, int cou // 現在のタイプ別の1番目の拡張子を拝借 WCHAR szExts[MAX_TYPES_EXTS]; CDocTypeManager::GetFirstExt(m_pCommanderView->m_pTypeData->m_szTypeExts, szExts, _countof(szExts)); - int nExtLen = wcslen( szExts ); + auto nExtLen = wcsnlen_s( szExts, _countof(szExts) ); wcscat( szCurrentPath, L"\\dmy" ); if( nExtLen ){ wcscat( szCurrentPath, L"." ); diff --git a/sakura_core/config/system_constants.h b/sakura_core/config/system_constants.h index e9bedb5ac9..d2ef125a58 100644 --- a/sakura_core/config/system_constants.h +++ b/sakura_core/config/system_constants.h @@ -752,4 +752,7 @@ enum e_PM_SETCARETPOS_SELECTSTATE { //! ウィンドウ一覧表示 #define MYWM_DLGWINLIST (WM_APP+225) + +//! 行数を取得 +#define MYWM_GETLINECOUNT (WM_APP+226) #endif /* SAKURA_SYSTEM_CONSTANTS_DACC287C_DAC4_4FC7_8AEC_8DB5BE6BFB8B_H_ */ diff --git a/sakura_core/dlg/CDlgGrep.cpp b/sakura_core/dlg/CDlgGrep.cpp index a58c89a67b..e94a1914b6 100644 --- a/sakura_core/dlg/CDlgGrep.cpp +++ b/sakura_core/dlg/CDlgGrep.cpp @@ -75,6 +75,7 @@ static void SetGrepFolder( HWND hwndCtrl, LPCWSTR folder ); CDlgGrep::CDlgGrep() { + m_bEnableThisText = true; m_bSubFolder = FALSE; // サブフォルダからも検索する m_bFromThisText = FALSE; // この編集中のテキストから検索する m_sSearchOption.Reset(); // 検索オプション @@ -557,6 +558,20 @@ BOOL CDlgGrep::OnBnClicked( int wID ) return TRUE; case IDCANCEL: // ::EndDialog( hwndDlg, FALSE ); + if (::IsDlgButtonChecked(GetHwnd(), IDC_CHK_FROMTHISTEXT)) { + if (m_pShareData->m_sSearchKeywords.m_aGrepFiles.size()) { + wcscpy(m_szFile, m_pShareData->m_sSearchKeywords.m_aGrepFiles[0]); /* 検索ファイル */ + } + if (m_pShareData->m_sSearchKeywords.m_aGrepFolders.size()) { + wcscpy(m_szFolder, m_pShareData->m_sSearchKeywords.m_aGrepFolders[0]); /* 検索フォルダ */ + } + if (m_pShareData->m_sSearchKeywords.m_aExcludeFiles.size()) { + wcscpy(m_szExcludeFile, m_pShareData->m_sSearchKeywords.m_aExcludeFiles[0]); /* 除外ファイル */ + } + if (m_pShareData->m_sSearchKeywords.m_aExcludeFolders.size()) { + wcscpy(m_szExcludeFolder, m_pShareData->m_sSearchKeywords.m_aExcludeFolders[0]); /* 除外フォルダ */ + } + } CloseDialog( FALSE ); return TRUE; } @@ -685,7 +700,7 @@ void CDlgGrep::SetData( void ) } // To Here Jun. 29, 2001 genta - if( m_szCurrentFilePath[0] != L'\0' ){ + if( m_bEnableThisText ){ ::EnableWindow( GetItemHwnd( IDC_CHK_FROMTHISTEXT ), TRUE ); }else{ ::EnableWindow( GetItemHwnd( IDC_CHK_FROMTHISTEXT ), FALSE ); @@ -707,24 +722,36 @@ void CDlgGrep::SetData( void ) void CDlgGrep::SetDataFromThisText( bool bChecked ) { BOOL bEnableControls = TRUE; - if( 0 != m_szCurrentFilePath[0] && bChecked ){ - WCHAR szWorkFolder[MAX_PATH]; - WCHAR szWorkFile[MAX_PATH]; - // 2003.08.01 Moca ファイル名はスペースなどは区切り記号になるので、""で囲い、エスケープする - szWorkFile[0] = L'"'; - SplitPath_FolderAndFile( m_szCurrentFilePath, szWorkFolder, szWorkFile + 1 ); - wcscat( szWorkFile, L"\"" ); // 2003.08.01 Moca - ::DlgItem_SetText( GetHwnd(), IDC_COMBO_FILE, szWorkFile ); - - SetGrepFolder( GetItemHwnd(IDC_COMBO_FOLDER), szWorkFolder ); - - ::CheckDlgButton( GetHwnd(), IDC_CHK_SUBFOLDER, BST_UNCHECKED ); + if( bChecked ){ + ::DlgItem_GetText(GetHwnd(), IDC_COMBO_FILE, m_szFile, _countof2(m_szFile)); + ::DlgItem_GetText(GetHwnd(), IDC_COMBO_FOLDER, m_szFolder, _countof2(m_szFolder)); + ::DlgItem_GetText(GetHwnd(), IDC_COMBO_EXCLUDE_FILE, m_szExcludeFile, _countof2(m_szExcludeFile)); + ::DlgItem_GetText(GetHwnd(), IDC_COMBO_EXCLUDE_FOLDER, m_szExcludeFolder, _countof2(m_szExcludeFolder)); + + ::DlgItem_SetText( GetHwnd(), IDC_COMBO_FILE, LS(STR_DLGGREP_THISDOC) ); + SetGrepFolder( GetItemHwnd(IDC_COMBO_FOLDER), LS(STR_DLGGREP_THISDOC) ); + ::DlgItem_SetText( GetHwnd(), IDC_COMBO_EXCLUDE_FILE, L"" ); + ::DlgItem_SetText( GetHwnd(), IDC_COMBO_EXCLUDE_FOLDER, L"" ); bEnableControls = FALSE; + }else{ + std::wstring strFile(m_szFile); + if (strFile.substr(0, 6) == L":HWND:") { + wcsncpy_s(m_szFile, _countof2(m_szFile), L"*.*", _TRUNCATE); + } + ::DlgItem_SetText(GetHwnd(), IDC_COMBO_FILE, m_szFile); + ::DlgItem_SetText(GetHwnd(), IDC_COMBO_FOLDER, m_szFolder); + ::DlgItem_SetText(GetHwnd(), IDC_COMBO_EXCLUDE_FILE, m_szExcludeFile); + ::DlgItem_SetText(GetHwnd(), IDC_COMBO_EXCLUDE_FOLDER, m_szExcludeFolder); } ::EnableWindow( GetItemHwnd( IDC_COMBO_FILE ), bEnableControls ); ::EnableWindow( GetItemHwnd( IDC_COMBO_FOLDER ), bEnableControls ); ::EnableWindow( GetItemHwnd( IDC_BUTTON_FOLDER ), bEnableControls ); ::EnableWindow( GetItemHwnd( IDC_CHK_SUBFOLDER ), bEnableControls ); + ::EnableWindow( GetItemHwnd( IDC_BUTTON_FILEOPENDIR ), bEnableControls ); + ::EnableWindow( GetItemHwnd( IDC_COMBO_EXCLUDE_FILE ), bEnableControls ); + ::EnableWindow( GetItemHwnd( IDC_COMBO_EXCLUDE_FOLDER ), bEnableControls ); + ::EnableWindow( GetItemHwnd( IDC_BUTTON_FOLDER_UP ), bEnableControls ); + ::EnableWindow( GetItemHwnd( IDC_BUTTON_CURRENTFOLDER ), bEnableControls ); return; } @@ -790,6 +817,22 @@ int CDlgGrep::GetData( void ) /* 検索ファイル */ ::DlgItem_GetText( GetHwnd(), IDC_COMBO_FILE, m_szFile, _countof2(m_szFile) ); + bool bFromThisText = IsDlgButtonCheckedBool(GetHwnd(), IDC_CHK_FROMTHISTEXT); + if( bFromThisText ){ + WCHAR szHwnd[_MAX_PATH]; +#ifdef _WIN64 + auto_sprintf(szHwnd, L":HWND:%016I64x", ::GetParent(GetHwnd())); +#else + auto_sprintf(szHwnd, L":HWND:%08x", ::GetParent(GetHwnd())); +#endif + m_szFile = szHwnd; + }else{ + std::wstring strFile(m_szFile); + if (strFile.substr(0, 6) == L":HWND:") { + ErrorMessage(GetHwnd(), LS(STR_DLGGREP_THISDOC_ERROR)); + return FALSE; + } + } /* 検索フォルダ */ ::DlgItem_GetText( GetHwnd(), IDC_COMBO_FOLDER, m_szFolder, _countof2(m_szFolder) ); /* 除外ファイル */ @@ -827,7 +870,9 @@ int CDlgGrep::GetData( void ) return FALSE; } - { + if( bFromThisText ){ + m_szFolder[0] = L'\0'; + }else{ //カレントディレクトリを保存。このブロックから抜けるときに自動でカレントディレクトリは復元される。 CCurrentDirectoryBackupPoint cCurDirBackup; diff --git a/sakura_core/dlg/CDlgGrep.h b/sakura_core/dlg/CDlgGrep.h index d5c7b29018..67b61cda80 100644 --- a/sakura_core/dlg/CDlgGrep.h +++ b/sakura_core/dlg/CDlgGrep.h @@ -42,6 +42,7 @@ class CDlgGrep : public CDialog int DoModal( HINSTANCE, HWND, const WCHAR* ); /* モーダルダイアログの表示 */ // HWND DoModeless( HINSTANCE, HWND, const char* ); /* モードレスダイアログの表示 */ + bool m_bEnableThisText; BOOL m_bSubFolder;/*!< サブフォルダからも検索する */ BOOL m_bFromThisText;/*!< この編集中のテキストから検索する */ diff --git a/sakura_core/dlg/CDlgGrepReplace.cpp b/sakura_core/dlg/CDlgGrepReplace.cpp index d6e6ae897f..c220a25cc5 100644 --- a/sakura_core/dlg/CDlgGrepReplace.cpp +++ b/sakura_core/dlg/CDlgGrepReplace.cpp @@ -42,7 +42,7 @@ const DWORD p_helpids[] = { IDC_CHK_PASTE, HIDC_GREP_REP_CHK_PASTE, //クリップボードから貼り付け IDC_CHK_WORD, HIDC_GREP_REP_CHK_WORD, //単語単位 IDC_CHK_SUBFOLDER, HIDC_GREP_REP_CHK_SUBFOLDER, //サブフォルダも検索 -// IDC_CHK_FROMTHISTEXT, HIDC_GREP_REP_CHK_FROMTHISTEXT, //このファイルから + IDC_CHK_FROMTHISTEXT, HIDC_GREP_REP_CHK_FROMTHISTEXT, //このファイルから IDC_CHK_LOHICASE, HIDC_GREP_REP_CHK_LOHICASE, //大文字小文字 IDC_CHK_REGULAREXP, HIDC_GREP_REP_CHK_REGULAREXP, //正規表現 IDC_CHK_BACKUP, HIDC_GREP_REP_CHK_BACKUP, //バックアップ作成 @@ -192,6 +192,9 @@ void CDlgGrepReplace::SetData( void ) CheckDlgButtonBool( GetHwnd(), IDC_CHK_BACKUP, m_bBackup ); CDlgGrep::SetData(); + + /* 編集中テキストから検索チェックを無効化 */ + ::EnableWindow(GetItemHwnd(IDC_CHK_FROMTHISTEXT), FALSE); } /*! ダイアログデータの取得 diff --git a/sakura_core/env/CFileNameManager.cpp b/sakura_core/env/CFileNameManager.cpp index a1b2bcaef7..0fed19777a 100644 --- a/sakura_core/env/CFileNameManager.cpp +++ b/sakura_core/env/CFileNameManager.cpp @@ -453,9 +453,9 @@ bool CFileNameManager::GetMenuFullLabel( pszCharset = szCodePageName; } - int ret = auto_snprintf_s( pszOutput, nBuffSize, L"%s%s%s %s%s", + int ret = auto_snprintf_s( pszOutput, nBuffSize, L"%s%s%s%s%s", szAccKey, (bFavorite ? L"★ " : L""), pszName, - (bModified ? L"*":L" "), pszCharset + (bModified ? L" *":L""), pszCharset ); return 0 < ret; } diff --git a/sakura_core/sakura.hh b/sakura_core/sakura.hh index 4d7e90e03b..8c5fa74124 100644 --- a/sakura_core/sakura.hh +++ b/sakura_core/sakura.hh @@ -810,7 +810,7 @@ #define HIDC_GREP_BUTTON_HELP 12004 //ヘルプ #define HIDC_GREP_CHK_WORD 12005 //単語単位 #define HIDC_GREP_CHK_SUBFOLDER 12006 //サブフォルダも検索 -#define HIDC_GREP_CHK_FROMTHISTEXT 12007 //このファイルから +#define HIDC_GREP_CHK_FROMTHISTEXT 12007 //このテキストから #define HIDC_GREP_CHK_LOHICASE 12008 //大文字小文字 #define HIDC_GREP_CHK_REGULAREXP 12009 //正規表現 // #define HIDC_GREP_CHK_KANJICODEAUTODETECT 12010 //文字コードセット自動判別 @@ -1148,6 +1148,7 @@ #define HIDC_GREP_REP_CHK_PASTE 14505 //クリップボードから貼り付け #define HIDC_GREP_REP_CHK_WORD 14506 //単語単位 #define HIDC_GREP_REP_CHK_SUBFOLDER 14507 //サブフォルダも検索 +#define HIDC_GREP_REP_CHK_FROMTHISTEXT 14804 //このテキストから #define HIDC_GREP_REP_CHK_LOHICASE 14509 //大文字小文字 #define HIDC_GREP_REP_CHK_REGULAREXP 14510 //正規表現 #define HIDC_GREP_REP_CHK_BACKUP 14511 //バックアップ作成 diff --git a/sakura_core/sakura_rc.rc b/sakura_core/sakura_rc.rc index a829f5847d..79e4d6f6c7 100644 --- a/sakura_core/sakura_rc.rc +++ b/sakura_core/sakura_rc.rc @@ -143,7 +143,7 @@ BEGIN RTEXT "検索場所(&L):",IDC_STATIC,4,50,52,8 COMBOBOX IDC_COMBO_FOLDER,60,50,254,120,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&...",IDC_BUTTON_FOLDER,316,50,16,10 - CONTROL "編集中のファイルから検索(&M)",IDC_CHK_FROMTHISTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,60,64,120,8 + CONTROL "編集中のテキストから検索(&M)",IDC_CHK_FROMTHISTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,60,64,120,8 CONTROL "サブフォルダも検索(&S)",IDC_CHK_SUBFOLDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,60,74,120,8 CONTROL "カレントフォルダが初期値(&D)",IDC_CHK_DEFAULTFOLDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,60,84,120,8 PUSHBUTTON "上階層へ(&U)",IDC_BUTTON_FOLDER_UP,230,64,50,14 @@ -193,7 +193,7 @@ BEGIN RTEXT "検索場所(&L):",IDC_STATIC,4,64,52,8 COMBOBOX IDC_COMBO_FOLDER,60,64,254,120,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&...",IDC_BUTTON_FOLDER,316,64,16,10 - CONTROL "編集中のファイルから検索(&M)",IDC_CHK_FROMTHISTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,60,78,120,8 + CONTROL "編集中のテキストから検索(&M)",IDC_CHK_FROMTHISTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,60,78,120,8 CONTROL "サブフォルダも検索(&S)",IDC_CHK_SUBFOLDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,60,88,120,8 CONTROL "カレントフォルダが初期値(&D)",IDC_CHK_DEFAULTFOLDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,60,98,120,8 PUSHBUTTON "上階層へ(&U)",IDC_BUTTON_FOLDER_UP,230,78,50,14 @@ -3175,6 +3175,8 @@ BEGIN STR_DLGGREP4 "検索対象フォルダを指定してください。" STR_DLGGREP5 "検索対象フォルダが正しくありません。" STR_DLGGREP6 "検索対象フォルダが長すぎます。" + STR_DLGGREP_THISDOC "(現在のドキュメント)" + STR_DLGGREP_THISDOC_ERROR "対象ファイルに:HWND:は入力できません" STR_DLGJUMP1 "正しく行番号を入力してください。" STR_DLGJUMP_PSLQL "%d 行 %s パッケージ仕様部" STR_DLGOPNFL1 "変換なし" diff --git a/sakura_core/view/CEditView_Command.cpp b/sakura_core/view/CEditView_Command.cpp index 4acd37125c..b64327b82c 100644 --- a/sakura_core/view/CEditView_Command.cpp +++ b/sakura_core/view/CEditView_Command.cpp @@ -32,6 +32,7 @@ #include "env/CShareData.h" #include "env/DLLSHAREDATA.h" #include "env/CTagJumpManager.h" +#include "env/CSakuraEnvironment.h" #include "util/file.h" #include "util/module.h" #include "util/window.h" @@ -60,7 +61,7 @@ bool CEditView::TagJumpSub( bool* pbJumpToSelf //!< [out] オプションNULL可。自分にジャンプしたか ) { - HWND hwndOwner; + HWND hwndOwner = NULL; POINT poCaret; // 2004/06/21 novice タグジャンプ機能追加 TagJump tagJump; @@ -76,18 +77,30 @@ bool CEditView::TagJumpSub( // 予め絶対パスに変換する.(キーワードヘルプジャンプで用いる) // 2007.05.19 ryoji 相対パスは設定ファイルからのパスを優先 WCHAR szJumpToFile[1024]; - if( bRelFromIni && _IS_REL_PATH( pszFileName ) ){ - GetInidirOrExedir( szJumpToFile, pszFileName ); - } - else { - wcscpy( szJumpToFile, pszFileName ); - } + HWND hwndTarget = NULL; + if( 0 == wcsncmp(pszFileName, L":HWND:[", 7) ){ +#ifdef _WIN64 + _stscanf(pszFileName + 7, L"%016I64x", &hwndTarget); +#else + _stscanf(pszFileName + 7, L"%08x", &hwndTarget); +#endif + if( !IsSakuraMainWindow(hwndTarget) ){ + return false; + } + }else{ + if( bRelFromIni && _IS_REL_PATH( pszFileName ) ){ + GetInidirOrExedir( szJumpToFile, pszFileName ); + } + else { + wcscpy( szJumpToFile, pszFileName ); + } - /* ロングファイル名を取得する */ - WCHAR szWork[1024]; - if( FALSE != ::GetLongFileName( szJumpToFile, szWork ) ) - { - wcscpy( szJumpToFile, szWork ); + /* ロングファイル名を取得する */ + WCHAR szWork[1024]; + if( FALSE != ::GetLongFileName( szJumpToFile, szWork ) ) + { + wcscpy( szJumpToFile, szWork ); + } } // 2004/06/21 novice タグジャンプ機能追加 @@ -108,8 +121,11 @@ bool CEditView::TagJumpSub( /* 指定ファイルが開かれているか調べる */ /* 開かれている場合は開いているウィンドウのハンドルも返す */ /* ファイルを開いているか */ - if( CShareData::getInstance()->IsPathOpened( szJumpToFile, &hwndOwner ) ) + if( hwndTarget || CShareData::getInstance()->IsPathOpened( szJumpToFile, &hwndOwner ) ) { + if( hwndTarget ){ + hwndOwner = hwndTarget; + } // 2004.05.13 Moca マイナス値は無効 if( 0 < ptJumpTo.y ){ /* カーソルを移動させる */ diff --git a/sakura_core/window/CEditWnd.cpp b/sakura_core/window/CEditWnd.cpp index 5b16b2f0fa..5bcca9f732 100644 --- a/sakura_core/window/CEditWnd.cpp +++ b/sakura_core/window/CEditWnd.cpp @@ -1946,6 +1946,10 @@ LRESULT CEditWnd::DispatchEvent( wmemcpy( m_pShareData->m_sWorkBuffer.GetWorkBuffer(), pLine, nEnd ); return nLineLen; } + case MYWM_GETLINECOUNT: + { + return GetDocument()->m_cDocLineMgr.GetLineCount(); + } // 2010.05.11 Moca MYWM_ADDSTRINGLEN_Wを追加 NULセーフ case MYWM_ADDSTRINGLEN_W: diff --git a/sakura_lang_en_US/sakura_lang_rc.rc b/sakura_lang_en_US/sakura_lang_rc.rc index 2cd03ae46b..4928a3a56b 100644 --- a/sakura_lang_en_US/sakura_lang_rc.rc +++ b/sakura_lang_en_US/sakura_lang_rc.rc @@ -149,7 +149,7 @@ BEGIN RTEXT "&Look in:",IDC_STATIC,4,50,64,8 COMBOBOX IDC_COMBO_FOLDER,72,50,282,120,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&...",IDC_BUTTON_FOLDER,356,50,16,10 - CONTROL "Current file (&M)",IDC_CHK_FROMTHISTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,72,64,120,8 + CONTROL "Current text (&M)",IDC_CHK_FROMTHISTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,72,64,120,8 CONTROL "Include &subfolders",IDC_CHK_SUBFOLDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,72,74,120,8 CONTROL "Set current folder as &default",IDC_CHK_DEFAULTFOLDER, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,72,84,120,8 @@ -202,7 +202,7 @@ BEGIN RTEXT "&Look in:",IDC_STATIC,4,64,64,8 COMBOBOX IDC_COMBO_FOLDER,72,64,282,120,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&...",IDC_BUTTON_FOLDER,356,64,16,10 - CONTROL "Current file (&M)",IDC_CHK_FROMTHISTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,72,78,120,8 + CONTROL "Current text (&M)",IDC_CHK_FROMTHISTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,72,78,120,8 CONTROL "Inlucde &subfolders",IDC_CHK_SUBFOLDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,72,88,120,8 CONTROL "Set current folder as &default",IDC_CHK_DEFAULTFOLDER, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,72,98,120,8 @@ -3212,6 +3212,7 @@ BEGIN STR_DLGGREP4 "Please define the target search folder." STR_DLGGREP5 "Target folder is not correct." STR_DLGGREP6 "Target folder is too long" + STR_DLGGREP_THISDOC "(Current document)" STR_DLGJUMP1 "Please input correct line number" STR_DLGJUMP_PSLQL "%d Ln %s Package Specification" STR_DLGOPNFL1 "as is"