OSDN Git Service

Add a feature to save/restore compare options to/from a project file. (#915)
authorJun Tajima <56220423+tjmprm77@users.noreply.github.com>
Sat, 14 Aug 2021 00:03:56 +0000 (09:03 +0900)
committerGitHub <noreply@github.com>
Sat, 14 Aug 2021 00:03:56 +0000 (09:03 +0900)
Also, change the behavior of the "Options..." popup menu in the Select Files or Folders dialog.
- Even if the values in the popup menu are changed, it is not saved in the WinMerge option at that time.
- The values in the popup menu are saved in the WinMerge options when the "Compare" button is clicked.
- The "Include Subfolders" item in the popup menu is deleted.

Src/MainFrm.cpp
Src/Merge.cpp
Src/Merge.rc
Src/OpenView.cpp
Src/OpenView.h
Src/ProjectFile.cpp
Src/ProjectFile.h
Src/resource.h

index 8a59bf7..7bfc1e2 100644 (file)
@@ -1558,6 +1558,8 @@ void CMainFrame::ApplyDiffOptions()
                pMergeDoc->RefreshOptions();
                pMergeDoc->FlushAndRescan(true);
        }
+       for (auto pOpenDoc : GetAllOpenDocs())
+               pOpenDoc->RefreshOptions();
 }
 
 /// Get list of OpenDocs (documents underlying edit sessions)
@@ -2763,6 +2765,8 @@ void CMainFrame::OnUpdateIncludeSubfolders(CCmdUI* pCmdUI)
 void CMainFrame::OnCompareMethod(UINT nID)
 { 
        GetOptionsMgr()->SaveOption(OPT_CMP_METHOD, nID - ID_DIFF_OPTIONS_COMPMETHOD_FULL_CONTENTS);
+       for (auto pOpenDoc : GetAllOpenDocs())
+               pOpenDoc->RefreshOptions();
 }
 
 void CMainFrame::OnUpdateCompareMethod(CCmdUI* pCmdUI)
index a14ca3f..4331870 100644 (file)
@@ -1281,6 +1281,21 @@ bool CMergeApp::LoadAndOpenProjectFile(const String& sProject, const String& sRe
 
                GetOptionsMgr()->SaveOption(OPT_CMP_INCLUDE_SUBDIRS, bRecursive);
 
+               if (projItem.HasIgnoreWhite())
+                       GetOptionsMgr()->SaveOption(OPT_CMP_IGNORE_WHITESPACE, projItem.GetIgnoreWhite());
+               if (projItem.HasIgnoreBlankLines())
+                       GetOptionsMgr()->SaveOption(OPT_CMP_IGNORE_BLANKLINES, projItem.GetIgnoreBlankLines());
+               if (projItem.HasIgnoreCase())
+                       GetOptionsMgr()->SaveOption(OPT_CMP_IGNORE_CASE, projItem.GetIgnoreCase());
+               if (projItem.HasIgnoreEol())
+                       GetOptionsMgr()->SaveOption(OPT_CMP_IGNORE_EOL, projItem.GetIgnoreEol());
+               if (projItem.HasIgnoreCodepage())
+                       GetOptionsMgr()->SaveOption(OPT_CMP_IGNORE_CODEPAGE, projItem.GetIgnoreCodepage());
+               if (projItem.HasFilterCommentsLines())
+                       GetOptionsMgr()->SaveOption(OPT_CMP_FILTER_COMMENTLINES, projItem.GetFilterCommentsLines());
+               if (projItem.HasCompareMethod())
+                       GetOptionsMgr()->SaveOption(OPT_CMP_METHOD, projItem.GetCompareMethod());
+
                rtn &= GetMainFrame()->DoFileOrFolderOpen(&tFiles, dwFlags, nullptr, sReportFile, bRecursive,
                        nullptr, pInfoUnpacker.get(), pInfoPrediffer.get());
        }
index 2ac8397..80555ff 100644 (file)
@@ -906,6 +906,34 @@ BEGIN
     END\r
 END\r
 \r
+IDR_POPUP_PROJECT_DIFF_OPTIONS MENU\r
+BEGIN\r
+    POPUP "_POPUP_"\r
+    BEGIN\r
+        POPUP "W&hitespaces"\r
+        BEGIN\r
+            MENUITEM "Com&pare", ID_PROJECT_DIFF_OPTIONS_WHITESPACE_COMPARE\r
+            MENUITEM "I&gnore changes", ID_PROJECT_DIFF_OPTIONS_WHITESPACE_IGNORE\r
+            MENUITEM "Ig&nore all", ID_PROJECT_DIFF_OPTIONS_WHITESPACE_IGNOREALL\r
+        END\r
+        MENUITEM "Ignore blan&k lines", ID_PROJECT_DIFF_OPTIONS_IGNORE_BLANKLINES\r
+        MENUITEM "Ignore &case", ID_PROJECT_DIFF_OPTIONS_IGNORE_CASE\r
+        MENUITEM "Igno&re carriage return differences (Windows/Unix/Mac)", ID_PROJECT_DIFF_OPTIONS_IGNORE_EOL\r
+        MENUITEM "Ignore codepage &differences", ID_PROJECT_DIFF_OPTIONS_IGNORE_CODEPAGE\r
+        MENUITEM "Ignore c&omment differences", ID_PROJECT_DIFF_OPTIONS_IGNORE_COMMENTS\r
+        MENUITEM SEPARATOR\r
+        POPUP "&Compare method:"\r
+        BEGIN\r
+            MENUITEM "Full Contents", ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_FULL_CONTENTS\r
+            MENUITEM "Quick Contents", ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_QUICK_CONTENTS\r
+            MENUITEM "Binary Contents", ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_BINARY_CONTENTS\r
+            MENUITEM "Modified Date", ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_MODDATE\r
+            MENUITEM "Modified Date and Size", ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_DATESIZE\r
+            MENUITEM "Size", ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_SIZE\r
+        END\r
+    END\r
+END\r
+\r
 IDR_POPUP_NEW MENU\r
 BEGIN\r
     POPUP "_POPUP_"\r
