// WinMerge: an interactive diff/merge utility
// Copyright (C) 1997-2000 Thingamahoochie Software
// Author: Dean Grimm
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-//
+// SPDX-License-Identifier: GPL-2.0-or-later
/////////////////////////////////////////////////////////////////////////////
/**
* @file MainFrm.cpp
#include "BCMenu.h"
#include "OpenFrm.h"
#include "DirFrame.h" // Include type information
-#include "ChildFrm.h"
+#include "MergeEditFrm.h"
#include "HexMergeFrm.h"
#include "DirView.h"
#include "DirDoc.h"
#include "HexMergeView.h"
#include "ImgMergeFrm.h"
#include "LineFiltersList.h"
+#include "SubstitutionFiltersList.h"
#include "ConflictFileParser.h"
#include "LineFiltersDlg.h"
+#include "SubstitutionFiltersDlg.h"
#include "paths.h"
#include "Environment.h"
#include "PatchTool.h"
#include "VersionInfo.h"
#include "Bitmap.h"
#include "CCrystalTextMarkers.h"
+#include "utils/hqbitmap.h"
+#include "UniFile.h"
+#include "TFile.h"
+#include "Shell.h"
+#include "WindowsManagerDialog.h"
using std::vector;
using boost::begin;
#define new DEBUG_NEW
#endif
-static void LoadToolbarImageList(int imageWidth, UINT nIDResource, UINT nIDResourceMask, bool bGrayscale, CImageList& ImgList);
+static void LoadToolbarImageList(int orgImageWidth, int newImageHeight, UINT nIDResource, bool bGrayscale, CImageList& ImgList);
static CPtrList &GetDocList(CMultiDocTemplate *pTemplate);
template<class DocClass>
-DocClass * GetMergeDocForDiff(CMultiDocTemplate *pTemplate, CDirDoc *pDirDoc, int nFiles);
+DocClass * GetMergeDocForDiff(CMultiDocTemplate *pTemplate, CDirDoc *pDirDoc, int nFiles, bool bMakeVisible = true);
/**
* @brief A table associating menuitem id, icon and menus to apply.
*/
const CMainFrame::MENUITEM_ICON CMainFrame::m_MenuIcons[] = {
{ ID_FILE_OPENCONFLICT, IDB_FILE_OPENCONFLICT, CMainFrame::MENU_ALL },
- { ID_FILE_NEW3, IDB_FILE_NEW3, CMainFrame::MENU_ALL },
+ { ID_FILE_NEW_TABLE, IDB_FILE_NEW_TABLE, CMainFrame::MENU_ALL },
+ { ID_FILE_NEW_HEX, IDB_FILE_NEW_HEX, CMainFrame::MENU_ALL },
+ { ID_FILE_NEW_IMAGE, IDB_FILE_NEW_IMAGE, CMainFrame::MENU_ALL },
+ { ID_FILE_NEW3, IDB_FILE_NEW3, CMainFrame::MENU_ALL },
+ { ID_FILE_NEW3_TABLE, IDB_FILE_NEW3_TABLE, CMainFrame::MENU_ALL },
+ { ID_FILE_NEW3_HEX, IDB_FILE_NEW3_HEX, CMainFrame::MENU_ALL },
+ { ID_FILE_NEW3_IMAGE, IDB_FILE_NEW3_IMAGE, CMainFrame::MENU_ALL },
{ ID_EDIT_COPY, IDB_EDIT_COPY, CMainFrame::MENU_ALL },
{ ID_EDIT_CUT, IDB_EDIT_CUT, CMainFrame::MENU_ALL },
{ ID_EDIT_PASTE, IDB_EDIT_PASTE, CMainFrame::MENU_ALL },
{ ID_TOOLS_CUSTOMIZECOLUMNS, IDB_TOOLS_COLUMNS, CMainFrame::MENU_ALL },
{ ID_TOOLS_GENERATEPATCH, IDB_TOOLS_GENERATEPATCH, CMainFrame::MENU_ALL },
{ ID_PLUGINS_LIST, IDB_PLUGINS_LIST, CMainFrame::MENU_ALL },
- { ID_COPY_FROM_LEFT, IDB_COPY_FROM_LEFT, CMainFrame::MENU_ALL },
- { ID_COPY_FROM_RIGHT, IDB_COPY_FROM_RIGHT, CMainFrame::MENU_ALL },
{ ID_FILE_PRINT, IDB_FILE_PRINT, CMainFrame::MENU_FILECMP },
{ ID_TOOLS_GENERATEREPORT, IDB_TOOLS_GENERATEREPORT, CMainFrame::MENU_FILECMP },
{ ID_EDIT_TOGGLE_BOOKMARK, IDB_EDIT_TOGGLE_BOOKMARK, CMainFrame::MENU_FILECMP },
{ ID_EDIT_CLEAR_ALL_BOOKMARKS, IDB_EDIT_CLEAR_ALL_BOOKMARKS, CMainFrame::MENU_FILECMP },
{ ID_VIEW_ZOOMIN, IDB_VIEW_ZOOMIN, CMainFrame::MENU_FILECMP },
{ ID_VIEW_ZOOMOUT, IDB_VIEW_ZOOMOUT, CMainFrame::MENU_FILECMP },
+ { ID_COPY_FROM_LEFT, IDB_COPY_FROM_LEFT, CMainFrame::MENU_FILECMP },
+ { ID_COPY_FROM_RIGHT, IDB_COPY_FROM_RIGHT, CMainFrame::MENU_FILECMP },
+ { ID_LINES_R2L, IDB_COPY_SELECTED_LINES_TO_LEFT, CMainFrame::MENU_FILECMP },
+ { ID_LINES_L2R, IDB_COPY_SELECTED_LINES_TO_RIGHT, CMainFrame::MENU_FILECMP },
+ { ID_COPY_LINES_FROM_LEFT, IDB_COPY_SELECTED_LINES_FROM_LEFT, CMainFrame::MENU_FILECMP },
+ { ID_COPY_LINES_FROM_RIGHT, IDB_COPY_SELECTED_LINES_FROM_RIGHT, CMainFrame::MENU_FILECMP },
{ ID_MERGE_COMPARE, IDB_MERGE_COMPARE, CMainFrame::MENU_FOLDERCMP },
{ ID_MERGE_COMPARE_LEFT1_LEFT2, IDB_MERGE_COMPARE_LEFT1_LEFT2, CMainFrame::MENU_FOLDERCMP },
{ ID_MERGE_COMPARE_RIGHT1_RIGHT2, IDB_MERGE_COMPARE_RIGHT1_RIGHT2,CMainFrame::MENU_FOLDERCMP },
ON_COMMAND(ID_HELP_CONTENTS, OnHelpContents)
ON_WM_CLOSE()
ON_COMMAND(ID_TOOLS_GENERATEPATCH, OnToolsGeneratePatch)
+ ON_WM_TIMER()
ON_WM_DESTROY()
ON_COMMAND_RANGE(ID_UNPACK_MANUAL, ID_UNPACK_AUTO, OnPluginUnpackMode)
ON_UPDATE_COMMAND_UI_RANGE(ID_UNPACK_MANUAL, ID_UNPACK_AUTO, OnUpdatePluginUnpackMode)
ON_UPDATE_COMMAND_UI(ID_RELOAD_PLUGINS, OnUpdateReloadPlugins)
ON_COMMAND(ID_RELOAD_PLUGINS, OnReloadPlugins)
ON_COMMAND(ID_HELP_GETCONFIG, OnSaveConfigData)
- ON_COMMAND(ID_FILE_NEW, OnFileNew)
- ON_COMMAND(ID_FILE_NEW3, OnFileNew3)
+ ON_COMMAND(ID_FILE_NEW, (OnFileNew<2, FRAME_FILE>))
+ ON_COMMAND(ID_FILE_NEW_TABLE, (OnFileNew<2, FRAME_FILE, true>))
+ ON_COMMAND(ID_FILE_NEW_HEX, (OnFileNew<2, FRAME_HEXFILE>))
+ ON_COMMAND(ID_FILE_NEW_IMAGE, (OnFileNew<2, FRAME_IMGFILE>))
+ ON_COMMAND(ID_FILE_NEW3, (OnFileNew<3, FRAME_FILE>))
+ ON_COMMAND(ID_FILE_NEW3_TABLE, (OnFileNew<2, FRAME_FILE, true>))
+ ON_COMMAND(ID_FILE_NEW3_HEX, (OnFileNew<3, FRAME_HEXFILE>))
+ ON_COMMAND(ID_FILE_NEW3_IMAGE, (OnFileNew<3, FRAME_IMGFILE>))
ON_COMMAND(ID_TOOLS_FILTERS, OnToolsFilters)
ON_COMMAND(ID_VIEW_STATUS_BAR, OnViewStatusBar)
ON_UPDATE_COMMAND_UI(ID_VIEW_TAB_BAR, OnUpdateViewTabBar)
ON_COMMAND(ID_FILE_OPENCONFLICT, OnFileOpenConflict)
ON_COMMAND(ID_PLUGINS_LIST, OnPluginsList)
ON_UPDATE_COMMAND_UI(ID_STATUS_PLUGIN, OnUpdatePluginName)
- ON_NOTIFY(TBN_DROPDOWN, AFX_IDW_TOOLBAR, OnDiffOptionsDropDown)
+ ON_NOTIFY(TBN_DROPDOWN, AFX_IDW_TOOLBAR, OnToolbarButtonDropDown)
ON_COMMAND_RANGE(IDC_DIFF_WHITESPACE_COMPARE, IDC_DIFF_WHITESPACE_IGNOREALL, OnDiffWhitespace)
ON_UPDATE_COMMAND_UI_RANGE(IDC_DIFF_WHITESPACE_COMPARE, IDC_DIFF_WHITESPACE_IGNOREALL, OnUpdateDiffWhitespace)
- ON_COMMAND(IDC_DIFF_CASESENSITIVE, OnDiffCaseSensitive)
- ON_UPDATE_COMMAND_UI(IDC_DIFF_CASESENSITIVE, OnUpdateDiffCaseSensitive)
+ ON_COMMAND(IDC_DIFF_IGNORECASE, OnDiffIgnoreCase)
+ ON_UPDATE_COMMAND_UI(IDC_DIFF_IGNORECASE, OnUpdateDiffIgnoreCase)
ON_COMMAND(IDC_DIFF_IGNOREEOL, OnDiffIgnoreEOL)
ON_UPDATE_COMMAND_UI(IDC_DIFF_IGNOREEOL, OnUpdateDiffIgnoreEOL)
+ ON_COMMAND(IDC_DIFF_IGNORECP, OnDiffIgnoreCP)
+ ON_UPDATE_COMMAND_UI(IDC_DIFF_IGNORECP, OnUpdateDiffIgnoreCP)
ON_COMMAND(IDC_RECURS_CHECK, OnIncludeSubfolders)
ON_UPDATE_COMMAND_UI(IDC_RECURS_CHECK, OnUpdateIncludeSubfolders)
ON_COMMAND_RANGE(ID_COMPMETHOD_FULL_CONTENTS, ID_COMPMETHOD_SIZE, OnCompareMethod)
ON_COMMAND_RANGE(ID_MRU_FIRST, ID_MRU_LAST, OnMRUs)
ON_UPDATE_COMMAND_UI(ID_MRU_FIRST, OnUpdateNoMRUs)
ON_UPDATE_COMMAND_UI(ID_NO_MRU, OnUpdateNoMRUs)
+ ON_COMMAND(ID_FIRSTFILE, OnFirstFile)
+ ON_UPDATE_COMMAND_UI(ID_FIRSTFILE, OnUpdateFirstFile)
+ ON_COMMAND(ID_PREVFILE, OnPrevFile)
+ ON_UPDATE_COMMAND_UI(ID_PREVFILE, OnUpdatePrevFile)
+ ON_COMMAND(ID_NEXTFILE, OnNextFile)
+ ON_UPDATE_COMMAND_UI(ID_NEXTFILE, OnUpdateNextFile)
+ ON_COMMAND(ID_LASTFILE, OnLastFile)
+ ON_UPDATE_COMMAND_UI(ID_LASTFILE, OnUpdateLastFile)
+ ON_COMMAND(ID_ACCEL_QUIT, &CMainFrame::OnAccelQuit)
+ ON_MESSAGE(WMU_CHILDFRAMEADDED, &CMainFrame::OnChildFrameAdded)
+ ON_MESSAGE(WMU_CHILDFRAMEREMOVED, &CMainFrame::OnChildFrameRemoved)
+ ON_MESSAGE(WMU_CHILDFRAMEACTIVATE, &CMainFrame::OnChildFrameActivate)
+ ON_MESSAGE(WMU_CHILDFRAMEACTIVATED, &CMainFrame::OnChildFrameActivated)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
: m_bFirstTime(true)
, m_pDropHandler(nullptr)
, m_bShowErrors(false)
+, m_lfDiff(Options::Font::Load(GetOptionsMgr(), OPT_FONT_FILECMP))
+, m_lfDir(Options::Font::Load(GetOptionsMgr(), OPT_FONT_DIRCMP))
{
}
{
GetOptionsMgr()->SaveOption(OPT_TABBAR_AUTO_MAXWIDTH, m_wndTabBar.GetAutoMaxWidth());
strdiff::Close();
+
+ m_arrChild.RemoveAll();
}
-#ifdef _UNICODE
const TCHAR CMainFrame::szClassName[] = _T("WinMergeWindowClassW");
-#else
-const TCHAR CMainFrame::szClassName[] = _T("WinMergeWindowClassA");
-#endif
+
/**
* @brief Change MainFrame window class name
* see http://support.microsoft.com/kb/403825/ja
if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
- m_lfDiff = Options::Font::Load(GetOptionsMgr(), OPT_FONT_FILECMP);
- m_lfDir = Options::Font::Load(GetOptionsMgr(), OPT_FONT_DIRCMP);
-
+ m_wndMDIClient.SubclassWindow(m_hWndMDIClient);
+
if (!CreateToolbar())
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
theApp.SetIndicators(m_wndStatusBar, StatusbarIndicators,
- countof(StatusbarIndicators));
+ static_cast<int>(std::size(StatusbarIndicators)));
const int lpx = CClientDC(this).GetDeviceCaps(LOGPIXELSX);
auto pointToPixel = [lpx](int point) { return MulDiv(point, lpx, 72); };
m_pDropHandler = new DropHandler(std::bind(&CMainFrame::OnDropFiles, this, std::placeholders::_1));
RegisterDragDrop(m_hWnd, m_pDropHandler);
+ m_wndMDIClient.ModifyStyleEx(WS_EX_CLIENTEDGE, 0);
+
return 0;
}
+void CMainFrame::OnTimer(UINT_PTR nIDEvent)
+{
+ CMDIFrameWnd::OnTimer(nIDEvent);
+
+ if (nIDEvent == IDT_UPDATEMAINMENU)
+ {
+ KillTimer(nIDEvent);
+
+ BOOL bMaximized;
+ MDIGetActive(&bMaximized);
+
+ // When MDI maximized the window icon is drawn on the menu bar, so we
+ // need to notify it that our icon has changed.
+ if (bMaximized)
+ DrawMenuBar();
+
+ OnUpdateFrameTitle(FALSE);
+ }
+}
+
void CMainFrame::OnDestroy(void)
{
- if (m_pDropHandler)
+ if (m_pDropHandler != nullptr)
RevokeDragDrop(m_hWnd);
}
-static HMENU GetSubmenu(HMENU mainMenu, UINT nIDFirstMenuItem, bool bFirstSubmenu)
+static HMENU GetSubmenu(HMENU menu, bool bFirstSubmenu)
{
- int i;
- for (i = 0 ; i < ::GetMenuItemCount(mainMenu) ; i++)
- if (::GetMenuItemID(::GetSubMenu(mainMenu, i), 0) == nIDFirstMenuItem)
- break;
- HMENU menu = ::GetSubMenu(mainMenu, i);
-
if (!bFirstSubmenu)
{
// look for last submenu
- for (i = ::GetMenuItemCount(menu) ; i >= 0 ; i--)
- if (::GetSubMenu(menu, i) != NULL)
+ for (int i = ::GetMenuItemCount(menu) ; i >= 0 ; i--)
+ if (::GetSubMenu(menu, i) != nullptr)
return ::GetSubMenu(menu, i);
}
else
{
// look for first submenu
- for (i = 0 ; i < ::GetMenuItemCount(menu) ; i++)
- if (::GetSubMenu(menu, i) != NULL)
+ for (int i = 0 ; i < ::GetMenuItemCount(menu) ; i++)
+ if (::GetSubMenu(menu, i) != nullptr)
return ::GetSubMenu(menu, i);
}
// error, submenu not found
- return NULL;
+ return nullptr;
+}
+
+static HMENU GetSubmenu(HMENU mainMenu, UINT nIDFirstMenuItem, bool bFirstSubmenu)
+{
+ int i;
+ for (i = 0 ; i < ::GetMenuItemCount(mainMenu) ; i++)
+ if (::GetMenuItemID(::GetSubMenu(mainMenu, i), 0) == nIDFirstMenuItem)
+ break;
+ HMENU menu = ::GetSubMenu(mainMenu, i);
+ if (!menu)
+ return nullptr;
+ return GetSubmenu(menu, bFirstSubmenu);
}
/**
*/
HMENU CMainFrame::NewMenu(int view, int ID)
{
- int menu_view, index;
+ int menu_view;
if (m_pMenus[view] == nullptr)
{
m_pMenus[view].reset(new BCMenu());
if (view == MENU_IMGMERGEVIEW)
{
- BCMenu *pMenu = new BCMenu;
- pMenu->LoadMenu(MAKEINTRESOURCE(IDR_POPUP_IMGMERGEVIEW));
- m_pMenus[view]->InsertMenu(4, MF_BYPOSITION | MF_POPUP, (UINT_PTR)pMenu->GetSubMenu(0)->m_hMenu, const_cast<TCHAR *>(LoadResString(IDS_IMAGE_MENU).c_str()));
+ m_pImageMenu.reset(new BCMenu);
+ m_pImageMenu->LoadMenu(MAKEINTRESOURCE(IDR_POPUP_IMGMERGEVIEW));
+ m_pMenus[view]->InsertMenu(4, MF_BYPOSITION | MF_POPUP, (UINT_PTR)m_pImageMenu->GetSubMenu(0)->m_hMenu, const_cast<TCHAR *>(LoadResString(IDS_IMAGE_MENU).c_str()));
}
// Load bitmaps to menuitems
- for (index = 0; index < countof(m_MenuIcons); index ++)
+ for (auto& menu_icon: m_MenuIcons)
{
- if (menu_view == (m_MenuIcons[index].menusToApply & menu_view))
+ if (menu_view == (menu_icon.menusToApply & menu_view))
{
- m_pMenus[view]->ModifyODMenu(NULL, m_MenuIcons[index].menuitemID, m_MenuIcons[index].iconResID);
+ m_pMenus[view]->ModifyODMenu(nullptr, menu_icon.menuitemID, menu_icon.iconResID);
}
}
static void
FileLocationGuessEncodings(FileLocation & fileloc, int iGuessEncoding)
{
- fileloc.encoding = GuessCodepageEncoding(fileloc.filepath, iGuessEncoding);
+ fileloc.encoding = codepage_detect::Guess(fileloc.filepath, iGuessEncoding);
}
bool CMainFrame::ShowAutoMergeDoc(CDirDoc * pDirDoc,
const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/,
const PackingInfo * infoUnpacker /*= nullptr*/)
{
- int pane;
+ ASSERT(pDirDoc != nullptr);
+
+ if (sReportFile.empty() && pDirDoc->CompareFilesIfFilesAreLarge(nFiles, ifileloc))
+ return false;
+
+ String unpackedFileExtension;
+ if (infoUnpacker && GetOptionsMgr()->GetBool(OPT_PLUGINS_ENABLED))
+ {
+ std::vector<String> filepaths(nFiles);
+ std::transform(ifileloc, ifileloc + nFiles, filepaths.begin(),
+ [](auto& file) { return file.filepath; });
+ String filteredFilenames = strutils::join(filepaths.begin(), filepaths.end(), _T("|"));
+ unpackedFileExtension = FileTransform::GetUnpackedFileExtension(filteredFilenames, infoUnpacker);
+ }
FileFilterHelper filterImg, filterBin;
filterImg.UseMask(true);
filterImg.SetMask(GetOptionsMgr()->GetString(OPT_CMP_IMG_FILEPATTERNS));
filterBin.UseMask(true);
filterBin.SetMask(GetOptionsMgr()->GetString(OPT_CMP_BIN_FILEPATTERNS));
- for (pane = 0; pane < nFiles; ++pane)
+ for (int pane = 0; pane < nFiles; ++pane)
{
- if (filterImg.includeFile(ifileloc[pane].filepath) && CImgMergeFrame::IsLoadable())
+ String filepath = ifileloc[pane].filepath + unpackedFileExtension;
+ if (filterImg.includeFile(filepath) && CImgMergeFrame::IsLoadable())
return ShowImgMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker);
- else if (filterBin.includeFile(ifileloc[pane].filepath) && CHexMergeView::IsLoadable())
+ else if (filterBin.includeFile(filepath) && CHexMergeView::IsLoadable())
return ShowHexMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker);
}
- return ShowMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker);
+ return ShowTextOrTableMergeDoc({}, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker);
+}
+
+bool CMainFrame::ShowMergeDoc(UINT nID, CDirDoc* pDirDoc,
+ int nFiles, const FileLocation ifileloc[],
+ const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/,
+ const PackingInfo* infoUnpacker /*= nullptr*/)
+{
+ switch (nID)
+ {
+ case ID_MERGE_COMPARE_TEXT:
+ return GetMainFrame()->ShowTextMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
+ strDesc, sReportFile, infoUnpacker);
+ case ID_MERGE_COMPARE_TABLE:
+ return GetMainFrame()->ShowTableMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
+ strDesc, sReportFile, infoUnpacker);
+ case ID_MERGE_COMPARE_HEX:
+ return GetMainFrame()->ShowHexMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
+ strDesc, sReportFile, infoUnpacker);
+ case ID_MERGE_COMPARE_IMAGE:
+ return GetMainFrame()->ShowImgMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
+ strDesc, sReportFile, infoUnpacker);
+ default:
+ return GetMainFrame()->ShowAutoMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
+ strDesc, sReportFile, infoUnpacker);
+ }
}
std::array<bool, 3> GetROFromFlags(int nFiles, const DWORD dwFlags[])
* @param [in] infoUnpacker Plugin info.
* @return success/failure
*/
-bool CMainFrame::ShowMergeDoc(CDirDoc * pDirDoc,
+bool CMainFrame::ShowTextOrTableMergeDoc(std::optional<bool> table, CDirDoc * pDirDoc,
int nFiles, const FileLocation ifileloc[],
const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/,
const PackingInfo * infoUnpacker /*= nullptr*/)
{
- if (!m_pMenus[MENU_MERGEVIEW])
+ if (m_pMenus[MENU_MERGEVIEW] == nullptr)
theApp.m_pDiffTemplate->m_hMenuShared = NewMergeViewMenu();
- CMergeDoc * pMergeDoc = GetMergeDocForDiff<CMergeDoc>(theApp.m_pDiffTemplate, pDirDoc, nFiles);
+ CMergeDoc * pMergeDoc = GetMergeDocForDiff<CMergeDoc>(theApp.m_pDiffTemplate, pDirDoc, nFiles, false);
// Make local copies, so we can change encoding if we guess it below
FileLocation fileloc[3];
std::copy_n(ifileloc, nFiles, fileloc);
- ASSERT(pMergeDoc); // must ASSERT to get an answer to the question below ;-)
- if (!pMergeDoc)
+ ASSERT(pMergeDoc != nullptr); // must ASSERT to get an answer to the question below ;-)
+ if (pMergeDoc == nullptr)
return false; // when does this happen ?
// if an unpacker is selected, it must be used during LoadFromFile
{
FileLocationGuessEncodings(fileloc[pane], iGuessEncodingType);
}
-
- // TODO (Perry, 2005-12-04)
- // Should we do any unification if unicodings are different?
-
-
-#ifndef _UNICODE
- // In ANSI (8-bit) build, character loss can occur in merging
- // if the two buffers use different encodings
- if (pane > 0 && fileloc[pane - 1].encoding.m_codepage != fileloc[pane].encoding.m_codepage)
- {
- CString msg;
- msg.Format(theApp.LoadString(IDS_SUGGEST_IGNORECODEPAGE).c_str(), fileloc[pane - 1].encoding.m_codepage,fileloc[pane].encoding.m_codepage);
- int msgflags = MB_YESNO | MB_ICONQUESTION | MB_DONT_ASK_AGAIN;
- // Two files with different codepages
- // Warn and propose to use the default codepage for both
- int userChoice = AfxMessageBox(msg, msgflags);
- if (userChoice == IDYES)
- {
- fileloc[pane - 1].encoding.SetCodepage(ucr::getDefaultCodepage());
- fileloc[pane - 1].encoding.m_bom = false;
- fileloc[pane].encoding.SetCodepage(ucr::getDefaultCodepage());
- fileloc[pane].encoding.m_bom = false;
- }
- }
-#endif
}
+ pMergeDoc->SetEnableTableEditing(table);
+
// Note that OpenDocs() takes care of closing compare window when needed.
- if (!pMergeDoc->OpenDocs(nFiles, fileloc, GetROFromFlags(nFiles, dwFlags).data(), strDesc, GetActivePaneFromFlags(nFiles, dwFlags)))
+ bool bResult = pMergeDoc->OpenDocs(nFiles, fileloc, GetROFromFlags(nFiles, dwFlags).data(), strDesc);
+ if (bResult)
+ {
+ if (CMergeEditFrame *pFrame = pMergeDoc->GetParentFrame())
+ if (!pFrame->IsActivated())
+ pFrame->InitialUpdateFrame(pMergeDoc, true);
+ }
+ else
+ {
return false;
+ }
for (int pane = 0; pane < nFiles; pane++)
{
bool bModified = (dwFlags[pane] & FFILEOPEN_MODIFIED) > 0;
if (bModified)
{
- pMergeDoc->m_ptBuf[pane]->SetModified(TRUE);
+ pMergeDoc->m_ptBuf[pane]->SetModified(true);
pMergeDoc->UpdateHeaderPath(pane);
}
if (dwFlags[pane] & FFILEOPEN_AUTOMERGE)
}
}
+ pMergeDoc->MoveOnLoad(GetActivePaneFromFlags(nFiles, dwFlags));
+
if (!sReportFile.empty())
pMergeDoc->GenerateReport(sReportFile);
return true;
}
+bool CMainFrame::ShowTextMergeDoc(CDirDoc* pDirDoc,
+ int nFiles, const FileLocation ifileloc[],
+ const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/,
+ const PackingInfo* infoUnpacker /*= nullptr*/)
+{
+ return ShowTextOrTableMergeDoc(false, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker);
+}
+
+bool CMainFrame::ShowTableMergeDoc(CDirDoc* pDirDoc,
+ int nFiles, const FileLocation ifileloc[],
+ const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/,
+ const PackingInfo* infoUnpacker /*= nullptr*/)
+{
+ return ShowTextOrTableMergeDoc(true, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker);
+}
+
bool CMainFrame::ShowHexMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/,
const PackingInfo * infoUnpacker /*= nullptr*/)
{
- if (!m_pMenus[MENU_HEXMERGEVIEW])
+ if (m_pMenus[MENU_HEXMERGEVIEW] == nullptr)
theApp.m_pHexMergeTemplate->m_hMenuShared = NewHexMergeViewMenu();
CHexMergeDoc *pHexMergeDoc = GetMergeDocForDiff<CHexMergeDoc>(theApp.m_pHexMergeTemplate, pDirDoc, nFiles);
- if (!pHexMergeDoc)
+ if (pHexMergeDoc == nullptr)
return false;
- if (!pHexMergeDoc->OpenDocs(nFiles, fileloc, GetROFromFlags(nFiles, dwFlags).data(), strDesc, GetActivePaneFromFlags(nFiles, dwFlags)))
+ pHexMergeDoc->SetUnpacker(infoUnpacker);
+
+ if (!pHexMergeDoc->OpenDocs(nFiles, fileloc, GetROFromFlags(nFiles, dwFlags).data(), strDesc))
return false;
+
+ pHexMergeDoc->MoveOnLoad(GetActivePaneFromFlags(nFiles, dwFlags));
if (!sReportFile.empty())
pHexMergeDoc->GenerateReport(sReportFile);
if (!CImgMergeFrame::menu.m_hMenu)
CImgMergeFrame::menu.m_hMenu = NewImgMergeViewMenu();
pImgMergeFrame->SetSharedMenu(CImgMergeFrame::menu.m_hMenu);
-
+ pImgMergeFrame->SetUnpacker(infoUnpacker);
pImgMergeFrame->SetDirDoc(pDirDoc);
pDirDoc->AddMergeDoc(pImgMergeFrame);
- if (!pImgMergeFrame->OpenDocs(nFiles, fileloc, GetROFromFlags(nFiles, dwFlags).data(), strDesc, GetActivePaneFromFlags(nFiles, dwFlags), this))
- return ShowMergeDoc(pDirDoc, nFiles, fileloc, dwFlags, strDesc, sReportFile, infoUnpacker);
+ if (!pImgMergeFrame->OpenDocs(nFiles, fileloc, GetROFromFlags(nFiles, dwFlags).data(), strDesc, this))
+ return ShowTextMergeDoc(pDirDoc, nFiles, fileloc, dwFlags, strDesc, sReportFile, infoUnpacker);
for (int pane = 0; pane < nFiles; pane++)
{
pImgMergeFrame->DoAutoMerge(pane);
}
+ pImgMergeFrame->MoveOnLoad(GetActivePaneFromFlags(nFiles, dwFlags));
+
if (!sReportFile.empty())
pImgMergeFrame->GenerateReport(sReportFile);
return true;
}
+bool CMainFrame::ShowTextMergeDoc(CDirDoc* pDirDoc, int nBuffers, const String text[],
+ const String strDesc[], const String& strFileExt)
+{
+ FileLocation fileloc[3];
+ DWORD dwFlags[3] = {};
+ CDirDoc* pDirDoc2 = pDirDoc->GetMainView() ? pDirDoc :
+ static_cast<CDirDoc*>(theApp.m_pDirTemplate->CreateNewDocument());
+ for (int nBuffer = 0; nBuffer < nBuffers; ++nBuffer)
+ {
+ TempFilePtr wTemp(new TempFile());
+ String workFile = wTemp->Create(_T("text_"), strFileExt);
+ m_tempFiles.push_back(wTemp);
+ wTemp->Create(_T(""), strFileExt);
+ UniStdioFile file;
+ if (file.OpenCreateUtf8(workFile))
+ {
+ file.WriteString(text[nBuffer]);
+ }
+ fileloc[nBuffer].setPath(workFile);
+ }
+ return ShowTextMergeDoc(pDirDoc2, nBuffers, fileloc, dwFlags, strDesc);
+}
+
/**
* @brief Show GNU licence information in notepad (local file) or in Web Browser
*/
void CMainFrame::OnHelpGnulicense()
{
const String spath = paths::ConcatPath(env::GetProgPath(), LicenseFile);
- theApp.OpenFileOrUrl(spath.c_str(), LicenceUrl);
+ shell::OpenFileOrUrl(spath.c_str(), LicenceUrl);
}
/**
LANGID lang = static_cast<LANGID>(GetOptionsMgr()->GetInt(OPT_SELECTED_LANGUAGE));
if (lang != theApp.m_pLangDlg->GetLangId())
{
- theApp.m_pLangDlg->SetLanguage(lang, TRUE);
+ theApp.m_pLangDlg->SetLanguage(lang, true);
// Update status bar inicator texts
theApp.SetIndicators(m_wndStatusBar, 0, 0);
String filterPath = GetOptionsMgr()->GetString(OPT_FILTER_USERPATH);
theApp.m_pGlobalFileFilter->SetUserFilterPath(filterPath);
+ CCrystalTextView::RENDERING_MODE nRenderingMode = static_cast<CCrystalTextView::RENDERING_MODE>(GetOptionsMgr()->GetInt(OPT_RENDERING_MODE));
+ CCrystalTextView::SetRenderingModeDefault(nRenderingMode);
+
theApp.UpdateCodepageModule();
strdiff::SetBreakChars(GetOptionsMgr()->GetString(OPT_BREAK_SEPARATORS).c_str());
params += _T("/r ");
if (!filter.empty())
params += _T("/f \"") + filter + _T("\" ");
- return JumpList::AddToRecentDocs(_T(""), params, title, params, 0);
-}
+ Concurrent::CreateTask([params, title](){
+ CoInitialize(nullptr);
+ JumpList::AddToRecentDocs(_T(""), params, title, params, 0);
+ CoUninitialize();
+ return 0;
+ });
+ return true;
+}
/**
* @brief Begin a diff: open dirdoc if it is directories, else open a mergedoc for editing.
* @param [in] pszLeft Left-side path.
const DWORD dwFlags[] /*= nullptr*/, const String strDesc[] /*= nullptr*/, const String& sReportFile /*= T("")*/, bool bRecurse /*= false*/, CDirDoc *pDirDoc/*= nullptr*/,
String prediffer /*= _T("")*/, const PackingInfo *infoUnpacker /*= nullptr*/)
{
- if (pDirDoc && !pDirDoc->CloseMergeDocs())
+ if (pDirDoc != nullptr && !pDirDoc->CloseMergeDocs())
return false;
- FileTransform::g_UnpackerMode = static_cast<PLUGIN_MODE>(theApp.GetProfileInt(_T("Settings"), _T("UnpackerMode"), PLUGIN_MANUAL));
- FileTransform::g_PredifferMode = static_cast<PLUGIN_MODE>(theApp.GetProfileInt(_T("Settings"), _T("PredifferMode"), PLUGIN_MANUAL));
+ FileTransform::g_UnpackerMode = static_cast<PLUGIN_MODE>(GetOptionsMgr()->GetInt(OPT_PLUGINS_UNPACKER_MODE));
+ FileTransform::g_PredifferMode = static_cast<PLUGIN_MODE>(GetOptionsMgr()->GetInt(OPT_PLUGINS_PREDIFFER_MODE));
Merge7zFormatMergePluginScope scope(infoUnpacker);
PathContext tFiles;
- if (pFiles)
+ if (pFiles != nullptr)
tFiles = *pFiles;
bool bRO[3] = {0};
if (dwFlags)
paths::PATH_EXISTENCE pathsType = paths::GetPairComparability(tFiles, IsArchiveFile);
if (pathsType == paths::DOES_NOT_EXIST)
{
- if (!m_pMenus[MENU_OPENVIEW])
+ if (m_pMenus[MENU_OPENVIEW] == nullptr)
theApp.m_pOpenTemplate->m_hMenuShared = NewOpenViewMenu();
COpenDoc *pOpenDoc = static_cast<COpenDoc *>(theApp.m_pOpenTemplate->CreateNewDocument());
if (dwFlags)
pOpenDoc->m_bRecurse = bRecurse;
if (infoUnpacker)
pOpenDoc->m_infoHandler = *infoUnpacker;
- CFrameWnd *pFrame = theApp.m_pOpenTemplate->CreateNewFrame(pOpenDoc, NULL);
+ CFrameWnd *pFrame = theApp.m_pOpenTemplate->CreateNewFrame(pOpenDoc, nullptr);
theApp.m_pOpenTemplate->InitialUpdateFrame(pFrame, pOpenDoc);
return true;
}
}
}
- CTempPathContext *pTempPathContext = NULL;
+ CTempPathContext *pTempPathContext = nullptr;
if (pathsType == paths::IS_EXISTING_DIR)
{
DecompressResult res= DecompressArchive(m_hWnd, tFiles);
// Determine if we want a new dirview open, now that we know if it was
// an archive. Don't open a new dirview if we are comparing files.
- if (!pDirDoc)
+ if (pDirDoc == nullptr)
{
if (pathsType == paths::IS_EXISTING_DIR)
{
CDirDoc::m_nDirsTemp = tFiles.GetSize();
- if (!m_pMenus[MENU_DIRVIEW])
+ if (m_pMenus[MENU_DIRVIEW] == nullptr)
theApp.m_pDirTemplate->m_hMenuShared = NewDirViewMenu();
- pDirDoc = static_cast<CDirDoc*>(theApp.m_pDirTemplate->OpenDocumentFile(NULL));
+ pDirDoc = static_cast<CDirDoc*>(theApp.m_pDirTemplate->OpenDocumentFile(nullptr));
}
else
{
// open the diff
if (pathsType == paths::IS_EXISTING_DIR)
{
- if (pDirDoc)
+ if (pDirDoc != nullptr)
{
// Anything that can go wrong inside InitCompare() will yield an
// exception. There is no point in checking return value.
pDirDoc->SetReportFile(sReportFile);
pDirDoc->SetDescriptions(strDesc);
- pDirDoc->SetTitle(NULL);
+ pDirDoc->SetTitle(nullptr);
for (int nIndex = 0; nIndex < tFiles.GetSize(); nIndex++)
pDirDoc->SetReadOnly(nIndex, bRO[nIndex]);
infoUnpacker);
}
- if (pFiles && (!dwFlags || !(dwFlags[0] & FFILEOPEN_NOMRU)))
+ if (pFiles != nullptr && (!dwFlags || !(dwFlags[0] & FFILEOPEN_NOMRU)))
{
String filter = GetOptionsMgr()->GetString(OPT_FILEFILTER_CURRENT);
AddToRecentDocs(*pFiles, (unsigned *)dwFlags, bRecurse, filter);
return true;
}
+bool CMainFrame::DoFileOpen(UINT nID, const PathContext* pFiles /*= nullptr*/,
+ const DWORD dwFlags[] /*= nullptr*/, const String strDesc[] /*= nullptr*/)
+{
+ CDirDoc* pDirDoc = static_cast<CDirDoc*>(theApp.m_pDirTemplate->CreateNewDocument());
+ FileLocation fileloc[3];
+ for (int pane = 0; pane < pFiles->GetSize(); pane++)
+ fileloc[pane].setPath((*pFiles)[pane]);
+ return ShowMergeDoc(nID, pDirDoc, pFiles->GetSize(), fileloc,
+ dwFlags, strDesc);
+}
+
void CMainFrame::UpdateFont(FRAMETYPE frame)
{
if (frame == FRAME_FOLDER)
{
for (auto pDoc : GetAllDirDocs())
{
- if (pDoc)
+ if (pDoc != nullptr)
{
CDirView *pView = pDoc->GetMainView();
- if (pView)
+ if (pView != nullptr)
pView->SetFont(m_lfDir);
}
}
for (auto pDoc : GetAllMergeDocs())
{
CMergeDoc *pMergeDoc = dynamic_cast<CMergeDoc *>(pDoc);
- if (pMergeDoc)
+ if (pMergeDoc != nullptr)
for (auto& pView: pMergeDoc->GetViewList())
pView->SetFont(m_lfDiff);
}
{
FRAMETYPE frame = GetFrameType(GetActiveFrame());
CHOOSEFONT cf = { sizeof CHOOSEFONT };
- LOGFONT *lf = NULL;
+ LOGFONT *lf = nullptr;
cf.Flags = CF_INITTOLOGFONTSTRUCT|CF_FORCEFONTEXIST|CF_SCREENFONTS;
if (frame == FRAME_FILE)
cf.Flags |= CF_FIXEDPITCHONLY; // Only fixed-width fonts for merge view
pDoc->UpdateResources();
for (auto pDoc : GetAllOpenDocs())
pDoc->UpdateResources();
+ for (auto pFrame: GetAllImgMergeFrames())
+ pFrame->UpdateResources();
}
/**
m_bFirstTime = false;
- WINDOWPLACEMENT wp;
+ WINDOWPLACEMENT wp = {};
wp.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(&wp);
wp.rcNormalPosition.left=theApp.GetProfileInt(_T("Settings"), _T("MainLeft"),0);
GetOptionsMgr()->SaveOption(OPT_FILEFILTER_CURRENT, filter);
// save main window position
- WINDOWPLACEMENT wp;
+ WINDOWPLACEMENT wp = {};
wp.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(&wp);
theApp.WriteProfileInt(_T("Settings"), _T("MainLeft"),wp.rcNormalPosition.left);
theApp.WriteProfileInt(_T("Settings"), _T("MainBottom"),wp.rcNormalPosition.bottom);
theApp.WriteProfileInt(_T("Settings"), _T("MainMax"), (wp.showCmd == SW_MAXIMIZE));
- // Close Non-Document/View frame with confirmation
- CMDIChildWnd *pChild = static_cast<CMDIChildWnd *>(CWnd::FromHandle(m_hWndMDIClient)->GetWindow(GW_CHILD));
- while (pChild)
+ for (auto pFrame: GetAllImgMergeFrames())
{
- CMDIChildWnd *pNextChild = static_cast<CMDIChildWnd *>(pChild->GetWindow(GW_HWNDNEXT));
- if (GetFrameType(pChild) == FRAME_IMGFILE)
- {
- if (!static_cast<CImgMergeFrame *>(pChild)->CloseNow())
- return;
- }
- pChild = pNextChild;
+ if (!pFrame->CloseNow())
+ return;
}
CMDIFrameWnd::OnClose();
// Re-read MergeDoc settings (also updates view settings)
// and rescan using new options
pMergeDoc->RefreshOptions();
- pMergeDoc->FlushAndRescan(TRUE);
+ pMergeDoc->FlushAndRescan(true);
}
}
return static_cast<HexMergeDocList &>(GetDocList(theApp.m_pHexMergeTemplate));
}
+std::list<CImgMergeFrame *> CMainFrame::GetAllImgMergeFrames()
+{
+ std::list<CImgMergeFrame *> list;
+ // Close Non-Document/View frame with confirmation
+ CMDIChildWnd *pChild = static_cast<CMDIChildWnd *>(CWnd::FromHandle(m_hWndMDIClient)->GetWindow(GW_CHILD));
+ while (pChild != nullptr)
+ {
+ CMDIChildWnd *pNextChild = static_cast<CMDIChildWnd *>(pChild->GetWindow(GW_HWNDNEXT));
+ if (GetFrameType(pChild) == FRAME_IMGFILE)
+ list.push_back(static_cast<CImgMergeFrame *>(pChild));
+ pChild = pNextChild;
+ }
+ return list;
+}
+
/**
* @brief Obtain a merge doc to display a difference in files.
* @return Pointer to CMergeDoc to use.
*/
template<class DocClass>
-DocClass * GetMergeDocForDiff(CMultiDocTemplate *pTemplate, CDirDoc *pDirDoc, int nFiles)
+DocClass * GetMergeDocForDiff(CMultiDocTemplate *pTemplate, CDirDoc *pDirDoc, int nFiles, bool bMakeVisible)
{
// Create a new merge doc
DocClass::m_nBuffersTemp = nFiles;
- DocClass *pMergeDoc = static_cast<DocClass*>(pTemplate->OpenDocumentFile(NULL));
- if (pMergeDoc)
+ DocClass *pMergeDoc = static_cast<DocClass*>(pTemplate->OpenDocumentFile(nullptr, bMakeVisible));
+ if (pMergeDoc != nullptr)
{
pDirDoc->AddMergeDoc(pMergeDoc);
pMergeDoc->SetDirDoc(pDirDoc);
PathContext tFiles(dropped_files);
const size_t fileCount = tFiles.GetSize();
- // If Ctrl pressed, do recursive compare
- bool recurse = !!::GetAsyncKeyState(VK_CONTROL) || GetOptionsMgr()->GetBool(OPT_CMP_INCLUDE_SUBDIRS);
+ bool recurse = GetOptionsMgr()->GetBool(OPT_CMP_INCLUDE_SUBDIRS);
+ // Do a reverse comparison with the current 'Include Subfolders' settings when pressing Control key
+ if (::GetAsyncKeyState(VK_CONTROL) & 0x8000)
+ recurse = !recurse;
// If user has <Shift> pressed with one file selected,
// assume it is an archive and set filenames to same
}
}
- DoFileOpen(&tFiles, dwFlags, NULL, _T(""), recurse);
+ DoFileOpen(&tFiles, dwFlags, nullptr, _T(""), recurse);
}
void CMainFrame::OnPluginUnpackMode(UINT nID )
switch (nID)
{
case ID_UNPACK_MANUAL:
- FileTransform::g_UnpackerMode = PLUGIN_MANUAL;
+ FileTransform::g_UnpackerMode = PLUGIN_MODE::PLUGIN_MANUAL;
break;
case ID_UNPACK_AUTO:
- FileTransform::g_UnpackerMode = PLUGIN_AUTO;
+ FileTransform::g_UnpackerMode = PLUGIN_MODE::PLUGIN_AUTO;
break;
}
- theApp.WriteProfileInt(_T("Settings"), _T("UnpackerMode"), FileTransform::g_UnpackerMode);
+ GetOptionsMgr()->SaveOption(OPT_PLUGINS_UNPACKER_MODE, static_cast<int>(FileTransform::g_UnpackerMode));
}
void CMainFrame::OnUpdatePluginUnpackMode(CCmdUI* pCmdUI)
pCmdUI->Enable(GetOptionsMgr()->GetBool(OPT_PLUGINS_ENABLED));
if (pCmdUI->m_nID == ID_UNPACK_MANUAL)
- pCmdUI->SetRadio(PLUGIN_MANUAL == FileTransform::g_UnpackerMode);
+ pCmdUI->SetRadio(PLUGIN_MODE::PLUGIN_MANUAL == FileTransform::g_UnpackerMode);
if (pCmdUI->m_nID == ID_UNPACK_AUTO)
- pCmdUI->SetRadio(PLUGIN_AUTO == FileTransform::g_UnpackerMode);
+ pCmdUI->SetRadio(PLUGIN_MODE::PLUGIN_AUTO == FileTransform::g_UnpackerMode);
}
void CMainFrame::OnPluginPrediffMode(UINT nID )
{
switch (nID)
{
case ID_PREDIFFER_MANUAL:
- FileTransform::g_PredifferMode = PLUGIN_MANUAL;
+ FileTransform::g_PredifferMode = PLUGIN_MODE::PLUGIN_MANUAL;
break;
case ID_PREDIFFER_AUTO:
- FileTransform::g_PredifferMode = PLUGIN_AUTO;
+ FileTransform::g_PredifferMode = PLUGIN_MODE::PLUGIN_AUTO;
break;
}
PrediffingInfo infoPrediffer;
pMergeDoc->SetPrediffer(&infoPrediffer);
for (auto pDirDoc : GetAllDirDocs())
pDirDoc->GetPluginManager().SetPrediffSettingAll(FileTransform::g_PredifferMode);
- theApp.WriteProfileInt(_T("Settings"), _T("PredifferMode"), FileTransform::g_PredifferMode);
+ GetOptionsMgr()->SaveOption(OPT_PLUGINS_PREDIFFER_MODE, static_cast<int>(FileTransform::g_PredifferMode));
}
void CMainFrame::OnUpdatePluginPrediffMode(CCmdUI* pCmdUI)
pCmdUI->Enable(GetOptionsMgr()->GetBool(OPT_PLUGINS_ENABLED));
if (pCmdUI->m_nID == ID_PREDIFFER_MANUAL)
- pCmdUI->SetRadio(PLUGIN_MANUAL == FileTransform::g_PredifferMode);
+ pCmdUI->SetRadio(PLUGIN_MODE::PLUGIN_MANUAL == FileTransform::g_PredifferMode);
if (pCmdUI->m_nID == ID_PREDIFFER_AUTO)
- pCmdUI->SetRadio(PLUGIN_AUTO == FileTransform::g_PredifferMode);
+ pCmdUI->SetRadio(PLUGIN_MODE::PLUGIN_AUTO == FileTransform::g_PredifferMode);
}
/**
* @brief Called when "Reload Plugins" item is updated
// update the editor scripts submenu
HMENU scriptsSubmenu = GetScriptsSubmenu(m_hMenuDefault);
- if (scriptsSubmenu != NULL)
+ if (scriptsSubmenu != nullptr)
CMergeEditView::createScriptsSubmenu(scriptsSubmenu);
UpdatePrediffersMenu();
}
{
// NB: GetActiveDocument does not return the Merge Doc
// even when the merge edit view is in front
- // NB: CChildFrame::GetActiveView returns NULL when location view active
+ // NB: CMergeEditFrame::GetActiveView returns `nullptr` when location view active
// So we have this rather complicated logic to try to get a merge edit view
// We look at the front child window, which should be a frame
- // and we can get a MergeEditView from it, if it is a CChildFrame
+ // and we can get a MergeEditView from it, if it is a CMergeEditFrame
// (DirViews use a different frame type)
- CChildFrame * pFrame = dynamic_cast<CChildFrame *>(GetActiveFrame());
- if (!pFrame) return 0;
+ CMergeEditFrame * pFrame = dynamic_cast<CMergeEditFrame *>(GetActiveFrame());
+ if (pFrame == nullptr) return nullptr;
// Try to get the active MergeEditView (ie, left or right)
if (pFrame->GetActiveView() != nullptr && pFrame->GetActiveView()->IsKindOf(RUNTIME_CLASS(CMergeEditView)))
{
void CMainFrame::UpdatePrediffersMenu()
{
CMenu* menu = GetMenu();
- if (menu == NULL)
+ if (menu == nullptr)
{
return;
}
HMENU hMainMenu = menu->m_hMenu;
HMENU prediffersSubmenu = GetPrediffersSubmenu(hMainMenu);
- if (prediffersSubmenu != NULL)
+ if (prediffersSubmenu != nullptr)
{
CMergeEditView * pEditView = GetActiveMergeEditView();
- if (pEditView)
+ if (pEditView != nullptr)
pEditView->createPrediffersSubmenu(prediffersSubmenu);
else
{
int i = GetMenuItemCount(prediffersSubmenu);
while (i --)
::DeleteMenu(prediffersSubmenu, 0, MF_BYPOSITION);
- ::AppendMenu(prediffersSubmenu, MF_SEPARATOR, 0, NULL);
+ ::AppendMenu(prediffersSubmenu, MF_SEPARATOR, 0, nullptr);
}
}
}
if (configLog.WriteLogFile(sError))
{
String sFileName = configLog.GetFileName();
- theApp.OpenFileToExternalEditor(sFileName);
+ CMergeApp::OpenFileToExternalEditor(sFileName);
}
else
{
* @sa CMergeDoc::OpenDocs()
* @sa CMergeDoc::TrySaveAs()
*/
-void CMainFrame::FileNew(int nPanes)
+void CMainFrame::FileNew(int nPanes, FRAMETYPE frameType, bool table)
{
CDirDoc *pDirDoc = static_cast<CDirDoc*>(theApp.m_pDirTemplate->CreateNewDocument());
strDesc[1] = _("Untitled right");
fileloc[0].encoding.SetCodepage(ucr::getDefaultCodepage());
fileloc[1].encoding.SetCodepage(ucr::getDefaultCodepage());
- ShowMergeDoc(pDirDoc, 2, fileloc, dwFlags, strDesc);
}
else
{
fileloc[0].encoding.SetCodepage(ucr::getDefaultCodepage());
fileloc[1].encoding.SetCodepage(ucr::getDefaultCodepage());
fileloc[2].encoding.SetCodepage(ucr::getDefaultCodepage());
- ShowMergeDoc(pDirDoc, 3, fileloc, dwFlags, strDesc);
}
+ UINT nID = ID_MERGE_COMPARE_TEXT;
+ switch (frameType)
+ {
+ case FRAME_FILE: nID = !table ? ID_MERGE_COMPARE_TEXT : ID_MERGE_COMPARE_TABLE; break;
+ case FRAME_HEXFILE: nID = ID_MERGE_COMPARE_HEX; break;
+ case FRAME_IMGFILE: nID = ID_MERGE_COMPARE_IMAGE; break;
+ }
+ ShowMergeDoc(nID, pDirDoc, nPanes, fileloc, dwFlags, strDesc);
}
/**
* @sa CMergeDoc::OpenDocs()
* @sa CMergeDoc::TrySaveAs()
*/
+template <int nFiles, CMainFrame::FRAMETYPE frameType, bool table>
void CMainFrame::OnFileNew()
{
- FileNew(2);
-}
-
-void CMainFrame::OnFileNew3()
-{
- FileNew(3);
+ FileNew(nFiles, frameType, table);
}
/**
String title = _("Filters");
CPropertySheet sht(title.c_str());
LineFiltersDlg lineFiltersDlg;
+ SubstitutionFiltersDlg substitutionFiltersDlg;
FileFiltersDlg fileFiltersDlg;
- vector<FileFilterInfo> fileFilters;
std::unique_ptr<LineFiltersList> lineFilters(new LineFiltersList());
+ std::unique_ptr<SubstitutionFiltersList> SubstitutionFilters(new SubstitutionFiltersList());
String selectedFilter;
const String origFilter = theApp.m_pGlobalFileFilter->GetFilterNameOrMask();
sht.AddPage(&fileFiltersDlg);
sht.AddPage(&lineFiltersDlg);
+ sht.AddPage(&substitutionFiltersDlg);
sht.m_psh.dwFlags |= PSH_NOAPPLYNOW; // Hide 'Apply' button since we don't need it
// Make sure all filters are up-to-date
theApp.m_pGlobalFileFilter->ReloadUpdatedFilters();
- theApp.m_pGlobalFileFilter->GetFileFilters(&fileFilters, selectedFilter);
- fileFiltersDlg.SetFilterArray(&fileFilters);
+ fileFiltersDlg.SetFilterArray(theApp.m_pGlobalFileFilter->GetFileFilters(selectedFilter));
fileFiltersDlg.SetSelected(selectedFilter);
const bool lineFiltersEnabledOrig = GetOptionsMgr()->GetBool(OPT_LINEFILTER_ENABLED);
lineFiltersDlg.m_bIgnoreRegExp = lineFiltersEnabledOrig;
lineFilters->CloneFrom(theApp.m_pLineFilters.get());
lineFiltersDlg.SetList(lineFilters.get());
+ SubstitutionFilters->CloneFrom(theApp.m_pSubstitutionFiltersList.get());
+ substitutionFiltersDlg.SetList(SubstitutionFilters.get());
+
+ sht.SetActivePage(AfxGetApp()->GetProfileInt(_T("Settings"), _T("FilterStartPage"), 0));
+
if (sht.DoModal() == IDOK)
{
String strNone = _("<None>");
FRAMETYPE frame = GetFrameType(pFrame);
if (frame == FRAME_FILE)
{
- if (lineFiltersEnabledOrig != linefiltersEnabled ||
- !theApp.m_pLineFilters->Compare(lineFilters.get()))
+ if
+ (
+ linefiltersEnabled != lineFiltersEnabledOrig
+ || !lineFilters->Compare(theApp.m_pLineFilters.get())
+ || !SubstitutionFilters->Compare(theApp.m_pSubstitutionFiltersList.get())
+ )
{
bFileCompareRescan = true;
}
theApp.m_pLineFilters->CloneFrom(lineFilters.get());
theApp.m_pLineFilters->SaveFilters();
+ theApp.m_pSubstitutionFiltersList->CloneFrom(SubstitutionFilters.get());
+ theApp.m_pSubstitutionFiltersList->SaveFilters();
+
if (bFileCompareRescan)
{
for (auto pMergeDoc : GetAllMergeDocs())
- pMergeDoc->FlushAndRescan(TRUE);
+ pMergeDoc->FlushAndRescan(true);
}
else if (bFolderCompareRescan)
{
{
if (theApp.m_bEscShutdown && m_wndTabBar.GetItemCount() <= 1)
{
- AfxGetMainWnd()->PostMessage(WM_COMMAND, ID_APP_EXIT);
+ AfxGetMainWnd()->SendMessage(WM_COMMAND, ID_APP_EXIT);
return TRUE;
}
- else if (GetOptionsMgr()->GetBool(OPT_CLOSE_WITH_ESC) && m_wndTabBar.GetItemCount() == 0)
+ else if (GetOptionsMgr()->GetInt(OPT_CLOSE_WITH_ESC) == 1 && m_wndTabBar.GetItemCount() == 0)
{
AfxGetMainWnd()->PostMessage(WM_COMMAND, ID_APP_EXIT);
return FALSE;
}
}
+
+ if (WM_KEYDOWN == pMsg->message && VK_TAB == pMsg->wParam && GetAsyncKeyState(VK_CONTROL) < 0 && m_arrChild.GetSize() > 1)
+ {
+ CWindowsManagerDialog* pDlg = new CWindowsManagerDialog;
+ pDlg->Create(CWindowsManagerDialog::IDD, this);
+ pDlg->ShowWindow(SW_SHOW);
+ return TRUE;
+ }
+
return CMDIFrameWnd::PreTranslateMessage(pMsg);
}
GetOptionsMgr()->SaveOption(OPT_RESIZE_PANES, bResize);
// TODO: Introduce a common merge frame superclass?
CFrameWnd *pActiveFrame = GetActiveFrame();
- if (CChildFrame *pFrame = DYNAMIC_DOWNCAST(CChildFrame, pActiveFrame))
+ if (CMergeEditFrame *pFrame = DYNAMIC_DOWNCAST(CMergeEditFrame, pActiveFrame))
{
pFrame->UpdateAutoPaneResize();
if (bResize)
// store this as the new project path
GetOptionsMgr()->SaveOption(OPT_PROJECTS_PATH, strProjectPath);
- theApp.LoadAndOpenProjectFile(sFilepath.c_str());
+ theApp.LoadAndOpenProjectFile(sFilepath);
}
/**
LRESULT CMainFrame::OnUser1(WPARAM wParam, LPARAM lParam)
{
- CFrameWnd * pFrame = GetActiveFrame();
- if (pFrame)
- {
- IMergeDoc *pMergeDoc = dynamic_cast<IMergeDoc *>(pFrame->GetActiveDocument());
- if (!pMergeDoc)
- pMergeDoc = dynamic_cast<IMergeDoc *>(pFrame);
- if (pMergeDoc)
- pMergeDoc->CheckFileChanged();
- }
+ if (IMergeDoc *pMergeDoc = GetActiveIMergeDoc())
+ pMergeDoc->CheckFileChanged();
return 0;
}
void CMainFrame::OnWindowCloseAll()
{
CMDIChildWnd *pChild = MDIGetActive();
- while (pChild)
+ while (pChild != nullptr)
{
CDocument* pDoc;
- if ((pDoc = pChild->GetActiveDocument()) != NULL)
+ if ((pDoc = pChild->GetActiveDocument()) != nullptr)
{
if (!pDoc->SaveModified())
return;
*/
void CMainFrame::OnUpdateWindowCloseAll(CCmdUI* pCmdUI)
{
- const MergeDocList &mergedocs = GetAllMergeDocs();
- if (!mergedocs.IsEmpty())
- {
- pCmdUI->Enable(TRUE);
- return;
- }
-
- const DirDocList &dirdocs = GetAllDirDocs();
- pCmdUI->Enable(!dirdocs.IsEmpty());
+ pCmdUI->Enable(MDIGetActive() != nullptr);
}
/**
*/
void CMainFrame::OnSaveProject()
{
- if (!m_pMenus[MENU_OPENVIEW])
+ if (m_pMenus[MENU_OPENVIEW] == nullptr)
theApp.m_pOpenTemplate->m_hMenuShared = NewOpenViewMenu();
COpenDoc *pOpenDoc = static_cast<COpenDoc *>(theApp.m_pOpenTemplate->CreateNewDocument());
{
CMergeDoc * pMergeDoc = static_cast<CMergeDoc *>(pFrame->GetActiveDocument());
pOpenDoc->m_files = pMergeDoc->m_filePaths;
- for (size_t pane = 0; pane < pOpenDoc->m_files.size(); ++pane)
+ for (int pane = 0; pane < pOpenDoc->m_files.GetSize(); ++pane)
pOpenDoc->m_dwFlags[pane] = FFILEOPEN_PROJECT | (pMergeDoc->m_ptBuf[pane]->GetReadOnly() ? FFILEOPEN_PROJECT : 0);
pOpenDoc->m_bRecurse = GetOptionsMgr()->GetBool(OPT_CMP_INCLUDE_SUBDIRS);
pOpenDoc->m_strExt = theApp.m_pGlobalFileFilter->GetFilterNameOrMask();
pOpenDoc->m_strExt = static_cast<FileFilterHelper *>(ctxt.m_piFilterGlobal)->GetFilterNameOrMask();
}
- CFrameWnd *pOpenFrame = theApp.m_pOpenTemplate->CreateNewFrame(pOpenDoc, NULL);
+ CFrameWnd *pOpenFrame = theApp.m_pOpenTemplate->CreateNewFrame(pOpenDoc, nullptr);
theApp.m_pOpenTemplate->InitialUpdateFrame(pOpenFrame, pOpenDoc);
}
{
CWnd * activeWindow = GetActiveWindow();
if (activeWindow != this)
- FlashWindowEx(FLASHW_ALL | FLASHW_TIMERNOFG, 0, 0);
+ FlashWindowEx(FLASHW_ALL | FLASHW_TIMERNOFG, 3, 0);
}
#if _MFC_VER > 0x0600
CMDIFrameWnd::OnActivateApp(bActive, hTask);
#endif
- CFrameWnd * pFrame = GetActiveFrame();
- if (pFrame)
- {
- IMergeDoc *pMergeDoc = dynamic_cast<IMergeDoc *>(pFrame->GetActiveDocument());
- if (!pMergeDoc)
- pMergeDoc = dynamic_cast<IMergeDoc *>(pFrame);
- if (pMergeDoc)
- PostMessage(WM_USER+1);
- }
+ if (IMergeDoc *pMergeDoc = GetActiveIMergeDoc())
+ PostMessage(WM_USER+1);
}
BOOL CMainFrame::CreateToolbar()
return FALSE;
}
- if (!m_wndReBar.Create(this))
+ if (!m_wndReBar.Create(this, RBS_BANDBORDERS,
+ WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_ALIGN_TOP))
{
return FALSE;
}
LoadToolbarImages();
UINT nID, nStyle;
- int iImage;
- int index = m_wndToolBar.GetToolBarCtrl().CommandToIndex(ID_OPTIONS);
- m_wndToolBar.GetButtonInfo(index, nID, nStyle, iImage);
- nStyle |= TBSTYLE_DROPDOWN;
- m_wndToolBar.SetButtonInfo(index, nID, nStyle, iImage);
+ for (auto cmd : { ID_OPTIONS, ID_FILE_NEW, ID_FILE_OPEN, ID_FILE_SAVE })
+ {
+ int iImage;
+ int index = m_wndToolBar.GetToolBarCtrl().CommandToIndex(cmd);
+ m_wndToolBar.GetButtonInfo(index, nID, nStyle, iImage);
+ nStyle |= TBSTYLE_DROPDOWN;
+ m_wndToolBar.SetButtonInfo(index, nID, nStyle, iImage);
+ }
if (!GetOptionsMgr()->GetBool(OPT_SHOW_TOOLBAR))
{
/** @brief Load toolbar images from the resource. */
void CMainFrame::LoadToolbarImages()
{
- const int toolbarSize = 16 << GetOptionsMgr()->GetInt(OPT_TOOLBAR_SIZE);
+ const int toolbarNewImgSize = MulDiv(16, GetSystemMetrics(SM_CXSMICON), 16) * (1 + GetOptionsMgr()->GetInt(OPT_TOOLBAR_SIZE));
+ const int toolbarOrgImgSize = toolbarNewImgSize <= 20 ? 16 : 32;
CToolBarCtrl& BarCtrl = m_wndToolBar.GetToolBarCtrl();
- m_ToolbarImages[TOOLBAR_IMAGES_ENABLED].DeleteImageList();
- m_ToolbarImages[TOOLBAR_IMAGES_DISABLED].DeleteImageList();
+ m_ToolbarImages[TOOLBAR_IMAGES_ENABLED].Detach();
+ m_ToolbarImages[TOOLBAR_IMAGES_DISABLED].Detach();
CSize sizeButton(0, 0);
- LoadToolbarImageList(toolbarSize,
- toolbarSize <= 16 ? IDB_TOOLBAR_ENABLED : IDB_TOOLBAR_ENABLED32,
- toolbarSize <= 16 ? IDB_TOOLBAR_ENABLED_MASK : IDB_TOOLBAR_ENABLED_MASK32,
+ LoadToolbarImageList(toolbarOrgImgSize, toolbarNewImgSize,
+ toolbarOrgImgSize <= 16 ? IDB_TOOLBAR_ENABLED : IDB_TOOLBAR_ENABLED32,
false, m_ToolbarImages[TOOLBAR_IMAGES_ENABLED]);
- LoadToolbarImageList(toolbarSize,
- toolbarSize <= 16 ? IDB_TOOLBAR_ENABLED : IDB_TOOLBAR_ENABLED32,
- toolbarSize <= 16 ? IDB_TOOLBAR_ENABLED_MASK : IDB_TOOLBAR_ENABLED_MASK32,
+ LoadToolbarImageList(toolbarOrgImgSize, toolbarNewImgSize,
+ toolbarOrgImgSize <= 16 ? IDB_TOOLBAR_ENABLED : IDB_TOOLBAR_ENABLED32,
true, m_ToolbarImages[TOOLBAR_IMAGES_DISABLED]);
- sizeButton = CSize(toolbarSize + 8, toolbarSize + 8);
+
+ sizeButton = CSize(toolbarNewImgSize + 8, toolbarNewImgSize + 8);
BarCtrl.SetButtonSize(sizeButton);
- BarCtrl.SetImageList(&m_ToolbarImages[TOOLBAR_IMAGES_ENABLED]);
- BarCtrl.SetDisabledImageList(&m_ToolbarImages[TOOLBAR_IMAGES_DISABLED]);
- m_ToolbarImages[TOOLBAR_IMAGES_ENABLED].Detach();
- m_ToolbarImages[TOOLBAR_IMAGES_DISABLED].Detach();
+ if (CImageList *pImgList = BarCtrl.SetImageList(&m_ToolbarImages[TOOLBAR_IMAGES_ENABLED]))
+ pImgList->DeleteImageList();
+ if (CImageList *pImgList = BarCtrl.SetDisabledImageList(&m_ToolbarImages[TOOLBAR_IMAGES_DISABLED]))
+ pImgList->DeleteImageList();
// resize the rebar.
REBARBANDINFO rbbi = { sizeof REBARBANDINFO };
/**
- * @brief Load a transparent 24-bit color image list.
+ * @brief Load a transparent 32-bit color image list.
*/
-static void LoadHiColImageList(UINT nIDResource, UINT nIDResourceMask, int nWidth, int nHeight, int nCount, bool bGrayscale, CImageList& ImgList)
+static void LoadHiColImageList(UINT nIDResource, int nWidth, int nHeight, int nNewWidth, int nNewHeight, int nCount, bool bGrayscale, CImageList& ImgList)
{
- CBitmap bm, bmMask;
- bm.Attach(LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(nIDResource), IMAGE_BITMAP, nWidth * nCount, nHeight, LR_DEFAULTCOLOR));
- bmMask.Attach(LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(nIDResourceMask), IMAGE_BITMAP, nWidth * nCount, nHeight, LR_MONOCHROME));
- if (bGrayscale)
- GrayScale(&bm);
- VERIFY(ImgList.Create(nWidth, nHeight, ILC_COLORDDB|ILC_MASK, nCount, 0));
- int nIndex = ImgList.Add(&bm, &bmMask);
+ CBitmap bm;
+ bm.Attach(LoadBitmapAndConvertTo32bit(AfxGetInstanceHandle(), nIDResource, nNewWidth * nCount, nNewHeight, bGrayscale, RGB(0xff, 0, 0xff)));
+
+ VERIFY(ImgList.Create(nNewWidth, nNewHeight, ILC_COLOR32, nCount, 0));
+ int nIndex = ImgList.Add(&bm, nullptr);
ASSERT(-1 != nIndex);
}
/**
* @brief Load toolbar image list.
*/
-static void LoadToolbarImageList(int imageWidth, UINT nIDResource, UINT nIDResourceMask, bool bGrayscale,
- CImageList& ImgList)
+static void LoadToolbarImageList(int orgImageWidth, int newImageWidth, UINT nIDResource, bool bGrayscale, CImageList& ImgList)
{
- const int ImageCount = 22;
- const int imageHeight = imageWidth - 1;
- LoadHiColImageList(nIDResource, nIDResourceMask, imageWidth, imageHeight, ImageCount, bGrayscale, ImgList);
+ const int ImageCount = 26;
+ const int orgImageHeight = orgImageWidth - 1;
+ const int newImageHeight = newImageWidth - 1;
+ LoadHiColImageList(nIDResource, orgImageWidth, orgImageHeight, newImageWidth, newImageHeight, ImageCount, bGrayscale, ImgList);
}
/**
{
CFrameWnd::OnUpdateFrameTitle(bAddToTitle);
- if (m_wndTabBar.m_hWnd)
+ if (m_wndTabBar.m_hWnd != nullptr)
m_wndTabBar.UpdateTabs();
}
// this is the command id, not the button index
AfxExtractSubString(strTipText, strFullText.c_str(), 1, '\n');
}
-#ifndef _UNICODE
if (pNMHDR->code == TTN_NEEDTEXTA)
- lstrcpyn(pTTTA->szText, strTipText, countof(pTTTA->szText));
+ _wcstombsz(pTTTA->szText, strTipText, static_cast<ULONG>(std::size(pTTTA->szText)));
else
- _mbstowcsz(pTTTW->szText, strTipText, countof(pTTTW->szText));
-#else
- if (pNMHDR->code == TTN_NEEDTEXTA)
- _wcstombsz(pTTTA->szText, strTipText, countof(pTTTA->szText));
- else
- lstrcpyn(pTTTW->szText, strTipText, countof(pTTTW->szText));
-#endif
+ lstrcpyn(pTTTW->szText, strTipText, static_cast<int>(std::size(pTTTW->szText)));
*pResult = 0;
// bring the tooltip window above other popup windows
void CMainFrame::OnHelpReleasenotes()
{
const String sPath = paths::ConcatPath(env::GetProgPath(), RelNotes);
- ShellExecute(NULL, _T("open"), sPath.c_str(), NULL, NULL, SW_SHOWNORMAL);
+ shell::Open(sPath.c_str());
}
/**
*/
void CMainFrame::OnHelpTranslations()
{
- ShellExecute(NULL, _T("open"), TranslationsUrl, NULL, NULL, SW_SHOWNORMAL);
+ shell::Open(TranslationsUrl);
}
/**
return conflictCompared;
}
+bool CMainFrame::DoSelfCompare(UINT nID, const String& file, const String strDesc[] /*= nullptr*/)
+{
+ String ext = paths::FindExtension(file);
+ TempFilePtr wTemp(new TempFile());
+ String copiedFile = wTemp->Create(_T("self-compare_"), ext);
+ m_tempFiles.push_back(wTemp);
+
+ TFile(file).copyTo(copiedFile);
+
+ String strDesc2[2] = {
+ (strDesc && !strDesc[0].empty()) ? strDesc[0] : _("Original File"),
+ (strDesc && !strDesc[1].empty()) ? strDesc[1] : _("") };
+ DWORD dwFlags[2] = {FFILEOPEN_READONLY | FFILEOPEN_NOMRU, FFILEOPEN_NOMRU};
+ PathContext tmpPathContext(copiedFile, file);
+ return DoFileOpen(nID, &tmpPathContext, dwFlags, strDesc2);
+}
+
/**
* @brief Get type of frame (File/Folder compare).
* @param [in] pFrame Pointer to frame to check.
* @return FRAMETYPE of the given frame.
*/
-CMainFrame::FRAMETYPE CMainFrame::GetFrameType(const CFrameWnd * pFrame) const
+CMainFrame::FRAMETYPE CMainFrame::GetFrameType(const CFrameWnd * pFrame)
{
- bool bMergeFrame = !!pFrame->IsKindOf(RUNTIME_CLASS(CChildFrame));
+ bool bMergeFrame = !!pFrame->IsKindOf(RUNTIME_CLASS(CMergeEditFrame));
bool bHexMergeFrame = !!pFrame->IsKindOf(RUNTIME_CLASS(CHexMergeFrame));
bool bImgMergeFrame = !!pFrame->IsKindOf(RUNTIME_CLASS(CImgMergeFrame));
bool bDirFrame = !!pFrame->IsKindOf(RUNTIME_CLASS(CDirFrame));
dlg.DoModal();
}
-void CMainFrame::OnDiffOptionsDropDown(NMHDR* pNMHDR, LRESULT* pResult)
+void CMainFrame::OnToolbarButtonDropDown(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMTOOLBAR pToolBar = reinterpret_cast<LPNMTOOLBAR>(pNMHDR);
ClientToScreen(&(pToolBar->rcButton));
BCMenu menu;
- VERIFY(menu.LoadMenu(IDR_POPUP_DIFF_OPTIONS));
+ int id;
+ switch (pToolBar->iItem)
+ {
+ case ID_FILE_NEW:
+ id = IDR_POPUP_NEW;
+ break;
+ case ID_FILE_OPEN:
+ id = IDR_POPUP_OPEN;
+ break;
+ case ID_FILE_SAVE:
+ id = IDR_POPUP_SAVE;
+ break;
+ default:
+ id = IDR_POPUP_DIFF_OPTIONS;
+ break;
+ }
+ VERIFY(menu.LoadMenu(id));
theApp.TranslateMenu(menu.m_hMenu);
CMenu* pPopup = menu.GetSubMenu(0);
if (pPopup != nullptr)
pCmdUI->Enable();
}
-void CMainFrame::OnDiffCaseSensitive()
+void CMainFrame::OnDiffIgnoreCase()
{
GetOptionsMgr()->SaveOption(OPT_CMP_IGNORE_CASE, !GetOptionsMgr()->GetBool(OPT_CMP_IGNORE_CASE));
ApplyDiffOptions();
}
-void CMainFrame::OnUpdateDiffCaseSensitive(CCmdUI* pCmdUI)
+void CMainFrame::OnUpdateDiffIgnoreCase(CCmdUI* pCmdUI)
{
- pCmdUI->SetCheck(!GetOptionsMgr()->GetBool(OPT_CMP_IGNORE_CASE));
+ pCmdUI->SetCheck(GetOptionsMgr()->GetBool(OPT_CMP_IGNORE_CASE));
pCmdUI->Enable();
}
pCmdUI->Enable();
}
+void CMainFrame::OnDiffIgnoreCP()
+{
+ GetOptionsMgr()->SaveOption(OPT_CMP_IGNORE_CODEPAGE, !GetOptionsMgr()->GetBool(OPT_CMP_IGNORE_CODEPAGE));
+ ApplyDiffOptions();
+}
+
+void CMainFrame::OnUpdateDiffIgnoreCP(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(GetOptionsMgr()->GetBool(OPT_CMP_IGNORE_CODEPAGE));
+ pCmdUI->Enable();
+}
+
void CMainFrame::OnIncludeSubfolders()
{
GetOptionsMgr()->SaveOption(OPT_CMP_INCLUDE_SUBDIRS, !GetOptionsMgr()->GetBool(OPT_CMP_INCLUDE_SUBDIRS));
void CMainFrame::OnMRUs(UINT nID)
{
std::vector<JumpList::Item> mrus = JumpList::GetRecentDocs(GetOptionsMgr()->GetInt(OPT_MRU_MAX));
- const size_t idx = nID - ID_MRU_FIRST;
+ const size_t idx = static_cast<size_t>(nID) - ID_MRU_FIRST;
if (idx < mrus.size())
{
MergeCmdLineInfo cmdInfo((_T("\"") + mrus[idx].path + _T("\" ") + mrus[idx].params).c_str());
void CMainFrame::OnUpdateNoMRUs(CCmdUI* pCmdUI)
{
// append the MRU submenu
- HMENU hMenu = GetSubmenu(AfxGetMainWnd()->GetMenu()->m_hMenu, ID_FILE_NEW, false);
- if (hMenu == NULL)
+ CMenu *pMenu = pCmdUI->m_pSubMenu ? pCmdUI->m_pSubMenu : pCmdUI->m_pMenu;
+ if (pMenu == nullptr)
return;
+ HMENU hMenu = pMenu->m_hMenu;
// empty the menu
size_t i = ::GetMenuItemCount(hMenu);
pCmdUI->SetText(_T(""));
}
+/**
+ * @brief Move to next file
+ */
+void CMainFrame::OnNextFile()
+{
+ if (IMergeDoc* pMergeDoc = GetActiveIMergeDoc())
+ if (CDirDoc* pDirDoc = pMergeDoc->GetDirDoc())
+ pDirDoc->MoveToNextFile(pMergeDoc);
+}
+
+/**
+ * @brief Called when Move to next file is updated
+ */
+void CMainFrame::OnUpdateNextFile(CCmdUI* pCmdUI)
+{
+ bool enabled = false;
+ if (IMergeDoc* pMergeDoc = GetActiveIMergeDoc())
+ if (CDirDoc* pDirDoc = pMergeDoc->GetDirDoc())
+ enabled = !pDirDoc->IsLastFile();
+ pCmdUI->Enable(enabled);
+}
+
+/**
+ * @brief Move to previous file
+ */
+void CMainFrame::OnPrevFile()
+{
+ if (IMergeDoc* pMergeDoc = GetActiveIMergeDoc())
+ if (CDirDoc* pDirDoc = pMergeDoc->GetDirDoc())
+ pDirDoc->MoveToPrevFile(pMergeDoc);
+}
+
+/**
+ * @brief Called when Move to previous file is updated
+ */
+void CMainFrame::OnUpdatePrevFile(CCmdUI* pCmdUI)
+{
+ bool enabled = false;
+ if (IMergeDoc* pMergeDoc = GetActiveIMergeDoc())
+ if (CDirDoc* pDirDoc = pMergeDoc->GetDirDoc())
+ enabled = !pDirDoc->IsFirstFile();
+ pCmdUI->Enable(enabled);
+}
+
+/**
+ * @brief Move to first file
+ */
+void CMainFrame::OnFirstFile()
+{
+ if (IMergeDoc* pMergeDoc = GetActiveIMergeDoc())
+ if (CDirDoc* pDirDoc = pMergeDoc->GetDirDoc())
+ pDirDoc->MoveToFirstFile(pMergeDoc);
+}
+
+/**
+ * @brief Called when Move to first file is updated
+ */
+void CMainFrame::OnUpdateFirstFile(CCmdUI* pCmdUI)
+{
+ bool enabled = false;
+ if (IMergeDoc* pMergeDoc = GetActiveIMergeDoc())
+ if (CDirDoc* pDirDoc = pMergeDoc->GetDirDoc())
+ enabled = !pDirDoc->IsFirstFile();
+ pCmdUI->Enable(enabled);
+}
+
+/**
+ * @brief Move to last file
+ */
+void CMainFrame::OnLastFile()
+{
+ if (IMergeDoc* pMergeDoc = GetActiveIMergeDoc())
+ if (CDirDoc* pDirDoc = pMergeDoc->GetDirDoc())
+ pDirDoc->MoveToLastFile(pMergeDoc);
+}
+
+/**
+ * @brief Called when Move to last file item is updated
+ */
+void CMainFrame::OnUpdateLastFile(CCmdUI* pCmdUI)
+{
+ bool enabled = false;
+ if (IMergeDoc* pMergeDoc = GetActiveIMergeDoc())
+ if (CDirDoc* pDirDoc = pMergeDoc->GetDirDoc())
+ enabled = !pDirDoc->IsLastFile();
+ pCmdUI->Enable(enabled);
+}
+
void CMainFrame::ReloadMenu()
{
// set the menu of the main frame window
HMENU hNewMergeMenu = pMainFrame->NewMergeViewMenu();
HMENU hNewImgMergeMenu = pMainFrame->NewImgMergeViewMenu();
HMENU hNewDirMenu = pMainFrame->NewDirViewMenu();
- if (hNewDefaultMenu && hNewMergeMenu && hNewDirMenu)
+ if (hNewDefaultMenu != nullptr && hNewMergeMenu != nullptr && hNewDirMenu != nullptr)
{
// Note : for Windows98 compatibility, use FromHandle and not Attach/Detach
CMenu * pNewDefaultMenu = CMenu::FromHandle(hNewDefaultMenu);
CMenu * pNewDirMenu = CMenu::FromHandle(hNewDirMenu);
CWnd *pFrame = CWnd::FromHandle(::GetWindow(pMainFrame->m_hWndMDIClient, GW_CHILD));
- while (pFrame)
+ while (pFrame != nullptr)
{
- if (pFrame->IsKindOf(RUNTIME_CLASS(CChildFrame)))
- static_cast<CChildFrame *>(pFrame)->SetSharedMenu(hNewMergeMenu);
+ if (pFrame->IsKindOf(RUNTIME_CLASS(CMergeEditFrame)))
+ static_cast<CMergeEditFrame *>(pFrame)->SetSharedMenu(hNewMergeMenu);
if (pFrame->IsKindOf(RUNTIME_CLASS(CHexMergeFrame)))
static_cast<CHexMergeFrame *>(pFrame)->SetSharedMenu(hNewMergeMenu);
if (pFrame->IsKindOf(RUNTIME_CLASS(CImgMergeFrame)))
}
CFrameWnd *pActiveFrame = pMainFrame->GetActiveFrame();
- if (pActiveFrame)
+ if (pActiveFrame != nullptr)
{
- if (pActiveFrame->IsKindOf(RUNTIME_CLASS(CChildFrame)))
- pMainFrame->MDISetMenu(pNewMergeMenu, NULL);
+ if (pActiveFrame->IsKindOf(RUNTIME_CLASS(CMergeEditFrame)))
+ pMainFrame->MDISetMenu(pNewMergeMenu, nullptr);
else if (pActiveFrame->IsKindOf(RUNTIME_CLASS(CHexMergeFrame)))
- pMainFrame->MDISetMenu(pNewMergeMenu, NULL);
+ pMainFrame->MDISetMenu(pNewMergeMenu, nullptr);
else if (pActiveFrame->IsKindOf(RUNTIME_CLASS(CImgMergeFrame)))
- pMainFrame->MDISetMenu(pNewImgMergeMenu, NULL);
+ pMainFrame->MDISetMenu(pNewImgMergeMenu, nullptr);
else if (pActiveFrame->IsKindOf(RUNTIME_CLASS(CDirFrame)))
- pMainFrame->MDISetMenu(pNewDirMenu, NULL);
+ pMainFrame->MDISetMenu(pNewDirMenu, nullptr);
else
- pMainFrame->MDISetMenu(pNewDefaultMenu, NULL);
+ pMainFrame->MDISetMenu(pNewDefaultMenu, nullptr);
}
else
- pMainFrame->MDISetMenu(pNewDefaultMenu, NULL);
+ pMainFrame->MDISetMenu(pNewDefaultMenu, nullptr);
// Don't delete the old menu
// There is a bug in BCMenu or in Windows98 : the new menu does not
// appear correctly if we destroy the old one
- // if (pOldDefaultMenu)
+ // if (pOldDefaultMenu != nullptr)
// pOldDefaultMenu->DestroyMenu();
- // if (pOldMergeMenu)
+ // if (pOldMergeMenu != nullptr)
// pOldMergeMenu->DestroyMenu();
- // if (pOldDirMenu)
+ // if (pOldDirMenu = nullptr)
// pOldDirMenu->DestroyMenu();
// m_hMenuDefault is used to redraw the main menu when we close a child frame
}
}
+IMergeDoc* CMainFrame::GetActiveIMergeDoc()
+{
+ CFrameWnd* pFrame = GetActiveFrame();
+ if (!pFrame)
+ return nullptr;
+ IMergeDoc* pMergeDoc = dynamic_cast<IMergeDoc*>(pFrame->GetActiveDocument());
+ if (!pMergeDoc)
+ pMergeDoc = dynamic_cast<IMergeDoc *>(pFrame);
+ return pMergeDoc;
+}
+
void CMainFrame::UpdateDocTitle()
{
CDocManager* pDocManager = AfxGetApp()->m_pDocManager;
}
}
}
+
+void CMainFrame::OnAccelQuit()
+{
+ // TODO: Add your command handler code here
+
+ SendMessage(WM_CLOSE);
+}
+
+LRESULT CMainFrame::OnChildFrameAdded(WPARAM wParam, LPARAM lParam)
+{
+ for (int i = 0; i < m_arrChild.GetSize(); ++i)
+ {
+ if (reinterpret_cast<CMDIChildWnd*>(lParam) == m_arrChild.GetAt(i))
+ {
+ return 0;
+ }
+ }
+
+ m_arrChild.InsertAt(0, (CMDIChildWnd*)lParam);
+
+ return 1;
+}
+
+LRESULT CMainFrame::OnChildFrameRemoved(WPARAM wParam, LPARAM lParam)
+{
+ for (int i = 0; i < m_arrChild.GetSize(); ++i)
+ {
+ if (reinterpret_cast<CMDIChildWnd*>(lParam) == m_arrChild.GetAt(i))
+ {
+ m_arrChild.RemoveAt(i);
+ break;
+ }
+ }
+
+ return 1;
+}
+
+LRESULT CMainFrame::OnChildFrameActivate(WPARAM wParam, LPARAM lParam)
+{
+ for (int i = 0; i < m_arrChild.GetSize(); ++i)
+ {
+ if (reinterpret_cast<CMDIChildWnd*>(lParam) == m_arrChild.GetAt(i))
+ {
+ CMDIChildWnd* pMDIChild = m_arrChild.GetAt(i);
+ if (pMDIChild->IsIconic())
+ pMDIChild->ShowWindow(SW_RESTORE);
+ MDIActivate(pMDIChild);
+ break;
+ }
+ }
+
+ return 1;
+}
+// put lParam as index 0 in m_arrChild
+LRESULT CMainFrame::OnChildFrameActivated(WPARAM wParam, LPARAM lParam)
+{
+ for (int i = 0; i < m_arrChild.GetSize(); ++i)
+ {
+ if (reinterpret_cast<CMDIChildWnd*>(lParam) == m_arrChild.GetAt(i))
+ {
+ m_arrChild.RemoveAt(i);
+ break;
+ }
+ }
+
+ m_arrChild.InsertAt(0, (CMDIChildWnd*)lParam);
+
+ return 1;
+}