Add new items to top.
(This summarizes all changes to all files under Src, including Src\Languages.)
+2006-04-05 Kimmo
+ PATCH: [ 1460749 ] Print relative paths to patch files
+ Src: DiffWrapper.cpp DiffWrapper.h MainFrm.cpp MergeDoc.cpp PatchDlg.h
+ PatchTool.cpp PatchTool.h
+
2006-04-05 Takashi
BUG: [ 1458714 ] [Replace All] doesn't work
Src/editlib: ceditreplacedlg.cpp
line_end_char = '\n';
}
+/**
+ * @brief Destructor.
+ */
CDiffWrapper::~CDiffWrapper()
{
if (m_infoPrediffer)
}
/**
- * @brief Sets filename of produced patch-file
+ * @brief Sets filename of produced patch-file.
+ * @param [in] file Filename of patch file.
*/
-void CDiffWrapper::SetPatchFile(CString file)
+void CDiffWrapper::SetPatchFile(const CString &file)
{
m_sPatchFile = file;
m_sPatchFile.Replace('/', '\\');
}
/**
- * @brief Sets pointer to external diff-list filled when analysing files
+ * @brief Sets pointer to DiffList getting compare results.
+ * CDiffWrapper adds compare results to DiffList. This function
+ * sets external DiffList which gets compare results.
+ * @param [in] difflist Pointer to DiffList getting compare results.
*/
void CDiffWrapper::SetDiffList(DiffList *diffList)
{
}
/**
- * @brief Returns current set of options used by diff-engine
+ * @brief Returns current set of options used by diff-engine.
+ * This function converts internally used diff-options to
+ * format used outside CDiffWrapper and returns them.
+ * @param [in,out] options Pointer to structure getting used options.
*/
-void CDiffWrapper::GetOptions(DIFFOPTIONS *options)
+void CDiffWrapper::GetOptions(DIFFOPTIONS *options) const
{
ASSERT(options);
InternalGetOptions(options);
}
/**
- * @brief Set options used by diff-engine
+ * @brief Set options for Diff-engine.
+ * This function converts given options to format CDiffWrapper uses
+ * internally and stores them.
+ * @param [in] options Pointer to structure having new options.
*/
-void CDiffWrapper::SetOptions(DIFFOPTIONS *options)
+void CDiffWrapper::SetOptions(const DIFFOPTIONS *options)
{
ASSERT(options);
InternalSetOptions(options);
* @brief Set text tested to find the prediffer automatically.
* Most probably a concatenated string of both filenames.
*/
-void CDiffWrapper::SetTextForAutomaticPrediff(CString text)
+void CDiffWrapper::SetTextForAutomaticPrediff(const CString &text)
{
m_sToFindPrediffer = text;
}
}
/**
- * @brief Get options used for patch creation
+ * @brief Returns current set of options used for patch-file creation.
+ * @param [in, out] options Pointer to structure where options are stored.
*/
-void CDiffWrapper::GetPatchOptions(PATCHOPTIONS *options)
+void CDiffWrapper::GetPatchOptions(PATCHOPTIONS *options) const
{
ASSERT(options);
options->nContext = m_settings.context;
}
/**
- * @brief Set options used for patch creation
+ * @brief Set options used for patch-file creation.
+ * @param [in] options Pointer to structure having new options.
*/
-void CDiffWrapper::SetPatchOptions(PATCHOPTIONS *options)
+void CDiffWrapper::SetPatchOptions(const PATCHOPTIONS *options)
{
ASSERT(options);
m_settings.context = options->nContext;
}
/**
- * @brief Determines if external diff-list is used
+ * @brief Determines if external results-list is used.
+ * When diff'ing files results are stored to external DiffList,
+ * set by SetDiffList(). This function determines if we are currently
+ * using that external list.
+ * @return TRUE if results are added to external DiffList.
*/
BOOL CDiffWrapper::GetUseDiffList() const
{
}
/**
- * @brief Enables/disables external diff-list usage
+ * @brief Enables/disables external result-list.
+ * CDiffWrapper uses external DiffList to return compare results.
+ * This function enables/disables usage of that external DiffList.
+ * @param [in] bUseDifList TRUE if external DiffList is used.
+ * @return Old value of the setting.
*/
BOOL CDiffWrapper::SetUseDiffList(BOOL bUseDiffList)
{
}
/**
- * @brief Determines if patch-file is created
+ * @brief Determines if patch-file is created.
+ * @return TRUE if patch file will be created.
*/
BOOL CDiffWrapper::GetCreatePatchFile() const
{
}
/**
- * @brief Enables/disables creation of patch-file
+ * @brief Enables/disables creation of patch-file.
+ * @param [in] bCreatePatchFile If TRUE patch file will be created.
+ * @return Previous value for setting.
*/
BOOL CDiffWrapper::SetCreatePatchFile(BOOL bCreatePatchFile)
{
}
/**
- * @brief Runs diff-engine
+ * @brief Set source paths for diffing two files.
+ * Sets full paths to two files we are diffing.
+ * @param [in] filepath1 First file to compare "original file".
+ * @param [in] filepath2 Second file to compare "changed file".
+ */
+void CDiffWrapper::SetPaths(const CString &filepath1, const CString &filepath2)
+{
+ m_s1File = filepath1;
+ m_s2File = filepath2;
+}
+
+/**
+ * @brief Set alternative paths for compared files.
+ * Sets alternative paths for diff'ed files. These alternative paths might not
+ * be real paths. For example when creating a patch file from folder compare
+ * we want to use relative paths.
+ * @param [in] altPath1 Alternative file path of first file.
+ * @param [in] altPath2 Alternative file path of second file.
*/
-BOOL CDiffWrapper::RunFileDiff(CString & filepath1, CString & filepath2, ARETEMPFILES areTempFiles)
+void CDiffWrapper::SetAlternativePaths(const CString &altPath1, const CString &altPath2)
{
+ m_s1AlternativePath = altPath1;
+ m_s2AlternativePath = altPath2;
+}
+
+/**
+ * @brief Runs diff-engine.
+ */
+BOOL CDiffWrapper::RunFileDiff(ARETEMPFILES areTempFiles)
+{
+ CString filepath1(m_s1File);
+ CString filepath2(m_s2File);
filepath1.Replace('/', '\\');
filepath2.Replace('/', '\\');
// Create patch file
if (!m_status.bBinaries && m_bCreatePatchFile)
{
- WritePatchFile(script, filepath1, filepath1, &inf[0]);
+ WritePatchFile(script, &inf[0]);
}
// Go through diffs adding them to WinMerge's diff list
/**
* @brief Return current diffutils options
*/
-void CDiffWrapper::InternalGetOptions(DIFFOPTIONS *options)
+void CDiffWrapper::InternalGetOptions(DIFFOPTIONS *options) const
{
int nIgnoreWhitespace = 0;
/**
* @brief Set diffutils options
*/
-void CDiffWrapper::InternalSetOptions(DIFFOPTIONS *options)
+void CDiffWrapper::InternalSetOptions(const DIFFOPTIONS *options)
{
m_settings.ignoreAllSpace = (options->nIgnoreWhitespace == WHITESPACE_IGNORE_ALL);
m_settings.ignoreSpaceChange = (options->nIgnoreWhitespace == WHITESPACE_IGNORE_CHANGE);
* Writes patch file using already computed diffutils script. Converts path
* delimiters from \ to / since we want to keep compatibility with patch-tools.
* @param [in] script list of changes.
- * @param [in] filepath1 first file
- * @param [in] filepath2 second file
* @param [in] inf file_data table containing filenames
* @todo filepath1 and filepath2 aren't really needed, paths are already in inf.
*/
-void CDiffWrapper::WritePatchFile(struct change * script,
- const CString & filepath1, const CString & filepath2,
- file_data * inf)
+void CDiffWrapper::WritePatchFile(struct change * script, file_data * inf)
{
USES_CONVERSION;
file_data inf_patch[2] = {0};
CopyMemory(&inf_patch, inf, sizeof(file_data) * 2);
- CString pathLeft = inf_patch[0].name;
- pathLeft.Replace('\\', '/');
- CString pathRight = inf_patch[1].name;
- pathRight.Replace('\\', '/');
- inf_patch[0].name = strdup(T2CA(pathLeft));
- inf_patch[1].name = strdup(T2CA(pathRight));
+
+ // Get paths, primarily use alternative paths, only if they are empty
+ // use full filepaths
+ CString path1(m_s1AlternativePath);
+ CString path2(m_s2AlternativePath);
+ if (path1.IsEmpty())
+ path1 = m_s1File;
+ if (path2.IsEmpty())
+ path2 = m_s2File;
+ path1.Replace('\\', '/');
+ path2.Replace('\\', '/');
+ inf_patch[0].name = strdup(T2CA(path1));
+ inf_patch[1].name = strdup(T2CA(path2));
outfile = NULL;
if (!m_sPatchFile.IsEmpty())
{
CString switches = FormatSwitchString();
_ftprintf(outfile, _T("diff%s %s %s\n"),
- switches, filepath1, filepath2);
+ switches, path1, path2);
}
// Output patchfile
*/
struct DIFFOPTIONS
{
- int nIgnoreWhitespace;
- BOOL bIgnoreCase;
- BOOL bIgnoreBlankLines;
- BOOL bIgnoreEol;
+ int nIgnoreWhitespace; /**< Ignore whitespace -option. */
+ BOOL bIgnoreCase; /**< Ignore case -option. */
+ BOOL bIgnoreBlankLines; /**< Ignore blank lines -option. */
+ BOOL bIgnoreEol; /**< Ignore EOL differences -option. */
};
/**
*/
struct PATCHOPTIONS
{
- enum output_style outputStyle;
- int nContext;
- BOOL bAddCommandline;
+ enum output_style outputStyle; /**< Patch file style. */
+ int nContext; /**< Number of context lines. */
+ BOOL bAddCommandline; /**< Add diff-style commandline to patch file. */
};
/**
public:
CDiffWrapper();
~CDiffWrapper();
- void SetPatchFile(CString file);
+ void SetPatchFile(const CString &file);
void SetDiffList(DiffList *diffList);
- void GetOptions(DIFFOPTIONS *options);
- void SetOptions(DIFFOPTIONS *options);
- void SetTextForAutomaticPrediff(CString text);
+ void GetOptions(DIFFOPTIONS *options) const;
+ void SetOptions(const DIFFOPTIONS *options);
+ void SetTextForAutomaticPrediff(const CString &text);
void SetPrediffer(PrediffingInfo * prediffer =NULL);
void GetPrediffer(PrediffingInfo * prediffer);
- void GetPatchOptions(PATCHOPTIONS *options);
- void SetPatchOptions(PATCHOPTIONS *options);
+ void GetPatchOptions(PATCHOPTIONS *options) const;
+ void SetPatchOptions(const PATCHOPTIONS *options);
BOOL GetUseDiffList() const;
BOOL SetUseDiffList(BOOL bUseDiffList);
void SetDetectMovedBlocks(BOOL bDetectMovedBlocks) { m_bDetectMovedBlocks = bDetectMovedBlocks; }
BOOL SetAppendFiles(BOOL bAppendFiles);
BOOL GetCreatePatchFile() const;
BOOL SetCreatePatchFile(BOOL bCreatePatchFile);
- BOOL RunFileDiff(CString & filepath1, CString & filepath2, ARETEMPFILES areTempFiles);
+ void SetPaths(const CString &filepath1, const CString &filepath2);
+ void SetAlternativePaths(const CString &altPath1, const CString &altPath2);
+ BOOL RunFileDiff(ARETEMPFILES areTempFiles);
void GetDiffStatus(DIFFSTATUS *status);
void AddDiffRange(UINT begin0, UINT end0, UINT begin1, UINT end1, BYTE op);
void FixLastDiffRange(int leftBufferLines, int rightBufferLines, BOOL left);
void ClearMovedLists();
protected:
- void InternalGetOptions(DIFFOPTIONS *options);
- void InternalSetOptions(DIFFOPTIONS *options);
+ void InternalGetOptions(DIFFOPTIONS *options) const;
+ void InternalSetOptions(const DIFFOPTIONS *options);
void SwapToInternalSettings();
void SwapToGlobalSettings();
CString FormatSwitchString();
BOOL Diff2Files(struct change ** diffs, DiffFileData *diffData,
int * bin_status);
void LoadWinMergeDiffsFromDiffUtilsScript(struct change * script, const file_data * inf);
- void WritePatchFile(struct change * script, const CString & filepath1, const CString & filepath2, file_data * inf);
+ void WritePatchFile(struct change * script, file_data * inf);
private:
- DIFFSETTINGS m_settings;
+ DIFFSETTINGS m_settings;
DIFFSETTINGS m_globalSettings; // Temp for storing globals
DIFFSTATUS m_status;
- CString m_sPatchFile;
+ CString m_s1File; /**< Full path to first diff'ed file. */
+ CString m_s2File; /**< Full path to second diff'ed file. */
+ CString m_s1AlternativePath; /**< First file's alternative path (may be relative). */
+ CString m_s2AlternativePath; /**< Second file's alternative path (may be relative). */
+ CString m_sPatchFile; /**< Full path to created patch file. */
/// prediffer info are stored only for MergeDoc
PrediffingInfo * m_infoPrediffer;
/// prediffer info are stored only for MergeDoc
CString m_sToFindPrediffer;
- BOOL m_bUseDiffList;
- BOOL m_bDetectMovedBlocks;
- BOOL m_bCreatePatchFile;
- BOOL m_bAddCmdLine;
- BOOL m_bAppendFiles;
+ BOOL m_bUseDiffList; /**< Are results returned in difflist? */
+ BOOL m_bDetectMovedBlocks; /**< Are moved blocks detected? */
+ BOOL m_bCreatePatchFile; /**< Do we create a patch file? */
+ BOOL m_bAddCmdLine; /**< Do we add commandline to patch file? */
+ BOOL m_bAppendFiles; /**< Do we append to existing patch file? */
int m_nDiffs;
DiffList *m_pDiffList;
CMap<int, int, int, int> m_moved0;
CDirView *pView = pDoc->GetMainView();
// Get selected items from folder compare
+ BOOL bValidFiles = TRUE;
int ind = pView->GetFirstSelectedInd();
- while (ind != -1)
+ while (ind != -1 && bValidFiles)
{
const DIFFITEM item = pView->GetItemAt(ind);
if (item.isBin())
+ {
AfxMessageBox(IDS_CANNOT_CREATE_BINARYPATCH, MB_ICONWARNING |
MB_DONT_DISPLAY_AGAIN, IDS_CANNOT_CREATE_BINARYPATCH);
+ bValidFiles = FALSE;
+ }
else if (item.isDirectory())
+ {
AfxMessageBox(IDS_CANNOT_CREATE_DIRPATCH, MB_ICONWARNING |
MB_DONT_DISPLAY_AGAIN, IDS_CANNOT_CREATE_DIRPATCH);
+ bValidFiles = FALSE;
+ }
- CString leftFile = item.getLeftFilepath(pDoc->GetLeftBasePath());
- if (!leftFile.IsEmpty())
- leftFile += _T("\\") + item.sLeftFilename;
- CString rightFile = item.getRightFilepath(pDoc->GetRightBasePath());
- if (!rightFile.IsEmpty())
- rightFile += _T("\\") + item.sRightFilename;
-
- patcher.AddFiles(leftFile, rightFile);
- pView->GetNextSelectedInd(ind);
+ if (bValidFiles)
+ {
+ // Format full paths to files (leftFile/rightFile)
+ CString leftFile = item.getLeftFilepath(pDoc->GetLeftBasePath());
+ if (!leftFile.IsEmpty())
+ leftFile += _T("\\") + item.sLeftFilename;
+ CString rightFile = item.getRightFilepath(pDoc->GetRightBasePath());
+ if (!rightFile.IsEmpty())
+ rightFile += _T("\\") + item.sRightFilename;
+
+ // Format relative paths to files in folder compare
+ CString leftpatch = item.sLeftSubdir;
+ if (!leftpatch.IsEmpty())
+ leftpatch += _T("/");
+ leftpatch += item.sLeftFilename;
+ CString rightpatch = item.sRightSubdir;
+ if (!rightpatch.IsEmpty())
+ rightpatch += _T("/");
+ rightpatch += item.sRightFilename;
+ patcher.AddFiles(leftFile, leftpatch, rightFile, rightpatch);
+ pView->GetNextSelectedInd(ind);
+ }
}
}
// Clear moved lines lists
m_diffWrapper.ClearMovedLists();
- // Run diff
- CString sLeftFilepath = m_pTempFiles->GetLeft();
- CString sRightFilepath = m_pTempFiles->GetRight();
- diffSuccess = m_diffWrapper.RunFileDiff(sLeftFilepath, sRightFilepath, YESTEMPFILES);
+ // Set paths for diffing and run diff
+ m_diffWrapper.SetPaths(m_pTempFiles->GetLeft(), m_pTempFiles->GetRight());
+ diffSuccess = m_diffWrapper.RunFileDiff(YESTEMPFILES);
// Read diff-status
DIFFSTATUS status;
struct PATCHFILES
{
CString lfile; /**< Left file */
+ CString pathLeft; /**< Left path added to patch file */
CString rfile; /**< Right file */
+ CString pathRight; /**< Right path added to patch file */
time_t ltime; /**< Left time */
time_t rtime; /**< Right time */
+ PATCHFILES() : ltime(0), rtime(0) {};
};
/**
/**
* @brief Adds files to list for patching
*/
-void CPatchTool::AddFiles(CString file1, CString file2)
+void CPatchTool::AddFiles(const CString &file1, const CString &file2)
{
PATCHFILES files;
files.lfile = file1;
m_fileList.AddTail(files);
}
+void CPatchTool::AddFiles(const CString &file1, const CString &altPath1,
+ const CString &file2, const CString &altPath2)
+{
+ PATCHFILES files;
+ files.lfile = file1;
+ files.rfile = file2;
+ files.pathLeft = altPath1;
+ files.pathRight = altPath2;
+
+ // TODO: Read and add file's timestamps
+ m_fileList.AddTail(files);
+}
+
/**
* @brief Create patch from files given
* @note Files can be given using AddFiles() or selecting using
// Set up DiffWrapper
m_diffWrapper.SetPrediffer(NULL);
- bDiffSuccess = m_diffWrapper.RunFileDiff(filename1, filename2, NOTEMPFILES);
+ m_diffWrapper.SetPaths(files.lfile, files.rfile);
+ m_diffWrapper.SetAlternativePaths(files.pathLeft, files.pathRight);
+ bDiffSuccess = m_diffWrapper.RunFileDiff(NOTEMPFILES);
m_diffWrapper.GetDiffStatus(&status);
if (!bDiffSuccess)
#include "PatchDlg.h"
/**
- * @brief Provides patch creation functionality
+ * @brief Provides patch creation functionality.
*/
class CPatchTool
{
public:
- void AddFiles(CString file1, CString file2);
+ void AddFiles(const CString &file1, const CString &file2);
+ void AddFiles(const CString &file1, const CString &altPath1,
+ const CString &file2, const CString &altPath2);
int CreatePatch();
CString GetPatchFile() const;
BOOL GetOpenToEditor() const;
BOOL ShowDialog();
private:
- CList<PATCHFILES,PATCHFILES> m_fileList;
- CDiffWrapper m_diffWrapper;
- CPatchDlg m_dlgPatch;
- CString m_sPatchFile;
- BOOL m_bOpenToEditor;
+ CList<PATCHFILES, PATCHFILES&> m_fileList; /**< List of files to patch. */
+ CDiffWrapper m_diffWrapper; /**< DiffWrapper instance we use to create patch. */
+ CPatchDlg m_dlgPatch; /**< Dialog for selecting files and options. */
+ CString m_sPatchFile; /**< Patch file path and filename. */
+ BOOL m_bOpenToEditor; /**< Is patch file opened to external editor? */
};
#endif // _PATCHTOOL_H_
\ No newline at end of file