index 81d4e67..6b090d6 100644 (file)
@@ -73,7 +73,21 @@ BEGIN_MESSAGE_MAP(COpenView, CFormView)
        ON_WM_TIMER()
        ON_BN_CLICKED(IDC_SELECT_FILTER, OnSelectFilter)
        ON_BN_CLICKED(IDC_OPTIONS, OnOptions)
-       ON_NOTIFY(BCN_DROPDOWN, IDC_OPTIONS, OnDropDownOptions)
+       ON_NOTIFY(BCN_DROPDOWN, IDC_OPTIONS, (OnDropDown<IDC_OPTIONS, IDR_POPUP_PROJECT_DIFF_OPTIONS>))
+       ON_COMMAND_RANGE(ID_PROJECT_DIFF_OPTIONS_WHITESPACE_COMPARE, ID_PROJECT_DIFF_OPTIONS_WHITESPACE_IGNOREALL, OnDiffWhitespace)
+       ON_UPDATE_COMMAND_UI_RANGE(ID_PROJECT_DIFF_OPTIONS_WHITESPACE_COMPARE, ID_PROJECT_DIFF_OPTIONS_WHITESPACE_IGNOREALL, OnUpdateDiffWhitespace)
+       ON_COMMAND(ID_PROJECT_DIFF_OPTIONS_IGNORE_BLANKLINES, OnDiffIgnoreBlankLines)
+       ON_UPDATE_COMMAND_UI(ID_PROJECT_DIFF_OPTIONS_IGNORE_BLANKLINES, OnUpdateDiffIgnoreBlankLines)
+       ON_COMMAND(ID_PROJECT_DIFF_OPTIONS_IGNORE_CASE, OnDiffIgnoreCase)
+       ON_UPDATE_COMMAND_UI(ID_PROJECT_DIFF_OPTIONS_IGNORE_CASE, OnUpdateDiffIgnoreCase)
+       ON_COMMAND(ID_PROJECT_DIFF_OPTIONS_IGNORE_EOL, OnDiffIgnoreEOL)
+       ON_UPDATE_COMMAND_UI(ID_PROJECT_DIFF_OPTIONS_IGNORE_EOL, OnUpdateDiffIgnoreEOL)
+       ON_COMMAND(ID_PROJECT_DIFF_OPTIONS_IGNORE_CODEPAGE, OnDiffIgnoreCP)
+       ON_UPDATE_COMMAND_UI(ID_PROJECT_DIFF_OPTIONS_IGNORE_CODEPAGE, OnUpdateDiffIgnoreCP)
+       ON_COMMAND(ID_PROJECT_DIFF_OPTIONS_IGNORE_COMMENTS, OnDiffIgnoreComments)
+       ON_UPDATE_COMMAND_UI(ID_PROJECT_DIFF_OPTIONS_IGNORE_COMMENTS, OnUpdateDiffIgnoreComments)
+       ON_COMMAND_RANGE(ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_FULL_CONTENTS, ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_SIZE, OnCompareMethod)
+       ON_UPDATE_COMMAND_UI_RANGE(ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_FULL_CONTENTS, ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_SIZE, OnUpdateCompareMethod)
        ON_WM_ACTIVATE()
        ON_COMMAND(ID_LOAD_PROJECT, OnLoadProject)
        ON_COMMAND(ID_SAVE_PROJECT, OnSaveProject)
@@ -116,6 +130,13 @@ COpenView::COpenView()
        , m_hIconRotate(theApp.LoadIcon(IDI_ROTATE2))
        , m_hCursorNo(LoadCursor(nullptr, IDC_NO))
        , m_retryCount(0)
