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 IsItemMovable(const DIFFITEM &di, int index);
144 bool IsItemDeletable(const DIFFITEM &di, int index);
145 bool IsItemDeletableOnBoth(const CDiffContext& ctxt, const DIFFITEM &di);
146 bool AreItemsOpenable(const CDiffContext& ctxt, SELECTIONTYPE selectionType, const DIFFITEM &di1, const DIFFITEM &di2, bool openableForDir = true);
147 bool AreItemsOpenable(const CDiffContext& ctxt, const DIFFITEM &di1, const DIFFITEM &di2, const DIFFITEM &di3, bool openableForDir = true);
148 bool IsItemOpenableOn(const DIFFITEM &di, int index);
149 bool IsItemOpenableOnWith(const DIFFITEM &di, int index);
150 bool IsItemCopyableToOn(const DIFFITEM &di, int index);
151 bool IsItemNavigableDiff(const CDiffContext& ctxt, const DIFFITEM &di);
152 bool IsItemExistAll(const CDiffContext& ctxt, const DIFFITEM &di);
153 bool IsShowable(const CDiffContext& ctxt, const DIFFITEM &di, const DirViewFilterSettings& filter);
155 bool GetOpenOneItem(const CDiffContext& ctxt, DIFFITEM *pos1, const DIFFITEM *pdi[3],
156 PathContext &paths, int & sel1, bool & isDir, int nPane[3], FileTextEncoding encoding[3], String& errmsg, bool openableForDir = true);
157 bool GetOpenTwoItems(const CDiffContext& ctxt, SELECTIONTYPE selectionType, DIFFITEM *pos1, DIFFITEM *pos2, const DIFFITEM *pdi[3],
158 PathContext &paths, int & sel1, int & sel2, bool & isDir, int nPane[3], FileTextEncoding encoding[3], String& errmsg, bool openableForDir = true);
159 bool GetOpenThreeItems(const CDiffContext& ctxt, DIFFITEM *pos1, DIFFITEM *pos2, DIFFITEM *pos3, const DIFFITEM *pdi[3],
160 PathContext &paths, int & sel1, int & sel2, int & sel3, bool & isDir, int nPane[3], FileTextEncoding encoding[3], String& errmsg, bool openableForDir = true);
162 void GetItemFileNames(const CDiffContext& ctxt, const DIFFITEM& di, String& strLeft, String& strRight);
163 PathContext GetItemFileNames(const CDiffContext& ctxt, const DIFFITEM& di);
164 String GetItemFileName(const CDiffContext& ctx, const DIFFITEM &di, int index);
165 int GetColImage(const DIFFITEM &di);
167 void SetDiffStatus(DIFFITEM& di, unsigned diffcode, unsigned mask);
168 void SetDiffCompare(DIFFITEM& di, unsigned diffcode);
169 void CopyDiffSideAndProperties(DIFFITEM& di, int src, int dst);
170 void UnsetDiffSide(DIFFITEM& di, int index);
171 void UpdateStatusFromDisk(CDiffContext& ctxt, DIFFITEM& di, int index);
172 int UpdateCompareFlagsAfterSync(DIFFITEM& di, bool bRecursive);
173 void UpdatePaths(int nDirs, DIFFITEM& di);
174 void SetDiffCounts(DIFFITEM& di, unsigned diffs, unsigned ignored);
175 void SetItemViewFlag(DIFFITEM& di, unsigned flag, unsigned mask);
176 void SetItemViewFlag(CDiffContext& ctxt, unsigned flag, unsigned mask);
177 void MarkForRescan(DIFFITEM& di);
179 bool RenameOnSameDir(const String& szOldFileName, const String& szNewFileName);
181 void ExpandSubdirs(CDiffContext& ctxt, DIFFITEM& dip);
182 void ExpandAllSubdirs(CDiffContext &ctxt);
183 void CollapseAllSubdirs(CDiffContext &ctxt);
184 DirViewTreeState *SaveTreeState(const CDiffContext& ctxt);
185 void RestoreTreeState(CDiffContext &ctxt, DirViewTreeState *pTreeState);
187 AllowUpwardDirectory::ReturnCode
188 CheckAllowUpwardDirectory(const CDiffContext& ctxt, const CTempPathContext *pTempPathContext, PathContext &pathsParent);
190 inline int SideToIndex(const CDiffContext& ctxt, SIDE_TYPE stype)
194 case SIDE_MIDDLE: return ctxt.GetCompareDirs() == 3 ? 1 : -1;
195 case SIDE_RIGHT: return ctxt.GetCompareDirs() - 1;
200 struct ConfirmationNeededException
210 struct ContentsChangedException
212 explicit ContentsChangedException(const String& failpath);
216 struct FileOperationException
218 explicit FileOperationException(const String& msg);
224 typedef bool (DirActions::*method_type2)(const DIFFITEM& di) const;
225 typedef FileActionScript *(DirActions::*method_type)(FileActionScript *, const std::pair<int, const DIFFITEM *>& it) const;
227 DirActions(const CDiffContext& ctxt, const bool RO[], method_type func = nullptr, method_type2 func2 = nullptr) :
228 m_ctxt(ctxt), m_RO(RO), m_cur_method(func), m_cur_method2(func2) {}
230 template <SIDE_TYPE src, SIDE_TYPE dst>
231 bool IsItemCopyableOnTo(const DIFFITEM& di) const
233 return (di.diffcode.diffcode != 0 && !m_RO[SideToIndex(m_ctxt, dst)] && ::IsItemCopyable(di, SideToIndex(m_ctxt, src)));
236 template <SIDE_TYPE src>
237 bool IsItemCopyableToOn(const DIFFITEM& di) const
239 return (di.diffcode.diffcode != 0 && ::IsItemCopyableToOn(di, SideToIndex(m_ctxt, src)));
242 bool IsItemCopyableBothToOn(const DIFFITEM& di) const
244 if (di.diffcode.diffcode != 0)
247 for (i = 0; i < m_ctxt.GetCompareDirs(); ++i)
249 if (!::IsItemCopyableToOn(di, i))
252 return (i == m_ctxt.GetCompareDirs());
258 * @brief Return whether the specified diff item is renamable.
259 * @param [in] di Diff item to check
260 * @return true if the specified diff item is renamable.
262 bool IsItemRenamable(const DIFFITEM& di) const
264 int nDirs = m_ctxt.GetCompareDirs();
265 for (int i = 0; i < nDirs; i++)
266 if (di.diffcode.exists(i) && m_RO[i])
271 template <SIDE_TYPE src, SIDE_TYPE dst>
272 bool IsItemMovableOnTo(const DIFFITEM& di) const
274 const int idx = SideToIndex(m_ctxt, src);
275 return (di.diffcode.diffcode != 0 && !m_RO[idx] && !m_RO[SideToIndex(m_ctxt, dst)] && ::IsItemMovable(di, idx));
278 template <SIDE_TYPE src>
279 bool IsItemMovableToOn(const DIFFITEM& di) const
281 const int idx = SideToIndex(m_ctxt, src);
282 return (di.diffcode.diffcode != 0 && !m_RO[idx] && IsItemDeletable(di, idx) && ::IsItemCopyableToOn(di, idx));
285 template <SIDE_TYPE src>
286 bool IsItemDeletableOn(const DIFFITEM& di) const
288 const int idx = SideToIndex(m_ctxt, src);
289 return (di.diffcode.diffcode != 0 && !m_RO[idx] && IsItemDeletable(di, idx));
292 bool IsItemDeletableOnBoth(const DIFFITEM& di) const
294 if (di.diffcode.diffcode != 0)
297 for (i = 0; i < m_ctxt.GetCompareDirs(); ++i)
299 if (m_RO[i] || !IsItemDeletable(di, i))
302 return (i == m_ctxt.GetCompareDirs());
306 bool IsItemDeletableOnEitherOrBoth(const DIFFITEM& di) const
308 if (di.diffcode.diffcode != 0)
311 for (i = 0; i < m_ctxt.GetCompareDirs(); ++i)
313 if (!m_RO[i] && IsItemDeletable(di, i))
316 return (i < m_ctxt.GetCompareDirs());
321 template <SIDE_TYPE src>
322 bool IsItemOpenableOn(const DIFFITEM& di) const
324 return (di.diffcode.diffcode != 0 && ::IsItemOpenableOn(di, SideToIndex(m_ctxt, src)));
327 template <SIDE_TYPE src>
328 bool IsItemOpenableOnWith(const DIFFITEM& di) const
330 return (di.diffcode.diffcode != 0 && ::IsItemOpenableOnWith(di, SideToIndex(m_ctxt, src)));
333 template <SIDE_TYPE src>
334 bool IsParentFolderOpenable(const DIFFITEM& di) const
336 return (di.diffcode.diffcode != 0 && di.diffcode.exists(SideToIndex(m_ctxt, src)));
339 bool IsItemFile(const DIFFITEM& di) const
341 return (di.diffcode.diffcode != 0 && !di.diffcode.isDirectory());
344 template <SIDE_TYPE src>
345 bool IsItemExist(const DIFFITEM& di) const
347 return (di.diffcode.diffcode != 0 && di.diffcode.exists(SideToIndex(m_ctxt, src)));
350 template <SIDE_TYPE src>
351 bool IsItemEditableEncoding(const DIFFITEM& di) const
353 const int index = SideToIndex(m_ctxt, src);
354 return (di.diffcode.diffcode != 0 && di.diffcode.exists(index) && di.diffFileInfo[index].IsEditableEncoding());
357 bool IsItemNavigableDiff(const DIFFITEM& di) const
359 return ::IsItemNavigableDiff(m_ctxt, di);
362 FileActionScript *CopyItem(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it, SIDE_TYPE src, SIDE_TYPE dst) const
364 const DIFFITEM& di = *it.second;
365 const int srcidx = SideToIndex(m_ctxt, src);
366 const int dstidx = SideToIndex(m_ctxt, dst);
367 if (di.diffcode.diffcode != 0 && !m_RO[dstidx] && IsItemCopyable(di, srcidx))
370 act.src = GetItemFileName(m_ctxt, di, srcidx);
371 act.dest = GetItemFileName(m_ctxt, di, dstidx);
373 // We must check that paths still exists
374 if (paths::DoesPathExist(act.src) == paths::DOES_NOT_EXIST)
375 throw ContentsChangedException(act.src);
377 act.context = it.first;
378 act.dirflag = di.diffcode.isDirectory();
379 act.atype = FileAction::ACT_COPY;
380 act.UIResult = FileActionItem::UI_SYNC;
381 act.UIOrigin = srcidx;
382 act.UIDestination = dstidx;
383 pscript->AddActionItem(act);
388 template<SIDE_TYPE src, SIDE_TYPE to>
389 FileActionScript *Copy(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it) const
391 return CopyItem(pscript, it, src, to);
394 FileActionScript *MoveItem(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it, SIDE_TYPE src, SIDE_TYPE dst) const
396 const DIFFITEM& di = *it.second;
397 const int srcidx = SideToIndex(m_ctxt, src);
398 const int dstidx = SideToIndex(m_ctxt, dst);
399 if (di.diffcode.diffcode != 0 && !m_RO[dstidx] && IsItemMovable(di, srcidx))
402 act.src = GetItemFileName(m_ctxt, di, srcidx);
403 act.dest = GetItemFileName(m_ctxt, di, dstidx);
405 // We must check that paths still exists
406 if (paths::DoesPathExist(act.src) == paths::DOES_NOT_EXIST)
407 throw ContentsChangedException(act.src);
409 act.context = it.first;
410 act.dirflag = di.diffcode.isDirectory();
411 act.atype = FileAction::ACT_MOVE;
412 act.UIResult = FileActionItem::UI_MOVE;
413 act.UIOrigin = srcidx;
414 act.UIDestination = dstidx;
415 pscript->AddActionItem(act);
420 template<SIDE_TYPE src, SIDE_TYPE to>
421 FileActionScript *Move(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it) const
423 return MoveItem(pscript, it, src, to);
426 FileActionScript *DeleteItem(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it, SIDE_TYPE src) const
428 const DIFFITEM& di = *it.second;
429 const int index = SideToIndex(m_ctxt, src);
430 if (di.diffcode.diffcode != 0 && !m_RO[index] && IsItemDeletable(di, index))
433 act.src = GetItemFileName(m_ctxt, di, index);
435 // We must check that path still exists
436 if (paths::DoesPathExist(act.src) == paths::DOES_NOT_EXIST)
437 throw ContentsChangedException(act.src);
439 act.context = it.first;
440 act.dirflag = di.diffcode.isDirectory();
441 act.atype = FileAction::ACT_DEL;
442 act.UIOrigin = index;
443 act.UIResult = FileActionItem::UI_DEL;
444 pscript->AddActionItem(act);
449 template<SIDE_TYPE src>
450 FileActionScript *DeleteOn(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it) const
452 return DeleteItem(pscript, it, src);
455 FileActionScript *DeleteOnBoth(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it) const
457 const DIFFITEM& di = *it.second;
459 if (di.diffcode.diffcode != 0 && IsItemDeletableOnBoth(di) &&
460 (std::count(m_RO, m_RO + m_ctxt.GetCompareDirs(), true) == 0))
462 for (int i = 0; i < m_ctxt.GetCompareDirs(); ++i)
465 act.src = GetItemFileName(m_ctxt, di, i);
466 // We must first check that paths still exists
467 if (paths::DoesPathExist(act.src) == paths::DOES_NOT_EXIST)
468 throw ContentsChangedException(act.src);
469 act.context = it.first;
470 act.dirflag = di.diffcode.isDirectory();
471 act.atype = FileAction::ACT_DEL;
473 act.UIResult = FileActionItem::UI_DEL;
474 pscript->AddActionItem(act);
480 FileActionScript *DeleteOnEitherOrBoth(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it) const
482 const DIFFITEM& di = *it.second;
483 if (di.diffcode.diffcode != 0)
485 for (int i = 0; i < m_ctxt.GetCompareDirs(); ++i)
487 if (IsItemDeletable(di, i) && !m_RO[i])
490 act.src = GetItemFileName(m_ctxt, di, i);
491 // We must first check that paths still exists
492 if (paths::DoesPathExist(act.src) == paths::DOES_NOT_EXIST)
493 throw ContentsChangedException(act.src);
494 act.UIResult = FileActionItem::UI_DEL;
495 act.dirflag = di.diffcode.isDirectory();
496 act.context = it.first;
498 act.atype = FileAction::ACT_DEL;
499 pscript->AddActionItem(act);
506 FileActionScript *CopyOrMoveItemTo(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it, FileAction::ACT_TYPE atype, SIDE_TYPE src) const
508 const int index = SideToIndex(m_ctxt, src);
509 const DIFFITEM& di = *it.second;
511 if (di.diffcode.diffcode != 0 && di.diffcode.exists(index) &&
512 (atype == FileAction::ACT_MOVE ? (!m_RO[index] && IsItemDeletable(di, index)) : true))
515 act.src = GetItemFileName(m_ctxt, di, index);
517 // We must check that path still exists
518 if (paths::DoesPathExist(act.src) == paths::DOES_NOT_EXIST)
519 throw ContentsChangedException(act.src);
521 act.dest = paths::ConcatPath(pscript->m_destBase, di.diffFileInfo[index].GetFile());
522 act.dirflag = di.diffcode.isDirectory();
523 act.context = it.first;
525 act.UIResult = (atype == FileAction::ACT_COPY) ? FileActionItem::UI_DONT_CARE : FileActionItem::UI_DEL;
526 act.UIOrigin = index;
527 pscript->AddActionItem(act);
532 template<SIDE_TYPE src>
533 FileActionScript *CopyTo(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it) const
535 return CopyOrMoveItemTo(pscript, it, FileAction::ACT_COPY, src);
538 template<SIDE_TYPE src>
539 FileActionScript *MoveTo(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it) const
541 return CopyOrMoveItemTo(pscript, it, FileAction::ACT_MOVE, src);
544 FileActionScript *operator()(FileActionScript *pscript, const std::pair<int, const DIFFITEM *>& it) const
546 return ((*this).*m_cur_method)(pscript, it);
549 bool operator()(const DIFFITEM &di) const
551 return ((*this).*m_cur_method2)(di);
554 method_type m_cur_method;
555 method_type2 m_cur_method2;
556 const CDiffContext& m_ctxt;
561 Counts() : count(0), total(0) {}
562 Counts(int c, int t): count(c), total(t) {}
567 template<class InputIterator, class Predicate>
568 Counts Count(const InputIterator& begin, const InputIterator& end, const Predicate& pred)
570 int count = 0, total = 0;
571 for (InputIterator it = begin; it != end; ++it)
577 return Counts(count, total);
581 * @brief Rename selected item on both left and right sides.
583 * @param szNewItemName [in] New item name.
585 * @return true if at least one file was renamed successfully.
587 template<class InputIterator>
588 bool DoItemRename(InputIterator& it, const CDiffContext& ctxt, const String& szNewItemName)
591 int nDirs = ctxt.GetCompareDirs();
593 assert(it != InputIterator());
595 // We must check that paths still exists
597 paths = ::GetItemFileNames(ctxt, di);
598 for (int index = 0; index < nDirs; index++)
600 if (di.diffcode.exists(index) && paths::DoesPathExist(paths[index]) == paths::DOES_NOT_EXIST)
601 throw ContentsChangedException(paths[index]);
604 bool bRename[3] = {false};
605 for (int index = 0; index < nDirs; index++)
607 if (di.diffcode.exists(index))
608 bRename[index] = RenameOnSameDir(paths[index], szNewItemName);
611 if (std::count(bRename, bRename + nDirs, true) == 0)
614 di.diffcode.setSideNone();
615 for (int index = 0; index < nDirs; index++)
617 di.diffFileInfo[index].filename = szNewItemName;
618 bool bSetSideFlag = bRename[index];
621 paths::PATH_EXISTENCE pathExist = paths::DoesPathExist(GetItemFileName(ctxt, di, index));
622 bool bIsDirectory = di.diffcode.isDirectory();
623 if (((pathExist == paths::IS_EXISTING_DIR) && bIsDirectory) || ((pathExist == paths::IS_EXISTING_FILE) && !bIsDirectory))
627 di.diffcode.setSideFlag(index);
632 template<class InputIterator, class OutputIterator>
633 OutputIterator CopyPathnames(const InputIterator& begin, const InputIterator& end, OutputIterator result, SIDE_TYPE stype, const CDiffContext& ctxt)
635 const int index = SideToIndex(ctxt, stype);
636 for (InputIterator it = begin; it != end; ++it)
638 const DIFFITEM& di = *it;
639 if (di.diffcode.exists(index))
641 *result = GetItemFileName(ctxt, di, index);
648 template<class InputIterator, class OutputIterator>
649 OutputIterator CopyBothPathnames(const InputIterator& begin, const InputIterator& end, OutputIterator result, const CDiffContext& ctxt)
651 for (InputIterator it = begin; it != end; ++it)
653 const DIFFITEM& di = *it;
654 for (int i = 0; i < ctxt.GetCompareDirs(); ++i)
656 if (di.diffcode.exists(i))
658 *result = GetItemFileName(ctxt, di, i);
666 template<class InputIterator, class OutputIterator>
667 OutputIterator CopyFilenames(const InputIterator& begin, const InputIterator& end, OutputIterator result)
669 for (InputIterator it = begin; it != end; ++it)
671 const DIFFITEM& di = *it;
672 if (!di.diffcode.isDirectory())
674 *result = di.diffFileInfo[0].filename;
681 template<class InputIterator, class OutputIterator>
682 OutputIterator CopyPathnamesForDragAndDrop(const InputIterator& begin, const InputIterator& end, OutputIterator result, const CDiffContext& ctxt)
684 for (InputIterator it = begin; it != end; ++it)
686 const DIFFITEM& di = *it;
688 // check for special items (e.g not "..")
689 if (di.diffcode.diffcode == 0)
692 for (int i = 0; i < ctxt.GetCompareDirs(); ++i)
694 if (di.diffcode.exists(i))
696 *result = GetItemFileName(ctxt, di, i);
704 template<class InputIterator, class BinaryFunction>
705 void ApplyFolderNameAndFileName(const InputIterator& begin, const InputIterator& end, SIDE_TYPE stype,
706 const CDiffContext& ctxt, BinaryFunction func)
708 int index = SideToIndex(ctxt, stype);
709 for (InputIterator it = begin; it != end; ++it)
711 const DIFFITEM& di = *it;
712 if (di.diffcode.diffcode == 0) // Invalid value, this must be special item
714 String filename = di.diffFileInfo[index].filename;
715 String currentDir = di.getFilepath(index, ctxt.GetNormalizedPath(index));
716 func(currentDir, filename);
721 * @brief Apply specified setting for prediffing to all selected items
723 template<class InputIterator>
724 void ApplyPluginPipeline(const InputIterator& begin, const InputIterator& end, const CDiffContext& ctxt, bool unpacker, const String& pluginPipeline)
726 // Unlike other group actions, here we don't build an action list
727 // to execute; we just apply this change directly
728 if( !ctxt.m_bPluginsEnabled || ctxt.m_piPluginInfos == nullptr )
730 for (InputIterator it = begin; it != end; ++it)
732 const DIFFITEM& di = *it;
733 if (!di.diffcode.isDirectory())
735 PackingInfo * infoUnpacker = nullptr;
736 PrediffingInfo * infoPrediffer = nullptr;
737 String filteredFilenames = ctxt.GetFilteredFilenames(di);
738 const_cast<CDiffContext&>(ctxt).FetchPluginInfos(filteredFilenames, &infoUnpacker, &infoPrediffer);
740 infoUnpacker->SetPluginPipeline(pluginPipeline);
742 infoPrediffer->SetPluginPipeline(pluginPipeline);
748 * @brief Updates just before displaying plugin context view in list
750 template<class InputIterator>
751 std::tuple<int, int, int> CountPluginNoneAutoOthers(const InputIterator& begin, const InputIterator& end, const CDiffContext& ctxt, bool unpacker)
756 if( !ctxt.m_bPluginsEnabled || ctxt.m_piPluginInfos == nullptr )
757 return std::make_tuple(nNone, nAuto, nOthers);
759 for (InputIterator it = begin; it != end; ++it)
761 const DIFFITEM& di = *it;
762 if (di.diffcode.diffcode == 0) // Invalid value, this must be special item
765 // note the prediffer flag for 'files present on both sides and not skipped'
766 if (!di.diffcode.isDirectory() && !di.diffcode.isBin() && IsItemExistAll(ctxt, di)
767 && !di.diffcode.isResultFiltered())
769 PackingInfo * infoUnpacker;
770 PrediffingInfo * infoPrediffer;
771 String filteredFilenames = ctxt.GetFilteredFilenames(di);
772 const_cast<CDiffContext&>(ctxt).FetchPluginInfos(filteredFilenames, &infoUnpacker, &infoPrediffer);
773 String pluginPipeline = unpacker ? infoUnpacker->GetPluginPipeline() : infoPrediffer->GetPluginPipeline();
774 if (pluginPipeline.empty())
776 else if (pluginPipeline == _T("<Automatic>"))
782 return std::make_tuple(nNone, nAuto, nOthers);
785 template<class InputIterator>
786 IntToIntMap CountCodepages(const InputIterator& begin, const InputIterator& end, const CDiffContext& ctxt)
789 for (InputIterator it = begin; it != end; ++it)
791 const DIFFITEM& di = *it;
792 for (int i = 0; i < ctxt.GetCompareDirs(); ++i)
794 if (di.diffcode.diffcode != 0 && di.diffcode.exists(i))
795 map.Increment(di.diffFileInfo[i].encoding.m_codepage);
801 template<class InputIterator>
802 void ApplyCodepage(const InputIterator& begin, const InputIterator& end, CDiffContext& ctxt, const bool affect[3], int nCodepage)
804 for (InputIterator it = begin; it != end; ++it)
807 if (di.diffcode.diffcode == 0) // Invalid value, this must be special item
809 if (di.diffcode.isDirectory())
812 for (int i = 0; i < ctxt.GetCompareDirs(); ++i)
814 // Does it exist on left? (ie, right or both)
815 if (affect[i] && di.diffcode.exists(i) && di.diffFileInfo[i].IsEditableEncoding())
817 di.diffFileInfo[i].encoding.SetCodepage(nCodepage);
823 /// get file name on specified side for first selected item
824 template<class InputIterator>
825 String GetSelectedFileName(InputIterator& it, SIDE_TYPE stype, const CDiffContext& ctxt)
827 if (it == InputIterator())
829 return GetItemFileName(ctxt, *it, SideToIndex(ctxt, stype));