1 /////////////////////////////////////////////////////////////////////////////
2 // WinMerge: an interactive diff/merge utility
3 // Copyright (C) 1997 Dean P. Grimm
4 // SPDX-License-Identifier: GPL-2.0-or-later
5 /////////////////////////////////////////////////////////////////////////////
9 * @brief Declaration of class CDirView
13 /////////////////////////////////////////////////////////////////////////////
18 #include "OptionsDirColors.h"
19 #include "SortHeaderCtrl.h"
20 #include "UnicodeString.h"
21 #include "DirItemIterator.h"
22 #include "DirActions.h"
24 class FileActionScript;
26 typedef enum { eMain, eContext } eMenuType;
33 class DirCompProgressBar;
36 class CLoadSaveCodepageDlg;
37 class CShellContextMenu;
39 class DirViewColItems;
40 class DirItemEnumerator;
44 * @brief Position value for special items (..) in directory compare view.
46 const uintptr_t SPECIAL_ITEM_POS = (uintptr_t)(reinterpret_cast<DIFFITEM *>( - 1L));
48 /** Default column width in directory compare */
49 const UINT DefColumnWidth = 150;
52 * @brief Directory compare results view.
54 * Directory compare view is list-view based, so it shows one result (for
55 * folder or file, commonly called as 'item') in one line. User can select
56 * visible columns, re-order columns, sort by column etc.
58 * Actual data is stored in CDiffContext in CDirDoc. Dircompare items and
59 * CDiffContext items are linked by storing POSITION of CDiffContext item
60 * as CDirView listitem key.
62 class CDirView : public CListView
64 friend struct FileCmpReport;
65 friend DirItemEnumerator;
67 CDirView(); // protected constructor used by dynamic creation
68 DECLARE_DYNCREATE(CDirView)
72 CDirDoc* GetDocument(); // non-debug version is inline
73 // const version, for const methods to be able to call
74 const CDirDoc * GetDocument() const { return const_cast<CDirView *>(this)->GetDocument(); }
75 const CDiffContext& GetDiffContext() const;
76 CDiffContext& GetDiffContext();
80 CDirFrame * GetParentFrame();
82 void StartCompare(CompareStats *pCompareStats);
84 void RedisplayChildren(DIFFITEM *diffpos, int level, UINT &index, int &alldiffs);
85 void UpdateResources();
86 void LoadColumnHeaderItems();
87 DIFFITEM *GetItemKey(int idx) const;
88 int GetItemIndex(DIFFITEM *key);
89 // for populating list
90 void DeleteItem(int sel, bool removeDIFFITEM = false);
91 void DeleteAllDisplayItems();
92 void SetFont(const LOGFONT & lf);
94 void SortColumnsAppropriately();
96 UINT GetSelectedCount() const;
97 int GetFirstSelectedInd();
98 void AddParentFolderItem(bool bEnable);
99 void RefreshOptions();
103 void MoveToNextDiff();
104 void MoveToPrevDiff();
107 void SetActivePane(int pane);
109 // Implementation types
112 // Implementation in DirActions.cpp
114 void GetItemFileNames(int sel, String& strLeft, String& strRight) const;
115 void GetItemFileNames(int sel, PathContext * paths) const;
116 void FormatEncodingDialogDisplays(CLoadSaveCodepageDlg * dlg);
117 DirActions MakeDirActions(DirActions::method_type func) const;
118 DirActions MakeDirActions(DirActions::method_type2 func) const;
119 Counts Count(DirActions::method_type2 func) const;
120 void DoDirAction(DirActions::method_type func, const String& status_message);
121 void DoDirActionTo(SIDE_TYPE stype, DirActions::method_type func, const String& status_message);
122 void DoOpen(SIDE_TYPE stype);
123 void DoOpenWith(SIDE_TYPE stype);
124 void DoOpenWithEditor(SIDE_TYPE stype);
125 void DoOpenParentFolder(SIDE_TYPE stype);
126 void DoUpdateOpen(SELECTIONTYPE selectionType, CCmdUI* pCmdUI, bool openableForDir = true);
127 void ConfirmAndPerformActions(FileActionScript & actions);
128 void PerformActionList(FileActionScript & actions);
129 void UpdateAfterFileScript(FileActionScript & actionList);
130 void DoFileEncodingDialog();
132 // End DirActions.cpp
133 void ReflectGetdispinfo(NMLVDISPINFO *);
135 // Implementation in DirViewColHandler.cpp
137 void UpdateColumnNames();
138 void SetColAlignments();
139 // class CompareState is used to pass parameters to the PFNLVCOMPARE callback function.
143 const DirViewColItems *const pColItems;
144 const CDiffContext *const pCtxt;
146 const bool bSortAscending;
147 const bool bTreeMode;
149 CompareState(const CDiffContext *pCtxt, const DirViewColItems *pColItems, int sortCol, bool bSortAscending, bool bTreeMode);
150 static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
152 void UpdateDiffItemStatus(UINT nIdx);
155 void NameColumn(const DirColInfo *col, int subitem);
156 int AddNewItem(int i, DIFFITEM *diffpos, int iImage, int iIndent);
157 // End DirViewCols.cpp
162 // ClassWizard generated virtual function overrides
163 //{{AFX_VIRTUAL(CDirView)
165 virtual void OnInitialUpdate();
166 virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
168 virtual BOOL PreTranslateMessage(MSG* pMsg);
169 virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
170 virtual BOOL OnChildNotify(UINT, WPARAM, LPARAM, LRESULT*);
171 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
177 int GetFocusedItem();
178 int GetFirstDifferentItem();
179 int GetLastDifferentItem();
180 int AddSpecialItems();
181 std::vector<String> GetCurrentColRegKeys();
182 void OpenSpecialItems(DIFFITEM *pos1, DIFFITEM *pos2, DIFFITEM *pos3);
184 // Implementation data
186 CSortHeaderCtrl m_ctlSortHeader;
187 CImageList m_imageList;
188 CImageList m_imageState;
190 std::unique_ptr<IListCtrl> m_pIList;
191 int m_nEscCloses; /**< Cached value for option for ESC closing window */
192 bool m_bExpandSubdirs;
193 CFont m_font; /**< User-selected font */
194 UINT m_nHiddenItems; /**< Count of items we have hidden */
195 bool m_bTreeMode; /**< `true` if tree mode is on*/
196 DirViewFilterSettings m_dirfilter;
197 std::unique_ptr<DirCompProgressBar> m_pCmpProgressBar;
198 clock_t m_compareStart; /**< Starting process time of the compare */
199 bool m_bUserCancelEdit; /**< `true` if the user cancels rename */
200 String m_lastCopyFolder; /**< Last Copy To -target folder. */
202 std::optional<int> m_firstDiffItem;
203 std::optional<int> m_lastDiffItem;
204 DIRCOLORSETTINGS m_cachedColors; /**< Cached color settings */
207 std::unique_ptr<CShellContextMenu> m_pShellContextMenuLeft; /**< Shell context menu for group of left files */
208 std::unique_ptr<CShellContextMenu> m_pShellContextMenuMiddle; /**< Shell context menu for group of middle files */
209 std::unique_ptr<CShellContextMenu> m_pShellContextMenuRight; /**< Shell context menu for group of right files */
210 HMENU m_hCurrentMenu; /**< Current shell context menu (either left or right) */
211 std::unique_ptr<DirViewTreeState> m_pSavedTreeState;
212 std::unique_ptr<DirViewColItems> m_pColItems;
215 // Generated message map functions
216 afx_msg void OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult);
217 afx_msg void OnContextMenu(CWnd*, CPoint point);
218 //{{AFX_MSG(CDirView)
219 afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
220 afx_msg void OnDirCopy(UINT id);
221 template<SIDE_TYPE srctype, SIDE_TYPE dsttype>
222 afx_msg void OnCtxtDirCopy();
223 afx_msg void OnUpdateDirCopy(CCmdUI* pCmdUI);
224 template<SIDE_TYPE srctype, SIDE_TYPE dsttype>
225 afx_msg void OnUpdateCtxtDirCopy(CCmdUI* pCmdUI);
226 template<SIDE_TYPE stype>
227 afx_msg void OnCtxtDirDel();
228 template<SIDE_TYPE stype>
229 afx_msg void OnUpdateCtxtDirDel(CCmdUI* pCmdUI);
230 afx_msg void OnCtxtDirDelBoth();
231 afx_msg void OnUpdateCtxtDirDelBoth(CCmdUI* pCmdUI);
232 template<SIDE_TYPE stype>
233 afx_msg void OnCtxtDirOpen();
234 template<SIDE_TYPE stype>
235 afx_msg void OnUpdateCtxtDirOpen(CCmdUI* pCmdUI);
236 template<SIDE_TYPE stype>
237 afx_msg void OnCtxtDirOpenWith();
238 template<SIDE_TYPE stype>
239 afx_msg void OnUpdateCtxtDirOpenWith(CCmdUI* pCmdUI);
240 template<SIDE_TYPE stype>
241 afx_msg void OnCtxtDirOpenWithEditor();
242 template<SIDE_TYPE stype>
243 afx_msg void OnUpdateCtxtDirOpenWithEditor(CCmdUI* pCmdUI);
244 template<SIDE_TYPE stype>
245 afx_msg void OnCtxtDirOpenParentFolder();
246 template<SIDE_TYPE stype>
247 afx_msg void OnUpdateCtxtDirOpenParentFolder(CCmdUI* pCmdUI);
248 template<SIDE_TYPE stype>
249 afx_msg void OnCtxtDirCopyTo();
250 template<SIDE_TYPE stype>
251 afx_msg void OnUpdateCtxtDirCopyTo(CCmdUI* pCmdUI);
252 afx_msg void OnUpdateCtxtDirCopyBothTo(CCmdUI* pCmdUI);
253 afx_msg void OnUpdateCtxtDirCopyBothDiffsOnlyTo(CCmdUI* pCmdUI);
254 template<SIDE_TYPE stype>
255 afx_msg void OnUpdateCtxtDirCopy2(CCmdUI* pCmdUI);
256 afx_msg void OnUpdateCtxtDirCopyBoth2(CCmdUI* pCmdUI);
257 afx_msg void OnDestroy();
258 afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
259 afx_msg void OnClick(NMHDR* pNMHDR, LRESULT* pResult);
260 afx_msg void OnFirstdiff();
261 afx_msg void OnUpdateFirstdiff(CCmdUI* pCmdUI);
262 afx_msg void OnLastdiff();
263 afx_msg void OnUpdateLastdiff(CCmdUI* pCmdUI);
264 afx_msg void OnNextdiff();
265 afx_msg void OnUpdateNextdiff(CCmdUI* pCmdUI);
266 afx_msg void OnPrevdiff();
267 afx_msg void OnUpdatePrevdiff(CCmdUI* pCmdUI);
268 afx_msg void OnCurdiff();
269 afx_msg void OnUpdateCurdiff(CCmdUI* pCmdUI);
270 afx_msg void OnUpdateSave(CCmdUI* pCmdUI);
271 afx_msg LRESULT OnUpdateUIMessage(WPARAM wParam, LPARAM lParam);
272 afx_msg void OnRefresh();
273 afx_msg void OnUpdateRefresh(CCmdUI* pCmdUI);
274 afx_msg void OnTimer(UINT_PTR nIDEvent);
275 afx_msg void OnEditColumns();
276 template<SIDE_TYPE stype>
277 afx_msg void OnReadOnly();
278 template<SIDE_TYPE stype>
279 afx_msg void OnUpdateReadOnly(CCmdUI* pCmdUI);
280 afx_msg void OnUpdateStatusLeftRO(CCmdUI* pCmdUI);
281 afx_msg void OnUpdateStatusMiddleRO(CCmdUI* pCmdUI);
282 afx_msg void OnUpdateStatusRightRO(CCmdUI* pCmdUI);
283 afx_msg void OnCustomizeColumns();
284 afx_msg void OnCtxtOpenWithUnpacker();
285 afx_msg void OnUpdateCtxtOpenWithUnpacker(CCmdUI* pCmdUI);
286 afx_msg void OnToolsGenerateReport();
287 afx_msg LRESULT OnGenerateFileCmpReport(WPARAM wParam, LPARAM lParam);
288 afx_msg void OnToolsGeneratePatch();
290 afx_msg void OnCtxtDirZip();
291 template<SIDE_TYPE stype>
292 afx_msg void OnCtxtDirShellContextMenu();
293 afx_msg void OnSelectAll();
294 afx_msg void OnUpdateSelectAll(CCmdUI* pCmdUI);
295 afx_msg void OnPluginPredifferMode(UINT nID);
296 afx_msg void OnUpdatePluginPredifferMode(CCmdUI* pCmdUI);
297 template<SIDE_TYPE side>
298 afx_msg void OnCopyPathnames();
299 afx_msg void OnCopyBothPathnames();
300 afx_msg void OnCopyFilenames();
301 afx_msg void OnUpdateCopyFilenames(CCmdUI* pCmdUI);
302 template<SIDE_TYPE side>
303 afx_msg void OnCopyToClipboard();
304 afx_msg void OnCopyBothToClipboard();
305 afx_msg void OnItemRename();
306 afx_msg void OnUpdateItemRename(CCmdUI* pCmdUI);
307 afx_msg void OnHideFilenames();
308 afx_msg void OnSize(UINT nType, int cx, int cy);
309 template<SIDE_TYPE stype>
310 afx_msg void OnCtxtDirMoveTo();
311 template<SIDE_TYPE stype>
312 afx_msg void OnUpdateCtxtDirMoveTo(CCmdUI* pCmdUI);
313 afx_msg void OnUpdateHideFilenames(CCmdUI* pCmdUI);
314 afx_msg void OnDelete();
315 afx_msg void OnUpdateDelete(CCmdUI* pCmdUI);
316 afx_msg void OnMarkedRescan();
317 afx_msg void OnUpdateStatusNum(CCmdUI* pCmdUI);
318 afx_msg void OnViewShowHiddenItems();
319 afx_msg void OnUpdateViewShowHiddenItems(CCmdUI* pCmdUI);
320 afx_msg void OnViewTreeMode();
321 afx_msg void OnUpdateViewTreeMode(CCmdUI* pCmdUI);
322 afx_msg void OnViewExpandAllSubdirs();
323 afx_msg void OnUpdateViewExpandAllSubdirs(CCmdUI* pCmdUI);
324 afx_msg void OnViewCollapseAllSubdirs();
325 afx_msg void OnUpdateViewCollapseAllSubdirs(CCmdUI* pCmdUI);
326 afx_msg void OnViewSwapPanes();
327 afx_msg void OnOptionsShowDifferent();
328 afx_msg void OnOptionsShowIdentical();
329 afx_msg void OnOptionsShowUniqueLeft();
330 afx_msg void OnOptionsShowUniqueMiddle();
331 afx_msg void OnOptionsShowUniqueRight();
332 afx_msg void OnOptionsShowBinaries();
333 afx_msg void OnOptionsShowSkipped();
334 afx_msg void OnOptionsShowDifferentLeftOnly();
335 afx_msg void OnOptionsShowDifferentMiddleOnly();
336 afx_msg void OnOptionsShowDifferentRightOnly();
337 afx_msg void OnOptionsShowMissingLeftOnly();
338 afx_msg void OnOptionsShowMissingMiddleOnly();
339 afx_msg void OnOptionsShowMissingRightOnly();
340 afx_msg void OnUpdateOptionsShowdifferent(CCmdUI* pCmdUI);
341 afx_msg void OnUpdateOptionsShowidentical(CCmdUI* pCmdUI);
342 afx_msg void OnUpdateOptionsShowuniqueleft(CCmdUI* pCmdUI);
343 afx_msg void OnUpdateOptionsShowuniquemiddle(CCmdUI* pCmdUI);
344 afx_msg void OnUpdateOptionsShowuniqueright(CCmdUI* pCmdUI);
345 afx_msg void OnUpdateOptionsShowBinaries(CCmdUI* pCmdUI);
346 afx_msg void OnUpdateOptionsShowSkipped(CCmdUI* pCmdUI);
347 afx_msg void OnUpdateOptionsShowDifferentLeftOnly(CCmdUI* pCmdUI);
348 afx_msg void OnUpdateOptionsShowDifferentMiddleOnly(CCmdUI* pCmdUI);
349 afx_msg void OnUpdateOptionsShowDifferentRightOnly(CCmdUI* pCmdUI);
350 afx_msg void OnUpdateOptionsShowMissingLeftOnly(CCmdUI* pCmdUI);
351 afx_msg void OnUpdateOptionsShowMissingMiddleOnly(CCmdUI* pCmdUI);
352 afx_msg void OnUpdateOptionsShowMissingRightOnly(CCmdUI* pCmdUI);
353 afx_msg void OnMergeCompare();
354 template<SELECTIONTYPE seltype>
355 afx_msg void OnMergeCompare2();
356 afx_msg void OnMergeCompareNonHorizontally();
357 afx_msg void OnMergeCompareXML();
358 afx_msg void OnMergeCompareAs(UINT nID);
359 afx_msg void OnUpdateMergeCompare(CCmdUI *pCmdUI);
360 template<SELECTIONTYPE seltype>
361 afx_msg void OnUpdateMergeCompare2(CCmdUI *pCmdUI);
362 afx_msg void OnViewCompareStatistics();
363 afx_msg void OnFileEncoding();
364 afx_msg void OnHelp();
365 afx_msg void OnEditCopy();
366 afx_msg void OnEditCut();
367 afx_msg void OnEditPaste();
368 afx_msg void OnEditUndo();
369 afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI);
370 afx_msg void OnItemChanged(NMHDR* pNMHDR, LRESULT* pResult);
371 afx_msg void OnBeginLabelEdit(NMHDR* pNMHDR, LRESULT* pResult);
372 afx_msg void OnEndLabelEdit(NMHDR* pNMHDR, LRESULT* pResult);
373 afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
374 afx_msg void OnSearch();
375 afx_msg void OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult);
376 afx_msg void OnBnClickedComparisonStop();
377 afx_msg void OnBnClickedComparisonPause();
378 afx_msg void OnBnClickedComparisonContinue();
380 DECLARE_MESSAGE_MAP()
381 bool OnHeaderBeginDrag(LPNMHEADER hdr, LRESULT* pResult);
382 bool OnHeaderEndDrag(LPNMHEADER hdr, LRESULT* pResult);
385 void Open(const PathContext& paths, DWORD dwFlags[3], PackingInfo * infoUnpacker = nullptr);
386 void OpenSelection(SELECTIONTYPE selectionType = SELECTIONTYPE_NORMAL, PackingInfo * infoUnpacker = nullptr, bool openableForDir = true);
387 void OpenSelectionAs(UINT id);
388 bool GetSelectedItems(int * sel1, int * sel2, int * sel3);
389 void OpenParentDirectory();
390 template<SIDE_TYPE srctype, SIDE_TYPE dsttype>
391 void DoUpdateDirCopy(CCmdUI* pCmdUI, eMenuType menuType);
392 const DIFFITEM &GetDiffItem(int sel) const;
393 DIFFITEM &GetDiffItem(int sel);
394 int GetSingleSelectedItem() const;
395 void MoveFocus(int currentInd, int i, int selCount);
397 void FixReordering();
398 void HeaderContextMenu(CPoint point, int i);
399 void ListContextMenu(CPoint point, int i);
400 bool ListShellContextMenu(SIDE_TYPE side);
401 void ShowShellContextMenu(SIDE_TYPE side);
402 CShellContextMenu* GetCorrespondingShellContextMenu(HMENU hMenu) const;
403 void ReloadColumns();
404 bool IsLabelEdit() const;
405 void CollapseSubdir(int sel);
406 void ExpandSubdir(int sel, bool bRecursive = false);
407 void GetColors(int nRow, int nCol, COLORREF& clrBk, COLORREF& clrText) const;
409 DirItemIterator Begin() const { return DirItemIterator(m_pIList.get()); }
410 DirItemIterator End() const { return DirItemIterator(); }
411 DirItemIterator RevBegin() const { return DirItemIterator(m_pIList.get(), -1, false, true); }
412 DirItemIterator RevEnd() const { return DirItemIterator(); }
413 DirItemIterator SelBegin() const { return DirItemIterator(m_pIList.get(), -1, true); }
414 DirItemIterator SelEnd() const { return DirItemIterator(); }
415 DirItemIterator SelRevBegin() const { return DirItemIterator(m_pIList.get(), -1, true, true); }
416 DirItemIterator SelRevEnd() const { return DirItemIterator(); }
419 #ifndef _DEBUG // debug version in DirView.cpp
420 inline CDirDoc* CDirView::GetDocument()
421 { return reinterpret_cast<CDirDoc*>(m_pDocument); }