+       , m_nIgnoreWhite(0)
+       , m_bIgnoreBlankLines(false)
+       , m_bIgnoreCase(false)
+       , m_bIgnoreEol(false)
+       , m_bIgnoreCodepage(false)
+       , m_bFilterCommentsLines(false)
+       , m_nCompareMethod(0)
 {
        // CWnd::EnableScrollBarCtrl() called inside CScrollView::UpdateBars() is quite slow.
        // Therefore, set m_bInsideUpdate = TRUE so that CScrollView::UpdateBars() does almost nothing.
@@ -283,6 +304,14 @@ void COpenView::OnInitialUpdate()
        if (!bOverwriteRecursive)
                m_bRecurse = GetOptionsMgr()->GetBool(OPT_CMP_INCLUDE_SUBDIRS);
 
+       m_nIgnoreWhite = GetOptionsMgr()->GetInt(OPT_CMP_IGNORE_WHITESPACE);
+       m_bIgnoreBlankLines = GetOptionsMgr()->GetBool(OPT_CMP_IGNORE_BLANKLINES);
+       m_bIgnoreCase = GetOptionsMgr()->GetBool(OPT_CMP_IGNORE_CASE);
+       m_bIgnoreEol = GetOptionsMgr()->GetBool(OPT_CMP_IGNORE_EOL);
+       m_bIgnoreCodepage = GetOptionsMgr()->GetBool(OPT_CMP_IGNORE_CODEPAGE);
+       m_bFilterCommentsLines = GetOptionsMgr()->GetBool(OPT_CMP_FILTER_COMMENTLINES);
+       m_nCompareMethod = GetOptionsMgr()->GetInt(OPT_CMP_METHOD);
+
        UpdateData(FALSE);
        SetStatus(IDS_OPEN_FILESDIRS);
 
@@ -293,6 +322,15 @@ void COpenView::OnInitialUpdate()
 void COpenView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
 {
        m_bRecurse = GetDocument()->m_bRecurse;
+
+       m_nIgnoreWhite = GetOptionsMgr()->GetInt(OPT_CMP_IGNORE_WHITESPACE);
+       m_bIgnoreBlankLines = GetOptionsMgr()->GetBool(OPT_CMP_IGNORE_BLANKLINES);
+       m_bIgnoreCase = GetOptionsMgr()->GetBool(OPT_CMP_IGNORE_CASE);
+       m_bIgnoreEol = GetOptionsMgr()->GetBool(OPT_CMP_IGNORE_EOL);
+       m_bIgnoreCodepage = GetOptionsMgr()->GetBool(OPT_CMP_IGNORE_CODEPAGE);
+       m_bFilterCommentsLines = GetOptionsMgr()->GetBool(OPT_CMP_FILTER_COMMENTLINES);
+       m_nCompareMethod = GetOptionsMgr()->GetInt(OPT_CMP_METHOD);
+
        UpdateData(FALSE);
 }
 
@@ -638,6 +676,14 @@ void COpenView::OnCompare(UINT nID)
        GetOptionsMgr()->SaveOption(OPT_CMP_INCLUDE_SUBDIRS, m_bRecurse);
        LoadComboboxStates();
 
+       GetOptionsMgr()->SaveOption(OPT_CMP_IGNORE_WHITESPACE, m_nIgnoreWhite);
+       GetOptionsMgr()->SaveOption(OPT_CMP_IGNORE_BLANKLINES, m_bIgnoreBlankLines);
+       GetOptionsMgr()->SaveOption(OPT_CMP_IGNORE_CASE, m_bIgnoreCase);
+       GetOptionsMgr()->SaveOption(OPT_CMP_IGNORE_EOL, m_bIgnoreEol);
+       GetOptionsMgr()->SaveOption(OPT_CMP_IGNORE_CODEPAGE, m_bIgnoreCodepage);
+       GetOptionsMgr()->SaveOption(OPT_CMP_FILTER_COMMENTLINES, m_bFilterCommentsLines);
+       GetOptionsMgr()->SaveOption(OPT_CMP_METHOD, m_nCompareMethod);
+
        m_constraint.Persist(true, false);
 
        COpenDoc *pDoc = GetDocument();
@@ -767,6 +813,21 @@ void COpenView::OnLoadProject()
        if (projItem.HasUnpacker())
                m_strUnpackerPipeline = projItem.GetUnpacker();
 
+       if (projItem.HasIgnoreWhite())
+               m_nIgnoreWhite = projItem.GetIgnoreWhite();
+       if (projItem.HasIgnoreBlankLines())
+               m_bIgnoreBlankLines = projItem.GetIgnoreBlankLines();
+       if (projItem.HasIgnoreCase())
+               m_bIgnoreCase = projItem.GetIgnoreCase();
+       if (projItem.HasIgnoreEol())
+               m_bIgnoreEol = projItem.GetIgnoreEol();
+       if (projItem.HasIgnoreCodepage())
+               m_bIgnoreCodepage = projItem.GetIgnoreCodepage();
+       if (projItem.HasFilterCommentsLines())
+               m_bFilterCommentsLines = projItem.GetFilterCommentsLines();
+       if (projItem.HasCompareMethod())
+               m_nCompareMethod = projItem.GetCompareMethod();
+
        UpdateData(FALSE);
        UpdateButtonStates();
        LangMessageBox(IDS_PROJFILE_LOAD_SUCCESS, MB_ICONINFORMATION);
@@ -816,6 +877,15 @@ void COpenView::OnSaveProject()
        projItem.SetSubfolders(m_bRecurse);
        if (!m_strUnpackerPipeline.empty())
                projItem.SetUnpacker(m_strUnpackerPipeline);
+
+       projItem.SetIgnoreWhite(m_nIgnoreWhite);
+       projItem.SetIgnoreBlankLines(m_bIgnoreBlankLines);
+       projItem.SetIgnoreCase(m_bIgnoreCase);
+       projItem.SetIgnoreEol(m_bIgnoreEol);
+       projItem.SetIgnoreCodepage(m_bIgnoreCodepage);
+       projItem.SetFilterCommentsLines(m_bFilterCommentsLines);
+       projItem.SetCompareMethod(m_nCompareMethod);
+
        project.Items().push_back(projItem);
 
        if (!theApp.SaveProjectFile(fileName, project))
@@ -1259,16 +1329,129 @@ void COpenView::OnOptions()
        GetMainFrame()->PostMessage(WM_COMMAND, ID_OPTIONS);
 }
 
