#include "BCMenu.h"
#include "DirCmpReportDlg.h"
#include "DirCmpReport.h"
-#include "DirCompProgressBar.h"
#include "CompareStatisticsDlg.h"
#include "LoadSaveCodepageDlg.h"
#include "ConfirmFolderCopyDlg.h"
#include "PatchTool.h"
#include "SyntaxColors.h"
#include "Shell.h"
+#include "DirTravel.h"
#include <numeric>
#include <functional>
CDirView::CDirView()
: m_pList(nullptr)
- , m_nHiddenItems(0)
- , m_pCmpProgressBar(nullptr)
, m_compareStart(0)
+ , m_elapsed(0)
, m_bTreeMode(false)
, m_dirfilter(std::bind(&COptionsMgr::GetBool, GetOptionsMgr(), _1))
, m_pShellContextMenuLeft(nullptr)
m_dwDefaultStyle &= ~LVS_TYPEMASK;
// Show selection all the time, so user can see current item even when
// focus is elsewhere (ie, on file edit window)
- m_dwDefaultStyle |= LVS_REPORT | LVS_SHOWSELALWAYS | LVS_EDITLABELS;
+ m_dwDefaultStyle |= LVS_REPORT | LVS_SHOWSELALWAYS | LVS_EDITLABELS | LVS_OWNERDATA;
m_bTreeMode = GetOptionsMgr()->GetBool(OPT_TREE_MODE);
m_bExpandSubdirs = GetOptionsMgr()->GetBool(OPT_DIRVIEW_EXPAND_SUBDIRS);
ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, OnItemChanged)
ON_NOTIFY_REFLECT(LVN_BEGINLABELEDIT, OnBeginLabelEdit)
ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndLabelEdit)
+ ON_NOTIFY_REFLECT(LVN_ODFINDITEM, OnODFindItem)
ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnBeginDrag)
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
ON_UPDATE_COMMAND_UI(ID_MERGE_COMPARE_LEFT2_RIGHT1, OnUpdateMergeCompare2<SELECTIONTYPE_LEFT2RIGHT1>)
ON_COMMAND(ID_MERGE_COMPARE_NONHORIZONTALLY, OnMergeCompareNonHorizontally)
// Context menu -> Compare As
- ON_COMMAND_RANGE(ID_MERGE_COMPARE_TEXT, ID_MERGE_COMPARE_IMAGE, OnMergeCompareAs)
+ ON_COMMAND_RANGE(ID_MERGE_COMPARE_TEXT, ID_MERGE_COMPARE_WEBPAGE, OnMergeCompareAs)
ON_COMMAND_RANGE(ID_UNPACKERS_FIRST, ID_UNPACKERS_LAST, OnMergeCompareAs)
- ON_UPDATE_COMMAND_UI_RANGE(ID_MERGE_COMPARE_TEXT, ID_MERGE_COMPARE_IMAGE, OnUpdateMergeCompare)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_MERGE_COMPARE_TEXT, ID_MERGE_COMPARE_WEBPAGE, OnUpdateMergeCompare)
ON_UPDATE_COMMAND_UI(ID_NO_UNPACKER, OnUpdateNoUnpacker)
// Context menu -> Copy
ON_COMMAND(ID_DIR_COPY_LEFT_TO_RIGHT, (OnCtxtDirCopy<SIDE_LEFT, SIDE_RIGHT>))
ON_UPDATE_COMMAND_UI(ID_STATUS_RIGHTDIR_RO, OnUpdateStatusRightRO)
ON_UPDATE_COMMAND_UI(ID_STATUS_MIDDLEDIR_RO, OnUpdateStatusMiddleRO)
ON_UPDATE_COMMAND_UI(ID_STATUS_LEFTDIR_RO, OnUpdateStatusLeftRO)
- // Progress dialog
- ON_BN_CLICKED(IDC_COMPARISON_STOP, OnBnClickedComparisonStop)
- ON_BN_CLICKED(IDC_COMPARISON_PAUSE, OnBnClickedComparisonPause)
- ON_BN_CLICKED(IDC_COMPARISON_CONTINUE, OnBnClickedComparisonContinue)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
return 48;
}();
const int iconCY = iconCX;
- CListView::OnInitialUpdate();
+ __super::OnInitialUpdate();
m_pList = &GetListCtrl();
- m_pIList.reset(new IListCtrlImpl(m_pList->m_hWnd));
+ m_pIList.reset(new IListCtrlImpl(m_pList->m_hWnd, m_listViewItems));
CDirDoc* pDoc = GetDocument();
pDoc->SetDirView(this);
// Show selection across entire row.u
// Also allow user to rearrange columns via drag&drop of headers.
// Also enable infotips.
- DWORD exstyle = LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP | LVS_EX_INFOTIP;
+ DWORD exstyle = LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP | LVS_EX_INFOTIP | LVS_EX_DOUBLEBUFFER;
m_pList->SetExtendedStyle(exstyle);
}
BOOL CDirView::PreCreateWindow(CREATESTRUCT& cs)
{
- CListView::PreCreateWindow(cs);
+ __super::PreCreateWindow(cs);
cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
return TRUE;
}
*/
void CDirView::StartCompare(CompareStats *pCompareStats)
{
- if (m_pCmpProgressBar == nullptr)
- m_pCmpProgressBar.reset(new DirCompProgressBar());
-
- if (!::IsWindow(m_pCmpProgressBar->GetSafeHwnd()))
- m_pCmpProgressBar->Create(GetParentFrame());
-
- m_pCmpProgressBar->SetCompareStat(pCompareStats);
- m_pCmpProgressBar->StartUpdating();
-
- GetParentFrame()->ShowControlBar(m_pCmpProgressBar.get(), TRUE, FALSE);
-
m_compareStart = clock();
}
}
}
if (GetFocus() == this)
- CListView::OnLButtonDblClk(nFlags, point);
+ __super::OnLButtonDblClk(nFlags, point);
}
/**
index++;
if (di.HasChildren())
{
- m_pList->SetItemState(index - 1, INDEXTOSTATEIMAGEMASK((di.customFlags & ViewCustomFlags::EXPANDED) ? 2 : 1), LVIS_STATEIMAGEMASK);
if (di.customFlags & ViewCustomFlags::EXPANDED)
RedisplayChildren(ctxt.GetFirstChildDiffPosition(curdiffpos), level + 1, index, alldiffs);
}
}
else
{
- if (!ctxt.m_bRecursive || !di.diffcode.isDirectory() || !di.diffcode.existAll())
+ if (!ctxt.m_bRecursive || !di.diffcode.isDirectory() || (!di.diffcode.existAll() && !di.HasChildren()))
{
AddNewItem(index, curdiffpos, I_IMAGECALLBACK, 0);
index++;
GetParentFrame()->SetLastCompareResult(alldiffs);
SortColumnsAppropriately();
SetRedraw(TRUE);
+ m_pList->SetItemCount(static_cast<int>(m_listViewItems.size()));
+ m_pList->Invalidate();
}
/**
ASSERT(pPopup != nullptr);
int sel = GetFocusedItem();
+ if (sel == -1)
+ sel = GetFirstSelectedInd();
+ if (sel == -1)
+ return;
const DIFFITEM& di = GetDiffItem(sel);
if (GetDiffContext().m_bRecursive && di.diffcode.isDirectory())
pPopup->RemoveMenu(ID_MERGE_COMPARE, MF_BYCOMMAND);
try {
// First we build a list of desired actions
FileActionScript actionScript;
- actionScript.m_destBase = destPath;
+ actionScript.m_destBase = std::move(destPath);
DirItemWithIndexIterator begin(m_pIList.get(), -1, true);
DirItemWithIndexIterator end;
FileActionScript *rsltScript;
m_ctlSortHeader.SetSortImage(m_pColItems->ColLogToPhys(sortCol), bSortAscending);
//sort using static CompareFunc comparison function
CompareState cs(&GetDiffContext(), m_pColItems.get(), sortCol, bSortAscending, m_bTreeMode);
- GetListCtrl().SortItems(cs.CompareFunc, reinterpret_cast<DWORD_PTR>(&cs));
+ std::stable_sort(m_listViewItems.begin(), m_listViewItems.end(), [&cs](const ListViewOwnerDataItem& a, const ListViewOwnerDataItem& b)
+ { return CompareState::CompareFunc(a.lParam, b.lParam, reinterpret_cast<LPARAM>(&cs)) < 0; });
m_firstDiffItem.reset();
m_lastDiffItem.reset();
+
+ m_pList->Invalidate();
}
/// Do any last minute work as view closes
m_pColItems->SaveColumnWidths(std::bind(&CListCtrl::GetColumnWidth, m_pList, _1)));
}
- CListView::OnDestroy();
-
- GetMainFrame()->ClearStatusbarItemCount();
+ __super::OnDestroy();
}
/**
}
}
}
- CListView::OnChar(nChar, nRepCnt, nFlags);
+ __super::OnChar(nChar, nRepCnt, nFlags);
}
/**
m_pList->SetRedraw(FALSE); // Turn off updating (better performance)
dip.customFlags &= ~ViewCustomFlags::EXPANDED;
- m_pList->SetItemState(sel, INDEXTOSTATEIMAGEMASK(1), LVIS_STATEIMAGEMASK);
int count = m_pList->GetItemCount();
for (int i = sel + 1; i < count; i++)
const DIFFITEM& di = GetDiffItem(i);
if (!di.IsAncestor(&dip))
break;
+ m_listViewItems.erase(m_listViewItems.begin() + i);
m_pList->DeleteItem(i--);
count--;
}
return;
m_pList->SetRedraw(FALSE); // Turn off updating (better performance)
- m_pList->SetItemState(sel, INDEXTOSTATEIMAGEMASK(2), LVIS_STATEIMAGEMASK);
+
+ const int top = m_pList->GetTopIndex();
+ const size_t num = m_listViewItems.size();
CDiffContext &ctxt = GetDiffContext();
dip.customFlags |= ViewCustomFlags::EXPANDED;
int alldiffs;
RedisplayChildren(diffpos, dip.GetDepth() + 1, indext, alldiffs);
+ for (size_t i = 0; i < m_listViewItems.size() - num; ++i)
+ m_pList->InsertItem(sel + 1, nullptr);
+
SortColumnsAppropriately();
m_pList->SetRedraw(TRUE); // Turn updating back on
+ m_pList->SetItemCount(static_cast<int>(m_listViewItems.size()));
+ m_pList->EnsureVisible(top, TRUE);
+ m_pList->Invalidate();
}
/**
{
// Open subfolders
// Don't add folders to MRU
- GetMainFrame()->DoFileOrFolderOpen(&paths, dwFlags, nullptr, _T(""), GetDiffContext().m_bRecursive, (GetAsyncKeyState(VK_CONTROL) & 0x8000) ? nullptr : pDoc);
+ GetMainFrame()->DoFileOrFolderOpen(&paths, dwFlags, nullptr, _T(""), GetDiffContext().m_bRecursive,
+ ((GetAsyncKeyState(VK_CONTROL) & 0x8000) || GetDiffContext().m_bRecursive) ? nullptr : pDoc);
}
else if (HasZipSupport() && std::count_if(paths.begin(), paths.end(), ArchiveGuessFormat) == paths.GetSize())
{
GetDiffContext().FetchPluginInfos(filteredFilenames, &infoUnpacker, &infoPrediffer);
}
- GetMainFrame()->ShowAutoMergeDoc(GetDocument(), paths.GetSize(), fileloc,
+ GetMainFrame()->ShowAutoMergeDoc(0, GetDocument(), paths.GetSize(), fileloc,
dwFlags, strDesc, _T(""), infoUnpacker);
}
}
{
PackingInfo infoUnpacker(
CMainFrame::GetPluginPipelineByMenuId(id, FileTransform::UnpackerEventNames, ID_UNPACKERS_FIRST));
- GetMainFrame()->ShowAutoMergeDoc(pDoc, paths.GetSize(), fileloc, dwFlags, strDesc, _T(""), &infoUnpacker);
+ GetMainFrame()->DoFileOrFolderOpen(&paths, dwFlags, strDesc, _T(""),
+ ctxt.m_bRecursive, nullptr, &infoUnpacker, nullptr, 0);
}
else
{
*/
DIFFITEM *CDirView::GetItemKey(int idx) const
{
- return (DIFFITEM *) m_pList->GetItemData(idx);
+ ASSERT(idx >= 0 && idx < static_cast<int>(m_listViewItems.size()));
+ return reinterpret_cast<DIFFITEM*>(m_listViewItems[idx].lParam);
}
// SetItemKey & GetItemKey encapsulate how the display list items
if (m_bTreeMode)
{
CollapseSubdir(sel);
+ m_listViewItems.erase(m_listViewItems.begin() + sel);
m_pList->DeleteItem(sel);
}
else if (GetDiffContext().m_bRecursive || diffpos->HasChildren())
int cursel = it.m_sel;
++it;
if (di.IsAncestor(diffpos) || diffpos == &di)
+ {
+ m_listViewItems.erase(m_listViewItems.begin() + cursel);
m_pList->DeleteItem(cursel);
+ }
}
}
else
{
+ m_listViewItems.erase(m_listViewItems.begin() + sel);
m_pList->DeleteItem(sel);
}
if (removeDIFFITEM)
// item data are just positions (diffposes)
// that is, they contain no memory needing to be freed
m_pList->DeleteAllItems();
+ m_listViewItems.clear();
m_firstDiffItem.reset();
m_lastDiffItem.reset();
*/
int CDirView::GetItemIndex(DIFFITEM *key)
{
- LVFINDINFO findInfo;
-
- findInfo.flags = LVFI_PARAM; // Search for itemdata
- findInfo.lParam = (LPARAM)key;
- return m_pList->FindItem(&findInfo);
+ for (size_t i = 0; i < m_listViewItems.size(); ++i)
+ {
+ if (m_listViewItems[i].lParam == reinterpret_cast<LPARAM>(key))
+ return static_cast<int>(i);
+ }
+ return 0;
}
/**
m_pList->SetItemState(currentInd, 0, LVIS_SELECTED);
m_pList->SetItemState(currentInd, 0, LVIS_FOCUSED);
m_pList->SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
+ m_pList->SetSelectionMark(i);
}
// Move focus to specified item
{
// can't verify cast without introducing more coupling
// (CDirView doesn't include DirFrame.h)
- return static_cast<CDirFrame *>(CListView::GetParentFrame());
+ return static_cast<CDirFrame *>(__super::GetParentFrame());
}
void CDirView::OnRefresh()
// Check if we got 'ESC pressed' -message
if (pMsg->wParam == VK_ESCAPE)
{
- if (m_pCmpProgressBar != nullptr)
+ if (GetDocument()->m_diffThread.GetThreadState() == CDiffThread::THREAD_COMPARING)
{
- OnBnClickedComparisonStop();
+ GetDocument()->AbortCurrentScan();
return TRUE;
}
}
}
}
- return CListView::PreTranslateMessage(pMsg);
+ return __super::PreTranslateMessage(pMsg);
}
void CDirView::OnUpdateRefresh(CCmdUI* pCmdUI)
CDirDoc * pDoc = GetDocument();
ASSERT(pDoc != nullptr);
+ // Since the Collect thread deletes the DiffItems in the rescan by "Update selection",
+ // the UI update process should not be executed until the Collect thread process is completed
+ // to avoid accessing the deleted DiffItem.
+ if (pDoc->m_diffThread.IsMarkedRescan() && pDoc->m_diffThread.GetCollectThreadState() != CDiffThread::THREAD_COMPLETED)
+ {
+ ASSERT(0);
+ return 0; // return value unused
+ }
+
if (wParam == CDiffThread::EVENT_COMPARE_COMPLETED)
{
if (pDoc->GetDiffContext().m_pPropertySystem && pDoc->GetDiffContext().m_pPropertySystem->HasHashProperties())
pDoc->GetDiffContext().CreateDuplicateValueMap();
- // Close and destroy the dialog after compare
- if (m_pCmpProgressBar != nullptr)
- GetParentFrame()->ShowControlBar(m_pCmpProgressBar.get(), FALSE, FALSE);
- m_pCmpProgressBar.reset();
-
pDoc->CompareReady();
if (!pDoc->GetGeneratingReport())
MoveFocus(0, 0, 0);
// If compare took more than TimeToSignalCompare seconds, notify user
- clock_t elapsed = clock() - m_compareStart;
- GetParentFrame()->SetStatus(
- strutils::format(_("Elapsed time: %ld ms"), elapsed).c_str()
- );
- if (elapsed > TimeToSignalCompare * CLOCKS_PER_SEC)
+ m_elapsed = clock() - m_compareStart;
+ SetTimer(STATUSBAR_UPDATE, 150, nullptr);
+ if (m_elapsed > TimeToSignalCompare * CLOCKS_PER_SEC)
MessageBeep(IDOK);
GetMainFrame()->StartFlashing();
}
else
Redisplay();
}
+
+ HideItems(GetDiffContext().m_vCurrentlyHiddenItems);
}
return 0; // return value unused
}
-
BOOL CDirView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
NMHDR * hdr = reinterpret_cast<NMHDR *>(lParam);
if (hdr->code == HDN_BEGINDRAG)
return OnHeaderBeginDrag((LPNMHEADER)hdr, pResult);
- return CListView::OnNotify(wParam, lParam, pResult);
+ return __super::OnNotify(wParam, lParam, pResult);
}
BOOL CDirView::OnChildNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
return TRUE;
}
}
- return CListView::OnChildNotify(uMsg, wParam, lParam, pResult);
+ return __super::OnChildNotify(uMsg, wParam, lParam, pResult);
}
/**
{
KillTimer(STATUSBAR_UPDATE);
int items = GetSelectedCount();
- String msg = (items == 1) ? _("1 item selected") : strutils::format_string1(_("%1 items selected"), strutils::to_str(items));
+ String msg;
+ if (m_elapsed != 0)
+ {
+ msg = strutils::format(_("Elapsed time: %ld ms"), m_elapsed);
+ m_elapsed = 0;
+ }
+ else
+ {
+ msg = (items == 1) ? _("1 item selected") : strutils::format_string1(_("%1 items selected"), strutils::to_str(items));
+ }
GetParentFrame()->SetStatus(msg.c_str());
}
- CListView::OnTimer(nIDEvent);
+ __super::OnTimer(nIDEvent);
}
/**
return false;
}
- sLinkPath = di.diffFileInfo[0].GetFile();
+ sLinkPath = strutils::format(_T("%d_"), nIndex) + di.diffFileInfo[0].GetFile();
strutils::replace(sLinkPath, _T("\\"), _T("_"));
sLinkPath += _T(".html");
pReport->SetRootPaths(paths);
pReport->SetColumns(m_pColItems->GetDispColCount());
pReport->SetFileCmpReport(new FileCmpReport(this));
- pReport->SetList(new IListCtrlImpl(m_pList->m_hWnd));
+ pReport->SetList(new IListCtrlImpl(m_pList->m_hWnd, m_listViewItems));
pReport->SetReportType(dlg.m_nReportType);
pReport->SetReportFile(dlg.m_sReportFile);
pReport->SetCopyToClipboard(dlg.m_bCopyToClipboard);
{
case ID_PREDIFFER_SETTINGS_NONE:
case ID_UNPACKER_SETTINGS_NONE:
- pluginPipeline = _T("");
+ pluginPipeline.clear();
break;
case ID_PREDIFFER_SETTINGS_AUTO:
case ID_UNPACKER_SETTINGS_AUTO:
void CDirView::OnUpdateItemRename(CCmdUI* pCmdUI)
{
bool bEnabled = (1 == m_pList->GetSelectedCount());
- pCmdUI->Enable(bEnabled && SelBegin() != SelEnd());
+ if (bEnabled)
+ {
+ Counts counts = Count(&DirActions::IsItemRenamable);
+ bEnabled = (counts.count > 0 && counts.total == 1);
+ }
+ pCmdUI->Enable(bEnabled);
}
/**
*/
void CDirView::OnHideFilenames()
{
+ CDiffContext& ctxt = GetDiffContext();
+ int selection_index;
+ String hiddden_item_path;
+
m_pList->SetRedraw(FALSE); // Turn off updating (better performance)
DirItemIterator it;
+
while ((it = SelRevBegin()) != SelRevEnd())
{
DIFFITEM &di = *it;
+ selection_index = it.m_sel;
+ hiddden_item_path = di.getItemRelativePath();
SetItemViewFlag(di, ViewCustomFlags::HIDDEN, ViewCustomFlags::VISIBILITY);
- DeleteItem(it.m_sel);
- m_nHiddenItems++;
+ DeleteItem(selection_index);
+ ctxt.m_vCurrentlyHiddenItems.push_back(hiddden_item_path);
+ }
+ m_pList->SetRedraw(TRUE); // Turn updating back on
+}
+
+/**
+ * @brief determine if an item-relative-path is contained in the list of items to hide
+ */
+bool CDirView::IsItemToHide(const String& currentItem, const std::vector<String>& ItemsToHide) const
+{
+ return std::find(ItemsToHide.begin(), ItemsToHide.end(), currentItem) != ItemsToHide.end();
+}
+
+/**
+ * @brief hides items specified in the .winmerge file
+ */
+
+void CDirView::HideItems(const std::vector<String>& ItemsToHide)
+{
+ CDiffContext& ctxt = GetDiffContext();
+ DIFFITEM *diffpos = ctxt.GetFirstDiffPosition();
+ while (diffpos != nullptr)
+ {
+ DIFFITEM &di = ctxt.GetNextDiffRefPosition(diffpos);
+ if (IsItemToHide(di.getItemRelativePath(), ItemsToHide))
+ SetItemViewFlag(di, ViewCustomFlags::HIDDEN, ViewCustomFlags::VISIBILITY);
+ }
+
+ m_pList->SetRedraw(FALSE); // Turn off updating (better performance)
+
+ int num_hidden = 0;
+ const size_t num_to_hide = ItemsToHide.size();
+ DirItemIterator it = RevBegin();
+ while((num_hidden < num_to_hide) && (it != RevEnd()))
+ {
+ DIFFITEM& di = *it;
+ if (di.customFlags & ViewCustomFlags::HIDDEN)
+ {
+ DeleteItem(it.m_sel);
+ num_hidden++;
+ }
+ ++it;
}
+
m_pList->SetRedraw(TRUE); // Turn updating back on
}
*/
void CDirView::OnSize(UINT nType, int cx, int cy)
{
- CListView::OnSize(nType, cx, cy);
+ __super::OnSize(nType, cx, cy);
GetDocument()->SetTitle(nullptr);
}
if ((pNMListView->uOldState & LVIS_SELECTED) !=
(pNMListView->uNewState & LVIS_SELECTED))
{
- if ((pNMListView->iItem % 5000) > 0)
- SetTimer(STATUSBAR_UPDATE, 100, nullptr);
- else
- OnTimer(STATUSBAR_UPDATE);
+ SetTimer(STATUSBAR_UPDATE, 100, nullptr);
}
*pResult = 0;
}
*/
afx_msg void CDirView::OnBeginLabelEdit(NMHDR* pNMHDR, LRESULT* pResult)
{
- *pResult = (SelBegin() == SelEnd());
+ Counts counts = Count(&DirActions::IsItemRenamable);
+ *pResult = !(counts.count > 0 && counts.total == 1);
// If label edit is allowed.
if (*pResult == FALSE)
CString sText;
pEdit->GetWindowText(sText);
- if (!sText.IsEmpty())
+ if (!sText.IsEmpty() && paths::IsValidName(String(sText)))
{
try {
DirItemIterator it(m_pIList.get(), reinterpret_cast<NMLVDISPINFO *>(pNMHDR)->item.iItem);
+ DIFFITEM& di = *it;
+ unsigned sideFlags = (di.diffcode.diffcode & DIFFCODE::SIDEFLAGS);
*pResult = DoItemRename(it, GetDiffContext(), String(sText));
+ // Rescan the item if side flags change due to renaming.
+ if (*pResult)
+ {
+ if ((di.diffcode.diffcode & DIFFCODE::SIDEFLAGS) != sideFlags)
+ {
+ // Delete the item with the same file name as after renaming.
+ if (di.HasParent())
+ {
+ for (DIFFITEM* pItem = di.GetParentLink()->GetFirstChild(); pItem != nullptr; pItem = pItem->GetFwdSiblingLink())
+ {
+ if ((pItem != &di) && (pItem->diffcode.isDirectory() == di.diffcode.isDirectory()) && (collstr(pItem->diffFileInfo[0].filename, di.diffFileInfo[0].filename, false) == 0))
+ {
+ pItem->DelinkFromSiblings();
+ delete pItem;
+ break;
+ }
+ }
+ }
+ // Rescan the item.
+ MarkForRescan(di);
+ m_pSavedTreeState.reset(SaveTreeState(GetDiffContext()));
+ GetDocument()->SetMarkedRescan();
+ GetDocument()->Rescan();
+ }
+ else {
+ int nDirs = GetDiffContext().GetCompareDirs();
+ assert(nDirs == 2 || nDirs == 3);
+ UpdatePaths(nDirs, di);
+
+ int nIdx = reinterpret_cast<NMLVDISPINFO*>(pNMHDR)->item.iItem;
+ UpdateDiffItemStatus(nIdx);
+ }
+ }
} catch (ContentsChangedException& e) {
AfxMessageBox(e.m_msg.c_str(), MB_ICONWARNING);
}
}
+ else
+ {
+ LangMessageBox(IDS_ERROR_INVALID_DIR_FILE_NAME, MB_ICONWARNING);
+ }
}
}
+void CDirView::OnODFindItem(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ NMLVFINDITEM* pFindItem = reinterpret_cast<NMLVFINDITEM*>(pNMHDR);
+ if (pFindItem->lvfi.flags & LVFI_STRING)
+ {
+ String text = strutils::makelower(pFindItem->lvfi.psz);
+ for (size_t i = pFindItem->iStart; i < m_listViewItems.size(); ++i)
+ {
+ DIFFITEM *di = GetItemKey(static_cast<int>(i));
+ String filename = strutils::makelower(di->diffFileInfo[0].filename);
+ if (di && _tcsncmp(text.c_str(), filename.c_str(), text.length()) == 0)
+ {
+ *pResult = i;
+ return;
+ }
+ }
+ }
+ *pResult = -1;
+}
+
/**
* @brief Called when item is marked for rescan.
* This function marks selected items for rescan and rescans them.
*/
void CDirView::OnViewShowHiddenItems()
{
+ CDiffContext& ctxt = GetDiffContext();
SetItemViewFlag(GetDiffContext(), ViewCustomFlags::VISIBLE, ViewCustomFlags::VISIBILITY);
- m_nHiddenItems = 0;
+ ctxt.m_vCurrentlyHiddenItems.clear();
Redisplay();
}
*/
void CDirView::OnUpdateViewShowHiddenItems(CCmdUI* pCmdUI)
{
- pCmdUI->Enable(m_nHiddenItems > 0);
+ const CDiffContext& ctxt = GetDiffContext();
+ pCmdUI->Enable(ctxt.m_vCurrentlyHiddenItems.size() > 0);
}
/**
void CDirView::OnUpdateMergeCompare(CCmdUI *pCmdUI)
{
- bool openableForDir = !((pCmdUI->m_nID >= ID_MERGE_COMPARE_TEXT && pCmdUI->m_nID <= ID_MERGE_COMPARE_IMAGE) ||
+ bool openableForDir = !((pCmdUI->m_nID >= ID_MERGE_COMPARE_TEXT && pCmdUI->m_nID <= ID_MERGE_COMPARE_WEBPAGE) ||
(pCmdUI->m_nID >= ID_UNPACKERS_FIRST && pCmdUI->m_nID <= ID_UNPACKERS_LAST));
DoUpdateOpen(SELECTIONTYPE_NORMAL, pCmdUI, openableForDir);
pMenu->HandleMenuMessage(message, wParam, lParam, res);
}
- return CListView::WindowProc(message, wParam, lParam);
+ return __super::WindowProc(message, wParam, lParam);
}
/**
}
}
-void CDirView::OnBnClickedComparisonStop()
-{
- if (m_pCmpProgressBar != nullptr)
- m_pCmpProgressBar->EndUpdating();
- GetDocument()->AbortCurrentScan();
-}
-
-void CDirView::OnBnClickedComparisonPause()
-{
- if (m_pCmpProgressBar != nullptr)
- m_pCmpProgressBar->SetPaused(true);
- GetDocument()->PauseCurrentScan();
-}
-
-void CDirView::OnBnClickedComparisonContinue()
-{
- if (m_pCmpProgressBar != nullptr)
- m_pCmpProgressBar->SetPaused(false);
- GetDocument()->ContinueCurrentScan();
-}
-
/**
* @brief Populate colors for items in view, depending on difference status
*/
CDirDoc *pDoc = GetDocument();
m_pList->SetRedraw(FALSE); // Turn off updating (better performance)
int nRows = m_pList->GetItemCount();
+ CDiffContext& ctxt = GetDiffContext();
+
for (int currRow = nRows - 1; currRow >= 0; currRow--)
{
DIFFITEM *pos = GetItemKey(currRow);
bool bFound = false;
DIFFITEM &di = GetDiffItem(currRow);
PathContext paths;
+
for (int i = 0; i < pDoc->m_nDirs; i++)
{
if (di.diffcode.exists(i) && !di.diffcode.isDirectory())
}
if (!bFound)
{
+ String hiddden_item_path = di.getItemRelativePath();
SetItemViewFlag(di, ViewCustomFlags::HIDDEN, ViewCustomFlags::VISIBILITY);
DeleteItem(currRow);
- m_nHiddenItems++;
+ ctxt.m_vCurrentlyHiddenItems.push_back(hiddden_item_path);
}
}
m_pList->SetRedraw(TRUE); // Turn updating back on
*/
void CDirView::OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult)
{
- COleDataSource *DropData = new COleDataSource();
-
std::list<String> list;
CopyPathnamesForDragAndDrop(SelBegin(), SelEnd(), std::back_inserter(list), GetDiffContext());
String filesForDroping = strutils::join(list.begin(), list.end(), _T("\n")) + _T("\n");
HGLOBAL hMem = GlobalReAlloc(file.Detach(), (filesForDroping.length() + 1) * sizeof(TCHAR), 0);
if (hMem != nullptr)
{
+ COleDataSource* DropData = new COleDataSource();
DropData->CacheGlobalData(CF_UNICODETEXT, hMem);
DROPEFFECT de = DropData->DoDragDrop(DROPEFFECT_COPY | DROPEFFECT_MOVE, nullptr);
}
}
/// Add new item to list view
-int CDirView::AddNewItem(int i, DIFFITEM *diffpos, int iImage, int iIndent)
+void CDirView::AddNewItem(int i, DIFFITEM *diffpos, int iImage, int iIndent)
{
- LV_ITEM lvItem;
- lvItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE | LVIF_INDENT;
- lvItem.iItem = i;
+ ListViewOwnerDataItem lvItem;
lvItem.iIndent = iIndent;
- lvItem.iSubItem = 0;
- lvItem.pszText = LPSTR_TEXTCALLBACK;
lvItem.lParam = (LPARAM)diffpos;
lvItem.iImage = iImage;
- return GetListCtrl().InsertItem(&lvItem);
+ if (i == static_cast<int>(m_listViewItems.size()))
+ m_listViewItems.push_back(lvItem);
+ else
+ m_listViewItems.insert(m_listViewItems.begin() + i, lvItem);
}
/**
void CDirView::ReflectGetdispinfo(NMLVDISPINFO *pParam)
{
int nIdx = pParam->item.iItem;
+ if (nIdx >= static_cast<int>(m_listViewItems.size()))
+ return;
+ DIFFITEM *key = reinterpret_cast<DIFFITEM*>(m_listViewItems[nIdx].lParam);
int i = m_pColItems->ColPhysToLog(pParam->item.iSubItem);
- DIFFITEM *key = GetItemKey(nIdx);
if (IsDiffItemSpecial(key))
{
+ pParam->item.iImage = m_listViewItems[nIdx].iImage;
if (m_pColItems->IsColName(i))
{
pParam->item.pszText = _T("..");
if (pParam->item.mask & LVIF_IMAGE)
{
pParam->item.iImage = GetColImage(di);
+ if ((pParam->item.mask & LVIF_STATE) == 0)
+ {
+ // for WinXP
+ pParam->item.mask |= LVIF_STATE;
+ pParam->item.state = m_pList->GetItemState(nIdx, static_cast<UINT>(~LVIS_STATEIMAGEMASK));
+ }
+ }
+ if (pParam->item.mask & LVIF_INDENT)
+ {
+ pParam->item.iIndent = m_listViewItems[nIdx].iIndent;
+ }
+ if (pParam->item.mask & LVIF_STATE)
+ {
+ pParam->item.stateMask |= LVIS_STATEIMAGEMASK;
+ if (di.HasChildren())
+ pParam->item.state |= INDEXTOSTATEIMAGEMASK((di.customFlags & ViewCustomFlags::EXPANDED) ? 2 : 1);
}
}
dlg.AddColumn(m_pColItems->GetColDisplayName(l), m_pColItems->GetColDescription(l), l);
}
}
+ assert(m_pColItems->GetColCount() == dlg.GetColumns().size());
// Add default order of columns for resetting to defaults
for (l = 0; l < m_pColItems->GetColCount(); ++l)
if (m_pColItems->GetDispColCount() < 1)
{
- // Ignore them if they didn't leave a column showing
+ // Set them back to default if they didn't leave a column showing
+ // (However, if none of the items are checked, this process will not be executed because the "OK" button in the "Display Columns" dialog cannot be pressed.)
m_pColItems->ResetColumnOrdering();
}
- else
- {
- ReloadColumns();
- Redisplay();
- }
+ ReloadColumns();
+ Redisplay();
}
DirActions CDirView::MakeDirActions(DirActions::method_type func) const