OSDN Git Service

Perry:
authorChristian List <list1974@hotmail.com>
Tue, 3 Dec 2002 22:10:51 +0000 (22:10 +0000)
committerChristian List <list1974@hotmail.com>
Tue, 3 Dec 2002 22:10:51 +0000 (22:10 +0000)
 Implemented recursive directory delete
 Fix bug in EOL handling in crystaltextbuffer, and add optional EOL sensitivity.
 Added optional EOL insensitivity to gnu diff IO.c.
 Added status bar progress (file count) indicator during scanning
 Fixed tooltips of toolbar buttons to list correct hotkeys
 Split "Show Unique" option into "Show Left Unique" and "Show Right Unique"
 Added left files, left dirs, right files, right dirs to status bar feedback

17 files changed:
Src/Diff.cpp
Src/DiffContext.cpp
Src/DiffContext.h
Src/DirDoc.cpp
Src/DirView.cpp
Src/DirView.h
Src/MainFrm.cpp
Src/MainFrm.h
Src/Merge.rc
Src/PropGeneral.cpp
Src/PropGeneral.h
Src/diffutils/src/DIFF.H
Src/diffutils/src/IO.C
Src/editlib/ccrystaltextbuffer.cpp
Src/editlib/ccrystaltextbuffer.h
Src/readme.txt [new file with mode: 0644]
Src/resource.h