-void COpenView::OnDropDownOptions(NMHDR *pNMHDR, LRESULT *pResult)
+/**
+ * @brief Set "Whitespaces" setting.
+ * @param [in] nID Menu ID of the selected item
+ */
+void COpenView::OnDiffWhitespace(UINT nID)
 {
-       NMTOOLBAR dropDown = { 0 };
-       dropDown.hdr.code = TBN_DROPDOWN;
-       dropDown.hdr.hwndFrom = GetMainFrame()->GetDescendantWindow(AFX_IDW_TOOLBAR)->GetSafeHwnd();
-       dropDown.hdr.idFrom = AFX_IDW_TOOLBAR;
-       GetDlgItem(IDC_OPTIONS)->GetWindowRect(&dropDown.rcButton);
-       GetMainFrame()->ScreenToClient(&dropDown.rcButton);
-       GetMainFrame()->SendMessage(WM_NOTIFY, dropDown.hdr.idFrom, reinterpret_cast<LPARAM>(&dropDown));
-       *pResult = 0;
+       assert(nID >= ID_PROJECT_DIFF_OPTIONS_WHITESPACE_COMPARE && nID <= ID_PROJECT_DIFF_OPTIONS_WHITESPACE_IGNOREALL);
+
+       m_nIgnoreWhite = nID - ID_PROJECT_DIFF_OPTIONS_WHITESPACE_COMPARE;
+}
+
+/**
+ * @brief Update "Whitespaces" state.
+ * @param [in] pCmdUI UI component to update.
+ */
+void COpenView::OnUpdateDiffWhitespace(CCmdUI* pCmdUI)
+{
+       pCmdUI->SetRadio((pCmdUI->m_nID - ID_PROJECT_DIFF_OPTIONS_WHITESPACE_COMPARE) == static_cast<UINT>(m_nIgnoreWhite));
+}
+
+/**
+ * @brief Toggle "Ignore blank lines" setting.
+ */
+void COpenView::OnDiffIgnoreBlankLines()
+{
+       m_bIgnoreBlankLines = !m_bIgnoreBlankLines;
+}
+
+/**
+ * @brief Update "Ignore blank lines" state.
+ * @param [in] pCmdUI UI component to update.
+ */
+void COpenView::OnUpdateDiffIgnoreBlankLines(CCmdUI* pCmdUI)
+{
+       pCmdUI->SetCheck(m_bIgnoreBlankLines);
+}
+
+/**
+ * @brief Toggle "Ignore case" setting.
+ */
+void COpenView::OnDiffIgnoreCase()
+{
+       m_bIgnoreCase = !m_bIgnoreCase;
+}
+
+/**
+ * @brief Update "Ignore case" state.
+ * @param [in] pCmdUI UI component to update.
+ */
+void COpenView::OnUpdateDiffIgnoreCase(CCmdUI* pCmdUI)
+{
+       pCmdUI->SetCheck(m_bIgnoreCase);
+}
+
+/**
+ * @brief Toggle "Ignore carriage return differences" setting.
+ */
+void COpenView::OnDiffIgnoreEOL()
+{
+       m_bIgnoreEol = !m_bIgnoreEol;
+}
+
+/**
+ * @brief Update "Ignore carriage return differences" state.
+ * @param [in] pCmdUI UI component to update.
+ */
+void COpenView::OnUpdateDiffIgnoreEOL(CCmdUI* pCmdUI)
+{
+       pCmdUI->SetCheck(m_bIgnoreEol);
+}
+
+/**
+ * @brief Toggle "Ignore codepage differences" setting.
+ */
+void COpenView::OnDiffIgnoreCP()
+{
+       m_bIgnoreCodepage = !m_bIgnoreCodepage;
+}
+
+/**
+ * @brief Update "Ignore codepage differences" state.
+ * @param [in] pCmdUI UI component to update.
+ */
+void COpenView::OnUpdateDiffIgnoreCP(CCmdUI* pCmdUI)
+{
+       pCmdUI->SetCheck(m_bIgnoreCodepage);
+}
+
+/**
+ * @brief Toggle "Ignore comment differences" setting.
+ */
+void COpenView::OnDiffIgnoreComments()
+{
+       m_bFilterCommentsLines = !m_bFilterCommentsLines;
+}
+
+/**
+ * @brief Update "Ignore comment differences" state.
+ * @param [in] pCmdUI UI component to update.
+ */
+void COpenView::OnUpdateDiffIgnoreComments(CCmdUI* pCmdUI)
+{
+       pCmdUI->SetCheck(m_bFilterCommentsLines);
+}
+
+/**
+ * @brief Set "Compare method" setting.
+ * @param [in] nID Menu ID of the selected item
+ */
+void COpenView::OnCompareMethod(UINT nID)
+{
+       assert(nID >= ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_FULL_CONTENTS && nID <= ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_SIZE);
+
+       m_nCompareMethod = nID - ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_FULL_CONTENTS;
+}
+
+/**
+ * @brief Update "Compare method" state.
+ * @param [in] pCmdUI UI component to update.
+ */
+void COpenView::OnUpdateCompareMethod(CCmdUI* pCmdUI)
+{
+       pCmdUI->SetRadio((pCmdUI->m_nID - ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_FULL_CONTENTS) == static_cast<UINT>(m_nCompareMethod));
 }
 
 /** 
index a8c4be5..7be6d20 100644 (file)
@@ -81,6 +81,13 @@ private:
        std::array<bool, 3> m_bAutoCompleteReady;
        DropHandler *m_pDropHandler;
        int m_retryCount;
+       int m_nIgnoreWhite; /**< The value of the "Whitespaces" setting */
+       bool m_bIgnoreBlankLines; /**< The value of the "Ignore blank lines" setting */
+       bool m_bIgnoreCase; /**< The value of the "Ignore case" setting */
+       bool m_bIgnoreEol; /**< The value of the "Ignore carriage return differences" setting */
+       bool m_bIgnoreCodepage; /**< The value of the "Ignore codepage differences" setting */
+       bool m_bFilterCommentsLines; /**< The value of the "Ignore comment differences" setting */
+       int m_nCompareMethod; /**< The value of the "Compare method" setting */
 // Overrides
        public:
 virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
