int CGitIndexList::ReadIndex(CString dgitdir) { this->clear(); m_critRepoSec.Lock(); if (repository.Open(dgitdir)) { m_critRepoSec.Unlock(); return -1; } // add config files CAutoConfig config(true); CString projectConfig = dgitdir + _T("config"); CString globalConfig = g_Git.GetGitGlobalConfig(); CString globalXDGConfig = g_Git.GetGitGlobalXDGConfig(); CString systemConfig(CRegString(REG_SYSTEM_GITCONFIGPATH, _T(""), FALSE)); git_config_add_file_ondisk(config, CGit::GetGitPathStringA(projectConfig), GIT_CONFIG_LEVEL_LOCAL, FALSE); git_config_add_file_ondisk(config, CGit::GetGitPathStringA(globalConfig), GIT_CONFIG_LEVEL_GLOBAL, FALSE); git_config_add_file_ondisk(config, CGit::GetGitPathStringA(globalXDGConfig), GIT_CONFIG_LEVEL_XDG, FALSE); if (!systemConfig.IsEmpty()) git_config_add_file_ondisk(config, CGit::GetGitPathStringA(systemConfig), GIT_CONFIG_LEVEL_SYSTEM, FALSE); git_repository_set_config(repository, config); CAutoIndex index; // load index in order to enumerate files if (git_repository_index(index.GetPointer(), repository)) { repository.Free(); m_critRepoSec.Unlock(); return -1; } size_t ecount = git_index_entrycount(index); resize(ecount); for (size_t i = 0; i < ecount; ++i) { const git_index_entry *e = git_index_get_byindex(index, i); this->at(i).m_FileName.Empty(); this->at(i).m_FileName = CUnicodeUtils::GetUnicode(e->path); this->at(i).m_FileName.MakeLower(); this->at(i).m_ModifyTime = e->mtime.seconds; this->at(i).m_Flags = e->flags | e->flags_extended; this->at(i).m_IndexHash = e->id.id; this->at(i).m_Size = e->file_size; } g_Git.GetFileModifyTime(dgitdir + _T("index"), &this->m_LastModifyTime); std::sort(this->begin(), this->end(), SortIndex); m_critRepoSec.Unlock(); return 0; }
TEST(libgit2, TGitPatches) { CAutoTempDir tempdir; git_repository_init_options options = GIT_REPOSITORY_INIT_OPTIONS_INIT; options.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; CAutoRepository repo; ASSERT_EQ(0, git_repository_init_ext(repo.GetPointer(), CUnicodeUtils::GetUTF8(tempdir.GetTempDir()), &options)); CAutoConfig config; ASSERT_EQ(0, git_repository_config(config.GetPointer(), repo)); EXPECT_EQ(0, git_config_set_string(config, "core.autocrlf", "true")); EXPECT_EQ(0, git_config_set_string(config, "core.safecrlf", "true")); CAutoRepository repo2(tempdir.GetTempDir()); ASSERT_TRUE(repo2.IsValid()); CAutoIndex index; ASSERT_EQ(0, git_repository_index(index.GetPointer(), repo2)); CString testFile = tempdir.GetTempDir() + L"\\safecrlf-failure.txt"; EXPECT_TRUE(CStringUtils::WriteStringToTextFile(testFile, L"crlf\r\ncrlf\r\n")); EXPECT_EQ(0, git_index_add_bypath(index, "safecrlf-failure.txt")); EXPECT_TRUE(CStringUtils::WriteStringToTextFile(testFile, L"lf\nlf\n")); EXPECT_EQ(-1, git_index_add_bypath(index, "safecrlf-failure.txt")); EXPECT_TRUE(CStringUtils::WriteStringToTextFile(testFile, L"crlf\r\ncr\rcrlf\r\n")); EXPECT_EQ(0, git_index_add_bypath(index, "safecrlf-failure.txt")); EXPECT_EQ(0, git_config_set_string(config, "core.autocrlf", "input")); CAutoRepository repo3(tempdir.GetTempDir()); ASSERT_TRUE(repo3.IsValid()); ASSERT_EQ(0, git_repository_index(index.GetPointer(), repo3)); EXPECT_TRUE(CStringUtils::WriteStringToTextFile(testFile, L"crlf\r\ncrlf\r\n")); EXPECT_EQ(-1, git_index_add_bypath(index, "safecrlf-failure.txt")); }
TEST_P(GitWCRevStatusCBasicGitWithEmptyRepositoryFixture, EmptyRepoStagedFile) { CString file = m_Dir.GetTempDir() + L"\\somefile.txt"; EXPECT_TRUE(CStringUtils::WriteStringToTextFile(file, L"something\n")); CAutoRepository repo; ASSERT_EQ(0, git_repository_open(repo.GetPointer(), CUnicodeUtils::GetUTF8(m_Dir.GetTempDir()))); CAutoIndex index; ASSERT_EQ(0, git_repository_index(index.GetPointer(), repo)); ASSERT_EQ(0, git_index_add_bypath(index, "somefile.txt")); ASSERT_EQ(0, git_index_write(index)); GitWCRev_t GitStat3; EXPECT_TRUE(CStringUtils::WriteStringToTextFile(file, L"something\n")); EXPECT_EQ(0, GetStatus(m_Dir.GetTempDir(), GitStat3)); EXPECT_TRUE(GitStat3.bIsGitItem); EXPECT_TRUE(GitStat3.bIsUnborn); EXPECT_STREQ("master", GitStat3.CurrentBranch.c_str()); EXPECT_FALSE(GitStat3.bHasSubmodule); EXPECT_FALSE(GitStat3.HasMods); EXPECT_TRUE(GitStat3.HasUnversioned); EXPECT_EQ(0u, GitStat3.NumCommits); EXPECT_FALSE(GitStat3.bHasSubmoduleMods); EXPECT_FALSE(GitStat3.bHasSubmoduleNewCommits); EXPECT_FALSE(GitStat3.bHasSubmoduleUnversioned); EXPECT_FALSE(GitStat3.bIsTagged); EXPECT_STREQ(GIT_REV_ZERO_C, GitStat3.HeadHashReadable); EXPECT_STREQ("", GitStat3.HeadAuthor.c_str()); GitWCRev_t GitStat4; EXPECT_EQ(0, GetStatus(file, GitStat4)); EXPECT_FALSE(GitStat4.bIsGitItem); EXPECT_TRUE(GitStat4.bIsUnborn); EXPECT_STREQ("master", GitStat4.CurrentBranch.c_str()); EXPECT_FALSE(GitStat4.bHasSubmodule); EXPECT_FALSE(GitStat4.HasMods); EXPECT_TRUE(GitStat4.HasUnversioned); EXPECT_EQ(0u, GitStat4.NumCommits); EXPECT_FALSE(GitStat4.bHasSubmoduleMods); EXPECT_FALSE(GitStat4.bHasSubmoduleNewCommits); EXPECT_FALSE(GitStat4.bHasSubmoduleUnversioned); EXPECT_FALSE(GitStat4.bIsTagged); EXPECT_STREQ(GIT_REV_ZERO_C, GitStat4.HeadHashReadable); EXPECT_STREQ("", GitStat4.HeadAuthor.c_str()); }
int CTGitPathList::FillBasedOnIndexFlags(unsigned short flag, CTGitPathList* list /*nullptr*/) { Clear(); CTGitPath path; CAutoRepository repository(g_Git.GetGitRepository()); if (!repository) return -1; CAutoIndex index; if (git_repository_index(index.GetPointer(), repository)) return -1; int count; if (list == nullptr) count = 1; else count = list->GetCount(); for (int j = 0; j < count; ++j) { for (size_t i = 0, ecount = git_index_entrycount(index); i < ecount; ++i) { const git_index_entry *e = git_index_get_byindex(index, i); if (!e || !((e->flags | e->flags_extended) & flag) || !e->path) continue; CString one = CUnicodeUtils::GetUnicode(e->path); if (!(!list || (*list)[j].GetWinPathString().IsEmpty() || one == (*list)[j].GetGitPathString() || (PathIsDirectory(g_Git.CombinePath((*list)[j].GetWinPathString())) && one.Find((*list)[j].GetGitPathString() + _T("/")) == 0))) continue; //SetFromGit will clear all status path.SetFromGit(one); if ((e->flags | e->flags_extended) & GIT_IDXENTRY_SKIP_WORKTREE) path.m_Action = CTGitPath::LOGACTIONS_SKIPWORKTREE; else if ((e->flags | e->flags_extended) & GIT_IDXENTRY_VALID) path.m_Action = CTGitPath::LOGACTIONS_ASSUMEVALID; AddPath(path); } } RemoveDuplicates(); return 0; }
bool AddProgressCommand::SetFileMode(uint32_t mode) { CAutoRepository repo(g_Git.GetGitRepository()); if (!repo) { MessageBox(nullptr, g_Git.GetLibGit2LastErr(L"Could not open repository."), L"TortoiseGit", MB_ICONERROR); return false; } CAutoIndex index; if (git_repository_index(index.GetPointer(), repo)) { MessageBox(nullptr, g_Git.GetLibGit2LastErr(L"Could not get index."), L"TortoiseGit", MB_ICONERROR); return false; } if (git_index_read(index, true)) { MessageBox(nullptr, g_Git.GetLibGit2LastErr(L"Could not read index."), L"TortoiseGit", MB_ICONERROR); return false; } for (int i = 0; i < m_targetPathList.GetCount(); ++i) { if (m_targetPathList[i].IsDirectory()) continue; CStringA filePathA = CUnicodeUtils::GetMulti(m_targetPathList[i].GetGitPathString(), CP_UTF8).TrimRight(L'/'); auto entry = const_cast<git_index_entry*>(git_index_get_bypath(index, filePathA, 0)); entry->mode = mode; if (git_index_add(index, entry)) { MessageBox(nullptr, g_Git.GetLibGit2LastErr(L"Could not update index."), L"TortoiseGit", MB_ICONERROR); return false; } } if (git_index_write(index)) { MessageBox(nullptr, g_Git.GetLibGit2LastErr(L"Could not write index."), L"TortoiseGit", MB_ICONERROR); return false; } return true; }
bool DiffCommand::Execute() { bool bRet = false; CString path2 = CPathUtils::GetLongPathname(parser.GetVal(_T("path2"))); bool bAlternativeTool = !!parser.HasKey(_T("alternative")); // bool bBlame = !!parser.HasKey(_T("blame")); if (path2.IsEmpty()) { if (this->orgCmdLinePath.IsDirectory()) { CChangedDlg dlg; dlg.m_pathList = CTGitPathList(cmdLinePath); dlg.DoModal(); bRet = true; } else { if (cmdLinePath.IsEmpty()) return false; CGitDiff diff; //diff.SetAlternativeTool(bAlternativeTool); if ( parser.HasKey(_T("startrev")) && parser.HasKey(_T("endrev")) ) { if (parser.HasKey(_T("unified"))) bRet = !!CAppUtils::StartShowUnifiedDiff(nullptr, cmdLinePath, git_revnum_t(parser.GetVal(_T("endrev"))), cmdLinePath, git_revnum_t(parser.GetVal(_T("startrev"))), bAlternativeTool); else bRet = !!diff.Diff(&cmdLinePath, &cmdLinePath, git_revnum_t(parser.GetVal(_T("startrev"))), git_revnum_t(parser.GetVal(_T("endrev"))), false, parser.HasKey(_T("unified")) == TRUE, parser.GetLongVal(_T("line")), bAlternativeTool); } else { // check if it is a newly added (but uncommitted) file git_wc_status_kind status = git_wc_status_none; CString topDir; if (orgCmdLinePath.HasAdminDir(&topDir)) { CBlockCacheForPath cacheBlock(topDir); CAutoIndex index; CString adminDir; GitAdminDir::GetAdminDirPath(topDir, adminDir); if (!git_index_open(index.GetPointer(), CUnicodeUtils::GetUTF8(adminDir + _T("index")))) g_Git.Run(_T("git.exe update-index -- \"") + cmdLinePath.GetGitPathString() + _T("\""), nullptr); // make sure we get the right status GitStatus::GetFileStatus(topDir, cmdLinePath.GetWinPathString(), &status, true); if (index) git_index_write(index); } if (status == git_wc_status_added) { if (!g_Git.IsInitRepos()) { // this might be a rename, try to find original name BYTE_VECTOR cmdout; g_Git.Run(_T("git.exe diff-index --raw HEAD -M -C -z --"), &cmdout); CTGitPathList changedFiles; changedFiles.ParserFromLog(cmdout); for (int i = 0; i < changedFiles.GetCount(); ++i) { if (changedFiles[i].GetGitPathString() == cmdLinePath.GetGitPathString()) { if (!changedFiles[i].GetGitOldPathString().IsEmpty()) { CTGitPath oldPath(changedFiles[i].GetGitOldPathString()); if (parser.HasKey(_T("unified"))) return !!CAppUtils::StartShowUnifiedDiff(nullptr, cmdLinePath, git_revnum_t(_T("HEAD")), cmdLinePath, git_revnum_t(GIT_REV_ZERO), bAlternativeTool); return !!diff.Diff(&cmdLinePath, &oldPath, git_revnum_t(GIT_REV_ZERO), git_revnum_t(_T("HEAD")), false, parser.HasKey(_T("unified")) == TRUE, parser.GetLongVal(_T("line")), bAlternativeTool); } break; } } } cmdLinePath.m_Action = cmdLinePath.LOGACTIONS_ADDED; } if (parser.HasKey(_T("unified"))) bRet = !!CAppUtils::StartShowUnifiedDiff(nullptr, cmdLinePath, git_revnum_t(_T("HEAD")), cmdLinePath, git_revnum_t(GIT_REV_ZERO), bAlternativeTool); else bRet = !!diff.Diff(&cmdLinePath, &cmdLinePath, git_revnum_t(GIT_REV_ZERO), git_revnum_t(_T("HEAD")), false, parser.HasKey(_T("unified")) == TRUE, parser.GetLongVal(_T("line")), bAlternativeTool); } } } else { CGitDiff diff; if ( parser.HasKey(_T("startrev")) && parser.HasKey(_T("endrev")) && path2.Left(g_Git.m_CurrentDir.GetLength() + 1) == g_Git.m_CurrentDir + _T("\\")) { CTGitPath tgitPath2 = path2.Mid(g_Git.m_CurrentDir.GetLength() + 1); bRet = !!diff.Diff(&tgitPath2, &cmdLinePath, git_revnum_t(parser.GetVal(_T("startrev"))), git_revnum_t(parser.GetVal(_T("endrev"))), false, parser.HasKey(_T("unified")) == TRUE, parser.GetLongVal(_T("line")), bAlternativeTool); } else { bRet = CAppUtils::StartExtDiff( path2, orgCmdLinePath.GetWinPathString(), CString(), CString(), CString(), CString(), git_revnum_t(GIT_REV_ZERO), git_revnum_t(GIT_REV_ZERO), CAppUtils::DiffFlags().AlternativeTool(bAlternativeTool), parser.GetLongVal(_T("line"))); } } return bRet; }
int CGitIndexList::ReadIndex(CString dgitdir) { this->clear(); CAutoLocker lock(m_critRepoSec); if (repository.Open(dgitdir)) return -1; // add config files CAutoConfig config(true); CString projectConfig = dgitdir + _T("config"); CString globalConfig = g_Git.GetGitGlobalConfig(); CString globalXDGConfig = g_Git.GetGitGlobalXDGConfig(); CString systemConfig(CRegString(REG_SYSTEM_GITCONFIGPATH, _T(""), FALSE)); CString programDataConfig(GetProgramDataGitConfig()); git_config_add_file_ondisk(config, CGit::GetGitPathStringA(projectConfig), GIT_CONFIG_LEVEL_LOCAL, FALSE); git_config_add_file_ondisk(config, CGit::GetGitPathStringA(globalConfig), GIT_CONFIG_LEVEL_GLOBAL, FALSE); git_config_add_file_ondisk(config, CGit::GetGitPathStringA(globalXDGConfig), GIT_CONFIG_LEVEL_XDG, FALSE); if (!systemConfig.IsEmpty()) git_config_add_file_ondisk(config, CGit::GetGitPathStringA(systemConfig), GIT_CONFIG_LEVEL_SYSTEM, FALSE); if (!programDataConfig.IsEmpty()) git_config_add_file_ondisk(config, CGit::GetGitPathStringA(programDataConfig), GIT_CONFIG_LEVEL_PROGRAMDATA, FALSE); git_repository_set_config(repository, config); CAutoIndex index; // load index in order to enumerate files if (git_repository_index(index.GetPointer(), repository)) { repository.Free(); return -1; } m_bHasConflicts = FALSE; size_t ecount = git_index_entrycount(index); try { resize(ecount); } catch (const std::bad_alloc& ex) { repository.Free(); CTraceToOutputDebugString::Instance()(__FUNCTION__ ": Could not resize index-vector: %s\n", ex.what()); return -1; } for (size_t i = 0; i < ecount; ++i) { const git_index_entry *e = git_index_get_byindex(index, i); this->at(i).m_FileName = CUnicodeUtils::GetUnicode(e->path); this->at(i).m_FileName.MakeLower(); this->at(i).m_ModifyTime = e->mtime.seconds; this->at(i).m_Flags = e->flags; this->at(i).m_FlagsExtended = e->flags_extended; this->at(i).m_IndexHash = e->id.id; this->at(i).m_Size = e->file_size; m_bHasConflicts |= GIT_IDXENTRY_STAGE(e); } CGit::GetFileModifyTime(dgitdir + _T("index"), &this->m_LastModifyTime); std::sort(this->begin(), this->end(), SortIndex); return 0; }
LRESULT CMainWindow::DoCommand(int id, LPARAM lParam) { switch (id) { case ID_FILE_OPEN: { if (OpenDialog()) { picWindow1.SetPic(leftpicpath, L"", true); picWindow2.SetPic(rightpicpath, L"", false); if (bOverlap) { picWindow1.SetSecondPic(picWindow2.GetPic(), rightpictitle, rightpicpath); } else { picWindow1.SetSecondPic(); } RECT rect; GetClientRect(*this, &rect); PositionChildren(&rect); picWindow1.FitImageInWindow(); picWindow2.FitImageInWindow(); } } break; case ID_VIEW_IMAGEINFO: { bShowInfo = !bShowInfo; HMENU hMenu = GetMenu(*this); UINT uCheck = MF_BYCOMMAND; uCheck |= bShowInfo ? MF_CHECKED : MF_UNCHECKED; CheckMenuItem(hMenu, ID_VIEW_IMAGEINFO, uCheck); picWindow1.ShowInfo(bShowInfo); picWindow2.ShowInfo(bShowInfo); picWindow3.ShowInfo(bShowInfo); // change the state of the toolbar button TBBUTTONINFO tbi; tbi.cbSize = sizeof(TBBUTTONINFO); tbi.dwMask = TBIF_STATE; tbi.fsState = bShowInfo ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED; SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_IMAGEINFO, (LPARAM)&tbi); } break; case ID_VIEW_OVERLAPIMAGES: { bOverlap = !bOverlap; HMENU hMenu = GetMenu(*this); UINT uCheck = MF_BYCOMMAND; uCheck |= bOverlap ? MF_CHECKED : MF_UNCHECKED; CheckMenuItem(hMenu, ID_VIEW_OVERLAPIMAGES, uCheck); uCheck |= ((m_BlendType == CPicWindow::BLEND_ALPHA) && bOverlap) ? MF_CHECKED : MF_UNCHECKED; CheckMenuItem(hMenu, ID_VIEW_BLENDALPHA, uCheck); UINT uEnabled = MF_BYCOMMAND; uEnabled |= bOverlap ? MF_ENABLED : MF_DISABLED | MF_GRAYED; EnableMenuItem(hMenu, ID_VIEW_BLENDALPHA, uEnabled); // change the state of the toolbar button TBBUTTONINFO tbi; tbi.cbSize = sizeof(TBBUTTONINFO); tbi.dwMask = TBIF_STATE; tbi.fsState = bOverlap ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED; SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_OVERLAPIMAGES, (LPARAM)&tbi); tbi.fsState = ((m_BlendType == CPicWindow::BLEND_ALPHA) && bOverlap) ? TBSTATE_CHECKED : 0; if (bOverlap) tbi.fsState |= TBSTATE_ENABLED; else tbi.fsState = 0; SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_BLENDALPHA, (LPARAM)&tbi); if (bOverlap) tbi.fsState = 0; else tbi.fsState = bVertical ? TBSTATE_ENABLED | TBSTATE_CHECKED : TBSTATE_ENABLED; SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_ARRANGEVERTICAL, (LPARAM)&tbi); if (bOverlap) { bLinkedPositions = true; picWindow1.LinkPositions(bLinkedPositions); picWindow2.LinkPositions(bLinkedPositions); tbi.fsState = TBSTATE_CHECKED; } else tbi.fsState = bLinkedPositions ? TBSTATE_ENABLED | TBSTATE_CHECKED : TBSTATE_ENABLED; SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_LINKIMAGESTOGETHER, (LPARAM)&tbi); ShowWindow(picWindow2, bOverlap ? SW_HIDE : SW_SHOW); if (bOverlap) { picWindow1.StopTimer(); picWindow2.StopTimer(); picWindow1.SetSecondPic(picWindow2.GetPic(), rightpictitle, rightpicpath, picWindow2.GetHPos(), picWindow2.GetVPos()); picWindow1.SetBlendAlpha(m_BlendType, 0.5f); } else { picWindow1.SetSecondPic(); } picWindow1.SetOverlapMode(bOverlap); picWindow2.SetOverlapMode(bOverlap); RECT rect; GetClientRect(*this, &rect); PositionChildren(&rect); return 0; } break; case ID_VIEW_BLENDALPHA: { if (m_BlendType == CPicWindow::BLEND_ALPHA) m_BlendType = CPicWindow::BLEND_XOR; else m_BlendType = CPicWindow::BLEND_ALPHA; HMENU hMenu = GetMenu(*this); UINT uCheck = MF_BYCOMMAND; uCheck |= ((m_BlendType == CPicWindow::BLEND_ALPHA) && bOverlap) ? MF_CHECKED : MF_UNCHECKED; CheckMenuItem(hMenu, ID_VIEW_BLENDALPHA, uCheck); UINT uEnabled = MF_BYCOMMAND; uEnabled |= bOverlap ? MF_ENABLED : MF_DISABLED | MF_GRAYED; EnableMenuItem(hMenu, ID_VIEW_BLENDALPHA, uEnabled); // change the state of the toolbar button TBBUTTONINFO tbi; tbi.cbSize = sizeof(TBBUTTONINFO); tbi.dwMask = TBIF_STATE; tbi.fsState = ((m_BlendType == CPicWindow::BLEND_ALPHA) && bOverlap) ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED; SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_BLENDALPHA, (LPARAM)&tbi); picWindow1.SetBlendAlpha(m_BlendType, picWindow1.GetBlendAlpha()); PositionChildren(); } break; case ID_VIEW_TRANSPARENTCOLOR: { static COLORREF customColors[16] = {0}; CHOOSECOLOR ccDlg = { 0 }; ccDlg.lStructSize = sizeof(ccDlg); ccDlg.hwndOwner = m_hwnd; ccDlg.rgbResult = transparentColor; ccDlg.lpCustColors = customColors; ccDlg.Flags = CC_RGBINIT | CC_FULLOPEN; if(ChooseColor(&ccDlg)) { transparentColor = ccDlg.rgbResult; picWindow1.SetTransparentColor(transparentColor); picWindow2.SetTransparentColor(transparentColor); picWindow3.SetTransparentColor(transparentColor); // The color picker takes the focus and we don't get it back. ::SetFocus(picWindow1); } } break; case ID_VIEW_FITIMAGEWIDTHS: { bFitWidths = !bFitWidths; picWindow1.FitWidths(bFitWidths); picWindow2.FitWidths(bFitWidths); picWindow3.FitWidths(bFitWidths); HMENU hMenu = GetMenu(*this); UINT uCheck = MF_BYCOMMAND; uCheck |= bFitWidths ? MF_CHECKED : MF_UNCHECKED; CheckMenuItem(hMenu, ID_VIEW_FITIMAGEWIDTHS, uCheck); // change the state of the toolbar button TBBUTTONINFO tbi; tbi.cbSize = sizeof(TBBUTTONINFO); tbi.dwMask = TBIF_STATE; tbi.fsState = bFitWidths ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED; SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_FITIMAGEWIDTHS, (LPARAM)&tbi); } break; case ID_VIEW_FITIMAGEHEIGHTS: { bFitHeights = !bFitHeights; picWindow1.FitHeights(bFitHeights); picWindow2.FitHeights(bFitHeights); picWindow3.FitHeights(bFitHeights); HMENU hMenu = GetMenu(*this); UINT uCheck = MF_BYCOMMAND; uCheck |= bFitHeights ? MF_CHECKED : MF_UNCHECKED; CheckMenuItem(hMenu, ID_VIEW_FITIMAGEHEIGHTS, uCheck); // change the state of the toolbar button TBBUTTONINFO tbi; tbi.cbSize = sizeof(TBBUTTONINFO); tbi.dwMask = TBIF_STATE; tbi.fsState = bFitHeights ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED; SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_FITIMAGEHEIGHTS, (LPARAM)&tbi); } break; case ID_VIEW_LINKIMAGESTOGETHER: { bLinkedPositions = !bLinkedPositions; picWindow1.LinkPositions(bLinkedPositions); picWindow2.LinkPositions(bLinkedPositions); picWindow3.LinkPositions(bLinkedPositions); HMENU hMenu = GetMenu(*this); UINT uCheck = MF_BYCOMMAND; uCheck |= bLinkedPositions ? MF_CHECKED : MF_UNCHECKED; CheckMenuItem(hMenu, ID_VIEW_LINKIMAGESTOGETHER, uCheck); // change the state of the toolbar button TBBUTTONINFO tbi; tbi.cbSize = sizeof(TBBUTTONINFO); tbi.dwMask = TBIF_STATE; tbi.fsState = bLinkedPositions ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED; SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_LINKIMAGESTOGETHER, (LPARAM)&tbi); } break; case ID_VIEW_ALPHA0: picWindow1.SetBlendAlpha(m_BlendType, 0.0f); break; case ID_VIEW_ALPHA255: picWindow1.SetBlendAlpha(m_BlendType, 1.0f); break; case ID_VIEW_ALPHA127: picWindow1.SetBlendAlpha(m_BlendType, 0.5f); break; case ID_VIEW_ALPHATOGGLE: picWindow1.ToggleAlpha(); break; case ID_VIEW_FITIMAGESINWINDOW: { picWindow1.FitImageInWindow(); picWindow2.FitImageInWindow(); picWindow3.FitImageInWindow(); } break; case ID_VIEW_ORININALSIZE: { picWindow1.SetZoom(100, false); picWindow2.SetZoom(100, false); picWindow3.SetZoom(100, false); picWindow1.CenterImage(); picWindow2.CenterImage(); picWindow3.CenterImage(); } break; case ID_VIEW_ZOOMIN: { picWindow1.Zoom(true, false); if ((!(bFitWidths || bFitHeights))&&(!bOverlap)) { picWindow2.Zoom(true, false); picWindow3.Zoom(true, false); } } break; case ID_VIEW_ZOOMOUT: { picWindow1.Zoom(false, false); if ((!(bFitWidths || bFitHeights))&&(!bOverlap)) { picWindow2.Zoom(false, false); picWindow3.Zoom(false, false); } } break; case ID_VIEW_ARRANGEVERTICAL: { bVertical = !bVertical; RECT rect; GetClientRect(*this, &rect); if (bVertical) { RECT tbRect; GetWindowRect(hwndTB, &tbRect); LONG tbHeight = tbRect.bottom-tbRect.top-1; if (selectionPaths.size() != 3) { nSplitterPos = (rect.bottom-rect.top)/2+tbHeight; nSplitterPos2 = 0; } else { nSplitterPos = (rect.bottom-rect.top)/3+tbHeight; nSplitterPos2 = (rect.bottom-rect.top)*2/3+tbHeight; } } else { if (selectionPaths.size() != 3) { nSplitterPos = (rect.right-rect.left)/2; nSplitterPos2 = 0; } else { nSplitterPos = (rect.right-rect.left)/3; nSplitterPos2 = (rect.right-rect.left)*2/3; } } HMENU hMenu = GetMenu(*this); UINT uCheck = MF_BYCOMMAND; uCheck |= bVertical ? MF_CHECKED : MF_UNCHECKED; CheckMenuItem(hMenu, ID_VIEW_ARRANGEVERTICAL, uCheck); // change the state of the toolbar button TBBUTTONINFO tbi; tbi.cbSize = sizeof(TBBUTTONINFO); tbi.dwMask = TBIF_STATE; tbi.fsState = bVertical ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED; SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_ARRANGEVERTICAL, (LPARAM)&tbi); PositionChildren(&rect); } break; case ID_ABOUT: { CAboutDlg dlg(*this); dlg.DoModal(hInst, IDD_ABOUT, *this); } break; case SELECTBUTTON_ID: { HWND hSource = (HWND)lParam; FileType resolveWith; if (picWindow1 == hSource) resolveWith = FileTypeMine; else if (picWindow2 == hSource) resolveWith = FileTypeBase; else if (picWindow3 == hSource) resolveWith = FileTypeTheirs; else break; if (selectionResult.empty()) { PostQuitMessage(resolveWith); break; } CopyFile(selectionPaths[resolveWith].c_str(), selectionResult.c_str(), FALSE); CAutoBuf projectRoot; if (git_repository_discover(projectRoot, CUnicodeUtils::GetUTF8(selectionResult.c_str()), FALSE, nullptr) < 0 && strstr(projectRoot->ptr, "/.git/")) { PostQuitMessage(resolveWith); break; } CAutoRepository repository(projectRoot->ptr); if (!repository) { PostQuitMessage(resolveWith); break; } CStringA subpath = CUnicodeUtils::GetUTF8(selectionResult.c_str()).Mid((int)strlen(git_repository_workdir(repository))); CAutoIndex index; if (git_repository_index(index.GetPointer(), repository) || (git_index_get_bypath(index, subpath, 1) == nullptr && git_index_get_bypath(index, subpath, 2) == nullptr)) { PostQuitMessage(resolveWith); break; } CString sTemp; sTemp.Format(ResString(hResource, IDS_MARKASRESOLVED), (LPCTSTR)CPathUtils::GetFileNameFromPath(selectionResult.c_str())); if (MessageBox(m_hwnd, sTemp, L"TortoiseGitMerge", MB_YESNO | MB_ICONQUESTION) != IDYES) break; CString cmd; cmd.Format(L"\"%sTortoiseGitProc.exe\" /command:resolve /path:\"%s\" /closeonend:1 /noquestion /skipcheck /silent", (LPCTSTR)CPathUtils::GetAppDirectory(), selectionResult.c_str()); if (resolveMsgWnd) cmd.AppendFormat(L" /resolvemsghwnd:%I64d /resolvemsgwparam:%I64d /resolvemsglparam:%I64d", (__int64)resolveMsgWnd, (__int64)resolveMsgWParam, (__int64)resolveMsgLParam); STARTUPINFO startup = { 0 }; PROCESS_INFORMATION process = { 0 }; startup.cb = sizeof(startup); if (!CreateProcess(nullptr, cmd.GetBuffer(), nullptr, nullptr, FALSE, CREATE_UNICODE_ENVIRONMENT, nullptr, nullptr, &startup, &process)) { cmd.ReleaseBuffer(); PostQuitMessage(resolveWith); break; } cmd.ReleaseBuffer(); AllowSetForegroundWindow(process.dwProcessId); CloseHandle(process.hThread); CloseHandle(process.hProcess); PostQuitMessage(resolveWith); } break; case IDM_EXIT: ::PostQuitMessage(0); return 0; break; default: break; }; return 1; }
bool AddProgressCommand::Run(CGitProgressList* list, CString& sWindowTitle, int& m_itemCountTotal, int& m_itemCount) { ATLASSERT(!(m_bExecutable && m_bSymlink)); list->SetWindowTitle(IDS_PROGRS_TITLE_ADD, g_Git.CombinePath(m_targetPathList.GetCommonRoot().GetUIPathString()), sWindowTitle); list->SetBackgroundImage(IDI_ADD_BKG); if (m_bExecutable) list->ReportCmd(CString(MAKEINTRESOURCE(IDS_STATUSLIST_CONTEXT_ADD_EXE))); else if (m_bSymlink) list->ReportCmd(CString(MAKEINTRESOURCE(IDS_STATUSLIST_CONTEXT_ADD_LINK))); else list->ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_CMD_ADD))); m_itemCountTotal = m_targetPathList.GetCount(); if (g_Git.UsingLibGit2(CGit::GIT_CMD_ADD)) { CAutoRepository repo(g_Git.GetGitRepository()); if (!repo) { list->ReportGitError(); return false; } CAutoIndex index; if (git_repository_index(index.GetPointer(), repo)) { list->ReportGitError(); return false; } if (git_index_read(index, true)) { list->ReportGitError(); return false; } for (m_itemCount = 0; m_itemCount < m_itemCountTotal; ++m_itemCount) { CStringA filePathA = CUnicodeUtils::GetMulti(m_targetPathList[m_itemCount].GetGitPathString(), CP_UTF8).TrimRight(L'/'); if (git_index_add_bypath(index, filePathA)) { list->ReportGitError(); return false; } if (!m_targetPathList[m_itemCount].IsDirectory() && (m_bExecutable || m_bSymlink)) { auto entry = const_cast<git_index_entry*>(git_index_get_bypath(index, filePathA, 0)); if (m_bExecutable) entry->mode = GIT_FILEMODE_BLOB_EXECUTABLE; else if (m_bSymlink) entry->mode = GIT_FILEMODE_LINK; if (git_index_add(index, entry)) { list->ReportGitError(); return false; } } list->AddNotify(new CGitProgressList::WC_File_NotificationData(m_targetPathList[m_itemCount], CGitProgressList::WC_File_NotificationData::git_wc_notify_add)); if (list->IsCancelled() == TRUE) { list->ReportUserCanceled(); return false; } } if (git_index_write(index)) { list->ReportGitError(); return false; } } else { CMassiveGitTask mgt(L"add -f"); if (!mgt.ExecuteWithNotify(&m_targetPathList, list->m_bCancelled, CGitProgressList::WC_File_NotificationData::git_wc_notify_add, list)) return false; if (m_bExecutable) { if (!SetFileMode(GIT_FILEMODE_BLOB_EXECUTABLE)) return false; } else if (m_bSymlink) { if (!SetFileMode(GIT_FILEMODE_LINK)) return false; } } CShellUpdater::Instance().AddPathsForUpdate(m_targetPathList); m_PostCmdCallback = [this](DWORD status, PostCmdList& postCmdList) { if (status) return; if (m_bShowCommitButtonAfterAdd) postCmdList.emplace_back(IDI_COMMIT, IDS_MENUCOMMIT, [] { CString sCmd; sCmd.Format(L"/command:commit /path:\"%s\"", static_cast<LPCTSTR>(g_Git.m_CurrentDir)); CAppUtils::RunTortoiseGitProc(sCmd); }); if (!(m_bExecutable || m_bSymlink)) { postCmdList.emplace_back(IDI_ADD, IDS_STATUSLIST_CONTEXT_ADD_EXE, [this] { SetFileMode(GIT_FILEMODE_BLOB_EXECUTABLE); }); postCmdList.emplace_back(IDI_ADD, IDS_STATUSLIST_CONTEXT_ADD_LINK, [this] { SetFileMode(GIT_FILEMODE_LINK); }); } }; return true; }
BOOL CGitPropertyPage::PageProc (HWND /*hwnd*/, UINT uMessage, WPARAM wParam, LPARAM lParam) { switch (uMessage) { case WM_INITDIALOG: { InitWorkfileView(); return TRUE; } case WM_NOTIFY: { LPNMHDR point = (LPNMHDR)lParam; int code = point->code; // // Respond to notifications. // if (code == PSN_APPLY && m_bChanged) { do { CTGitPath path(filenames.front().c_str()); CString projectTopDir; if(!path.HasAdminDir(&projectTopDir) || path.IsDirectory()) break; int stripLength = projectTopDir.GetLength(); if (projectTopDir[stripLength - 1] != _T('\\')) ++stripLength; CAutoRepository repository(CUnicodeUtils::GetUTF8(projectTopDir)); if (!repository) break; CAutoIndex index; if (git_repository_index(index.GetPointer(), repository)) break; BOOL assumeValid = (BOOL)SendMessage(GetDlgItem(m_hwnd, IDC_ASSUMEVALID), BM_GETCHECK, 0, 0); BOOL skipWorktree = (BOOL)SendMessage(GetDlgItem(m_hwnd, IDC_SKIPWORKTREE), BM_GETCHECK, 0, 0); BOOL executable = (BOOL)SendMessage(GetDlgItem(m_hwnd, IDC_EXECUTABLE), BM_GETCHECK, 0, 0); BOOL symlink = (BOOL)SendMessage(GetDlgItem(m_hwnd, IDC_SYMLINK), BM_GETCHECK, 0, 0); bool changed = false; for (auto it = filenames.cbegin(); it < filenames.cend(); ++it) { CTGitPath file; file.SetFromWin(CString(it->c_str()).Mid(stripLength)); CStringA pathA = CUnicodeUtils::GetMulti(file.GetGitPathString(), CP_UTF8); size_t idx; if (!git_index_find(&idx, index, pathA)) { git_index_entry *e = const_cast<git_index_entry *>(git_index_get_byindex(index, idx)); // HACK if (assumeValid == BST_CHECKED) { if (!(e->flags & GIT_IDXENTRY_VALID)) { e->flags |= GIT_IDXENTRY_VALID; changed = true; } } else if (assumeValid != BST_INDETERMINATE) { if (e->flags & GIT_IDXENTRY_VALID) { e->flags &= ~GIT_IDXENTRY_VALID; changed = true; } } if (skipWorktree == BST_CHECKED) { if (!(e->flags_extended & GIT_IDXENTRY_SKIP_WORKTREE)) { e->flags_extended |= GIT_IDXENTRY_SKIP_WORKTREE; changed = true; } } else if (skipWorktree != BST_INDETERMINATE) { if (e->flags_extended & GIT_IDXENTRY_SKIP_WORKTREE) { e->flags_extended &= ~GIT_IDXENTRY_SKIP_WORKTREE; changed = true; } } if (executable == BST_CHECKED) { if (!(e->mode & 0111)) { e->mode |= 0111; changed = true; } } else if (executable != BST_INDETERMINATE) { if (e->mode & 0111) { e->mode &= ~0111; changed = true; } } if (symlink == BST_CHECKED) { if ((e->mode & GIT_FILEMODE_LINK) != GIT_FILEMODE_LINK) { e->mode |= GIT_FILEMODE_LINK; changed = true; } } else if (symlink != BST_INDETERMINATE) { if ((e->mode & GIT_FILEMODE_LINK) == GIT_FILEMODE_LINK) { e->mode &= ~GIT_FILEMODE_LINK; changed = true; } } if (changed) git_index_add(index, e); } } if (changed) { if (!git_index_write(index)) m_bChanged = false; } } while (0); } SetWindowLongPtr (m_hwnd, DWLP_MSGRESULT, FALSE); return TRUE; } case WM_DESTROY: return TRUE; case WM_COMMAND: PageProcOnCommand(wParam); break; } // switch (uMessage) if (uMessage == m_UpdateLastCommit) { DisplayCommit((git_commit *)lParam, IDC_LAST_HASH, IDC_LAST_SUBJECT, IDC_LAST_AUTHOR, IDC_LAST_DATE); return TRUE; } return FALSE; }
void CGitPropertyPage::InitWorkfileView() { if (filenames.empty()) return; CTGitPath path(filenames.front().c_str()); CString ProjectTopDir; if(!path.HasAdminDir(&ProjectTopDir)) return; CAutoRepository repository(CUnicodeUtils::GetUTF8(ProjectTopDir)); if (!repository) return; CString username; CString useremail; CString autocrlf; CString safecrlf; CAutoConfig config(repository); if (config) { config.GetString(L"user.name", username); config.GetString(L"user.email", useremail); config.GetString(L"core.autocrlf", autocrlf); config.GetString(L"core.safecrlf", safecrlf); } CString branch; CString remotebranch; if (!git_repository_head_detached(repository)) { CAutoReference head; if (git_repository_head_unborn(repository)) { git_reference_lookup(head.GetPointer(), repository, "HEAD"); branch = CUnicodeUtils::GetUnicode(git_reference_symbolic_target(head)); if (branch.Find(_T("refs/heads/")) == 0) branch = branch.Mid(11); // 11 = len("refs/heads/") } else if (!git_repository_head(head.GetPointer(), repository)) { const char * branchChar = git_reference_shorthand(head); branch = CUnicodeUtils::GetUnicode(branchChar); const char * branchFullChar = git_reference_name(head); CAutoBuf upstreambranchname; if (!git_branch_upstream_name(upstreambranchname, repository, branchFullChar)) { remotebranch = CUnicodeUtils::GetUnicode(CStringA(upstreambranchname->ptr, (int)upstreambranchname->size)); remotebranch = remotebranch.Mid(13); // 13=len("refs/remotes/") } } } else branch = _T("detached HEAD"); if (autocrlf.Trim().IsEmpty()) autocrlf = _T("false"); if (safecrlf.Trim().IsEmpty()) safecrlf = _T("false"); SetDlgItemText(m_hwnd,IDC_CONFIG_USERNAME,username.Trim()); SetDlgItemText(m_hwnd,IDC_CONFIG_USEREMAIL,useremail.Trim()); SetDlgItemText(m_hwnd,IDC_CONFIG_AUTOCRLF,autocrlf.Trim()); SetDlgItemText(m_hwnd,IDC_CONFIG_SAFECRLF,safecrlf.Trim()); SetDlgItemText(m_hwnd,IDC_SHELL_CURRENT_BRANCH,branch.Trim()); SetDlgItemText(m_hwnd,IDC_SHELL_REMOTE_BRANCH, remotebranch); git_oid oid; CAutoCommit HEADcommit; if (!git_reference_name_to_id(&oid, repository, "HEAD") && !git_commit_lookup(HEADcommit.GetPointer(), repository, &oid) && HEADcommit) DisplayCommit(HEADcommit, IDC_HEAD_HASH, IDC_HEAD_SUBJECT, IDC_HEAD_AUTHOR, IDC_HEAD_DATE); { int stripLength = ProjectTopDir.GetLength(); if (ProjectTopDir[stripLength - 1] != _T('\\')) ++stripLength; bool allAreFiles = true; for (auto it = filenames.cbegin(); it < filenames.cend(); ++it) { if (PathIsDirectory(it->c_str())) { allAreFiles = false; break; } } if (allAreFiles) { size_t assumevalid = 0; size_t skipworktree = 0; size_t executable = 0; size_t symlink = 0; do { CAutoIndex index; if (git_repository_index(index.GetPointer(), repository)) break; for (auto it = filenames.cbegin(); it < filenames.cend(); ++it) { CTGitPath file; file.SetFromWin(CString(it->c_str()).Mid(stripLength)); CStringA pathA = CUnicodeUtils::GetMulti(file.GetGitPathString(), CP_UTF8); size_t idx; if (!git_index_find(&idx, index, pathA)) { const git_index_entry *e = git_index_get_byindex(index, idx); if (e->flags & GIT_IDXENTRY_VALID) ++assumevalid; if (e->flags_extended & GIT_IDXENTRY_SKIP_WORKTREE) ++skipworktree; if (e->mode & 0111) ++executable; if ((e->mode & GIT_FILEMODE_LINK) == GIT_FILEMODE_LINK) ++symlink; } else { // do not show checkboxes for unversioned files ShowWindow(GetDlgItem(m_hwnd, IDC_ASSUMEVALID), SW_HIDE); ShowWindow(GetDlgItem(m_hwnd, IDC_SKIPWORKTREE), SW_HIDE); ShowWindow(GetDlgItem(m_hwnd, IDC_EXECUTABLE), SW_HIDE); ShowWindow(GetDlgItem(m_hwnd, IDC_SYMLINK), SW_HIDE); break; } } } while (0); if (assumevalid != 0 && assumevalid != filenames.size()) { SendMessage(GetDlgItem(m_hwnd, IDC_ASSUMEVALID), BM_SETSTYLE, (DWORD)GetWindowLong(GetDlgItem(m_hwnd, IDC_ASSUMEVALID), GWL_STYLE) & ~BS_AUTOCHECKBOX | BS_AUTO3STATE, 0); SendMessage(GetDlgItem(m_hwnd, IDC_ASSUMEVALID), BM_SETCHECK, BST_INDETERMINATE, 0); } else SendMessage(GetDlgItem(m_hwnd, IDC_ASSUMEVALID), BM_SETCHECK, (assumevalid == 0) ? BST_UNCHECKED : BST_CHECKED, 0); if (skipworktree != 0 && skipworktree != filenames.size()) { SendMessage(GetDlgItem(m_hwnd, IDC_SKIPWORKTREE), BM_SETSTYLE, (DWORD)GetWindowLong(GetDlgItem(m_hwnd, IDC_SKIPWORKTREE), GWL_STYLE) & ~BS_AUTOCHECKBOX | BS_AUTO3STATE, 0); SendMessage(GetDlgItem(m_hwnd, IDC_SKIPWORKTREE), BM_SETCHECK, BST_INDETERMINATE, 0); } else SendMessage(GetDlgItem(m_hwnd, IDC_SKIPWORKTREE), BM_SETCHECK, (skipworktree == 0) ? BST_UNCHECKED : BST_CHECKED, 0); if (executable != 0 && executable != filenames.size()) { SendMessage(GetDlgItem(m_hwnd, IDC_EXECUTABLE), BM_SETSTYLE, (DWORD)GetWindowLong(GetDlgItem(m_hwnd, IDC_EXECUTABLE), GWL_STYLE) & ~BS_AUTOCHECKBOX | BS_AUTO3STATE, 0); SendMessage(GetDlgItem(m_hwnd, IDC_EXECUTABLE), BM_SETCHECK, BST_INDETERMINATE, 0); EnableWindow(GetDlgItem(m_hwnd, IDC_SYMLINK), TRUE); } else { SendMessage(GetDlgItem(m_hwnd, IDC_EXECUTABLE), BM_SETCHECK, (executable == 0) ? BST_UNCHECKED : BST_CHECKED, 0); EnableWindow(GetDlgItem(m_hwnd, IDC_SYMLINK), (executable == 0) ? TRUE : FALSE); } if (symlink != 0 && symlink != filenames.size()) { SendMessage(GetDlgItem(m_hwnd, IDC_SYMLINK), BM_SETSTYLE, (DWORD)GetWindowLong(GetDlgItem(m_hwnd, IDC_SYMLINK), GWL_STYLE) & ~BS_AUTOCHECKBOX | BS_AUTO3STATE, 0); SendMessage(GetDlgItem(m_hwnd, IDC_SYMLINK), BM_SETCHECK, BST_INDETERMINATE, 0); EnableWindow(GetDlgItem(m_hwnd, IDC_EXECUTABLE), TRUE); } else { SendMessage(GetDlgItem(m_hwnd, IDC_SYMLINK), BM_SETCHECK, (symlink == 0) ? BST_UNCHECKED : BST_CHECKED, 0); EnableWindow(GetDlgItem(m_hwnd, IDC_EXECUTABLE), (symlink == 0) ? TRUE : FALSE); } } else { ShowWindow(GetDlgItem(m_hwnd, IDC_ASSUMEVALID), SW_HIDE); ShowWindow(GetDlgItem(m_hwnd, IDC_SKIPWORKTREE), SW_HIDE); ShowWindow(GetDlgItem(m_hwnd, IDC_EXECUTABLE), SW_HIDE); ShowWindow(GetDlgItem(m_hwnd, IDC_SYMLINK), SW_HIDE); } } if (filenames.size() == 1 && !PathIsDirectory(filenames[0].c_str())) { SetDlgItemText(m_hwnd, IDC_LAST_SUBJECT, CString(MAKEINTRESOURCE(IDS_LOADING))); _beginthread(LogThreadEntry, 0, this); } else ShowWindow(GetDlgItem(m_hwnd, IDC_STATIC_LASTMODIFIED), SW_HIDE); }