3 #include "UnicodeString.h"
4 #include "DiffContext.h"
5 #include "FileActionScript.h"
7 #include "IntToIntMap.h"
9 #include "FileTransform.h"
14 class FileActionScript;
15 class CTempPathContext;
18 * @brief Folder compare icon indexes.
19 * This `enum` defines indexes for the imagelist used for folder/file compare icons.
20 * Note that this enum must be in synch with code in CDirView::OnInitialUpdate() and
21 * GetColImage(). Also remember that icons are in resource file...
49 DIFFIMG_DIRUP_DISABLE,
65 SELECTIONTYPE_LEFT1LEFT2,
66 SELECTIONTYPE_RIGHT1RIGHT2,
67 SELECTIONTYPE_LEFT1RIGHT2,
68 SELECTIONTYPE_LEFT2RIGHT1
77 struct AllowUpwardDirectory
89 struct DirViewFilterSettings
91 template<class GetOptionBool>
92 explicit DirViewFilterSettings(GetOptionBool getoptbool)
94 show_skipped = getoptbool(OPT_SHOW_SKIPPED);
95 show_unique_left = getoptbool(OPT_SHOW_UNIQUE_LEFT);
96 show_unique_middle = getoptbool(OPT_SHOW_UNIQUE_MIDDLE);
97 show_unique_right = getoptbool(OPT_SHOW_UNIQUE_RIGHT);
98 show_binaries = getoptbool(OPT_SHOW_BINARIES);
99 show_identical = getoptbool(OPT_SHOW_IDENTICAL);
100 show_different = getoptbool(OPT_SHOW_DIFFERENT);
101 show_different_left_only = getoptbool(OPT_SHOW_DIFFERENT_LEFT_ONLY);
102 show_different_middle_only = getoptbool(OPT_SHOW_DIFFERENT_MIDDLE_ONLY);
103 show_different_right_only = getoptbool(OPT_SHOW_DIFFERENT_RIGHT_ONLY);
104 show_missing_left_only = getoptbool(OPT_SHOW_MISSING_LEFT_ONLY);
105 show_missing_middle_only = getoptbool(OPT_SHOW_MISSING_MIDDLE_ONLY);
106 show_missing_right_only = getoptbool(OPT_SHOW_MISSING_RIGHT_ONLY);
107 tree_mode = getoptbool(OPT_TREE_MODE);
110 bool show_unique_left;
111 bool show_unique_middle;
112 bool show_unique_right;
116 bool show_different_left_only;
117 bool show_different_middle_only;
118 bool show_different_right_only;
119 bool show_missing_left_only;
120 bool show_missing_middle_only;
121 bool show_missing_right_only;
125 typedef std::map<String, bool> DirViewTreeState;
127 String NumToStr(int n);
128 String FormatFilesAffectedString(int nFilesAffected, int nFilesTotal);
129 String FormatMenuItemString(SIDE_TYPE src, int count, int total);
130 String FormatMenuItemString(SIDE_TYPE src, SIDE_TYPE dst, int count, int total);
131 String FormatMenuItemStringAll(int nDirs, int count, int total);
132 String FormatMenuItemString(const String& fmt1, const String& fmt2, int count, int total);
133 String FormatMenuItemStringTo(SIDE_TYPE src, int count, int total);
134 String FormatMenuItemStringAllTo(int nDirs, int count, int total);
135 String FormatMenuItemStringDifferencesTo(int count, int total);
137 void ConfirmActionList(const CDiffContext& ctxt, const FileActionScript & actionList);
138 UPDATEITEM_TYPE UpdateDiffAfterOperation(const FileActionItem & act, CDiffContext& ctxt, DIFFITEM &di);
140 DIFFITEM *FindItemFromPaths(const CDiffContext& ctxt, const PathContext& paths);
142 bool IsItemCopyable(const DIFFITEM &di, int index);
143 bool IsItemDeletable(const DIFFITEM &di, int index);
144 bool IsItemDeletableOnBoth(const CDiffContext& ctxt, const DIFFITEM &di);
145 bool AreItemsOpenable(const CDiffContext& ctxt, SELECTIONTYPE selectionType, const DIFFITEM &di1, const DIFFITEM &di2, bool openableForDir = true);
146 bool AreItemsOpenable(const CDiffContext& ctxt, const DIFFITEM &di1, const DIFFITEM &di2, const DIFFITEM &di3, bool openableForDir = true);
147 bool IsItemOpenableOn(const DIFFITEM &di, int index);
148 bool IsItemOpenableOnWith(const DIFFITEM &di, int index);
149 bool IsItemCopyableToOn(const DIFFITEM &di, int index);
150 bool IsItemNavigableDiff(const CDiffContext& ctxt, const DIFFITEM &di);
151 bool IsItemExistAll(const CDiffContext& ctxt, const DIFFITEM &di);
152 bool IsShowable(const CDiffContext& ctxt, const DIFFITEM &di, const DirViewFilterSettings& filter);
154 bool GetOpenOneItem(const CDiffContext& ctxt, DIFFITEM *pos1, const DIFFITEM *pdi[3],
155 PathContext &paths, int & sel1, bool & isDir, int nPane[3], FileTextEncoding encoding[3], String& errmsg, bool openableForDir = true);
156 bool GetOpenTwoItems(const CDiffContext& ctxt, SELECTIONTYPE selectionType, DIFFITEM *pos1, DIFFITEM *pos2, const DIFFITEM *pdi[3],
157 PathContext &paths, int & sel1, int & sel2, bool & isDir, int nPane[3], FileTextEncoding encoding[3], String& errmsg, bool openableForDir = true);
158 bool GetOpenThreeItems(const CDiffContext& ctxt, DIFFITEM *pos1, DIFFITEM *pos2, DIFFITEM *pos3, const DIFFITEM *pdi[3],
159 PathContext &paths, int & sel1, int & sel2, int & sel3, bool & isDir, int nPane[3], FileTextEncoding encoding[3], String& errmsg, bool openableForDir = true);
161 void GetItemFileNames(const CDiffContext& ctxt, const DIFFITEM& di, String& strLeft, String& strRight);
162 PathContext GetItemFileNames(const CDiffContext& ctxt, const DIFFITEM& di);
163 String GetItemFileName(const CDiffContext& ctx, const DIFFITEM &di, int index);
164 int GetColImage(const DIFFITEM &di);
166 void SetDiffStatus(DIFFITEM& di, unsigned diffcode, unsigned mask);
167 void SetDiffCompare(DIFFITEM& di, unsigned diffcode);
168 void CopyDiffSide(DIFFITEM& di, int src, int dst);
169 void UnsetDiffSide(DIFFITEM& di, int index);
170 void UpdateStatusFromDisk(CDiffContext& ctxt, DIFFITEM& di, int index);
171 void SetDiffCounts(DIFFITEM& di, unsigned diffs, unsigned ignored);
172 void SetItemViewFlag(DIFFITEM& di, unsigned flag, unsigned mask);
173 void SetItemViewFlag(CDiffContext& ctxt, unsigned flag, unsigned mask);
174 void MarkForRescan(DIFFITEM& di);
176 bool RenameOnSameDir(const String& szOldFileName, const String& szNewFileName);
178 void ExpandSubdirs(CDiffContext& ctxt, DIFFITEM& dip);
179 void ExpandAllSubdirs(CDiffContext &ctxt);
180 void CollapseAllSubdirs(CDiffContext &ctxt);
181 DirViewTreeState *SaveTreeState(const CDiffContext& ctxt);
182 void RestoreTreeState(CDiffContext &ctxt, DirViewTreeState *pTreeState);
184 AllowUpwardDirectory::ReturnCode
185 CheckAllowUpwardDirectory(const CDiffContext& ctxt, const CTempPathContext *pTempPathContext, PathContext &pathsParent);
187 inline int SideToIndex(const CDiffContext& ctxt, SIDE_TYPE stype)
191 case SIDE_MIDDLE: return ctxt.GetCompareDirs() == 3 ? 1 : -1;
192 case SIDE_RIGHT: return ctxt.GetCompareDirs() - 1;
197 struct ConfirmationNeededException
207 struct ContentsChangedException
209 explicit ContentsChangedException(const String& failpath);
213 struct FileOperationException
215 explicit FileOperationException(const String& msg);
221 typedef bool (DirActions::*method_type2)(const DIFFITEM& di) const;
222 typedef FileActionScript *(DirActions::*method_type)(FileActionScript *, const std::pair<int, const DIFFITEM *>& it) const;
224 DirActions(const CDiffContext& ctxt, const bool RO[], method_type func = nullptr, method_type2 func2 = nullptr) :
225 m_ctxt(ctxt), m_RO(RO), m_cur_method(func), m_cur_method2(func2) {}
227 template <SIDE_TYPE src, SIDE_TYPE dst>
228 bool IsItemCopyableOnTo(const DIFFITEM& di) const
230 return (di.diffcode.diffcode != 0 && !m_RO[SideToIndex(m_ctxt, dst)] && ::IsItemCopyable(di, SideToIndex(m_ctxt, src)));
233 template <SIDE_TYPE src>
234 bool IsItemCopyableToOn(const DIFFITEM& di) const
236 return (di.diffcode.diffcode != 0 && ::IsItemCopyableToOn(di, SideToIndex(m_ctxt, src)));
239 bool IsItemCopyableBothToOn(const DIFFITEM& di) const
241 if (di.diffcode.diffcode != 0)
244 for (i = 0; i < m_ctxt.GetCompareDirs(); ++i)
246 if (!::IsItemCopyableToOn(di, i))
249 return (i == m_ctxt.GetCompareDirs());
254 template <SIDE_TYPE src>
255 bool IsItemMovableToOn(const DIFFITEM& di) const
257 const int idx = SideToIndex(m_ctxt, src);
258 return (di.diffcode.diffcode != 0 && !m_RO[idx] && IsItemDeletable(di, idx) && ::IsItemCopyableToOn(di, idx));
261 template <SIDE_TYPE src>
262 bool IsItemDeletableOn(const DIFFITEM& di) const
264 const int idx = SideToIndex(m_ctxt, src);
265 return (di.diffcode.diffcode != 0 && !m_RO[idx] && IsItemDeletable(di, idx));
268 bool IsItemDeletableOnBoth(const DIFFITEM& di) const
270 if (di.diffcode.diffcode != 0)
273 for (i = 0; i < m_ctxt.GetCompareDirs(); ++i)
275 if (m_RO[i] || !IsItemDeletable(di, i))
278 return (i == m_ctxt.GetCompareDirs());
282 bool IsItemDeletableOnEitherOrBoth(const DIFFITEM& di) const
284 if (di.diffcode.diffcode != 0)
287 for (i = 0; i < m_ctxt.GetCompareDirs(); ++i)
289 if (!m_RO[i] && IsItemDeletable(di, i))
292 return (i < m_ctxt.GetCompareDirs());
297 template <SIDE_TYPE src>
298 bool IsItemOpenableOn(const DIFFITEM& di) const
300 return (di.diffcode.diffcode != 0 && ::IsItemOpenableOn(di, SideToIndex(m_ctxt, src)));
303 template <SIDE_TYPE src>
304 bool IsItemOpenableOnWith(const DIFFITEM& di) const
306 return (di.diffcode.diffcode != 0 && ::IsItemOpenableOnWith(di, SideToIndex(m_ctxt, src)));
309 template <SIDE_TYPE src>
310 bool IsParentFolderOpenable(const DIFFITEM& di) const
312 return (di.diffcode.diffcode != 0 && di.diffcode.exists(SideToIndex(m_ctxt, src)));
315 bool IsItemFile(const DIFFITEM& di) const
317 return (di.diffcode.diffcode != 0 && !di.diffcode.isDirectory());
320 template <SIDE_TYPE src>
321 bool IsItemExist(const DIFFITEM& di) const
323 return (di.diffcode.diffcode != 0 && di.diffcode.exists(SideToIndex(m_ctxt, src)));
326 template <SIDE_TYPE src>
327 bool IsItemEditableEncoding(const DIFFITEM& di) const
329 const int index = SideToIndex(m_ctxt, src);
330 return (di.diffcode.diffcode != 0 && di.diffcode.exists(index) && di.diffFileInfo[index].IsEditableEncoding());
333 bool IsItemNavigableDiff(const DIFFITEM& di) const
335 return ::IsItemNavigableDiff(m_ctxt, di);
338 FileActionScript *CopyItem(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it, SIDE_TYPE src, SIDE_TYPE dst) const
340 const DIFFITEM& di = *it.second;
341 const int srcidx = SideToIndex(m_ctxt, src);
342 const int dstidx = SideToIndex(m_ctxt, dst);
343 if (di.diffcode.diffcode != 0 && !m_RO[dstidx] && IsItemCopyable(di, srcidx))
346 act.src = GetItemFileName(m_ctxt, di, srcidx);
347 act.dest = GetItemFileName(m_ctxt, di, dstidx);
349 // We must check that paths still exists
350 if (paths::DoesPathExist(act.src) == paths::DOES_NOT_EXIST)
351 throw ContentsChangedException(act.src);
353 act.context = it.first;
354 act.dirflag = di.diffcode.isDirectory();
355 act.atype = FileAction::ACT_COPY;
356 act.UIResult = FileActionItem::UI_SYNC;
357 act.UIOrigin = srcidx;
358 act.UIDestination = dstidx;
359 pscript->AddActionItem(act);
364 template<SIDE_TYPE src, SIDE_TYPE to>
365 FileActionScript *Copy(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it) const
367 return CopyItem(pscript, it, src, to);
370 FileActionScript *DeleteItem(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it, SIDE_TYPE src) const
372 const DIFFITEM& di = *it.second;
373 const int index = SideToIndex(m_ctxt, src);
374 if (di.diffcode.diffcode != 0 && !m_RO[index] && IsItemDeletable(di, index))
377 act.src = GetItemFileName(m_ctxt, di, index);
379 // We must check that path still exists
380 if (paths::DoesPathExist(act.src) == paths::DOES_NOT_EXIST)
381 throw ContentsChangedException(act.src);
383 act.context = it.first;
384 act.dirflag = di.diffcode.isDirectory();
385 act.atype = FileAction::ACT_DEL;
386 act.UIOrigin = index;
387 act.UIResult = FileActionItem::UI_DEL;
388 pscript->AddActionItem(act);
393 template<SIDE_TYPE src>
394 FileActionScript *DeleteOn(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it) const
396 return DeleteItem(pscript, it, src);
399 FileActionScript *DeleteOnBoth(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it) const
401 const DIFFITEM& di = *it.second;
403 if (di.diffcode.diffcode != 0 && IsItemDeletableOnBoth(di) &&
404 (std::count(m_RO, m_RO + m_ctxt.GetCompareDirs(), true) == 0))
406 for (int i = 0; i < m_ctxt.GetCompareDirs(); ++i)
409 act.src = GetItemFileName(m_ctxt, di, i);
410 // We must first check that paths still exists
411 if (paths::DoesPathExist(act.src) == paths::DOES_NOT_EXIST)
412 throw ContentsChangedException(act.src);
413 act.context = it.first;
414 act.dirflag = di.diffcode.isDirectory();
415 act.atype = FileAction::ACT_DEL;
417 act.UIResult = FileActionItem::UI_DEL;
418 pscript->AddActionItem(act);
424 FileActionScript *DeleteOnEitherOrBoth(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it) const
426 const DIFFITEM& di = *it.second;
427 if (di.diffcode.diffcode != 0)
429 for (int i = 0; i < m_ctxt.GetCompareDirs(); ++i)
431 if (IsItemDeletable(di, i) && !m_RO[i])
434 act.src = GetItemFileName(m_ctxt, di, i);
435 // We must first check that paths still exists
436 if (paths::DoesPathExist(act.src) == paths::DOES_NOT_EXIST)
437 throw ContentsChangedException(act.src);
438 act.UIResult = FileActionItem::UI_DEL;
439 act.dirflag = di.diffcode.isDirectory();
440 act.context = it.first;
442 act.atype = FileAction::ACT_DEL;
443 pscript->AddActionItem(act);
450 FileActionScript *CopyOrMoveItemTo(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it, FileAction::ACT_TYPE atype, SIDE_TYPE src) const
452 const int index = SideToIndex(m_ctxt, src);
453 const DIFFITEM& di = *it.second;
455 if (di.diffcode.diffcode != 0 && di.diffcode.exists(index) &&
456 (atype == FileAction::ACT_MOVE ? (!m_RO[index] && IsItemDeletable(di, index)) : true))
459 act.src = GetItemFileName(m_ctxt, di, index);
461 // We must check that path still exists
462 if (paths::DoesPathExist(act.src) == paths::DOES_NOT_EXIST)
463 throw ContentsChangedException(act.src);
465 act.dest = paths::ConcatPath(pscript->m_destBase, di.diffFileInfo[index].GetFile());
466 act.dirflag = di.diffcode.isDirectory();
467 act.context = it.first;
469 act.UIResult = (atype == FileAction::ACT_COPY) ? FileActionItem::UI_DONT_CARE : FileActionItem::UI_DEL;
470 act.UIOrigin = index;
471 pscript->AddActionItem(act);
476 template<SIDE_TYPE src>
477 FileActionScript *CopyTo(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it) const
479 return CopyOrMoveItemTo(pscript, it, FileAction::ACT_COPY, src);
482 template<SIDE_TYPE src>
483 FileActionScript *MoveTo(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it) const
485 return CopyOrMoveItemTo(pscript, it, FileAction::ACT_MOVE, src);
488 FileActionScript *operator()(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it) const
490 return ((*this).*m_cur_method)(pscript, it);
493 bool operator()(const DIFFITEM &di) const
495 return ((*this).*m_cur_method2)(di);
498 method_type m_cur_method;
499 method_type2 m_cur_method2;
500 const CDiffContext& m_ctxt;
505 Counts() : count(0), total(0) {}
506 Counts(int c, int t): count(c), total(t) {}
511 template<class InputIterator, class Predicate>
512 Counts Count(const InputIterator& begin, const InputIterator& end, const Predicate& pred)
514 int count = 0, total = 0;
515 for (InputIterator it = begin; it != end; ++it)
521 return Counts(count, total);
525 * @brief Rename selected item on both left and right sides.
527 * @param szNewItemName [in] New item name.
529 * @return true if at least one file was renamed successfully.
531 template<class InputIterator>
532 bool DoItemRename(InputIterator& it, const CDiffContext& ctxt, const String& szNewItemName)
535 int nDirs = ctxt.GetCompareDirs();
537 assert(it != InputIterator());
539 // We must check that paths still exists
541 paths = ::GetItemFileNames(ctxt, di);
542 for (int index = 0; index < nDirs; index++)
544 if (di.diffcode.exists(index) && paths::DoesPathExist(paths[index]) == paths::DOES_NOT_EXIST)
545 throw ContentsChangedException(paths[index]);
548 bool bRename[3] = {false};
549 for (int index = 0; index < nDirs; index++)
551 if (di.diffcode.exists(index))
552 bRename[index] = RenameOnSameDir(paths[index], szNewItemName);
555 if (std::count(bRename, bRename + nDirs, true) == 0)
558 di.diffcode.setSideNone();
559 for (int index = 0; index < nDirs; index++)
561 di.diffFileInfo[index].filename = szNewItemName;
562 if (bRename[index] || paths::DoesPathExist(GetItemFileName(ctxt, di, index)))
563 di.diffcode.setSideFlag(index);
568 template<class InputIterator, class OutputIterator>
569 OutputIterator CopyPathnames(const InputIterator& begin, const InputIterator& end, OutputIterator result, SIDE_TYPE stype, const CDiffContext& ctxt)
571 const int index = SideToIndex(ctxt, stype);
572 for (InputIterator it = begin; it != end; ++it)
574 const DIFFITEM& di = *it;
575 if (di.diffcode.exists(index))
577 *result = GetItemFileName(ctxt, di, index);
584 template<class InputIterator, class OutputIterator>
585 OutputIterator CopyBothPathnames(const InputIterator& begin, const InputIterator& end, OutputIterator result, const CDiffContext& ctxt)
587 for (InputIterator it = begin; it != end; ++it)
589 const DIFFITEM& di = *it;
590 for (int i = 0; i < ctxt.GetCompareDirs(); ++i)
592 if (di.diffcode.exists(i))
594 *result = GetItemFileName(ctxt, di, i);
602 template<class InputIterator, class OutputIterator>
603 OutputIterator CopyFilenames(const InputIterator& begin, const InputIterator& end, OutputIterator result)
605 for (InputIterator it = begin; it != end; ++it)
607 const DIFFITEM& di = *it;
608 if (!di.diffcode.isDirectory())
610 *result = di.diffFileInfo[0].filename;
617 template<class InputIterator, class OutputIterator>
618 OutputIterator CopyPathnamesForDragAndDrop(const InputIterator& begin, const InputIterator& end, OutputIterator result, const CDiffContext& ctxt)
620 for (InputIterator it = begin; it != end; ++it)
622 const DIFFITEM& di = *it;
624 // check for special items (e.g not "..")
625 if (di.diffcode.diffcode == 0)
628 for (int i = 0; i < ctxt.GetCompareDirs(); ++i)
630 if (di.diffcode.exists(i))
632 *result = GetItemFileName(ctxt, di, i);
640 template<class InputIterator, class BinaryFunction>
641 void ApplyFolderNameAndFileName(const InputIterator& begin, const InputIterator& end, SIDE_TYPE stype,
642 const CDiffContext& ctxt, BinaryFunction func)
644 int index = SideToIndex(ctxt, stype);
645 for (InputIterator it = begin; it != end; ++it)
647 const DIFFITEM& di = *it;
648 if (di.diffcode.diffcode == 0) // Invalid value, this must be special item
650 String filename = di.diffFileInfo[index].filename;
651 String currentDir = di.getFilepath(index, ctxt.GetNormalizedPath(index));
652 func(currentDir, filename);
657 * @brief Apply specified setting for prediffing to all selected items
659 template<class InputIterator>
660 void ApplyPluginPrediffSetting(const InputIterator& begin, const InputIterator& end, const CDiffContext& ctxt, PLUGIN_MODE newsetting)
662 // Unlike other group actions, here we don't build an action list
663 // to execute; we just apply this change directly
664 if( !ctxt.m_bPluginsEnabled || ctxt.m_piPluginInfos == nullptr )
666 for (InputIterator it = begin; it != end; ++it)
668 const DIFFITEM& di = *it;
669 if (!di.diffcode.isDirectory())
671 String filteredFilenames;
672 for (int i = 0; i < ctxt.GetCompareDirs(); ++i)
674 if (di.diffcode.exists(i))
676 if (!filteredFilenames.empty()) filteredFilenames += _T("|");
677 filteredFilenames += ::GetItemFileName(ctxt, di, i);
680 PackingInfo * infoUnpacker = nullptr;
681 PrediffingInfo * infoPrediffer = nullptr;
682 const_cast<CDiffContext&>(ctxt).FetchPluginInfos(filteredFilenames, &infoUnpacker, &infoPrediffer);
683 infoPrediffer->Initialize(newsetting);
689 * @brief Updates just before displaying plugin context view in list
691 template<class InputIterator>
692 std::pair<int, int> CountPredifferYesNo(const InputIterator& begin, const InputIterator& end, const CDiffContext& ctxt)
694 int nPredifferYes = 0;
695 int nPredifferNo = 0;
696 if( !ctxt.m_bPluginsEnabled || ctxt.m_piPluginInfos == nullptr )
697 return std::make_pair(nPredifferYes, nPredifferNo);
699 for (InputIterator it = begin; it != end; ++it)
701 const DIFFITEM& di = *it;
702 if (di.diffcode.diffcode == 0) // Invalid value, this must be special item
705 // note the prediffer flag for 'files present on both sides and not skipped'
706 if (!di.diffcode.isDirectory() && !di.diffcode.isBin() && IsItemExistAll(ctxt, di)
707 && !di.diffcode.isResultFiltered())
709 PathContext tFiles = GetItemFileNames(ctxt, di);
710 String filteredFilenames = strutils::join(tFiles.begin(), tFiles.end(), _T("|"));
711 PackingInfo * unpacker;
712 PrediffingInfo * prediffer;
713 const_cast<CDiffContext&>(ctxt).FetchPluginInfos(filteredFilenames, &unpacker, &prediffer);
714 if (prediffer->m_PluginOrPredifferMode == PLUGIN_MODE::PLUGIN_AUTO || !prediffer->m_PluginName.empty())
720 return std::make_pair(nPredifferYes, nPredifferNo);
723 template<class InputIterator>
724 IntToIntMap CountCodepages(const InputIterator& begin, const InputIterator& end, const CDiffContext& ctxt)
727 for (InputIterator it = begin; it != end; ++it)
729 const DIFFITEM& di = *it;
730 for (int i = 0; i < ctxt.GetCompareDirs(); ++i)
732 if (di.diffcode.diffcode != 0 && di.diffcode.exists(i))
733 map.Increment(di.diffFileInfo[i].encoding.m_codepage);
739 template<class InputIterator>
740 void ApplyCodepage(const InputIterator& begin, const InputIterator& end, CDiffContext& ctxt, const bool affect[3], int nCodepage)
742 for (InputIterator it = begin; it != end; ++it)
745 if (di.diffcode.diffcode == 0) // Invalid value, this must be special item
747 if (di.diffcode.isDirectory())
750 for (int i = 0; i < ctxt.GetCompareDirs(); ++i)
752 // Does it exist on left? (ie, right or both)
753 if (affect[i] && di.diffcode.exists(i) && di.diffFileInfo[i].IsEditableEncoding())
755 di.diffFileInfo[i].encoding.SetCodepage(nCodepage);
761 /// get file name on specified side for first selected item
762 template<class InputIterator>
763 String GetSelectedFileName(InputIterator& it, SIDE_TYPE stype, const CDiffContext& ctxt)
765 if (it == InputIterator())
767 return GetItemFileName(ctxt, *it, SideToIndex(ctxt, stype));