@@ -114,7 +121,6 @@ protected:
        afx_msg void OnSaveProject();
        template<UINT id, UINT popupid>
        afx_msg void OnDropDown(NMHDR *pNMHDR, LRESULT *pResult);
-       afx_msg void OnDropDownOptions(NMHDR *pNMHDR, LRESULT *pResult);
        afx_msg void OnSelchangePathCombo(UINT nID);
        afx_msg void OnSetfocusPathCombo(UINT id, NMHDR *pNMHDR, LRESULT *pResult);
        afx_msg void OnDragBeginPathCombo(UINT id, NMHDR *pNMHDR, LRESULT *pResult);
@@ -126,6 +132,20 @@ protected:
        afx_msg void OnSelectUnpacker();
        afx_msg void OnSelectFilter();
        afx_msg void OnOptions();
+       afx_msg void OnDiffWhitespace(UINT nID);
+       afx_msg void OnUpdateDiffWhitespace(CCmdUI* pCmdUI);
+       afx_msg void OnDiffIgnoreBlankLines();
+       afx_msg void OnUpdateDiffIgnoreBlankLines(CCmdUI* pCmdUI);
+       afx_msg void OnDiffIgnoreCase();
+       afx_msg void OnUpdateDiffIgnoreCase(CCmdUI* pCmdUI);
+       afx_msg void OnDiffIgnoreEOL();
+       afx_msg void OnUpdateDiffIgnoreEOL(CCmdUI* pCmdUI);
+       afx_msg void OnDiffIgnoreCP();
+       afx_msg void OnUpdateDiffIgnoreCP(CCmdUI* pCmdUI);
+       afx_msg void OnDiffIgnoreComments();
+       afx_msg void OnUpdateDiffIgnoreComments(CCmdUI* pCmdUI);
+       afx_msg void OnCompareMethod(UINT nID);
+       afx_msg void OnUpdateCompareMethod(CCmdUI* pCmdUI);
        afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
        afx_msg void OnEditAction(int msg, WPARAM wParam, LPARAM LPARAM);
        template <int MSG, int WPARAM = 0, int LPARAM = 0>
index 188b38e..adef642 100755 (executable)
@@ -42,6 +42,13 @@ const char Middle_ro_element_name[] = "middle-readonly";
 const char Right_ro_element_name[] = "right-readonly";
 const char Unpacker_element_name[] = "unpacker";
 const char Prediffer_element_name[] = "prediffer";
+const char White_spaces_element_name[] = "white-spaces";
+const char Ignore_blank_lines_element_name[] = "ignore-blank-lines";
+const char Ignore_case_element_name[] = "ignore-case";
+const char Ignore_cr_diff_element_name[] = "ignore-carriage-return-diff";
+const char Ignore_codepage_diff_element_name[] = "ignore-codepage-diff";
+const char Ignore_comment_diff_element_name[] = "ignore-comment-diff";
+const char Compare_method_element_name[] = "compare-method";
 
 namespace
 {
@@ -133,6 +140,41 @@ public:
                        currentItem.m_prediffer += xmlch2tstr(ch + start, length);
                        currentItem.m_bHasPrediffer = true;
                }