index e3baa7b..f891964 100644 (file)
@@ -435,6 +435,7 @@ compare_files (LPCTSTR dir0, LPCTSTR name0,
     {
       /* Both exist and neither is a directory.  */
       int o_binary = always_text_flag ? O_BINARY : 0;
+         if (!ignore_eol_diff) o_binary = O_BINARY;
       /* Open the files and record their descriptors.  */
 
       if (inf[0].desc == -2)
index cefbaeb..61ef60d 100644 (file)
@@ -36,7 +36,7 @@ static char THIS_FILE[]=__FILE__;
 // Construction/Destruction
 //////////////////////////////////////////////////////////////////////
 
-CDiffContext::CDiffContext(LPCTSTR pszLeft /*=NULL*/, LPCTSTR pszRight /*=NULL*/)
+CDiffContext::CDiffContext(LPCTSTR pszLeft /*=NULL*/, LPCTSTR pszRight /*=NULL*/, IDiffStatus * piStatus)
 {
        m_bRecurse=FALSE;
        m_strLeft = pszLeft;
@@ -45,6 +45,7 @@ CDiffContext::CDiffContext(LPCTSTR pszLeft /*=NULL*/, LPCTSTR pszRight /*=NULL*/
 
        pNamesLeft = NULL;
        pNamesRight = NULL;
+       m_piStatus = piStatus;
 }
 
 CDiffContext::CDiffContext(LPCTSTR pszLeft, LPCTSTR pszRight, CDiffContext& src)
@@ -54,6 +55,7 @@ CDiffContext::CDiffContext(LPCTSTR pszLeft, LPCTSTR pszRight, CDiffContext& src)
        m_strRight = pszRight;
        m_pList = src.m_pList;
        SetRegExp(src.m_strRegExp);
+       m_piStatus = src.m_piStatus;
 
        pNamesLeft = NULL;
        pNamesRight = NULL;
@@ -95,6 +97,9 @@ void CDiffContext::AddDiff(LPCTSTR pszFilename, LPCTSTR pszLeftDir, LPCTSTR pszR
 
 
        m_pList->AddTail(di);
+
+       if (m_piStatus)
+               m_piStatus->rptFile(code);
 }
 
 void CDiffContext::SetRegExp(LPCTSTR pszExp)
index 1a766d8..f111ba0 100644 (file)
@@ -34,12 +34,18 @@ typedef struct tagDIFFITEM {
 #define FILE_LDIRUNIQUE                6
 #define FILE_RDIRUNIQUE                7
 
+class IDiffStatus
+{
+public:
+       virtual void rptFile(BYTE code)=0;
+};
+
 class CDiffContext  
 {
 public:
        void SetRegExp(LPCTSTR pszExp);
        void AddDiff(LPCTSTR pszFilename, LPCTSTR pszLeftDir, LPCTSTR pszRightDir, long ltime, long rtime, BYTE code);
-       CDiffContext(LPCTSTR pszLeft = NULL, LPCTSTR pszRight = NULL);
+       CDiffContext(LPCTSTR pszLeft, LPCTSTR pszRight, IDiffStatus * piStatus);
        CDiffContext(LPCTSTR pszLeft, LPCTSTR pszRight, CDiffContext& src);
        virtual ~CDiffContext();
 
@@ -49,6 +55,8 @@ public:
        CString m_strRight;
        CRegExp m_rgx;
        CString m_strRegExp;
+       IDiffStatus * m_piStatus;
+
 
        struct dirdata ddLeft, ddRight;
        char *pNamesLeft;
index 520caf7..97c6472 100644 (file)
@@ -222,6 +222,8 @@ void CDirDoc::Redisplay()
        {
                curpos = pos;
                DIFFITEM di = m_pCtxt->m_dirlist.GetNext(pos);
+               BOOL leftside = (di.code==FILE_LUNIQUE || di.code==FILE_LDIRUNIQUE);
+               BOOL rightside = (di.code==FILE_RUNIQUE || di.code==FILE_RDIRUNIQUE);
                switch (di.code)
                {
                case FILE_DIFF:
@@ -260,7 +262,7 @@ void CDirDoc::Redisplay()
                case FILE_RUNIQUE:
                case FILE_LDIRUNIQUE:
                case FILE_RDIRUNIQUE:
-                       if (mf->m_bShowUnique
+                       if (((mf->m_bShowUniqueLeft && leftside) || (mf->m_bShowUniqueRight && rightside))
                                && (!mf->m_bHideBak || !FileExtMatches(di.filename,BACKUP_FILE_EXT)))
                        {
                                m_pView->AddItem(cnt, DV_NAME, di.filename);
index fde4c9c..584a6f4 100644 (file)
@@ -224,6 +224,7 @@ void CDirView::OnContextMenu(CWnd*, CPoint point)
                        pWndPopupOwner = pWndPopupOwner->GetParent();
 
                // invoke context menu
+               // this will invoke all the OnUpdate methods to enable/disable the individual items
                pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
                        pWndPopupOwner);
        }
@@ -251,12 +252,22 @@ void CDirView::OnDirCopyFileToLeft()
 {
        DoCopyFileToLeft();
 }
+// User chose (main menu) Copy from left to right
+void CDirView::OnDirCopyFileToRight() 
+{
+       DoCopyFileToRight();
+}
 
 // User chose (context men) Copy from right to left
 void CDirView::OnCtxtDirCopyFileToLeft()
 {
        DoCopyFileToLeft();
 }
+// User chose (context menu) Copy from left to right
+void CDirView::OnCtxtDirCopyFileToRight()
+{
+       DoCopyFileToRight();
+}
 
 // Prompt & copy item from right to left, if legal
 void CDirView::DoCopyFileToLeft() 
@@ -277,7 +288,6 @@ void CDirView::DoCopyFileToLeft()
        switch(di.code)
        {
        case FILE_LUNIQUE:
-               ConfirmAndDeleteAndUpdate(slFile, pos, sel);
                break;
        case FILE_RUNIQUE:
        case FILE_DIFF:
@@ -293,92 +303,16 @@ void CDirView::DoCopyFileToLeft()
                break;
        case FILE_LDIRUNIQUE:
        case FILE_RDIRUNIQUE:
-                       // TODO 2002-11-22: Enable uniques also, but must write code to do recursive copy
+               // TODO: Would be nice to allow copying directory
+               // but must write code for recursive copy
+               // and worse, this will make the item display invalid (new items not on it)
+               // Perry 2002-11-26
        case FILE_SAME:
        default:
                // Not allowed, and should have been disabled choices anyway
                break;
        }
 }
-
-// Update context menu Copy Right to Left item
-void CDirView::OnUpdateCtxtDirCopyFileToLeft(CCmdUI* pCmdUI) 
-{
-       DoUpdateDirCopyFileToLeft(pCmdUI);
-}
-
-// Update main menu Copy Right to Left item
-void CDirView::OnUpdateDirCopyFileToLeft(CCmdUI* pCmdUI) 
-{
-       DoUpdateDirCopyFileToLeft(pCmdUI);
-}
-
-// Should Copy to Left be enabled or disabled ? (both main menu & context menu use this)
-void CDirView::DoUpdateDirCopyFileToLeft(CCmdUI* pCmdUI) 
-{
-       int sel = m_pList->GetNextItem(-1, LVNI_SELECTED);
-       if (sel == -1)
-       {
-               // no item there
-               pCmdUI->Enable(FALSE);
-               return;
-       }
-       // found item (normal case)
-       // find item from document
-       POSITION pos;
-       const DIFFITEM& di = GetDiffItem(sel, pos);
-       // what we do depends on comparison result for this item
-       switch(di.code)
-       {
-       case FILE_LUNIQUE:
-               pCmdUI->Enable(FALSE); // no right item, so can't copy to left
-               break;
-       case FILE_RUNIQUE:
-       case FILE_DIFF:
-       case FILE_BINDIFF:
-               pCmdUI->Enable(TRUE);
-               break;
-       case FILE_SAME:
-               pCmdUI->Enable(FALSE);
-               break;
-       case FILE_LDIRUNIQUE:
-               pCmdUI->Enable(FALSE); // no right item, so can't copy to left
-               break;
-       case FILE_RDIRUNIQUE:
-       // TODO 2002-11-22: Enable unique also, but must write code to do recursive copy
-               pCmdUI->Enable(FALSE);
-               break;
-       default:
-               pCmdUI->Enable(FALSE);
-               break;
-       }
-}
-
-
-// Prompt & delete file, & remove its data entries
-void CDirView::ConfirmAndDeleteAndUpdate(LPCTSTR szFile, POSITION pos, int sel)
-{
-       // May want an option to suppress these message boxes
-
-       if (!mf->ConfirmAndDelete(szFile))
-               return;
-       // remove item data from document & screen
-       GetDocument()->m_pCtxt->m_dirlist.RemoveAt(pos);
-       GetListCtrl().DeleteItem(sel);
-}
-
-// User chose (main menu) Copy from left to right
-void CDirView::OnDirCopyFileToRight() 
-{
-       DoCopyFileToRight();
-}
-
-// User chose (context menu) Copy from left to right
-void CDirView::OnCtxtDirCopyFileToRight()
-{
-       DoCopyFileToRight();
-}
-
 // Prompt & copy item from left to right, if legal
 void CDirView::DoCopyFileToRight() 
 {
@@ -398,7 +332,6 @@ void CDirView::DoCopyFileToRight()
        switch(di.code)
        {
        case FILE_RUNIQUE:
-               ConfirmAndDeleteAndUpdate(srFile, pos, sel);
                break;
        case FILE_LUNIQUE:
        case FILE_DIFF:
@@ -415,7 +348,7 @@ void CDirView::DoCopyFileToRight()
                break;
        case FILE_LDIRUNIQUE:
        case FILE_RDIRUNIQUE:
-                       // TODO 2002-11-22: Enable uniques also, but must write code to do recursive copy
+                       // see comments in DoCopyFileToLeft
        case FILE_SAME:
        default:
                // Not allowed, and should have been disabled choices anyway
@@ -424,17 +357,67 @@ void CDirView::DoCopyFileToRight()
 }
 
 // Update context menu Copy Right to Left item
+void CDirView::OnUpdateCtxtDirCopyFileToLeft(CCmdUI* pCmdUI) 
+{
+       DoUpdateDirCopyFileToLeft(pCmdUI);
+}
+// Update context menu Copy Left to Right item
 void CDirView::OnUpdateCtxtDirCopyFileToRight(CCmdUI* pCmdUI) 
 {
        DoUpdateDirCopyFileToRight(pCmdUI);
 }
 
+// Update main menu Copy Right to Left item
+void CDirView::OnUpdateDirCopyFileToLeft(CCmdUI* pCmdUI) 
+{
+       DoUpdateDirCopyFileToLeft(pCmdUI);
+}
 // Update main menu Copy Left to Right item
 void CDirView::OnUpdateDirCopyFileToRight(CCmdUI* pCmdUI) 
 {
        DoUpdateDirCopyFileToRight(pCmdUI);
 }
 
+// Should Copy to Left be enabled or disabled ? (both main menu & context menu use this)
+void CDirView::DoUpdateDirCopyFileToLeft(CCmdUI* pCmdUI) 
+{
+       int sel = m_pList->GetNextItem(-1, LVNI_SELECTED);
+       if (sel == -1)
+       {
+               // no item there
+               pCmdUI->Enable(FALSE);
+               return;
+       }
+       // found item (normal case)
+       // find item from document
+       POSITION pos;
+       const DIFFITEM& di = GetDiffItem(sel, pos);
+       // what we do depends on comparison result for this item
+       switch(di.code)
+       {
+       case FILE_LUNIQUE:
+               pCmdUI->Enable(FALSE); // no right item, so can't copy to left
+               break;
+       case FILE_RUNIQUE:
+       case FILE_DIFF:
+       case FILE_BINDIFF:
+               pCmdUI->Enable(TRUE);
+               break;
+       case FILE_SAME:
+               pCmdUI->Enable(FALSE);
+               break;
+       case FILE_LDIRUNIQUE:
+               pCmdUI->Enable(FALSE); // no right item, so can't copy to left
+               break;
+       case FILE_RDIRUNIQUE:
+       // TODO 2002-11-22: Enable unique also, but must write code to do recursive copy
+               pCmdUI->Enable(TRUE);
+               break;
+       default:
+               pCmdUI->Enable(FALSE);
+               break;
+       }
+}
 // Should Copy to Right be enabled or disabled ? (both main menu & context menu use this)
 void CDirView::DoUpdateDirCopyFileToRight(CCmdUI* pCmdUI) 
 {
@@ -696,6 +679,11 @@ void CDirView::OnCtxtDirDelLeft()
 {
        DoDelLeft();
 }
+// User chose (context menu) delete right
+void CDirView::OnCtxtDirDelRight()
+{
+       DoDelRight();
+}
 
 // Prompt & delete left, if legal
 void CDirView::DoDelLeft() 
@@ -711,15 +699,60 @@ void CDirView::DoDelLeft()
        POSITION pos;
        const DIFFITEM& di = GetDiffItem(sel, pos);
 
-       ConfirmAndDeleteAndUpdate(slFile, pos, sel);
+       // need to know if file or directory
+       switch(di.code)
+       {
+       case FILE_LUNIQUE:
+       case FILE_DIFF:
+       case FILE_BINDIFF:
+               ConfirmAndDeleteFileAndUpdate(slFile, pos, sel);
+               break;
+       case FILE_LDIRUNIQUE:
+               ConfirmAndDeleteDirAndUpdate(slFile, pos, sel);
+               break;
+       }
+}
+// Prompt & delete right, if legal
+void CDirView::DoDelRight() 
+{
+       int sel = m_pList->GetNextItem(-1, LVNI_SELECTED);
+       if (sel == -1) return;
+
+       CString sl, sr, slFile, srFile;
+       if (!GetSelectedDirNames(sl, sr) || !GetSelectedFileNames(slFile, srFile))
+               return;
+
+       // find item from document
+       POSITION pos;
+       const DIFFITEM& di = GetDiffItem(sel, pos);
+
+       // need to know if file or directory
+       switch(di.code)
+       {
+       case FILE_RUNIQUE:
+       case FILE_DIFF:
+       case FILE_BINDIFF:
+               ConfirmAndDeleteFileAndUpdate(srFile, pos, sel);
+               break;
+       case FILE_RDIRUNIQUE:
+               ConfirmAndDeleteDirAndUpdate(srFile, pos, sel);
+               break;
+       }
 }
 
+// Enable/disable Delete Left menu choice on context menu
 void CDirView::OnUpdateCtxtDirDelLeft(CCmdUI* pCmdUI)
 {
        DoUpdateCtxtDirDelLeft(pCmdUI);
 }
 
-// Should Delete left be enabled or disabled ? (both main menu & context menu use this)
+// Enable/disable Delete Right menu choice on context menu
+void CDirView::OnUpdateCtxtDirDelRight(CCmdUI* pCmdUI) 
+{
+       DoUpdateCtxtDirDelRight(pCmdUI);
+}
+
+// Should Delete left be enabled or disabled ?
 void CDirView::DoUpdateCtxtDirDelLeft(CCmdUI* pCmdUI) 
 {
        int sel = m_pList->GetNextItem(-1, LVNI_SELECTED);
@@ -760,34 +793,6 @@ void CDirView::DoUpdateCtxtDirDelLeft(CCmdUI* pCmdUI)
                break;
        }
 }
-// User chose (context menu) delete right
-void CDirView::OnCtxtDirDelRight()
-{
-       DoDelRight();
-}
-
-// Prompt & delete right, if legal
-void CDirView::DoDelRight() 
-{
-       int sel = m_pList->GetNextItem(-1, LVNI_SELECTED);
-       if (sel == -1) return;
-
-       CString sl, sr, slFile, srFile;
-       if (!GetSelectedDirNames(sl, sr) || !GetSelectedFileNames(slFile, srFile))
-               return;
-
-       // find item from document
-       POSITION pos;
-       const DIFFITEM& di = GetDiffItem(sel, pos);
-
-       ConfirmAndDeleteAndUpdate(srFile, pos, sel);
-}
-
-void CDirView::OnUpdateCtxtDirDelRight(CCmdUI* pCmdUI) 
-{
-       DoUpdateCtxtDirDelRight(pCmdUI);
-}
-
 // Should Delete right be enabled or disabled ?
 void CDirView::DoUpdateCtxtDirDelRight(CCmdUI* pCmdUI) 
 {
@@ -829,3 +834,28 @@ void CDirView::DoUpdateCtxtDirDelRight(CCmdUI* pCmdUI)
                break;
        }
 }
+
+// Prompt & delete file, & remove its data entries
+void CDirView::ConfirmAndDeleteFileAndUpdate(LPCTSTR szFile, POSITION pos, int sel)
+{
+       // May want an option to suppress these message boxes
+
+       if (!mf->ConfirmAndDeleteFile(szFile))
+               return;
+       // remove item data from document & screen
+       GetDocument()->m_pCtxt->m_dirlist.RemoveAt(pos);
+       GetListCtrl().DeleteItem(sel);
+}
+
+// Prompt & delete directory, & remove its data entries
+void CDirView::ConfirmAndDeleteDirAndUpdate(LPCTSTR szDir, POSITION pos, int sel)
+{
+       // May want an option to suppress these message boxes
+
+       if (!mf->ConfirmAndDeleteDir(szDir))
+               return;
+       // remove item data from document & screen
+       // so, this assumes it is a unique entry (has no children listed)
+       GetDocument()->m_pCtxt->m_dirlist.RemoveAt(pos);
+       GetListCtrl().DeleteItem(sel);
+}
index 3dd7be8..d0bccde 100644 (file)
@@ -117,9 +117,10 @@ private:
        void ModifyPopup(CMenu * pPopup, int nStringResource, int nMenuId, LPCTSTR szPath);
        void DoDelLeft();
        void DoDelRight();
-       void ConfirmAndDeleteAndUpdate(LPCTSTR szFile, POSITION pos, int sel);
        void DoUpdateCtxtDirDelLeft(CCmdUI* pCmdUI);
        void DoUpdateCtxtDirDelRight(CCmdUI* pCmdUI);
+       void ConfirmAndDeleteFileAndUpdate(LPCTSTR szFile, POSITION pos, int sel);
+       void ConfirmAndDeleteDirAndUpdate(LPCTSTR szDir, POSITION pos, int sel);
 
 };
 
index 4bb3678..4ab6922 100644 (file)
@@ -70,10 +70,12 @@ BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
        //{{AFX_MSG_MAP(CMainFrame)
        ON_COMMAND(ID_OPTIONS_SHOWDIFFERENT, OnOptionsShowDifferent)
        ON_COMMAND(ID_OPTIONS_SHOWIDENTICAL, OnOptionsShowIdentical)
-       ON_COMMAND(ID_OPTIONS_SHOWUNIQUE, OnOptionsShowUnique)
+       ON_COMMAND(ID_OPTIONS_SHOWUNIQUELEFT, OnOptionsShowUniqueLeft)
+       ON_COMMAND(ID_OPTIONS_SHOWUNIQUERIGHT, OnOptionsShowUniqueRight)
        ON_UPDATE_COMMAND_UI(ID_OPTIONS_SHOWDIFFERENT, OnUpdateOptionsShowdifferent)
        ON_UPDATE_COMMAND_UI(ID_OPTIONS_SHOWIDENTICAL, OnUpdateOptionsShowidentical)
-       ON_UPDATE_COMMAND_UI(ID_OPTIONS_SHOWUNIQUE, OnUpdateOptionsShowunique)
+       ON_UPDATE_COMMAND_UI(ID_OPTIONS_SHOWUNIQUELEFT, OnUpdateOptionsShowuniqueleft)
+       ON_UPDATE_COMMAND_UI(ID_OPTIONS_SHOWUNIQUERIGHT, OnUpdateOptionsShowuniqueright)
        ON_WM_CREATE()
        ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
        ON_UPDATE_COMMAND_UI(ID_HIDE_BACKUP_FILES, OnUpdateHideBackupFiles)
@@ -93,6 +95,7 @@ static UINT indicators[] =
 {
        ID_SEPARATOR,           // status line indicator
        ID_SEPARATOR,
+       ID_SEPARATOR,
        ID_INDICATOR_CAPS,
        ID_INDICATOR_NUM,
        ID_INDICATOR_SCRL,
@@ -111,8 +114,10 @@ CMainFrame::CMainFrame()
        m_bFirstTime = TRUE;
 
        m_bIgnoreBlankLines = theApp.GetProfileInt(_T("Settings"), _T("IgnoreBlankLines"), FALSE)!=0;
+       m_bEolSensitive = theApp.GetProfileInt(_T("Settings"), _T("EolSensitive"), FALSE)!=0;
        m_bIgnoreCase = theApp.GetProfileInt(_T("Settings"), _T("IgnoreCase"), FALSE)!=0;
-       m_bShowUnique = theApp.GetProfileInt(_T("Settings"), _T("ShowUnique"), TRUE)!=0;
+       m_bShowUniqueLeft = theApp.GetProfileInt(_T("Settings"), _T("ShowUniqueLeft"), TRUE)!=0;
+       m_bShowUniqueRight = theApp.GetProfileInt(_T("Settings"), _T("ShowUniqueRight"), TRUE)!=0;
        m_bShowDiff = theApp.GetProfileInt(_T("Settings"), _T("ShowDifferent"), TRUE)!=0;
        m_bShowIdent = theApp.GetProfileInt(_T("Settings"), _T("ShowIdentical"), TRUE)!=0;
        m_bBackup = theApp.GetProfileInt(_T("Settings"), _T("BackupFile"), TRUE)!=0;
@@ -158,7 +163,8 @@ int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
        length_varies = (m_nIgnoreWhitespace!=0);
        ignore_case_flag = m_bIgnoreCase;
        ignore_blank_lines_flag = m_bIgnoreBlankLines;
-       ignore_some_changes = (m_nIgnoreWhitespace!=0) || m_bIgnoreCase || m_bIgnoreBlankLines;
+       ignore_eol_diff = !m_bEolSensitive;
+       ignore_some_changes = (m_nIgnoreWhitespace!=0) || m_bIgnoreCase || m_bIgnoreBlankLines || !m_bEolSensitive;
        // build the initial reg expression list
        RebuildRegExpList();
 
@@ -184,6 +190,7 @@ int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
                return -1;      // fail to create
        }
        m_wndStatusBar.SetPaneInfo(1, ID_DIFFNUM, 0, 150); 
+       m_wndStatusBar.SetPaneInfo(2, ID_DIFFSTATUS, 0, 200); 
 
        // TODO: Remove this if you don't want tool tips or a resizeable toolbar
        m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
@@ -258,6 +265,8 @@ void CMainFrame::ShowMergeDoc(LPCTSTR szLeft, LPCTSTR szRight)
                m_pMergeDoc->m_strRightFile = szRight;
                m_pMergeDoc->m_ltBuf.FreeAll();
                m_pMergeDoc->m_rtBuf.FreeAll();
+               m_pMergeDoc->m_ltBuf.SetEolSensitivity(m_bEolSensitive);
+               m_pMergeDoc->m_rtBuf.SetEolSensitivity(m_bEolSensitive);
                m_pMergeDoc->m_ltBuf.LoadFromFile(szLeft);
                m_pMergeDoc->m_rtBuf.LoadFromFile(szRight);
                
@@ -324,10 +333,18 @@ void CMainFrame::OnOptionsShowIdentical()
                m_pDirDoc->Redisplay();
 }
 
-void CMainFrame::OnOptionsShowUnique() 
+void CMainFrame::OnOptionsShowUniqueLeft() 
+{
+       m_bShowUniqueLeft = !m_bShowUniqueLeft;
+       theApp.WriteProfileInt(_T("Settings"), _T("ShowUniqueLeft"), m_bShowUniqueLeft);
+       if (m_pDirDoc != NULL)
+               m_pDirDoc->Redisplay();
+}
+
+void CMainFrame::OnOptionsShowUniqueRight() 
 {
-       m_bShowUnique = !m_bShowUnique;
-       theApp.WriteProfileInt(_T("Settings"), _T("ShowUnique"), m_bShowUnique);
+       m_bShowUniqueRight = !m_bShowUniqueRight;
+       theApp.WriteProfileInt(_T("Settings"), _T("ShowUniqueRight"), m_bShowUniqueRight);
        if (m_pDirDoc != NULL)
                m_pDirDoc->Redisplay();
 }
@@ -342,11 +359,15 @@ void CMainFrame::OnUpdateOptionsShowidentical(CCmdUI* pCmdUI)
        pCmdUI->SetCheck(m_bShowIdent);
 }
 
-void CMainFrame::OnUpdateOptionsShowunique(CCmdUI* pCmdUI) 
+void CMainFrame::OnUpdateOptionsShowuniqueleft(CCmdUI* pCmdUI) 
 {
-       pCmdUI->SetCheck(m_bShowUnique);
+       pCmdUI->SetCheck(m_bShowUniqueLeft);
 }
 
+void CMainFrame::OnUpdateOptionsShowuniqueright(CCmdUI* pCmdUI) 
+{
+       pCmdUI->SetCheck(m_bShowUniqueRight);
+}
 
 
 
@@ -604,6 +625,7 @@ void CMainFrame::OnProperties()
        gen.m_nIgnoreWhite = m_nIgnoreWhitespace;
        gen.m_bIgnoreCase = m_bIgnoreCase;
        gen.m_bIgnoreBlankLines = m_bIgnoreBlankLines;
+       gen.m_bEolSensitive = m_bEolSensitive;
        gen.m_bScroll = m_bScrollToFirst;
        gen.m_nTabSize = m_nTabSize;
        gen.m_bDisableSplash = theApp.m_bDisableSplash;
@@ -626,8 +648,10 @@ void CMainFrame::OnProperties()
                ignore_all_space_flag = (m_nIgnoreWhitespace==2);
                ignore_space_change_flag = (m_nIgnoreWhitespace==1);
                ignore_blank_lines_flag = m_bIgnoreBlankLines = gen.m_bIgnoreBlankLines;
+               m_bEolSensitive = gen.m_bEolSensitive;
+               ignore_eol_diff = !m_bEolSensitive;
                ignore_case_flag = m_bIgnoreCase = gen.m_bIgnoreCase;
-               ignore_some_changes = (m_nIgnoreWhitespace!=0) || m_bIgnoreCase || m_bIgnoreBlankLines;
+               ignore_some_changes = (m_nIgnoreWhitespace!=0) || m_bIgnoreCase || m_bIgnoreBlankLines || !m_bEolSensitive;
                length_varies = (m_nIgnoreWhitespace!=0);
                
                m_bIgnoreRegExp = filter.m_bIgnoreRegExp;
@@ -669,6 +693,62 @@ void CMainFrame::OnProperties()
        }
 }
 
