-/*******************************************************************************
-FILE: version.cpp
+/**
+ * @file version.cpp
+ *
+ * @brief Implementation of CVersionInfo class
+ */
-*******************************************************************************/
#include "stdafx.h"
#include "version.h"
{
if (!m_bQueryDone)
GetVersionInfo();
+ if (!m_dwVerInfoSize)
+ return _T("");
return MakeVersionString(m_FixedFileInfo.dwProductVersionMS
, m_FixedFileInfo.dwProductVersionLS);
}
+CString CVersionInfo::GetFixedFileVersion()
+{
+ if (!m_bQueryDone)
+ GetVersionInfo();
+ if (!m_dwVerInfoSize)
+ return _T("");
+ return MakeVersionString(m_FixedFileInfo.dwFileVersionMS
+ , m_FixedFileInfo.dwFileVersionLS);
+}
+
CString CVersionInfo::GetComments()
{
if (!m_bQueryDone)
void CVersionInfo::GetVersionInfo()
{
- DWORD dwVerInfoSize; // Size of version information block
DWORD dwVerHnd=0; // An 'ignored' parameter, always '0'
TCHAR szFileName[MAX_PATH];
else
_tcscpy(szFileName, m_strFileName);
- dwVerInfoSize = GetFileVersionInfoSize(szFileName, &dwVerHnd);
- if (dwVerInfoSize) {
+ m_dwVerInfoSize = GetFileVersionInfoSize(szFileName, &dwVerHnd);
+ if (m_dwVerInfoSize) {
HANDLE hMem;
- hMem = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
+ hMem = GlobalAlloc(GMEM_MOVEABLE, m_dwVerInfoSize);
m_lpstrVffInfo = (LPTSTR)GlobalLock(hMem);
- if (GetFileVersionInfo(szFileName, dwVerHnd, dwVerInfoSize, m_lpstrVffInfo))
+ if (GetFileVersionInfo(szFileName, dwVerHnd, m_dwVerInfoSize, m_lpstrVffInfo))
{
GetFixedVersionInfo();
if (m_strLanguage.IsEmpty()
-/*******************************************************************************
-FILE: version.h
+/**
+ * @file version.h
+ *
+ * @brief Declaration of CVersionInfo class
+ */
-*******************************************************************************/
#ifndef VERSIONTOOLS_H
#define VERSIONTOOLS_H
+/**
+ * @brief Class providing access to version information of a file
+ */
class CVersionInfo
{
LPTSTR m_lpstrVffInfo;
BOOL m_bQueryDone;
VS_FIXEDFILEINFO m_FixedFileInfo;
+ DWORD m_dwVerInfoSize; /**< Size of version information block (0 if missing) */
CString m_strFileName;
CString m_strLanguage;
CString GetSpecialBuild();
CString GetPrivateBuild();
CString GetFixedProductVersion();
+ CString GetFixedFileVersion();
protected:
void GetVersionInfo();
void GetFixedVersionInfo();
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
/////////////////////////////////////////////////////////////////////////////
-// DiffContext.cpp: implementation of the CDiffContext class.
-//
+/**
+ * @file DiffContext.cpp
+ *
+ * @brief Implementation of CDiffContext
+ */
+// RCS ID line follows -- this is updated by CVS
+// $Id$
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "merge.h"
+#include "version.h"
#include "DiffContext.h"
+#include "paths.h"
+#include "coretools.h"
#ifdef _DEBUG
#undef THIS_FILE
if (pNamesRight != NULL)
free(pNamesRight);
}
-
-void CDiffContext::AddDiff(LPCTSTR pszFilename, LPCTSTR pszLeftDir, LPCTSTR pszRightDir,
- long ltime, long rtime, BYTE code)
+/**
+ * @brief Fetch & return the fixed file version as a dotted string
+ */
+static CString GetFixedFileVersion(const CString & path)
+{
+ CVersionInfo ver(path);
+ return ver.GetFixedFileVersion();
+}
+
+/**
+ * @brief Add new diffitem to CDiffContext array
+ */
+void CDiffContext::AddDiff(LPCTSTR pszFilename, LPCTSTR szSubdir
+ , LPCTSTR pszLeftDir, LPCTSTR pszRightDir
+ , long lmtime, long rmtime
+ , long lctime, long rctime
+ , __int64 lsize, __int64 rsize
+ , BYTE code
+ )
{
DIFFITEM di;
di.sfilename = pszFilename;
- di.slpath = pszLeftDir;
- di.srpath = pszRightDir;
- di.ltime = ltime;
- di.rtime = rtime;
+ di.left.spath = pszLeftDir;
+ di.right.spath = pszRightDir;
+ di.left.mtime = lmtime;
+ di.right.mtime = rmtime;
+ di.left.ctime = lctime;
+ di.right.ctime = rctime;
di.code = code;
+ di.left.size = lsize;
+ di.right.size = rsize;
+ UpdateFieldsNeededForNewItems(di, di.left);
+ UpdateFieldsNeededForNewItems(di, di.right);
AddDiff(di);
}
di.code = status;
}
-void CDiffContext::UpdateTimes(POSITION diffpos, long leftTime, long rightTime)
+/**
+ * @brief Load all fields not provided in initial AddDiff call
+ */
+void CDiffContext::UpdateFieldsNeededForNewItems(DIFFITEM & di, DiffFileInfo & dfi)
{
- DIFFITEM & di = m_pList->GetAt(diffpos);
- if (leftTime)
- di.ltime = leftTime;
- if (rightTime)
- di.rtime = rightTime;
+ // attributes weren't passed, which means reading the file status
+ // so we may as well do them all
+ UpdateInfoFromDiskHalf(di, dfi);
}
+
+/**
+ * @brief Update information from disk
+ */
+void CDiffContext::UpdateInfoFromDisk(DIFFITEM & di)
+{
+ UpdateInfoFromDiskHalf(di, di.left);
+ UpdateInfoFromDiskHalf(di, di.right);
+}
+
+/**
+ * @brief Convert a FILETIME to a long (standard time)
+ */
+static long FileTimeToLong(FILETIME & ft)
+{
+ return CTime(ft).GetTime();
+}
+
+/**
+ * @brief Update information from disk (for one side)
+ */
+void CDiffContext::UpdateInfoFromDiskHalf(DIFFITEM & di, DiffFileInfo & dfi)
+{
+ UpdateVersion(di, dfi);
+
+ CString filepath = paths_ConcatPath(dfi.spath, di.sfilename);
+
+ // CFileFind doesn't expose the attributes
+ // CFileStatus doesn't expose 64 bit size
+
+ WIN32_FIND_DATA wfd;
+ HANDLE h = FindFirstFile(filepath, &wfd);
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ dfi.mtime = FileTimeToLong(wfd.ftLastWriteTime);
+ dfi.flags.reset();
+ if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
+ dfi.flags.flags += FileFlags::RO;
+ dfi.size = (wfd.nFileSizeHigh << 32) + wfd.nFileSizeLow;
+ FindClose(h);
+ }
+ else
+ {
+ dfi.mtime = 0;
+ dfi.size = 0;
+ dfi.flags.reset();
+ }
+}
+
+/**
+ * @brief Load file versions from disk
+ */
+void CDiffContext::UpdateVersion(DIFFITEM & di, DiffFileInfo & dfi)
+{
+ // Would be better to not check any text files
+ // but binary files are flagged as FILE_SAME not FILE_BINSAME
+ // when this is called (Perry 2003-08-21)
+ // and we also didn't flag binary for uniques
+ if (1)
+ {
+ CString filepath = paths_ConcatPath(dfi.spath, di.sfilename);
+ dfi.version = GetFixedFileVersion(filepath);
+ }
+}
+
+CString DIFFITEM::getLeftFilepath() const
+{
+ return paths_ConcatPath(left.spath, sfilename);
+}
+
+CString DIFFITEM::getRightFilepath() const
+{
+ return paths_ConcatPath(right.spath, sfilename);
+}
+
-// DiffContext.h: interface for the CDiffContext class.
-//
-//////////////////////////////////////////////////////////////////////
+/**
+ * @file DiffContext.h
+ *
+ * @brief Declarations of CDiffContext and diff structures
+ */
+// RCS ID line follows -- this is updated by CVS
+// $Id$
#if !defined(AFX_DIFFCONTEXT_H__D3CC86BE_F11E_11D2_826C_00A024706EDC__INCLUDED_)
#define AFX_DIFFCONTEXT_H__D3CC86BE_F11E_11D2_826C_00A024706EDC__INCLUDED_
-
-#if _MSC_VER > 1000
#pragma once
-#endif // _MSC_VER > 1000
#include "RegExp.h"
#define FILE_SKIP 9
#define FILE_DIRSKIP 10
+struct FileFlags
+{
+ int flags;
+ FileFlags() : flags(0) { }
+ void reset() { flags = 0; }
+ CString toString() const { return flags ? _T("RO") : _T(""); }
+
+ enum { RO=1 };
+};
+
+struct DIFFITEM;
+
+/**
+ * @brief information for file on one side of a diff
+ */
+struct DiffFileInfo
+{
+ long mtime; /**< time of last modification */
+ long ctime; /**< time of creation */
+ __int64 size; /**< file size in bytes */
+ CString version; /**< string of fixed file version, eg, 1.2.3.4 */
+ CString spath; /**< fully qualified directory of file */
+ FileFlags flags; /**< file attributes */
+ DiffFileInfo() : mtime(0), ctime(0), size(0) { }
+ // We could stash a pointer here to the parent DIFFITEM
+ // but, I ran into trouble with, I think, the DIFFITEM copy constructor
+};
+
+/**
+ * @brief information about one diff (including files on both sides)
+ */
struct DIFFITEM
{
+ DiffFileInfo left;
+ DiffFileInfo right;
CString sfilename;
+ CString sSubdir; //*< Common subdirectory from root of comparison */
CString sext;
- CString slpath;
- CString srpath;
- long ltime, rtime;
BYTE code;
- DIFFITEM() : ltime(0), rtime(0), code(FILE_ERROR) { }
+ CString getLeftFilepath() const;
+ CString getRightFilepath() const;
+ DIFFITEM() : code(0) { }
};
// Interface for reporting current file, as diff traverses file tree
void SetRegExp(LPCTSTR pszExp);
// add & remove differences
- void AddDiff(LPCTSTR pszFilename, LPCTSTR pszLeftDir, LPCTSTR pszRightDir, long ltime, long rtime, BYTE code);
+ void AddDiff(LPCTSTR pszFilename, LPCTSTR szSubdir, LPCTSTR pszLeftDir, LPCTSTR pszRightDir
+ , long lmtime, long rmtime, long lctime, long rctime
+ , __int64 lsize, __int64 rsize, BYTE code);
void AddDiff(DIFFITEM di);
void RemoveDiff(POSITION diffpos);
void RemoveAll();
+ void UpdateFieldsNeededForNewItems(DIFFITEM & di, DiffFileInfo & dfi);
+ void UpdateVersion(DIFFITEM & di, DiffFileInfo & dfi);
// to iterate over all differences on list
POSITION GetFirstDiffPosition();
// change an existing difference
void UpdateStatusCode(POSITION diffpos, BYTE status);
-
- void UpdateTimes(POSITION diffpos, long leftTime, long rightTime);
+ void UpdateInfoFromDisk(DIFFITEM & di);
+ void UpdateInfoFromDiskHalf(DIFFITEM & di, DiffFileInfo & dfi);
BOOL m_bRecurse;
CString m_strLeft;
// see Merge.cpp for license (GPLv2+) statement
//
/////////////////////////////////////////////////////////////////////////////
-// DirActions.cpp : implementation file
+/**
+ * @file DirActions.cpp
+ *
+ * @brief Implementation of methods of CDirView that copy/move/delete files
+ */
+// RCS ID line follows -- this is updated by CVS
+// $Id$
+
// It would be nice to make this independent of the UI (CDirView)
// but it needs access to the list of selected items.
// One idea would be to provide an iterator over them.
const CDiffContext * ctxt = GetDiffContext();
const DIFFITEM & di = ctxt->GetDiffAt(diffpos);
- strLeft = paths_ConcatPath(di.slpath, di.sfilename);
- strRight = paths_ConcatPath(di.srpath, di.sfilename);
+ strLeft = di.getLeftFilepath();
+ strRight = di.getRightFilepath();
}
// Open selected file on specified side
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
/////////////////////////////////////////////////////////////////////////////
-// DirDoc.cpp : implementation file
+/**
+ * @file DirDoc.cpp
+ *
+ * @brief Implementation file for CDirDoc
+ *
+ */
+// RCS ID line follows -- this is updated by CVS
+// $Id$
//
#include "stdafx.h"
case FILE_DIFF:
if (mf->m_bShowDiff)
{
- p = _tcsninc(di.slpath, llen);
+ p = _tcsninc(di.getLeftFilepath(), llen);
}
break;
case FILE_BINSAME:
if (mf->m_bShowIdent && mf->m_bShowBinaries)
{
- p = _tcsninc(di.slpath, llen);
+ p = _tcsninc(di.getLeftFilepath(), llen);
}
break;
case FILE_BINDIFF:
if (mf->m_bShowDiff && mf->m_bShowBinaries)
{
- p = _tcsninc(di.slpath, llen);
+ p = _tcsninc(di.getLeftFilepath(), llen);
}
break;
case FILE_LUNIQUE:
|| (mf->m_bShowUniqueRight && rightside))
{
if (di.code==FILE_LUNIQUE || di.code==FILE_LDIRUNIQUE)
- p = _tcsninc(di.slpath, llen);
+ {
+ p = _tcsninc(di.getLeftFilepath(), llen);
+ }
else
- p = _tcsninc(di.srpath, rlen);
+ {
+ p = _tcsninc(di.getRightFilepath(), rlen);
+ }
}
break;
case FILE_SAME:
if (mf->m_bShowIdent)
{
- p = _tcsninc(di.slpath, llen);
+ p = _tcsninc(di.getLeftFilepath(), llen);
}
break;
default: // error
- p = _tcsninc(di.slpath, llen);
+ p = _tcsninc(di.getLeftFilepath(), llen);
break;
}
return p;
void CDirDoc::Redisplay()
{
+m_pDirView->ToDoDeleteThisValidateColumnOrdering();
+
if (m_pCtxt == NULL)
return;
if (p)
{
- int i = m_pDirView->AddNewItem(cnt);
- m_pDirView->SetSubitem(i, DV_NAME, di.sfilename);
- m_pDirView->SetSubitem(i, DV_EXT, di.sext);
- s = _T(".");
- s += p;
- m_pDirView->SetSubitem(i, DV_PATH, s);
- m_pDirView->SetItemKey(i, curdiffpos);
- UpdateItemStatus(i, di);
+ int i = m_pDirView->AddDiffItem(cnt, di, p, curdiffpos);
+ UpdateScreenItemStatus(i, di);
cnt++;
}
}
+m_pDirView->ToDoDeleteThisValidateColumnOrdering();
}
CDirView * CDirDoc::GetMainView()
return mystats.st_mtime;
}
-static void UpdateTimes(DIFFITEM * pdi)
-{
- CString sLeft = (CString)pdi->slpath + _T("\\") + pdi->sfilename;
- pdi->ltime = GetFileModTime(sLeft);
-
- CString sRight = (CString)pdi->srpath + _T("\\") + pdi->sfilename;
- pdi->rtime = GetFileModTime(sRight);
-}
-
-static CString
-TimeString(const time_t * tim)
-{
- if (!tim) return _T("---");
- // _tcsftime does not respect user date customizations from
- // Regional Options/Configuration Regional; COleDateTime::Format does so.
- COleDateTime odt = *tim;
- return odt.Format();
-}
-void CDirDoc::SetItemStatus(UINT nIdx, LPCTSTR szStatus, int image, const time_t * ltime, const time_t * rtime)
-{
- m_pDirView->SetSubitem(nIdx, DV_STATUS, szStatus);
- m_pDirView->SetImage(nIdx, image);
- m_pDirView->SetSubitem(nIdx, DV_LTIME, TimeString(ltime));
- m_pDirView->SetSubitem(nIdx, DV_RTIME, TimeString(rtime));
-}
-
-void CDirDoc::UpdateItemStatus(UINT nIdx)
+/**
+ * @brief Update in-memory diffitem status from disk
+ */
+void CDirDoc::ReloadItemStatus(UINT nIdx)
{
POSITION diffpos = m_pDirView->GetItemKey(nIdx);
DIFFITEM di = m_pCtxt->GetDiffAt(diffpos);
- UpdateTimes(&di); // in case just copied (into existence) or modified
- UpdateItemStatus(nIdx, di);
+ m_pCtxt->UpdateInfoFromDisk(di); // in case just copied (into existence) or modified
+ UpdateScreenItemStatus(nIdx, di);
}
-
-void CDirDoc::UpdateItemStatus(UINT nIdx, DIFFITEM di)
+/**
+ * @brief Push current in-memory diffitem status out to screen for selected item
+ */
+void CDirDoc::UpdateScreenItemStatus(UINT nIdx, DIFFITEM di)
{
- CString s;
- switch (di.code)
- {
- case FILE_DIFF:
- VERIFY(s.LoadString(IDS_FILES_ARE_DIFFERENT));
- SetItemStatus(nIdx, s, FILE_DIFF, &di.ltime, &di.rtime);
- break;
- case FILE_BINDIFF:
- VERIFY(s.LoadString(IDS_BIN_FILES_DIFF));
- SetItemStatus(nIdx, s, FILE_BINDIFF, &di.ltime, &di.rtime);
- break;
- case FILE_BINSAME:
- VERIFY(s.LoadString(IDS_BIN_FILES_SAME));
- SetItemStatus(nIdx, s, FILE_BINSAME, &di.ltime, &di.rtime);
- break;
- case FILE_LUNIQUE:
- case FILE_LDIRUNIQUE:
- AfxFormatString1(s, IDS_ONLY_IN_FMT, di.slpath);
- SetItemStatus(nIdx, s, di.code, &di.ltime, NULL);
- break;
- case FILE_RUNIQUE:
- case FILE_RDIRUNIQUE:
- AfxFormatString1(s, IDS_ONLY_IN_FMT, di.srpath);
- SetItemStatus(nIdx, s, di.code, NULL, &di.rtime);
- break;
- case FILE_SAME:
- VERIFY(s.LoadString(IDS_IDENTICAL));
- SetItemStatus(nIdx, s, FILE_SAME, &di.ltime, &di.rtime);
- break;
- default: // error
- VERIFY(s.LoadString(IDS_CANT_COMPARE_FILES));
- SetItemStatus(nIdx, s, FILE_ERROR, (di.ltime>0 ? &di.ltime : NULL), (di.rtime>0 ? &di.rtime : NULL));
- break;
- }
-}
+ m_pDirView->UpdateDiffItemStatus(nIdx, di);
+}
+
void CDirDoc::InitStatusStrings()
{
return sReturn;
}
-BOOL CDirDoc::UpdateItemStatus(LPCTSTR pathLeft, LPCTSTR pathRight,
- UINT status)
+/**
+ * @brief Find the CDiffContext diffpos of an item from its left & right paths
+ */
+POSITION CDirDoc::FindItemFromPaths(LPCTSTR pathLeft, LPCTSTR pathRight)
{
POSITION pos = m_pCtxt->GetFirstDiffPosition();
POSITION currentPos;
- DIFFITEM current;
- int count = m_pCtxt->GetDiffCount();
- int i = 0;
- BOOL found = FALSE;
CString path1, file1;
SplitFilename(pathLeft, &path1, &file1, 0);
// Filenames must be identical
if (file1 != file2)
- return FALSE;
+ return NULL;
// Get first item
- current = m_pCtxt->GetDiffAt(pos);
+ DIFFITEM current = m_pCtxt->GetDiffAt(pos);
- while (i < count && found == FALSE)
+ int count = m_pCtxt->GetDiffCount();
+ for (int i=0; i < count; ++i)
{
// Save our current pos before getting next
currentPos = pos;
current = m_pCtxt->GetNextDiffPosition(pos);
- // Path can contain (because of difftools?) '/' and '\'
- // so for comparing purposes, convert whole path to use '\'
- current.srpath.Replace('/', '\\');
- current.slpath.Replace('/', '\\');
-
- if (path1 == current.slpath &&
- path2 == current.srpath &&
+ if (path1 == current.getLeftFilepath() &&
+ path2 == current.getRightFilepath() &&
file1 == current.sfilename)
{
- // Right item found!
- // Get index at view, update status to context
- // and tell view to update found item
- int ind = m_pDirView->GetItemIndex((DWORD)currentPos);
- current.code = (BYTE)status;
- m_pCtxt->UpdateStatusCode(currentPos, (BYTE)status);
- UpdateItemStatus(ind, current);
- found = TRUE;
+ return currentPos;
}
- i++;
}
- return found;
+ return NULL;
}
// stash away our view pointer
m_MergeDocs.RemoveAt(pos);
}
-BOOL CDirDoc::UpdateItemTimes(LPCTSTR pathLeft, LPCTSTR pathRight)
-{
- POSITION pos = m_pCtxt->GetFirstDiffPosition();
- POSITION currentPos;
- DIFFITEM current;
- int count = m_pCtxt->GetDiffCount();
- int i = 0;
- BOOL found = FALSE;
-
- CString path1, file1;
- SplitFilename(pathLeft, &path1, &file1, 0);
- CString path2, file2;
- SplitFilename(pathRight, &path2, &file2, 0);
-
- // Filenames must be identical
- if (file1 != file2)
- return FALSE;
-
- // Path can contain (because of difftools?) '/' and '\'
- // so for comparing purposes, convert whole path to use '\\'
- path1.Replace('/', '\\');
- path2.Replace('/', '\\');
-
- // Get first item
- current = m_pCtxt->GetDiffAt(pos);
-
- while (i < count && found == FALSE)
- {
- // Save our current pos before getting next
- currentPos = pos;
- current = m_pCtxt->GetNextDiffPosition( pos );
-
- // Path can contain (because of difftools?) '/' and '\'
- // so for comparing purposes, convert whole path to use '\'
- current.srpath.Replace('/', '\\');
- current.slpath.Replace('/', '\\');
-
- if (path1 == current.slpath &&
- path2 == current.srpath &&
- file1 == current.sfilename)
- {
- // Right item found!
- // Get index at view, update filetimes to context
- // and tell view to update found item
- int ind = m_pDirView->GetItemIndex((DWORD) currentPos);
- UpdateTimes(¤t);
- m_pCtxt->UpdateTimes(currentPos, current.ltime, current.rtime);
- UpdateItemStatus(ind, current);
- found = TRUE;
- }
- i++;
- }
- return found;
-}
-
// Prepare for reuse
// Close all our merge docs (which gives them chance to save)
// This may fail if user cancels a Save dialog
return pMergeDoc;
}
+/**
+ * @brief Item specified has changed on disk (and is now the same if unified==true).
+ */
+void CDirDoc::UpdateChangedItem(LPCTSTR pathLeft, LPCTSTR pathRight, bool unified)
+{
+ POSITION pos = FindItemFromPaths(pathLeft, pathRight);
+ ASSERT(pos);
+ int ind = m_pDirView->GetItemIndex((DWORD)pos);
+
+ // Get index at view, update filetimes to context
+ // and tell view to update found item
+ DIFFITEM current = m_pCtxt->GetDiffAt(pos);
+ m_pCtxt->UpdateInfoFromDisk(current);
+
+ if (unified)
+ {
+ // files have been unified -- that is, they are now identical
+ UINT status = FILE_SAME;
+ m_pCtxt->UpdateStatusCode(pos, (BYTE)status);
+ }
+
+ UpdateScreenItemStatus(ind, current);
+}
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
/////////////////////////////////////////////////////////////////////////////
+/**
+ * @file DirDoc.h
+ *
+ * @brief Declaration file for CDirDoc
+ *
+ */
+// RCS ID line follows -- this is updated by CVS
+// $Id$
+
#if !defined(AFX_DIRDOC_H__0B17B4C1_356F_11D1_95CD_444553540000__INCLUDED_)
#define AFX_DIRDOC_H__0B17B4C1_356F_11D1_95CD_444553540000__INCLUDED_
-
-#if _MSC_VER >= 1000
#pragma once
-#endif // _MSC_VER >= 1000
-// DirDoc.h : header file
-//
+
+
#include "Merge.h" // DirDocFilter theApp
#include "DirView.h"
#include "DiffContext.h"
// Implementation
public:
- BOOL UpdateItemTimes(LPCTSTR pathLeft, LPCTSTR pathRight);
- BOOL UpdateItemStatus( LPCTSTR pathLeft, LPCTSTR pathRight, UINT status );
+ void UpdateChangedItem(LPCTSTR pathLeft, LPCTSTR pathRight, bool unified);
+ POSITION FindItemFromPaths(LPCTSTR pathLeft, LPCTSTR pathRight);
void SetDiffContext(CDiffContext *pCtxt);
void UpdateResources();
void InitStatusStrings();
- void UpdateItemStatus(UINT nIdx);
- void SetItemStatus(UINT nIdx, LPCTSTR szStatus, int image, const time_t * ltime, const time_t * rtime);
+ void ReloadItemStatus(UINT nIdx);
void Redisplay();
void Rescan();
CDiffContext *m_pCtxt;
#endif
protected:
- void UpdateItemStatus(UINT nIdx, DIFFITEM di);
+ void UpdateScreenItemStatus(UINT nIdx, DIFFITEM di);
// Generated message map functions
//{{AFX_MSG(CDirDoc)
-/////////////////////////////////////////////////////////////////////////////
-// DirScan.cpp : implementation file
-//
+/**
+ * @file DirScan.cpp
+ *
+ * @brief Implementation of DirScan and helper functions
+ */
+// RCS ID line follows -- this is updated by CVS
+// $Id$
#include "stdafx.h"
#include "DirScan.h"
static char THIS_FILE[] = __FILE__;
#endif
-// directory or file info
+/**
+ * @brief directory or file info for one row in diff result
+ */
struct fentry
{
CString name;
long mtime;
+ long ctime;
_int64 size;
};
typedef CArray<fentry, fentry&> fentryArray;;
fentry ent;
CTime mtim;
finder.GetLastWriteTime(mtim);
+ CTime ctim;
+ finder.GetCreationTime(ctim);
ent.mtime = mtim.GetTime();
+ ent.ctime = ctim.GetTime();
ent.size = finder.GetLength64();
ent.name = finder.GetFileName();
if (finder.IsDirectory())
static void FilterAdd(const CString & sDir, const fentry * lent, const fentry * rent, int code, CDiffContext * pCtxt)
{
CString name, leftdir, rightdir;
- long rtime=0, ltime=0;
+ long rmtime=0, lmtime=0, rctime=0, lctime=0;
_int64 lsize=0, rsize=0;
if (lent)
{
leftdir = paths_ConcatPath(pCtxt->m_strNormalizedLeft, sDir);
- ltime = lent->mtime;
+ lmtime = lent->mtime;
+ lctime = lent->ctime;
lsize = lent->size;
name = lent->name;
}
if (rent)
{
rightdir = paths_ConcatPath(pCtxt->m_strNormalizedRight, sDir);
- rtime = rent->mtime;
+ rmtime = rent->mtime;
+ rctime = rent->ctime;
rsize = rent->size;
name = rent->name;
}
gLog.Write(_T("name=<%s>, leftdir=<%s>, rightdir=<%s>, code=%d")
, (LPCTSTR)name, (LPCTSTR)leftdir, (LPCTSTR)rightdir, code);
- pCtxt->AddDiff(name, leftdir, rightdir, ltime, rtime, code);
+ pCtxt->AddDiff(name, sDir, leftdir, rightdir
+ , lmtime, rmtime, lctime, rctime, lsize, rsize, code);
}
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
/////////////////////////////////////////////////////////////////////////////
-// DirView.cpp : implementation file
-//
+/**
+ * @file DirView.cpp
+ *
+ * @brief Main implementation file for CDirView
+ */
+// RCS ID line follows -- this is updated by CVS
// $Id$
#include "stdafx.h"
CDirView::CDirView()
: m_numcols(-1)
+, m_dispcols(-1)
+, m_bSortAscending(true)
+, m_pHeaderPopup(NULL)
{
m_pList = NULL;
}
ON_UPDATE_COMMAND_UI(ID_REFRESH, OnUpdateRefresh)
ON_WM_TIMER()
ON_WM_MOUSEMOVE()
+ ON_COMMAND(ID_EDIT_COLUMNS, OnEditColumns)
//}}AFX_MSG_MAP
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnClick)
ON_NOTIFY_REFLECT(LVN_GETINFOTIP, OnInfoTip)
void CDirView::OnDraw(CDC* /*pDC*/)
{
- CDocument* pDoc = GetDocument();
- // TODO: add draw code here
+ // This is a CListView, so it is wrapped around a Windows common control
+ // which does the drawing
}
/////////////////////////////////////////////////////////////////////////////
if (HWND hWnd = ListView_GetHeader(m_pList->m_hWnd))
m_ctlSortHeader.SubclassWindow(hWnd);
- LoadColumnOrders();
- AddColumns();
-
CBitmap bm;
VERIFY (m_imageList.Create (16, 16, ILC_MASK, 0, 1));
VERIFY (bm.LoadBitmap (IDB_LFILE));
bm.Detach();
m_pList->SetImageList (&m_imageList, LVSIL_SMALL);
- UpdateColumnNames();
- SetColumnWidths();
+ LoadColumnOrders();
+
+ ReloadColumns();
//m_ctlSortHeader.SetSortImage(m_sortColumn, m_bSortAscending);
CListViewEx::OnLButtonDblClk(nFlags, point);
}
+/**
+ * @brief Load or reload the columns (headers) of the list view
+ */
+void CDirView::ReloadColumns()
+{
+ LoadColumnHeaderItems();
+ToDoDeleteThisValidateColumnOrdering();
+
+ToDoDeleteThisValidateColumnOrdering();
+ UpdateColumnNames();
+ToDoDeleteThisValidateColumnOrdering();
+ SetColumnWidths();
+ToDoDeleteThisValidateColumnOrdering();
+}
+/**
+ * @brief User right-clicked somewhere in this view
+ */
void CDirView::OnContextMenu(CWnd*, CPoint point)
{
- // CG: This block was added by the Pop-up Menu component
+ if (!GetListCtrl().GetItemCount())
+ return;
+ int i=0;
+ if (point.x == -1 && point.y == -1)
{
- if (point.x == -1 && point.y == -1){
- //keystroke invocation
- CRect rect;
- GetClientRect(rect);
- ClientToScreen(rect);
-
- point = rect.TopLeft();
- point.Offset(5, 5);
+ //keystroke invocation
+ CRect rect;
+ GetClientRect(rect);
+ ClientToScreen(rect);
+
+ point = rect.TopLeft();
+ point.Offset(5, 5);
+ } else {
+ // Check if user right-clicked on header
+ // convert screen coordinates to client coordinates of listview
+ CPoint insidePt = point;
+ GetListCtrl().ScreenToClient(&insidePt);
+ // TODO: correct for hscroll ?
+ // Ask header control if click was on one of its header items
+ HDHITTESTINFO hhti;
+ memset(&hhti, 0, sizeof(hhti));
+ hhti.pt = insidePt;
+ int col = GetListCtrl().GetHeaderCtrl()->SendMessage(HDM_HITTEST, 0, (LPARAM)&hhti);
+ if (col >= 0)
+ {
+ // Presumably hhti.flags & HHT_ONHEADER is true
+ HeaderContextMenu(point, ColPhysToLog(col));
+ return;
}
+ // bail out if point is not in any row
+ LVHITTESTINFO lhti;
+ memset(&lhti, 0, sizeof(lhti));
+ insidePt = point;
+ ScreenToClient(&insidePt);
+ lhti.pt = insidePt;
+ i = GetListCtrl().HitTest(insidePt);
+ TRACE("i=%d\n", i);
+ if (i<0)
+ return;
+ }
+
+ ListContextMenu(point, i);
+}
- CMenu menu;
- VERIFY(menu.LoadMenu(IDR_POPUP_DIRVIEW));
+/**
+ * @brief Return nearest ancestor which is not a child window
+ */
+static CWnd * GetNonChildAncestor(CWnd * w)
+{
+ CWnd* parent = w;
+ while (parent->GetStyle() & WS_CHILD)
+ parent = parent->GetParent();
+ return parent;
+}
- CMenu* pPopup = menu.GetSubMenu(0);
- ASSERT(pPopup != NULL);
+/**
+ * @brief User right-clicked in listview rows
+ */
+void CDirView::ListContextMenu(CPoint point, int /*i*/)
+{
+ CMenu menu;
+ VERIFY(menu.LoadMenu(IDR_POPUP_DIRVIEW));
- // set the menu items with the proper directory names
- CString sl, sr;
- GetSelectedDirNames(sl, sr);
+ // 1st submenu of IDR_POPUP_DIRVIEW is for header popup
+ CMenu* pPopup = menu.GetSubMenu(0);
+ ASSERT(pPopup != NULL);
- // find non-child ancestor to use as menu parent
- CWnd* pWndPopupOwner = this;
- while (pWndPopupOwner->GetStyle() & WS_CHILD)
- pWndPopupOwner = pWndPopupOwner->GetParent();
+ // set the menu items with the proper directory names
+ CString sl, sr;
+ GetSelectedDirNames(sl, sr);
- // TODO: It would be more efficient to set
- // all the popup items now with one traverse over selected items
- // instead of using updates, in which we make a traverse for every item
- // Perry, 2002-12-04
- //
+ // find non-child ancestor to use as menu parent
+ CWnd * pWndPopupOwner = GetNonChildAncestor(this);
+ // TODO: It would be more efficient to set
+ // all the popup items now with one traverse over selected items
+ // instead of using updates, in which we make a traverse for every item
+ // Perry, 2002-12-04
- // 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);
- }
+ // 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);
}
+/**
+ * @brief User right-clicked on specified logical column
+ */
+void CDirView::HeaderContextMenu(CPoint point, int /*i*/)
+{
+ToDoDeleteThisValidateColumnOrdering();
+ CMenu menu;
+ VERIFY(menu.LoadMenu(IDR_POPUP_DIRVIEW));
+
+ // 2nd submenu of IDR_POPUP_DIRVIEW is for header popup
+ CMenu* pPopup = menu.GetSubMenu(1);
+ ASSERT(pPopup != NULL);
+
+ // find non-child ancestor to use as menu parent
+ CWnd * pWndPopupOwner = GetNonChildAncestor(this);
+
+ // 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);
+
+}
+
// Make a string out of a number
// TODO: Ought to introduce commas every three digits, except this is locale-specific
// How to do this with locale sensitivity ?
}
-// User chose (main menu) Copy from right to left
-void CDirView::OnDirCopyFileToLeft()
+/**
+ * @brief User chose (main menu) Copy from right to left
+ */
+void CDirView::OnDirCopyFileToLeft()
{
DoCopyFileToLeft();
}
-// User chose (main menu) Copy from left to right
-void CDirView::OnDirCopyFileToRight()
+/**
+ * @brief User chose (main menu) Copy from left to right
+ */
+void CDirView::OnDirCopyFileToRight()
{
DoCopyFileToRight();
}
}
}
-/// Assign column name, using string resource & current column ordering
-void CDirView::NameColumn(int id, int subitem)
-{
- CString s;
- VERIFY(s.LoadString(id));
- LV_COLUMN lvc;
- lvc.mask = LVCF_TEXT;
- lvc.pszText = (LPTSTR)((LPCTSTR)s);
- m_pList->SetColumn(m_colorder[subitem], &lvc);
-}
-
-/// Load column names from string table
-void CDirView::UpdateColumnNames()
-{
- NameColumn(IDS_FILENAME_HEADER, DV_NAME);
- NameColumn(IDS_EXTENSION_HEADER, DV_EXT);
- NameColumn(IDS_DIR_HEADER, DV_PATH);
- NameColumn(IDS_RESULT_HEADER, DV_STATUS);
- NameColumn(IDS_LTIME_HEADER, DV_LTIME);
- NameColumn(IDS_RTIME_HEADER, DV_RTIME);
-}
-
-/// Update any language-dependent data
+/**
+ * @brief Update any language-dependent data
+ */
void CDirView::UpdateResources()
{
UpdateColumnNames();
}
-/// Compare two specified rows during a sort operation (windows callback)
-int CALLBACK CDirView::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
-{
- // initialize structures to obtain required information
- CDirView* pView = reinterpret_cast<CDirView*>(lParamSort);
- POSITION diffposl = pView->GetItemKeyFromData(lParam1);
- POSITION diffposr = pView->GetItemKeyFromData(lParam2);
- DIFFITEM lDi = pView->GetDiffContext()->GetDiffAt(diffposl);
- DIFFITEM rDi = pView->GetDiffContext()->GetDiffAt(diffposr);
-
- // compare 'left' and 'right' parameters as appropriate
- int retVal = 0; // initialize for default case
- switch (pView->m_sortColumn)
- {
- case DV_NAME: // File name.
- retVal = lDi.sfilename.CompareNoCase(rDi.sfilename);
- break;
- case DV_PATH: // File Path.
- retVal = lDi.slpath.CompareNoCase(rDi.slpath);
- break;
- case DV_STATUS: // Diff Status.
- retVal = rDi.code-lDi.code;
- break;
- case DV_LTIME: // Time of left item
- retVal = rDi.ltime-lDi.ltime;
- break;
- case DV_RTIME: // Time of right item
- retVal = rDi.rtime-lDi.rtime;
- break;
- case DV_EXT: // File extension.
- retVal = lDi.sext.CompareNoCase(rDi.sext);
- break;
- }
- // return compare result, considering sort direction
- return (pView->m_bSortAscending)?retVal:-retVal;
-}
-
void CDirView::OnColumnClick(NMHDR *pNMHDR, LRESULT *pResult)
{
// set sort parameters and handle ascending/descending
else
{
m_sortColumn = sortcol;
- // date columns get default descending sort.
- if(m_sortColumn==DV_LTIME || m_sortColumn==DV_RTIME)
- {
- m_bSortAscending = false;
- }
- else
- {
- m_bSortAscending = true;
- }
+ // most columns start off ascending, but not dates
+ m_bSortAscending = IsDefaultSortAscending(m_sortColumn);
}
m_ctlSortHeader.SetSortImage(m_sortColumn, m_bSortAscending);
{
DeleteAllDisplayItems();
+ ValidateColumnOrdering();
SaveColumnOrders();
SaveColumnWidths();
if (mf->m_bScrollToFirst)
OnFirstdiff();
}
-// Add new item to list view
-int CDirView::AddNewItem(int i)
-{
- LV_ITEM lvItem;
- memset(&lvItem, 0, sizeof(lvItem));
- lvItem.iItem = i;
- return GetListCtrl().InsertItem(&lvItem);
-
-}
-
-// Set a subitem on an existing item
-void CDirView::SetSubitem(int item, int subitem, LPCTSTR sz)
-{
- LV_ITEM lvItem;
- memset(&lvItem, 0, sizeof(lvItem));
- lvItem.mask = LVIF_TEXT;
- lvItem.iItem = item;
- lvItem.iSubItem = m_colorder[subitem];
- lvItem.pszText = const_cast<LPTSTR>(sz);
- GetListCtrl().SetItem(&lvItem);
-}
BOOL CDirView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
return CListViewEx::OnNotify(wParam, lParam, pResult);
}
-/// User is starting to drag a column header
+/**
+ * @brief User is starting to drag a column header
+ */
BOOL CDirView::OnHeaderBeginDrag(LPNMHEADER hdr, LRESULT* pResult)
{
// save column widths before user reorders them
return TRUE;
}
-/// User just finished dragging a column header
+/**
+ * @brief User just finished dragging a column header
+ */
BOOL CDirView::OnHeaderEndDrag(LPNMHEADER hdr, LRESULT* pResult)
{
int src = hdr->iItem;
*pResult = !allowDrop;
if (allowDrop && src!=dest)
{
- // actually moved column
- m_colorder[m_invcolorder[src]] = dest;
- // shift all other affected columns
- int dir = src > dest ? +1 : -1;
- for (int i=dest; i!=src; i += dir)
- {
- m_colorder[m_invcolorder[i]] = i+dir;
- }
- // fix inverse mapping
- for (i=0; i<m_numcols; ++i)
- m_invcolorder[m_colorder[i]] = i;
- PostMessage(WM_TIMER, COLUMN_REORDER);
+ MoveColumn(src, dest);
}
return TRUE;
}
-/// Remove any windows reordering of columns
+/**
+ * @brief Remove any windows reordering of columns
+ */
void CDirView::FixReordering()
{
LVCOLUMN lvcol;
}
}
-/// Add columns to display, loading width & order from registry
-void CDirView::AddColumns()
-{
- for (int i=0; i<m_numcols; ++i)
- {
- int ix = m_invcolorder[i];
- CString sOrderKey;
- sOrderKey.Format(_T("WDirHdrOrder%d"), ix);
- int ord = theApp.GetProfileInt(_T("DirView"), sOrderKey, ix);
- LVCOLUMN lvcol;
- memset(&lvcol, 0, sizeof(lvcol));
- lvcol.mask = LVCF_FMT+LVCF_TEXT+LVCF_SUBITEM;
- lvcol.fmt = LVCFMT_LEFT;
- lvcol.pszText = _T("text"); // UpdateColumnNames fixes this
- lvcol.iSubItem = ix;
- m_pList->InsertColumn(i, &lvcol);
- }
-}
-
-/// Update all column widths (from registry to screen)
-// Necessary when user reorders columns
-void CDirView::SetColumnWidths()
+/** @brief Add columns to display, loading width & order from registry. */
+void CDirView::LoadColumnHeaderItems()
{
- LVCOLUMN lvcol;
- memset(&lvcol, 0, sizeof(lvcol));
- lvcol.mask = LVCF_WIDTH;
- CString sWidthKey;
- int cols = GetListCtrl().GetHeaderCtrl()->GetItemCount();
- int i;
+ bool dummyflag = false;
- for (i=0; i<cols; ++i)
+ CHeaderCtrl * h = m_pList->GetHeaderCtrl();
+ if (h->GetItemCount())
{
- sWidthKey.Format(_T("WDirHdr%d"), i);
- int w = max(10, theApp.GetProfileInt(_T("DirView"), sWidthKey, 150));
- GetListCtrl().SetColumnWidth(m_colorder[i], w);
+ dummyflag = true;
+ while (m_pList->GetHeaderCtrl()->GetItemCount()>1)
+ m_pList->DeleteColumn(1);
}
-}
-
-/// store current column widths into registry
-void CDirView::SaveColumnWidths()
-{
- int cols = GetListCtrl().GetHeaderCtrl()->GetItemCount();
- for (int i=0; i < cols; i++)
+ for (int i=0; i<m_dispcols; ++i)
{
- CString s;
- s.Format(_T("WDirHdr%d"), m_invcolorder[i]);
- int w = GetListCtrl().GetColumnWidth(i);
- theApp.WriteProfileInt(_T("DirView"), s, w);
+ LVCOLUMN lvc;
+ memset(&lvc, 0, sizeof(lvc));
+ lvc.mask = LVCF_FMT+LVCF_SUBITEM+LVCF_TEXT;
+ lvc.fmt = LVCFMT_LEFT;
+ lvc.pszText = _T("text");
+ lvc.iSubItem = i;
+ m_pList->InsertColumn(i, &lvc);
}
-}
+ if (dummyflag)
+ m_pList->DeleteColumn(1);
-/// store current column orders into registry
-void CDirView::SaveColumnOrders()
-{
- ASSERT(m_colorder.GetSize() == m_numcols);
- ASSERT(m_invcolorder.GetSize() == m_numcols);
- int cols = GetListCtrl().GetHeaderCtrl()->GetItemCount();
- for (int i=0; i < cols; i++)
- {
- CString key;
- key.Format(_T("WDirHdrOrder%d"), i);
- int ord = m_colorder[i];
- theApp.WriteProfileInt(_T("DirView"), key, ord);
- }
}
-/// load column orders from registry
-void CDirView::LoadColumnOrders()
+/// Update all column widths (from registry to screen)
+// Necessary when user reorders columns
+void CDirView::SetColumnWidths()
{
- ASSERT(m_numcols == -1);
- m_numcols = 6;
- m_colorder.SetSize(m_numcols);
- m_invcolorder.SetSize(m_numcols);
for (int i=0; i<m_numcols; ++i)
{
- m_colorder[i] = -1;
- m_invcolorder[i] = -1;
- }
-
- for (i=0; i<6; ++i)
- {
- CString key;
- key.Format(_T("WDirHdrOrder%d"), i);
- int ord = theApp.GetProfileInt(_T("DirView"), key, i);
- m_colorder[i] = ord;
- m_invcolorder[ord] = i;
- }
- // validate just loaded data
- BOOL valid=TRUE;
- for (i=0; i<m_numcols; ++i)
- {
- if (!(m_colorder[i]>=0 && m_colorder[i]<m_numcols))
- {
- valid=FALSE;
- break;
- }
- if (!(m_invcolorder[i]>=0 && m_invcolorder[i]<m_numcols))
+ int phy = ColLogToPhys(i);
+ if (phy >= 0)
{
- valid=FALSE;
- break;
+ CString sWidthKey = GetColRegValueNameBase(i) + _T("_Width");
+ int w = max(10, theApp.GetProfileInt(_T("DirView"), sWidthKey, 150));
+ GetListCtrl().SetColumnWidth(m_colorder[i], w);
}
}
- if (!valid)
+}
+
+/** @brief store current column widths into registry */
+void CDirView::SaveColumnWidths()
+{
+ for (int i=0; i < m_numcols; i++)
{
- // reset to identity
- for (int i=0; i<m_numcols; ++i)
+ int phy = ColLogToPhys(i);
+ if (phy >= 0)
{
- m_colorder[i] = i;
- m_invcolorder[i] = i;
+ CString sWidthKey = GetColRegValueNameBase(i) + _T("_Width");
+ int w = GetListCtrl().GetColumnWidth(phy);
+ theApp.WriteProfileInt(_T("DirView"), sWidthKey, w);
}
}
}
+/** @brief Fire off a resort of the data, to take place when things stabilize. */
+void CDirView::InitiateSort()
+{
+ PostMessage(WM_TIMER, COLUMN_REORDER);
+}
+
void CDirView::OnTimer(UINT nIDEvent)
{
if (nIDEvent == COLUMN_REORDER)
{
// Set text color based on timestamps
// Do not color unique items
- if (ditem.ltime == 0 || ditem.rtime == 0)
+ if (ditem.left.mtime == 0 || ditem.right.mtime == 0)
lplvcd->clrText = GetSysColor(COLOR_WINDOWTEXT);
else
{
- if (ditem.ltime < ditem.rtime)
+ if (ditem.left.mtime < ditem.right.mtime)
lplvcd->clrText = RGB(53, 164, 34);
- else if (ditem.ltime > ditem.rtime)
+ else if (ditem.left.mtime > ditem.right.mtime)
lplvcd->clrText = RGB(234, 21, 64);
else
// Make sure we use default color for ident. items
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
/////////////////////////////////////////////////////////////////////////////
+/**
+ * @file DirView.h
+ *
+ * @brief Declaration of class CDirView
+ */
//
+// RCS ID line follows -- this is updated by CVS
// $Id$
#if !defined(AFX_DirView_H__16E7C721_351C_11D1_95CD_444553540000__INCLUDED_)
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
-// DirView.h : header file
-//
+// TODO delete
+/*
#define DV_NAME 0
#define DV_PATH 1
#define DV_STATUS 2
#define DV_LTIME 3
#define DV_RTIME 4
#define DV_EXT 5
+*/
+
/////////////////////////////////////////////////////////////////////////////
// CDirView view
class CDirDoc;
class CDirFrame;
+/** View displaying results of a diff, one row per file */
class CDirView : public CListViewEx
{
protected:
public:
CDirFrame * GetParentFrame();
- static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
+
void UpdateResources();
- void UpdateColumnNames();
- void AddColumns();
+ void LoadColumnHeaderItems();
POSITION GetItemKey(int idx) const;
void SetItemKey(int idx, POSITION diffpos);
int GetItemIndex(DWORD key);
// for populating list
void DeleteAllDisplayItems();
void SetColumnWidths();
- int AddNewItem(int i);
- void SetSubitem(int item, int subitem, LPCTSTR sz);
UINT GetSelectedCount() const;
int GetFirstSelectedInd();
void PerformAndRemoveTopAction(ActionList & actions);
// End DirActions.cpp
+// Implementation in DirViewCols.cpp
+public:
+ void UpdateColumnNames();
+ static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
+ int AddDiffItem(int index, const DIFFITEM & di, LPCTSTR szPath, POSITION curdiffpos);
+ void UpdateDiffItemStatus(UINT nIdx, const DIFFITEM & di);
+ void ToDoDeleteThisValidateColumnOrdering() { ValidateColumnOrdering(); }
+private:
+ void InitiateSort();
+ void NameColumn(int id, int subitem);
+ int AddNewItem(int i);
+ void SetSubitem(int item, int phy, LPCTSTR sz);
+ bool IsDefaultSortAscending(int col) const;
+ int ColPhysToLog(int i) const { return m_invcolorder[i]; }
+ int ColLogToPhys(int i) const { return m_colorder[i]; } /**< -1 if not displayed */
+ CString GetColDisplayName(int col) const;
+ int GetColLogCount() const;
+ void LoadColumnOrders();
+ void ValidateColumnOrdering();
+ void ClearColumnOrders();
+ void ResetColumnOrdering();
+ void MoveColumn(int psrc, int pdest);
+ CString GetColRegValueNameBase(int col) const;
+ int GetColDefaultOrder(int col) const;
+// End DirViewCols.cpp
// Overrides
// ClassWizard generated virtual function overrides
// Implementation data
protected:
- CSortHeaderCtrl m_ctlSortHeader;
+ CSortHeaderCtrl m_ctlSortHeader;
CImageList m_imageList;
- bool m_bSortAscending; // is currently sorted ascending.
- int m_sortColumn; // index to column which is sorted
+ bool m_bSortAscending; /** < current column sort is ascending ? */
+ int m_sortColumn; /**< index of column currently used for sorting */
CListCtrl * m_pList;
int m_numcols;
- CArray<int, int> m_colorder;
- CArray<int, int> m_invcolorder;
+ int m_dispcols;
+ CArray<int, int> m_colorder; /**< colorder[logical#]=physical# */
+ CArray<int, int> m_invcolorder; /**< invcolorder[physical]=logical# */
CPoint m_ptLastMousePos;
+ CMenu * m_pHeaderPopup;
// Generated message map functions
afx_msg void OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnUpdateRefresh(CCmdUI* pCmdUI);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+ afx_msg void OnEditColumns();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
BOOL OnHeaderBeginDrag(LPNMHEADER hdr, LRESULT* pResult);
void MoveSelection(int currentInd, int i, int selCount);
void SaveColumnWidths();
void SaveColumnOrders();
- void LoadColumnOrders();
- void NameColumn(int id, int subitem);
void FixReordering();
+ void HeaderContextMenu(CPoint point, int i);
+ void ListContextMenu(CPoint point, int i);
+ void ReloadColumns();
};
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
/////////////////////////////////////////////////////////////////////////////
-// MainFrm.cpp : implementation of the CMainFrame class
-//
+/**
+ * @file MainFrm.cpp
+ *
+ * @brief Implementation of the CMainFrame class
+ */
+// RCS ID line follows -- this is updated by CVS
// $Id$
#include "stdafx.h"
// update DIFFITEM code
pDirDoc->m_pCtxt->UpdateStatusCode(diffpos, (BYTE)nStatus);
// update DIFFITEM time, and also tell views
- pDirDoc->UpdateItemStatus(idx);
+ pDirDoc->ReloadItemStatus(idx);
//m_pDirDoc->Redisplay();
}
# End Source File
# Begin Source File
+SOURCE=.\DirColsDlg.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\DirDoc.cpp
!IF "$(CFG)" == "Merge - Win32 Release"
# End Source File
# Begin Source File
+SOURCE=.\DirViewColHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DirViewColItems.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\dllver.cpp
# End Source File
# Begin Source File
# End Source File
# Begin Source File
+SOURCE=.\DirColsDlg.h
+# End Source File
+# Begin Source File
+
SOURCE=.\DirDoc.h
# End Source File
# Begin Source File
# End Source File
# Begin Source File
+SOURCE=.\DirViewColItems.h
+# End Source File
+# Begin Source File
+
SOURCE=.\dllver.h
# End Source File
# Begin Source File
IDR_POPUP_DIRVIEW MENU DISCARDABLE
BEGIN
- POPUP "_POPUP_"
+ POPUP "_ITEM_POPUP_"
BEGIN
MENUITEM "Copy file to left", ID_DIR_COPY_FILE_TO_LEFT
MENUITEM "Copy file to right", ID_DIR_COPY_FILE_TO_RIGHT
MENUITEM "Open right", ID_DIR_OPEN_RIGHT
MENUITEM "Open right with...", ID_DIR_OPEN_RIGHT_WITH
END
+ POPUP "_HDR_POPUP_"
+ BEGIN
+ MENUITEM "Edit columns", ID_EDIT_COLUMNS
+ END
END
IDR_POPUP_EDITOR_HEADERBAR MENU DISCARDABLE
WS_TABSTOP,WS_EX_STATICEDGE
END
+IDD_DIRCOLS DIALOG DISCARDABLE 0, 0, 273, 162
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Display Columns"
+FONT 8, "MS Sans Serif"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,141,129,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,81,129,50,14
+ GROUPBOX "Show columns",IDC_GROUP_SHOW,7,17,124,100
+ LISTBOX IDC_LIST_SHOW,42,31,83,79,LBS_NOINTEGRALHEIGHT |
+ LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "&Up",IDC_UP,13,43,23,13
+ PUSHBUTTON "&Down",IDC_DOWN,13,67,23,13
+ GROUPBOX "Hide columns",IDC_GROUP_HIDE,181,17,85,103
+ LISTBOX IDC_LIST_HIDE,192,31,66,79,LBS_NOINTEGRALHEIGHT |
+ LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "<==",IDC_ADD,141,41,29,11
+ PUSHBUTTON "==>",IDC_REMOVE,141,76,29,11
+END
+
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
TOPMARGIN, 7
BOTTOMMARGIN, 4
END
+
+ IDD_DIRCOLS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 266
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 155
+ END
END
#endif // APSTUDIO_INVOKED
STRINGTABLE DISCARDABLE
BEGIN
- IDS_FILENAME_HEADER "Filename"
- IDS_DIR_HEADER "Directory"
- IDS_RESULT_HEADER "Comparison result"
+ IDS_COLHDR_FILENAME "Filename"
+ IDS_COLHDR_DIR "Directory"
+ IDS_COLHDR_RESULT "Comparison result"
IDS_FILE_COMPARISON_TITLE "File Comparison"
IDS_DIFF_NUMBER_STATUS_FMT "Difference %1 of %2"
IDS_NO_DIFF_SEL_FMT "%1 Differences Found"
IDS_VSS_RUN_ERROR "Error executing versioning system command."
IDS_DIFF_OPEN_NO_SET_PROPS
"Modifications have been made to the current file comparison session. Some settings may not take place until the current file comparison is restarted."
- IDS_LTIME_HEADER "Left Date"
- IDS_RTIME_HEADER "Right Date"
- IDS_EXTENSION_HEADER "Extension"
+ IDS_COLHDR_LTIMEM "Left Date"
+ IDS_COLHDR_RTIMEM "Right Date"
+ IDS_COLHDR_EXTENSION "Extension"
IDS_CONFIRM_DELETE_ITEMS
"Are you sure you want to delete %1 of %2 selected item(s) ?"
IDS_DEL_LEFT_FMT "Delete left side %1 of %2 selected item(s)"
IDS_STATUS_COPYALL2L "Copying All to Left"
IDS_STATUS_COPYALL2R "Copying All to Right"
IDS_PROGRAMFILES "Programs|*.exe;*.bat;*.cmd|All Files (*.*)|*.*||"
+ IDS_COLHDR_RSIZE "Right Size"
+ IDS_COLHDR_LTIMEC "Left Creation Time"
+ IDS_COLHDR_RTIMEC "Right Creation Time"
+ IDS_COLHDR_NEWER "Newer File"
+ IDS_COLHDR_LVERSION "Left File Version"
+ IDS_COLHDR_RVERSION "Right File Version"
END
STRINGTABLE DISCARDABLE
IDC_STATIC_TITLE_RIGHT "Right click on the path to copy"
END
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_LEFTONLY "Left Only"
+ IDS_RIGHTONLY "Right Only"
+ IDS_COLHDR_RESULT_ABBR "Short Result"
+ IDS_COLHDR_LATTRIBUTES "Left Attributes"
+ IDS_COLHDR_RATTRIBUTES "Right Attributes"
+ IDS_COLHDR_LSIZE "Left Size"
+END
+
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
// If DirDoc contains diffs
if (m_pDirDoc->m_pCtxt)
{
- m_pDirDoc->UpdateItemTimes(m_strLeftFile,
- m_strRightFile);
- if (m_nDiffs == 0)
- m_pDirDoc->UpdateItemStatus(m_strLeftFile,
- m_strRightFile, FILE_SAME);
+ bool unified = (m_nDiffs==0); // true if status should be set to identical
+ m_pDirDoc->UpdateChangedItem(m_strLeftFile, m_strRightFile, unified);
}
}
}
// If DirDoc contains diffs
if (m_pDirDoc->m_pCtxt)
{
- m_pDirDoc->UpdateItemTimes(m_strLeftFile, m_strRightFile);
- if (m_nDiffs == 0)
- m_pDirDoc->UpdateItemStatus(m_strLeftFile,
- m_strRightFile, FILE_SAME);
+ bool unified = (m_nDiffs==0); // true if status should be set to identical
+ m_pDirDoc->UpdateChangedItem(m_strLeftFile, m_strRightFile, unified);
}
}
return result;
WinMerge\Merge.rc
Correction#1 værktøylinje(n)->verktøylinje(n)
Languages\Norwegian: MergeNorwegian.rc
+ PATCH: [ 781529 ] Make column info array, and add new columns
+ common: version.cpp version.h
+ WinMerge: DiffContext.cpp DiffContext.h DirActions.cpp DirDoc.cpp DirDoc.h
+ DirScan.cpp DirView.cpp DirView.h MainFrm.cpp Merge.dsp Merge.rc
+ MergeDoc.cpp resource.h
+ WinMerge new files: DirColsDlg.cpp DirColsDlg.h DirViewColHandler.cpp
+ DirViewColItems.cpp DirViewColItems.h
2003-08-22 Kimmo
PATCH: [ 787495 ] Create diffutils class (CDiffWrapper)
#define IDD_PROPPAGE_REGISTRY 113
#define IDD_EDITOR_HEADERBAR 114
#define IDR_POPUP_EDITOR_HEADERBAR 115
+#define IDD_DIRCOLS 117
#define IDS_VERSION_FMT 130
#define IDS_ALLFILES 131
#define IDS_CONFIRM_ALL_LEFT 132
#define IDS_SAVEVSS_FMT 157
#define IDS_VSSERROR 158
#define IDS_NOPROJECT 159
-#define IDS_FILENAME_HEADER 160
-#define IDS_DIR_HEADER 161
-#define IDS_RESULT_HEADER 162
+#define IDS_COLHDR_FILENAME 160
+#define IDS_COLHDR_DIR 161
+#define IDS_COLHDR_RESULT 162
#define IDS_FILE_COMPARISON_TITLE 163
#define IDS_DIFF_NUMBER_STATUS_FMT 164
#define IDS_NO_DIFF_SEL 165
#define IDS_VSS_CMD 168
#define IDS_VSS_RUN_ERROR 169
#define IDS_DIFF_OPEN_NO_SET_PROPS 170
-#define IDS_LTIME_HEADER 171
-#define IDS_RTIME_HEADER 172
-#define IDS_EXTENSION_HEADER 173
+#define IDS_COLHDR_LTIMEM 171
+#define IDS_COLHDR_RTIMEM 172
+#define IDS_COLHDR_EXTENSION 173
#define IDS_CONFIRM_DELETE_ITEMS 174
#define IDS_DEL_LEFT_FMT 175
#define IDS_DEL_RIGHT_FMT 176
#define IDS_DEL_BOTH_FMT 181
#define IDS_COPY_TO_RIGHT 182
#define IDS_COPY_TO_RIGHT_MAIN 183
+#define IDS_COLHDR_LSIZE 183
#define IDS_DELETE_DIR_FAILED 184
#define IDS_COPY_FILE_FAILED 185
#define IDS_COPY_DIR_FAILED 186
#define IDS_STATUS_COPYALL2L 199
#define IDS_STATUS_COPYALL2R 200
#define IDS_PROGRAMFILES 201
+#define IDS_COLHDR_RSIZE 202
+#define IDS_COLHDR_LTIMEC 203
+#define IDS_COLHDR_RTIMEC 204
+#define IDS_COLHDR_NEWER 205
+#define IDS_COLHDR_LVERSION 206
+#define IDS_COLHDR_RVERSION 207
+#define IDS_LEFTONLY 208
+#define IDS_RIGHTONLY 209
+#define IDS_COLHDR_RESULT_ABBR 210
+#define IDS_COLHDR_LATTRIBUTES 211
+#define IDS_COLHDR_RATTRIBUTES 212
#define IDB_EQUAL 213
#define IDB_NOTEQUAL 214
#define IDB_RFOLDER 215
#define IDC_WINMERGE_PATH_SAVE 1047
#define IDC_STATIC_TITLE_LEFT 1048
#define IDC_STATIC_TITLE_RIGHT 1049
+#define IDC_GROUP_SHOW 1053
+#define IDC_LIST_SHOW 1054
+#define IDC_UP 1055
+#define IDC_DOWN 1056
+#define IDC_GROUP_HIDE 1057
+#define IDC_LIST_HIDE 1058
+#define IDC_ADD 1059
+#define IDC_REMOVE 1060
#define IDS_NUM_REPLACED 8501
#define IDS_EDIT_TEXT_NOT_FOUND 8502
#define IDS_LINE_STATUS_INFO 8503
#define ID_EDIT_FIND_PREVIOUS 32820
#define ID_SHOWLINEDIFF 32821
#define ID_EDITOR_COPY_PATH 32822
+#define ID_EDIT_COLUMNS 32822
#define ID_EDITOR_COPY_FILENAME 32823
// Next default values for new objects
-//
+//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
-#define _APS_NEXT_RESOURCE_VALUE 116
-#define _APS_NEXT_COMMAND_VALUE 32822
-#define _APS_NEXT_CONTROL_VALUE 1050
+#define _APS_NEXT_RESOURCE_VALUE 118
+#define _APS_NEXT_COMMAND_VALUE 32823
+#define _APS_NEXT_CONTROL_VALUE 1061
#define _APS_NEXT_SYMED_VALUE 108
#endif
#endif