+               else if (nodename == White_spaces_element_name)
+               {
+                       currentItem.m_nIgnoreWhite = atoi(std::string(ch + start, length).c_str());
+                       currentItem.m_bHasIgnoreWhite = true;
+               }
+               else if (nodename == Ignore_blank_lines_element_name)
+               {
+                       currentItem.m_bIgnoreBlankLines = atoi(std::string(ch + start, length).c_str()) != 0;
+                       currentItem.m_bHasIgnoreBlankLines = true;
+               }
+               else if (nodename == Ignore_case_element_name)
+               {
+                       currentItem.m_bIgnoreCase = atoi(std::string(ch + start, length).c_str()) != 0;
+                       currentItem.m_bHasIgnoreCase = true;
+               }
+               else if (nodename == Ignore_cr_diff_element_name)
+               {
+                       currentItem.m_bIgnoreEol = atoi(std::string(ch + start, length).c_str()) != 0;
+                       currentItem.m_bHasIgnoreEol = true;
+               }
+               else if (nodename == Ignore_codepage_diff_element_name)
+               {
+                       currentItem.m_bIgnoreCodepage = atoi(std::string(ch + start, length).c_str()) != 0;
+                       currentItem.m_bHasIgnoreCodepage = true;
+               }
+               else if (nodename == Ignore_comment_diff_element_name)
+               {
+                       currentItem.m_bFilterCommentsLines = atoi(std::string(ch + start, length).c_str()) != 0;
+                       currentItem.m_bHasFilterCommentsLines = true;
+               }
+               else if (nodename == Compare_method_element_name)
+               {
+                       currentItem.m_nCompareMethod = atoi(std::string(ch + start, length).c_str());
+                       currentItem.m_bHasCompareMethod = true;
+               }
        }
        void ignorableWhitespace(const XMLChar ch[], int start, int length)     {}
        void processingInstruction(const XMLString& target, const XMLString& data) {}
@@ -163,6 +205,20 @@ const String ProjectFile::PROJECTFILE_EXT = toTString("WinMerge");
 , m_bLeftReadOnly(false)
 , m_bMiddleReadOnly(false)
 , m_bRightReadOnly(false)
+, m_bHasIgnoreWhite(false)
+, m_nIgnoreWhite(0)
+, m_bHasIgnoreBlankLines(false)
+, m_bIgnoreBlankLines(false)
+, m_bHasIgnoreCase(false)
+, m_bIgnoreCase(false)
+, m_bHasIgnoreEol(false)
+, m_bIgnoreEol(false)
+, m_bHasIgnoreCodepage(false)
+, m_bIgnoreCodepage(false)
+, m_bHasFilterCommentsLines(false)
+, m_bFilterCommentsLines(false)
+, m_bHasCompareMethod(false)
+, m_nCompareMethod(0)
 {
 }
 
@@ -301,6 +357,13 @@ bool ProjectFile::Save(const String& path) const
                                        writeElement(writer, Unpacker_element_name, toUTF8(item.m_unpacker));
                                if (!item.m_prediffer.empty())
                                        writeElement(writer, Prediffer_element_name, toUTF8(item.m_prediffer));
+                               writeElement(writer, White_spaces_element_name, std::to_string(item.m_nIgnoreWhite));
+                               writeElement(writer, Ignore_blank_lines_element_name, item.m_bIgnoreBlankLines ? "1" : "0");
+                               writeElement(writer, Ignore_case_element_name, item.m_bIgnoreCase ? "1" : "0");
+                               writeElement(writer, Ignore_cr_diff_element_name, item.m_bIgnoreEol ? "1" : "0");
+                               writeElement(writer, Ignore_codepage_diff_element_name, item.m_bIgnoreCodepage ? "1" : "0");
+                               writeElement(writer, Ignore_comment_diff_element_name, item.m_bFilterCommentsLines ? "1" : "0");
+                               writeElement(writer, Compare_method_element_name, std::to_string(item.m_nCompareMethod));
                        }
                        writer.endElement("", "", Paths_element_name);
                }
index 7806fbf..d8b3b7c 100755 (executable)
@@ -22,6 +22,13 @@ public:
        bool HasSubfolders() const;
        bool HasUnpacker() const;
        bool HasPrediffer() const;
+       bool HasIgnoreWhite() const;
+       bool HasIgnoreBlankLines() const;
+       bool HasIgnoreCase() const;
+       bool HasIgnoreEol() const;
+       bool HasIgnoreCodepage() const;
+       bool HasFilterCommentsLines() const;
+       bool HasCompareMethod() const;
 
        String GetLeft(bool * pReadOnly = nullptr) const;
        bool GetLeftReadOnly() const;
@@ -33,6 +40,13 @@ public:
        int GetSubfolders() const;
        String GetUnpacker() const;
        String GetPrediffer() const;
+       int GetIgnoreWhite() const;
+       bool GetIgnoreBlankLines() const;
+       bool GetIgnoreCase() const;
+       bool GetIgnoreEol() const;
+       bool GetIgnoreCodepage() const;
+       bool GetFilterCommentsLines() const;
+       int GetCompareMethod() const;
 
        void SetLeft(const String& sLeft, const bool * pReadOnly = nullptr);
        void SetMiddle(const String& sMiddle, const bool * pReadOnly = nullptr);
@@ -41,6 +55,13 @@ public:
        void SetSubfolders(bool bSubfolder);
        void SetUnpacker(const String& sUnpacker);
        void SetPrediffer(const String& sPrediffer);
+       void SetIgnoreWhite(int nIgnoreWhite);
+       void SetIgnoreBlankLines(bool bIgnoreBlankLines);
+       void SetIgnoreCase(bool bIgnoreCase);
+       void SetIgnoreEol(bool bIgnoreEol);
+       void SetIgnoreCodepage(bool bIgnoreCodepage);
+       void SetFilterCommentsLines(bool bFilterCommentsLines);
+       void SetCompareMethod(int nCompareMethod);
 
        void GetPaths(PathContext& files, bool & bSubFolders) const;
        void SetPaths(const PathContext& files, bool bSubFolders = false);