+// callback for progress during diff
+class MainFrmStatus : public IDiffStatus
+{
+public:
+       MainFrmStatus(CMainFrame * pFrame) : m_pFrame(pFrame) { m_pFrame->clearStatus(); }
+       virtual void rptFile(BYTE code) { m_pFrame->rptStatus(code); }
+private:
+       CMainFrame * m_pFrame;
+};
+
+// clear counters used to track diff progress
+void CMainFrame::clearStatus()
+{
+       m_nStatusFileSame = m_nStatusFileDiff = m_nStatusFileBinDiff = m_nStatusFileError
+                = m_nStatusLeftFileOnly = m_nStatusLeftDirOnly = m_nStatusRightFileOnly = m_nStatusRightDirOnly
+                = 0;
+}
+
+// diff completed another file
+void CMainFrame::rptStatus(BYTE code)
+{
+       switch(code)
+       {
+       case FILE_SAME:
+               ++m_nStatusFileSame;
+               break;
+       case FILE_DIFF:
+               ++m_nStatusFileDiff;
+               break;
+       case FILE_BINDIFF:
+               ++m_nStatusFileBinDiff;
+               break;
+       case FILE_ERROR:
+               ++m_nStatusFileError;
+               break;
+       case FILE_LUNIQUE:
+               ++m_nStatusLeftFileOnly;
+               break;
+       case FILE_LDIRUNIQUE:
+               ++m_nStatusLeftDirOnly;
+               break;
+       case FILE_RUNIQUE:
+               ++m_nStatusRightFileOnly;
+               break;
+       case FILE_RDIRUNIQUE:
+               ++m_nStatusRightDirOnly;
+               break;
+       }
+       CString s;
+       // AfxFormatString4 doesn't exist
+       s.Format(_T("s:%d d:%d lf:%d ld:%d rf:%d rd:%d bd:%d e:%d")
+               , m_nStatusFileSame, m_nStatusFileDiff, m_nStatusFileBinDiff, m_nStatusFileError
+               , m_nStatusLeftFileOnly, m_nStatusLeftDirOnly, m_nStatusRightFileOnly, m_nStatusRightDirOnly);
+       m_wndStatusBar.SetPaneText(2, s);
+
+}
 
 BOOL CMainFrame::DoFileOpen(LPCTSTR pszLeft /*=NULL*/, LPCTSTR pszRight /*=NULL*/, BOOL bRecurse /*= FALSE*/)
 {
@@ -727,7 +807,8 @@ BOOL CMainFrame::DoFileOpen(LPCTSTR pszLeft /*=NULL*/, LPCTSTR pszRight /*=NULL*
                                  _T("\tLeft: %s\r\n")
                                   _T("\tRight: %s\r\n")
                                  _T("\tRecurse: %d\r\n")
-                                 _T("\tShowUnique: %d\r\n")
+                                 _T("\tShowUniqueLeft: %d\r\n")
+                                 _T("\tShowUniqueRight: %d\r\n")
                                  _T("\tShowIdentical: %d\r\n")
                                  _T("\tShowDiff: %d\r\n")
                                  _T("\tHideBak: %d\r\n")
@@ -740,7 +821,8 @@ BOOL CMainFrame::DoFileOpen(LPCTSTR pszLeft /*=NULL*/, LPCTSTR pszRight /*=NULL*
                                  strLeft,
                                  strRight,
                                  bRecurse,
-                                 m_bShowUnique,
+                                 m_bShowUniqueLeft,
+                                 m_bShowUniqueRight,
                                  m_bShowIdent,
                                  m_bShowDiff,
                                  m_bHideBak,
@@ -759,7 +841,8 @@ BOOL CMainFrame::DoFileOpen(LPCTSTR pszLeft /*=NULL*/, LPCTSTR pszRight /*=NULL*
                        m_pDirDoc = (CDirDoc*)theApp.m_pDirTemplate->OpenDocumentFile(NULL);
                if (m_pDirDoc != NULL)
                {
-                       CDiffContext *pCtxt = new CDiffContext(strLeft, strRight);
+                       MainFrmStatus mfst(this);
+                       CDiffContext *pCtxt = new CDiffContext(strLeft, strRight, &mfst);
                        if (pCtxt != NULL)
                        {
                                m_pDirDoc->SetDiffContext(pCtxt);
@@ -796,7 +879,7 @@ BOOL CMainFrame::CreateBackup(LPCTSTR pszPath)
                        s.Format(_T("%s\\%s")  BACKUP_FILE_EXT, path, name);
 
                // get rid of the dest file
-               DeleteFile(s);
+               DeleteFile(s); // (errors are handled from MoveFile below)
 
                // move the sucker
                if (!MoveFile(pszPath, s)
@@ -813,8 +896,7 @@ BOOL CMainFrame::CreateBackup(LPCTSTR pszPath)
 }
 
 // Get user language description of error, if available
-static CString
-GetSystemErrorDesc(int nerr)
+CString CMainFrame::GetSystemErrorDesc(int nerr)
 {
        LPVOID lpMsgBuf;
        CString str = _T("?");
@@ -838,22 +920,22 @@ GetSystemErrorDesc(int nerr)
 }
 
 // trim trailing line returns
-static void TrimRightLines(CString & str)
+void CMainFrame::RemoveLineReturns(CString & str)
 {
        str.Replace(_T("\n"), _T(""));
        str.Replace(_T("\r"), _T(""));
 }
 
 // Delete file (return TRUE if deleted, else put up error & return FALSE)
-static BOOL DeleteOrError(LPCTSTR szFile)
+BOOL CMainFrame::DeleteFileOrError(LPCTSTR szFile)
 {
-       // TODO: 2002-11-22, need to handle deleting directories
        if (!DeleteFile(szFile))
        {
                CString sError = GetSystemErrorDesc(GetLastError());
-               TrimRightLines(sError);
+               RemoveLineReturns(sError);
+               sError += (CString)_T(" [") + szFile + _T("]");
                CString s;
-               AfxFormatString1(s, IDS_DELETE_FAILED, sError);
+               AfxFormatString1(s, IDS_DELETE_FILE_FAILED, sError);
                AfxMessageBox(s, MB_OK|MB_ICONSTOP);
                return FALSE;
        }
@@ -861,15 +943,64 @@ static BOOL DeleteOrError(LPCTSTR szFile)
 }
 
 // Prompt & delete file (return TRUE if deleted)
-BOOL CMainFrame::ConfirmAndDelete(LPCTSTR szFile)
+BOOL CMainFrame::ConfirmAndDeleteFile(LPCTSTR szFile)
+{
+       CString s;
+       AfxFormatString1(s, IDS_CONFIRM_DELETE_FILE, szFile);
+       if (AfxMessageBox(s, MB_YESNO|MB_ICONQUESTION)!=IDYES)
+               return FALSE;
+       return DeleteFileOrError(szFile);
+}
+
+// Prompt & delete directory (return TRUE if deleted)
+BOOL CMainFrame::ConfirmAndDeleteDir(LPCTSTR szDir)
 {
        CString s;
-       AfxFormatString1(s, IDS_CONFIRM_DELETE, szFile);
+       AfxFormatString1(s, IDS_CONFIRM_DELETE_DIR, szDir);
        if (AfxMessageBox(s, MB_YESNO|MB_ICONQUESTION)!=IDYES)
                return FALSE;
-       return DeleteOrError(szFile);
+       return DeleteRecurseDir(szDir);
 }
 
+// delete directory by recursively deleting all contents
+// gives up on first error
+BOOL CMainFrame::DeleteRecurseDir(LPCTSTR szDir)
+{
+       CFileFind finder;
+       CString sSpec = szDir;
+       sSpec += _T("\\*.*");
+       if (finder.FindFile(sSpec))
+       {
+               BOOL done=FALSE;
+               while (!done)
+               {
+                       done = !finder.FindNextFile();
+                       if (finder.IsDots()) continue;
+                       if (finder.IsDirectory())
+                       {
+                               if (!DeleteRecurseDir(finder.GetFilePath()))
+                                       return FALSE;
+                       }
+                       else
+                       {
+                               if (!DeleteFileOrError(finder.GetFilePath()))
+                                       return FALSE;
+                       }
+               }
+       }
+       finder.Close(); // must close the handle or RemoveDirectory will fail
+       if (!RemoveDirectory(szDir))
+       {
+               CString sError = GetSystemErrorDesc(GetLastError());
+               RemoveLineReturns(sError);
+               sError += (CString)_T(" [") + szDir + _T("]");
+               CString s;
+               AfxFormatString1(s, IDS_DELETE_FILE_FAILED, sError);
+               AfxMessageBox(s, MB_OK|MB_ICONSTOP);
+               return FALSE;
+       }
+       return TRUE;
+}
 
 BOOL CMainFrame::SyncFiles(LPCTSTR pszSrc, LPCTSTR pszDest)
 {
@@ -882,7 +1013,7 @@ BOOL CMainFrame::SyncFiles(LPCTSTR pszSrc, LPCTSTR pszDest)
                return FALSE;
        
        // Now it's just a matter of copying the right file to the left
-       DeleteFile(strSavePath);
+       DeleteFile(strSavePath); // (errors are handled from CopyFile below)
        if (!CopyFile(pszSrc, strSavePath, FALSE))
        {
                
index 97a2a42..dd084de 100644 (file)
@@ -46,15 +46,33 @@ public:
 
 // Attributes
 public:        
-       BOOL m_bShowUnique;
+       BOOL m_bShowUniqueLeft;
+       BOOL m_bShowUniqueRight;
        BOOL m_bShowDiff;
        BOOL m_bShowIdent;
        BOOL m_bBackup;
        LOGFONT m_lfDiff;
        BOOL m_bFontSpecified;
+       BOOL m_bEolSensitive;
 
 // Operations
 public:
+       CString GetSystemErrorDesc(int nerr);
+       void RemoveLineReturns(CString & str);
+       BOOL DeleteFileOrError(LPCTSTR szFile);
+       BOOL DeleteRecurseDir(LPCTSTR szDir);
+       BOOL ConfirmAndDeleteFile(LPCTSTR szFile);
+       BOOL ConfirmAndDeleteDir(LPCTSTR szDir);
+       void rptStatus(BYTE code);
+       void clearStatus();
+       BOOL SyncFiles(LPCTSTR pszSrc, LPCTSTR pszDest);
+       void UpdateCurrentFileStatus(UINT nStatus);
+       BOOL DoFileOpen(LPCTSTR pszLeft = NULL, LPCTSTR pszRight = NULL, BOOL bRecurse = FALSE);
+       void ShowMergeDoc(LPCTSTR szLeft, LPCTSTR szRight);
+       void UpdateResources();
+       HMENU NewDefaultMenu();
+       BOOL CreateBackup(LPCTSTR pszPath);
+       BOOL CheckSavePath(CString& strSavePath);
 
 // Overrides
        // ClassWizard generated virtual function overrides
@@ -64,23 +82,20 @@ public:
        virtual void ActivateFrame(int nCmdShow = -1);
        //}}AFX_VIRTUAL
 
-// Implementation
+// Implementation methods
+protected:
+       void CleanupFileBufs();
+       virtual ~CMainFrame();
+
+// Public implementation data
 public:
        BOOL m_bFirstTime;
        CString m_strSaveAsPath;
-       void CleanupFileBufs();
        BOOL m_bIgnoreBlankLines;
        BOOL m_bIgnoreCase;
        BOOL m_bIgnoreRegExp;
        CString m_sPattern;
-       void UpdateResources();
-       void UpdateCurrentFileStatus(UINT nStatus);
-       BOOL ConfirmAndDelete(LPCTSTR szFile);
-       BOOL SyncFiles(LPCTSTR pszSrc, LPCTSTR pszDest);
-       BOOL CreateBackup(LPCTSTR pszPath);
        UINT m_nTabSize;
-       BOOL DoFileOpen(LPCTSTR pszLeft = NULL, LPCTSTR pszRight = NULL, BOOL bRecurse = FALSE);
-       BOOL CheckSavePath(CString& strSavePath);
        CString m_strVssPath;
        CString m_strVssProject;
        CString m_strVssUser;      // BSP - Visual Source Safe User ID
@@ -89,12 +104,20 @@ public:
        BOOL m_bHideBak;
        int m_nIgnoreWhitespace;
        BOOL m_bScrollToFirst;
-       void ShowMergeDoc(LPCTSTR szLeft, LPCTSTR szRight);
        CMergeEditView *m_pLeft, *m_pRight;
        CMergeDoc *m_pMergeDoc;
        CDirDoc *m_pDirDoc;
-       virtual ~CMainFrame();
-       HMENU NewDefaultMenu();
+// Implementation data
+protected:
+       int m_nStatusFileSame;
+       int m_nStatusFileDiff;
+       int m_nStatusFileBinDiff;
+       int m_nStatusFileError;
+       int m_nStatusLeftFileOnly;
+       int m_nStatusLeftDirOnly;
+       int m_nStatusRightFileOnly;
+       int m_nStatusRightDirOnly;
+
 #ifdef _DEBUG
        virtual void AssertValid() const;
        virtual void Dump(CDumpContext& dc) const;
@@ -111,10 +134,12 @@ protected:
        //{{AFX_MSG(CMainFrame)
        afx_msg void OnOptionsShowDifferent();
        afx_msg void OnOptionsShowIdentical();
-       afx_msg void OnOptionsShowUnique();
+       afx_msg void OnOptionsShowUniqueLeft();
+       afx_msg void OnOptionsShowUniqueRight();
        afx_msg void OnUpdateOptionsShowdifferent(CCmdUI* pCmdUI);
        afx_msg void OnUpdateOptionsShowidentical(CCmdUI* pCmdUI);
-       afx_msg void OnUpdateOptionsShowunique(CCmdUI* pCmdUI);
+       afx_msg void OnUpdateOptionsShowuniqueleft(CCmdUI* pCmdUI);
+       afx_msg void OnUpdateOptionsShowuniqueright(CCmdUI* pCmdUI);
        afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
        afx_msg void OnFileOpen();
        afx_msg void OnUpdateHideBackupFiles(CCmdUI* pCmdUI);
index 2fa74e4..7c6edbd 100644 (file)
@@ -126,7 +126,8 @@ BEGIN
     BEGIN
         MENUITEM "Show &Identical Files",       ID_OPTIONS_SHOWIDENTICAL
         MENUITEM "Show &Different Files",       ID_OPTIONS_SHOWDIFFERENT
-        MENUITEM "Show &Unique Files",          ID_OPTIONS_SHOWUNIQUE
+        MENUITEM "Show Le&ft Unique Files",     ID_OPTIONS_SHOWUNIQUELEFT
+        MENUITEM "Show Ri&ght Unique Files",    ID_OPTIONS_SHOWUNIQUERIGHT
         MENUITEM "Hide *.&BAK Files",           ID_HIDE_BACKUP_FILES
         MENUITEM SEPARATOR
         MENUITEM "Select &Font...",             ID_VIEW_SELECTFONT
@@ -182,13 +183,13 @@ BEGIN
     VK_BACK,        ID_EDIT_UNDO,           VIRTKEY, ALT, NOINVERT
     VK_DELETE,      ID_EDIT_CUT,            VIRTKEY, SHIFT, NOINVERT
     VK_DOWN,        ID_NEXTDIFF,            VIRTKEY, ALT, NOINVERT
+    VK_END,         ID_LASTDIFF,            VIRTKEY, ALT, NOINVERT
     VK_F6,          ID_NEXT_PANE,           VIRTKEY, NOINVERT
     VK_F6,          ID_PREV_PANE,           VIRTKEY, SHIFT, NOINVERT
+    VK_HOME,        ID_FIRSTDIFF,           VIRTKEY, ALT, NOINVERT
     VK_INSERT,      ID_EDIT_COPY,           VIRTKEY, CONTROL, NOINVERT
     VK_INSERT,      ID_EDIT_PASTE,          VIRTKEY, SHIFT, NOINVERT
     VK_LEFT,        ID_R2L,                 VIRTKEY, ALT, NOINVERT
-    VK_NEXT,        ID_LASTDIFF,            VIRTKEY, ALT, NOINVERT
-    VK_PRIOR,       ID_FIRSTDIFF,           VIRTKEY, ALT, NOINVERT
     VK_RETURN,      ID_CURDIFF,             VIRTKEY, ALT, NOINVERT
     VK_RIGHT,       ID_L2R,                 VIRTKEY, ALT, NOINVERT
     VK_UP,          ID_PREVDIFF,            VIRTKEY, ALT, NOINVERT
@@ -294,7 +295,7 @@ BEGIN
     CONTROL         "Ignore &case",IDC_IGNCASE_CHECK,"Button",
                     BS_AUTOCHECKBOX | WS_TABSTOP,17,57,53,10
     CONTROL         "&Disable Splash Screen",IDC_DISABLE_SPLASH,"Button",
-                    BS_AUTOCHECKBOX | WS_TABSTOP,17,69,87,10
+                    BS_AUTOCHECKBOX | WS_TABSTOP,17,81,87,10
     CONTROL         "Compare &whitespace",IDC_WHITESPACE,"Button",
                     BS_AUTORADIOBUTTON | WS_GROUP,128,45,82,10
     CONTROL         "Ignore whitespace c&hange",IDC_WHITE_CHANGE,"Button",
@@ -304,6 +305,8 @@ BEGIN
     GROUPBOX        "Tabs",IDC_STATIC,7,105,221,30,WS_GROUP
     LTEXT           "&Tab size:",IDC_STATIC,15,119,30,8
     EDITTEXT        IDC_TAB_EDIT,47,118,27,12,ES_AUTOHSCROLL
+    CONTROL         "Sensitive to &EOL",IDC_EOL_SENSITIVE,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,17,68,69,10
 END
 
 IDD_LANGUAGE_SELECT DIALOG DISCARDABLE  0, 0, 213, 111
@@ -623,9 +626,9 @@ END
 STRINGTABLE DISCARDABLE 
 BEGIN
     ID_FILE_NEW             "Create a new document\nNew"
-    ID_FILE_OPEN            "Open an existing document\nOpen"
+    ID_FILE_OPEN            "Open an existing document\nOpen (Ctrl+O)"
     ID_FILE_CLOSE           "Close the active document\nClose"
-    ID_FILE_SAVE            "Save the active document\nSave"
+    ID_FILE_SAVE            "Save the active document\nSave (Ctrl+S)"
     ID_FILE_SAVE_AS         "Save the active document with a new name\nSave As"
     ID_FILE_PAGE_SETUP      "Change the printing options\nPage Setup"
     ID_FILE_PRINT_SETUP     "Change the printer and printing options\nPrint Setup"
@@ -721,13 +724,12 @@ END
 
 STRINGTABLE DISCARDABLE 
 BEGIN
-    ID_L2R                  "Copy the selected text to the right file\nCopy Right (Right Arrow)"
-    ID_R2L                  "Copy the selected text to the left file\nCopy Left (Left Arrow)"
+    ID_L2R                  "Copy the selected text to the right file\nCopy Right (Alt Right)"
+    ID_R2L                  "Copy the selected text to the left file\nCopy Left (Alt Left)"
     ID_OPTIONS_SHOWIDENTICAL "Displays files that are exactly the same"
     ID_OPTIONS_SHOWDIFFERENT "Displays files that have differences"
-    ID_OPTIONS_SHOWUNIQUE   "Displays files that exist in only one directory"
-    ID_PREVDIFF             "Scroll to the previous difference\nPrev Diff (Shift+Tab)"
-    ID_NEXTDIFF             "Scroll to the next difference\nNext Diff (Tab)"
+    ID_PREVDIFF             "Scroll to the previous difference\nPrev Diff (Alt Up)"
+    ID_NEXTDIFF             "Scroll to the next difference\nNext Diff (Alt Down)"
     ID_OPTIONS_BACKUPORIGINALFILE 
                             "Save a copy of the original as *.bak\nBackup"
 END
@@ -753,12 +755,16 @@ BEGIN
     ID_DIR_COPY_FILE_TO_RIGHT "Copy selected file to named directory"
     ID_VIEW_LANGUAGE        "Select the current user interfacce language\nLanguage"
     ID_HELP_CONTENTS        "Displays the WinMerge User's Guide\nHelp"
-    ID_FIRSTDIFF            "Scroll to the first difference\nFirst Diff"
-    ID_CURDIFF              "Scroll to the current difference\nCurrent Diff"
-    ID_LASTDIFF             "Scroll to the last difference\nLast Diff"
+    ID_FIRSTDIFF            "Scroll to the first difference\nFirst Diff (Alt+Home)"
+    ID_CURDIFF              "Scroll to the current difference\nCurrent Diff (Alt+Enter)"
+    ID_LASTDIFF             "Scroll to the last difference\nLast Diff (Alt+End)"
     ID_DIFFNUM              "placeholder"
     ID_DIR_DEL_LEFT         "Delete selected file on left"
     ID_DIR_DEL_RIGHT        "Delete selected file on right"
+    ID_DIFFSTATUS           "placeholder for status count"
+    ID_OPTIONS_SHOWUNIQUELEFT "Displays files that exist in only on left side"
+    ID_OPTIONS_SHOWUNIQUERIGHT 
+                            "Displays files that exist in only on right side"
 END
 
 STRINGTABLE DISCARDABLE 
@@ -770,7 +776,7 @@ BEGIN
                             "Unable to backup original file.\nContinue anyway?"
     IDS_PROPERTIES_TITLE    "Properties"
     IDS_OPEN_TITLE          "Open"
-    IDS_CONFIRM_DELETE      "Delete %1?"
+    IDS_CONFIRM_DELETE_FILE "Delete file %1?"
     IDS_EDIT_WINDOW_TITLE_FMT "Edit %1"
     IDS_FILESSAME           "The selected files are identical."
     IDS_FILEUNIQUE          "The selected file didn't exist in both directories and therefore couldn't be compared."
@@ -939,7 +945,9 @@ END
 STRINGTABLE DISCARDABLE 
 BEGIN
     IDS_DEL_RIGHT_FMT       "Del right: %1"
-    IDS_DELETE_FAILED       "Delete failed: %1"
+    IDS_DELETE_FILE_FAILED  "Delete file failed: %1"
+    IDS_CONFIRM_DELETE_DIR  "Delete directory %1?"
+    IDS_REMOVE_DIR_FAILED   "Remove directory failed: %1"
 END
 
 #endif    // English (U.S.) resources
index a4ee533..22edd6f 100644 (file)
@@ -44,6 +44,7 @@ CPropGeneral::CPropGeneral() : CPropertyPage(CPropGeneral::IDD)
        m_nTabSize = 0;
        m_bIgnoreCase = FALSE;
        m_bIgnoreBlankLines = FALSE;
+       m_bEolSensitive = FALSE;
        m_bDisableSplash = FALSE;
        m_nIgnoreWhite = -1;
        //}}AFX_DATA_INIT
@@ -62,6 +63,7 @@ void CPropGeneral::DoDataExchange(CDataExchange* pDX)
        DDX_Text(pDX, IDC_TAB_EDIT, m_nTabSize);
        DDX_Check(pDX, IDC_IGNCASE_CHECK, m_bIgnoreCase);
        DDX_Check(pDX, IDC_IGNBLANKS_CHECK, m_bIgnoreBlankLines);
+       DDX_Check(pDX, IDC_EOL_SENSITIVE, m_bEolSensitive);
        DDX_Check(pDX, IDC_DISABLE_SPLASH, m_bDisableSplash);
        DDX_Radio(pDX, IDC_WHITESPACE, m_nIgnoreWhite);
        //}}AFX_DATA_MAP
index cfef2f7..9b4c01e 100644 (file)
@@ -27,6 +27,7 @@ public:
        UINT    m_nTabSize;
        BOOL    m_bIgnoreCase;
        BOOL    m_bIgnoreBlankLines;
+       BOOL    m_bEolSensitive;
        BOOL    m_bDisableSplash;
        int             m_nIgnoreWhite;
        //}}AFX_DATA
index 5d3e87d..b3e28ed 100644 (file)
@@ -82,6 +82,9 @@ EXTERN int      horizon_lines;
 /* Ignore changes in horizontal white space (-b).  */
 EXTERN int      ignore_space_change_flag;
 
+/* Ignore end of line differences (at least between UNIX & DOS */
+EXTERN int      ignore_eol_diff;
+
 /* Ignore all horizontal white space (-w).  */
 EXTERN int      ignore_all_space_flag;
 
@@ -355,4 +358,4 @@ extern char const version_string[];
 
 #ifdef __cplusplus
 }
-#endif
\ No newline at end of file
+#endif
index e549dea..2105b25 100644 (file)
@@ -251,6 +251,7 @@ find_and_hash_each_line (current)
       h = 0;
 
       /* Hash this line until we find a newline. */
+      /* Perry 2002-11-26 added EOL insensitivity */
       if (ignore_case_flag)
        {
          if (ignore_all_space_flag)
@@ -262,6 +263,8 @@ find_and_hash_each_line (current)
          else if (ignore_space_change_flag)
            while ((c = *p++) != '\n')
              {
+               if (ignore_eol_diff && c=='\r' && *p=='\n')
+                 continue;
                if (isspace (c))
                  {
                    while (isspace (c = *p++))
@@ -274,7 +277,11 @@ find_and_hash_each_line (current)
              }
          else
            while ((c = *p++) != '\n')
+             {
+             if (ignore_eol_diff && c=='\r' && *p=='\n')
+               continue;
              h = HASH (h, isupper (c) ? tolower (c) : c);
+             }
        }
       else
        {
@@ -287,6 +294,8 @@ find_and_hash_each_line (current)
          else if (ignore_space_change_flag)
            while ((c = *p++) != '\n')
              {
+               if (ignore_eol_diff && c=='\r' && *p=='\n')
+                 continue;
                if (isspace (c))
                  {
                    while (isspace (c = *p++))
@@ -299,12 +308,21 @@ find_and_hash_each_line (current)
              }
          else
            while ((c = *p++) != '\n')
+             {
+             if (ignore_eol_diff && c=='\r' && *p=='\n')
+               continue;
              h = HASH (h, c);
+             }
        }
    hashing_done:;
 
       bucket = &buckets[h % nbuckets];
       length = (char const HUGE *) p - ip - ((char const HUGE *) p == incomplete_tail);
+      if (ignore_eol_diff && length>1 && p[-2]=='\r' && p[-1]=='\n')
+       {
+         ((char HUGE *)p)[-2] = '\n';
+         --length;
+       }
       for (i = *bucket;  ;  i = eqs[i].next)
        if (!i)
          {
index 86a8c24..e91d493 100644 (file)
@@ -432,11 +432,20 @@ LoadFromFile (LPCTSTR pszFileName, int nCrlfStyle /*= CRLF_STYLE_AUTOMATIC*/ )
                        
                        // detect both types of EOL for each line
                        // handles mixed mode files.
+                       // Perry (2002-11-26): What about MAC files ? They don't have 0x0A at all. I think this doesn't handle them.
                        if( c==0x0A )
                        {
-                               TCHAR prevChar = pcLineBuf[nCurrentLength-2];
+                               // 2002-11-26  Perry fixed bug & added optional sensitivity to CR
                                // remove EOL characters
-                               pcLineBuf[nCurrentLength - (prevChar==0x0D?2:1) ] = '\0';
+                               if (!m_EolSensitive && nCurrentLength>1)
+                               {
+                                       TCHAR prevChar = pcLineBuf[nCurrentLength-2];
+                                       pcLineBuf[nCurrentLength - (prevChar==0x0D?2:1) ] = '\0';
+                               }
+                               else
+                               {
+                                       pcLineBuf[nCurrentLength - 1] = '\0';
+                               }
                                nCurrentLength = 0;
                                if (m_nSourceEncoding >= 0)
                                        iconvert (pcLineBuf, m_nSourceEncoding, 1, m_nSourceEncoding == 15);
index 245094b..e0ecc46 100644 (file)
@@ -118,6 +118,7 @@ protected :
     BOOL m_bReadOnly;
     BOOL m_bModified;
     int m_nCRLFMode;
+       BOOL m_EolSensitive;
     BOOL m_bCreateBackupFile;
     int m_nUndoBufSize;
     int FindLineWithFlag (DWORD dwFlag);
@@ -272,6 +273,8 @@ public :
     BOOL GetReadOnly () const;
     void SetReadOnly (BOOL bReadOnly = TRUE);
 
+       void SetEolSensitivity(BOOL EolSensitive) { m_EolSensitive = EolSensitive; }
+
     //  Text modification functions
     BOOL InsertText (CCrystalTextView * pSource, int nLine, int nPos, LPCTSTR pszText, int &nEndLine, int &nEndChar, int nAction = CE_ACTION_UNKNOWN, BOOL bUpdate =TRUE);
     BOOL DeleteText (CCrystalTextView * pSource, int nStartLine, int nStartPos, int nEndLine, int nEndPos, int nAction = CE_ACTION_UNKNOWN, BOOL bUpdate =TRUE);
diff --git a/Src/readme.txt b/Src/readme.txt
new file mode 100644 (file)
index 0000000..f942de1
--- /dev/null
@@ -0,0 +1,11 @@
+2002-11-26  Perry
+ Implemented recursive directory delete
+ Fix bug in EOL handling in crystaltextbuffer, and add optional EOL sensitivity.
+ Added optional EOL insensitivity to gnu diff IO.c.
+ Added status bar progress (file count) indicator during scanning
+ Fixed tooltips of toolbar buttons to list correct hotkeys
+ Split "Show Unique" option into "Show Left Unique" and "Show Right Unique"
+
+2002-12-02
+ Added left files, left dirs, right files, right dirs to status bar feedback
+
index e1acc15..2f06215 100644 (file)
@@ -43,6 +43,7 @@
 #define IDS_PROPERTIES_TITLE            147
 #define IDS_OPEN_TITLE                  148
 #define IDS_CONFIRM_DELETE              149
+#define IDS_CONFIRM_DELETE_FILE         149
 #define IDS_EDIT_WINDOW_TITLE_FMT       150
 #define IDS_FILESSAME                   151
 #define IDS_FILEUNIQUE                  152
@@ -72,6 +73,9 @@
 #define IDS_DEL_LEFT_FMT                175
 #define IDS_DEL_RIGHT_FMT               176
 #define IDS_DELETE_FAILED               177
+#define IDS_DELETE_FILE_FAILED          177
+#define IDS_CONFIRM_DELETE_DIR          178
+#define IDS_REMOVE_DIR_FAILED           179
 #define IDB_EQUAL                       213
 #define IDB_NOTEQUAL                    214
 #define IDB_RFOLDER                     215
 #define IDC_WHITE_CHANGE                1025
 #define IDC_WHITESPACE                  1026
 #define IDC_USER                        1027
+#define IDC_EOL_SENSITIVE               1027
 #define IDC_PASSWORD                    1028
 #define IDC_DIFFERENCE_COLOR            1031
 #define IDC_SEL_DIFFERENCE_COLOR        1032
 #define ID_DIFFNUM                      32806
 #define ID_DIR_DEL_LEFT                 32807
 #define ID_DIR_DEL_RIGHT                32808
+#define ID_DIFFSTATUS                   32809
+#define ID_OPTIONS_SHOWUNIQUELEFT       32810
+#define ID_OPTIONS_SHOWUNIQUERIGHT      32811
 
 // Next default values for new objects
 // 
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_3D_CONTROLS                     1
 #define _APS_NEXT_RESOURCE_VALUE        135
-#define _APS_NEXT_COMMAND_VALUE         32809
+#define _APS_NEXT_COMMAND_VALUE         32812
 #define _APS_NEXT_CONTROL_VALUE         1032
 #define _APS_NEXT_SYMED_VALUE           106
 #endif