@@ -61,6 +82,20 @@ private:
        String m_unpacker; /**< Unpacker name or pipeline */
        bool m_bHasPrediffer; /**< Has prediffer? */
        String m_prediffer; /**< Prediffer name or pipeline */
+       bool m_bHasIgnoreWhite; /**< Has "Whitespaces" setting? */
+       int m_nIgnoreWhite; /**< The value of the "Whitespaces" setting */
+       bool m_bHasIgnoreBlankLines; /**< Has "Ignore blank lines" setting? */
+       bool m_bIgnoreBlankLines; /**< The value of the "Ignore blank lines" setting */
+       bool m_bHasIgnoreCase; /**< Has "Ignore case" setting? */
+       bool m_bIgnoreCase; /**< The value of the "Ignore case" setting */
+       bool m_bHasIgnoreEol; /**< Has "Ignore carriage return differences" setting? */
+       bool m_bIgnoreEol; /**< The value of the "Ignore carriage return differences" setting */
+       bool m_bHasIgnoreCodepage; /**< Has "Ignore codepage differences" setting? */
+       bool m_bIgnoreCodepage; /**< The value of the "Ignore codepage differences" setting */
+       bool m_bHasFilterCommentsLines; /**< Has "Ignore comment differences" setting? */
+       bool m_bFilterCommentsLines; /**< The value of the "Ignore comment differences" setting */
+       bool m_bHasCompareMethod; /**< Has "Compare method" setting? */
+       int m_nCompareMethod; /**< The value of the "Compare method" setting */
 };
 
 /**
@@ -145,6 +180,69 @@ inline bool ProjectFileItem::HasPrediffer() const
 }
 
 /** 
+ * @brief Returns if "Whitespaces" setting is defined in projectfile.
+ * @return true if project file has "Whitespaces" setting definition.
+ */
+inline bool ProjectFileItem::HasIgnoreWhite() const
+{
+       return m_bHasIgnoreWhite;
+}
+
+/** 
+ * @brief Returns if "Ignore blank lines" setting is defined in projectfile.
+ * @return true if project file has "Ignore blank lines" setting definition.
+ */
+inline bool ProjectFileItem::HasIgnoreBlankLines() const
+{
+       return m_bHasIgnoreBlankLines;
+}
+
+/** 
+ * @brief Returns if "Ignore case" setting is defined in projectfile.
+ * @return true if project file has "Ignore case" setting definition.
+ */
+inline bool ProjectFileItem::HasIgnoreCase() const
+{
+       return m_bHasIgnoreCase;
+}
+
+/** 
+ * @brief Returns if "Ignore carriage return differences" setting is defined in projectfile.
+ * @return true if project file has "Ignore carriage return differences" setting definition.
+ */
+inline bool ProjectFileItem::HasIgnoreEol() const
+{
+       return m_bHasIgnoreEol;
+}
+
+/** 
+ * @brief Returns if "Ignore codepage differences" setting is defined in projectfile.
+ * @return true if project file has "Ignore codepage differences" setting definition.
+ */
+inline bool ProjectFileItem::HasIgnoreCodepage() const
+{
+       return m_bHasIgnoreCodepage;
+}
+
+/** 
+ * @brief Returns if "Ignore comment differences" is defined in projectfile.
+ * @return true if project file has "Ignore comment differences" definition.
+ */
+inline bool ProjectFileItem::HasFilterCommentsLines() const
+{
+       return m_bHasFilterCommentsLines;
+}
+
+/** 
+ * @brief Returns if "Compare method" setting is defined in projectfile.
+ * @return true if project file has "Compare method" setting definition.
+ */
+inline bool ProjectFileItem::HasCompareMethod() const
+{
+       return m_bHasCompareMethod;
+}
+
+/** 
  * @brief Returns if left path is specified read-only.
  * @return true if left path is read-only, false otherwise.
  */
@@ -243,6 +341,132 @@ inline void ProjectFileItem::SetPrediffer(const String& sPrediffer)
 }
 
 /** 
+ * @brief Returns the value of the "Whitespaces" setting.
+ * @return The value of the "Whitespaces" setting
+ */
+inline int ProjectFileItem::GetIgnoreWhite() const
+{
+       return m_nIgnoreWhite;
+}
+
+/** 
+ * @brief Set the value of the "Whitespaces" setting.
+ * @param [in] nIgnoreWhite New value of the "Whitespaces" setting to set.
+ */
+inline void ProjectFileItem::SetIgnoreWhite(int nIgnoreWhite)
+{
+       m_nIgnoreWhite = nIgnoreWhite;
+}
+
+/** 
+ * @brief Returns the value of the "Ignore blank lines" setting.
+ * @return The value of the "Ignore blank lines" setting
+ */
+inline bool ProjectFileItem::GetIgnoreBlankLines() const
+{
+       return m_bIgnoreBlankLines;
+}
+
+/** 
+ * @brief Set the value of the "Ignore blank lines" setting.
+ * @param [in] bIgnoreBlankLines New value of the "Ignore blank lines" setting to set.
+ */
+inline void ProjectFileItem::SetIgnoreBlankLines(bool bIgnoreBlankLines)
+{
+       m_bIgnoreBlankLines = bIgnoreBlankLines;
+}
+
+/** 
+ * @brief Returns the value of the "Ignore case" setting.
+ * @return Unpacker name or pipelineThe value of the "Ignore case" setting
+ */
+inline bool ProjectFileItem::GetIgnoreCase() const
+{
+       return m_bIgnoreCase;
+}
+
+/** 
+ * @brief Set the value of the "Ignore case" setting.
+ * @param [in] bIgnoreCase New value of the "Ignore case" setting to set.
+ */
+inline void ProjectFileItem::SetIgnoreCase(bool bIgnoreCase)
+{
+       m_bIgnoreCase = bIgnoreCase;
+}
+
+/** 
+ * @brief Returns the value of the "Ignore carriage return differences" setting.
+ * @return The value of the "Ignore carriage return differences" setting
+ */
+inline bool ProjectFileItem::GetIgnoreEol() const
+{
+       return m_bIgnoreEol;
+}
+
+/** 
+ * @brief Set the value of the "Ignore carriage return differences" setting.
+ * @param [in] bIgnoreEol New value of the "Ignore carriage return differences" setting to set.
+ */
+inline void ProjectFileItem::SetIgnoreEol(bool bIgnoreEol)
+{
+       m_bIgnoreEol = bIgnoreEol;
+}
+
+/** 
+ * @brief Returns the value of the "Ignore codepage differences" setting.
+ * @return The value of the "Ignore codepage differences" setting
+ */
+inline bool ProjectFileItem::GetIgnoreCodepage() const
+{
+       return m_bIgnoreCodepage;
+}
+
+/** 
+ * @brief Set the value of the "Ignore codepage differences" setting.
+ * @param [in] bIgnoreCodepage New value of the "Ignore codepage differences" setting to set.
+ */
+inline void ProjectFileItem::SetIgnoreCodepage(bool bIgnoreCodepage)
+{
+       m_bIgnoreCodepage = bIgnoreCodepage;
+}
+
+/** 
+ * @brief Returns the value of the "Ignore comment differences" setting.
+ * @return The value of the "Ignore comment differences" setting
+ */
+inline bool ProjectFileItem::GetFilterCommentsLines() const
+{
+       return m_bFilterCommentsLines;
+}
+
+/** 
+ * @brief Set the value of the "Ignore comment differences" setting.
+ * @param [in] bFilterCommentsLines New value of the "Ignore comment differences" setting to set.
+ */
+inline void ProjectFileItem::SetFilterCommentsLines(bool bFilterCommentsLines)
+{
+       m_bFilterCommentsLines = bFilterCommentsLines;
+}
+
+/** 
+ * @brief Returns the value of the "Compare method" setting.
+ * @return The value of the "Compare method" setting
+ */
+inline int ProjectFileItem::GetCompareMethod() const
+{
+       return m_nCompareMethod;
+}
+
+/** 
+ * @brief Set the value of the "Compare method" setting.
+ * @param [in] nCompareMethod New value of the "Compare method" setting to set.
+ */
+inline void ProjectFileItem::SetCompareMethod(int nCompareMethod)
+{
+       m_nCompareMethod = nCompareMethod;
+}
+
+/** 
  * @brief 
  *
  * @param [in] paths Files in project
index 5997f15..0938153 100644 (file)
@@ -21,6 +21,7 @@
 #define IDR_POPUP_COMPARE               119\r
 #define IDR_POPUP_SAVE                  120\r
 #define IDR_POPUP_IMG_CTXT              121\r
+#define IDR_POPUP_PROJECT_DIFF_OPTIONS  122\r
 #define IDD_ABOUTBOX                    200\r
 #define IDD_OPEN                        202\r
 #define IDD_SAVECLOSING                 203\r
 #define ID_FILE_OPENCONFLICT            33121\r
 #define ID_LOAD_PROJECT                 33122\r
 #define ID_SAVE_PROJECT                 33123\r
+#define ID_PROJECT_DIFF_OPTIONS_WHITESPACE_COMPARE   33124\r
+#define ID_PROJECT_DIFF_OPTIONS_WHITESPACE_IGNORE    33125\r
+#define ID_PROJECT_DIFF_OPTIONS_WHITESPACE_IGNOREALL 33126\r
+#define ID_PROJECT_DIFF_OPTIONS_IGNORE_BLANKLINES    33127\r
+#define ID_PROJECT_DIFF_OPTIONS_IGNORE_CASE          33128\r
+#define ID_PROJECT_DIFF_OPTIONS_IGNORE_EOL           33129\r
+#define ID_PROJECT_DIFF_OPTIONS_IGNORE_CODEPAGE      33130\r
+#define ID_PROJECT_DIFF_OPTIONS_IGNORE_COMMENTS      33131\r
+#define ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_FULL_CONTENTS     33132\r
+#define ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_QUICK_CONTENTS    33133\r
+#define ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_BINARY_CONTENTS   33134\r
+#define ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_MODDATE           33135\r
+#define ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_DATESIZE          33136\r
+#define ID_PROJECT_DIFF_OPTIONS_COMPMETHOD_SIZE              33137\r
 #define ID_EDIT_TOGGLE_BOOKMARK         33145\r
 #define ID_EDIT_GOTO_NEXT_BOOKMARK      33146\r
 #define ID_EDIT_GOTO_PREV_BOOKMARK      33147\r