Folder as Workspace: Add dynamical sorting feature

Fix #1541
This commit is contained in:
Don HO 2020-03-28 04:54:21 +01:00
parent cb8fd0c438
commit 3a8b744dfe
No known key found for this signature in database
GPG Key ID: 6C429F1D8D84F46E
4 changed files with 71 additions and 19 deletions

View File

@ -65,9 +65,9 @@ FileBrowser::~FileBrowser()
delete folder; delete folder;
} }
for (const auto s : rootPaths) for (const auto cd : sortingDataArray)
{ {
delete s; delete cd;
} }
} }
@ -484,8 +484,8 @@ generic_string FileBrowser::getNodePath(HTREEITEM node) const
HTREEITEM temp = _treeView.getParent(parent); HTREEITEM temp = _treeView.getParent(parent);
if (temp == nullptr) if (temp == nullptr)
{ {
LPARAM param = _treeView.getItemParam(parent); SortingData4lParam* customData = reinterpret_cast<SortingData4lParam*>(_treeView.getItemParam(parent));
folderName = (param == 0) ? TEXT("") : *((generic_string *)param); folderName = customData->_rootPath;
} }
parent = temp; parent = temp;
fullPathArray.push_back(folderName); fullPathArray.push_back(folderName);
@ -564,7 +564,8 @@ void FileBrowser::notified(LPNMHDR notification)
size_t len = lstrlen(tvItem.pszText); size_t len = lstrlen(tvItem.pszText);
// Find the position of old label in File path // Find the position of old label in File path
generic_string *filePath = (generic_string *)tvnotif->item.lParam; SortingData4lParam* customData = reinterpret_cast<SortingData4lParam*>(tvnotif->item.lParam);
generic_string *filePath = &(customData->_rootPath);
size_t found = filePath->rfind(tvItem.pszText); size_t found = filePath->rfind(tvItem.pszText);
// If found the old label, replace it with the modified one // If found the old label, replace it with the modified one
@ -708,7 +709,7 @@ BrowserNodeType FileBrowser::getNodeType(HTREEITEM hItem)
return browserNodeType_file; return browserNodeType_file;
} }
// Root // Root
else if (tvItem.lParam != NULL) else if (tvItem.lParam != NULL && !reinterpret_cast<SortingData4lParam*>(tvItem.lParam)->_rootPath.empty())
{ {
return browserNodeType_root; return browserNodeType_root;
} }
@ -1049,14 +1050,17 @@ HTREEITEM FileBrowser::createFolderItemsFromDirStruct(HTREEITEM hParentItem, con
if (rootPath[len - 1] == '\\') if (rootPath[len - 1] == '\\')
rootPath[len - 1] = '\0'; rootPath[len - 1] = '\0';
generic_string* rootPathStr = new generic_string(rootPath); SortingData4lParam* customData = new SortingData4lParam(rootPath, TEXT(""), true);
rootPaths.push_back(rootPathStr); sortingDataArray.push_back(customData);
LPARAM lParamRootPath = reinterpret_cast<LPARAM>(rootPathStr);
hFolderItem = _treeView.addItem(directoryStructure._name.c_str(), TVI_ROOT, INDEX_CLOSE_ROOT, lParamRootPath); hFolderItem = _treeView.addItem(directoryStructure._name.c_str(), TVI_ROOT, INDEX_CLOSE_ROOT, reinterpret_cast<LPARAM>(customData));
} }
else else
{ {
hFolderItem = _treeView.addItem(directoryStructure._name.c_str(), hParentItem, INDEX_CLOSE_NODE); SortingData4lParam* customData = new SortingData4lParam(TEXT(""), directoryStructure._name, true);
sortingDataArray.push_back(customData);
hFolderItem = _treeView.addItem(directoryStructure._name.c_str(), hParentItem, INDEX_CLOSE_NODE, reinterpret_cast<LPARAM>(customData));
} }
for (const auto& folder : directoryStructure._subFolders) for (const auto& folder : directoryStructure._subFolders)
@ -1066,7 +1070,10 @@ HTREEITEM FileBrowser::createFolderItemsFromDirStruct(HTREEITEM hParentItem, con
for (const auto& file : directoryStructure._files) for (const auto& file : directoryStructure._files)
{ {
_treeView.addItem(file._name.c_str(), hFolderItem, INDEX_LEAF); SortingData4lParam* customData = new SortingData4lParam(TEXT(""), file._name, false);
sortingDataArray.push_back(customData);
_treeView.addItem(file._name.c_str(), hFolderItem, INDEX_LEAF, reinterpret_cast<LPARAM>(customData));
} }
_treeView.fold(hParentItem); _treeView.fold(hParentItem);
@ -1087,7 +1094,7 @@ HTREEITEM FileBrowser::getRootFromFullPath(const generic_string & rootPath) cons
tvItem.hItem = hItemNode; tvItem.hItem = hItemNode;
SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast<LPARAM>(&tvItem)); SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast<LPARAM>(&tvItem));
if (tvItem.lParam != 0 && rootPath == *((generic_string *)tvItem.lParam)) if (tvItem.lParam != 0 && rootPath == reinterpret_cast<SortingData4lParam *>(tvItem.lParam)->_rootPath)
node = hItemNode; node = hItemNode;
} }
return node; return node;
@ -1131,7 +1138,7 @@ vector<generic_string> FileBrowser::getRoots() const
tvItem.hItem = hItemNode; tvItem.hItem = hItemNode;
SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast<LPARAM>(&tvItem)); SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, reinterpret_cast<LPARAM>(&tvItem));
roots.push_back(*((generic_string *)tvItem.lParam)); roots.push_back(reinterpret_cast<SortingData4lParam*>(tvItem.lParam)->_rootPath);
} }
return roots; return roots;
} }
@ -1170,13 +1177,20 @@ bool FileBrowser::addInTree(const generic_string& rootPath, const generic_string
// No found, good - Action // No found, good - Action
if (::PathIsDirectory(addItemFullPath.c_str())) if (::PathIsDirectory(addItemFullPath.c_str()))
{ {
_treeView.addItem(linarPathArray[0].c_str(), node, INDEX_CLOSE_NODE); SortingData4lParam* customData = new SortingData4lParam(TEXT(""), linarPathArray[0], true);
sortingDataArray.push_back(customData);
_treeView.addItem(linarPathArray[0].c_str(), node, INDEX_CLOSE_NODE, reinterpret_cast<LPARAM>(customData));
} }
else else
{ {
_treeView.addItem(linarPathArray[0].c_str(), node, INDEX_LEAF); SortingData4lParam* customData = new SortingData4lParam(TEXT(""), linarPathArray[0], false);
sortingDataArray.push_back(customData);
_treeView.addItem(linarPathArray[0].c_str(), node, INDEX_LEAF, reinterpret_cast<LPARAM>(customData));
} }
_treeView.customSorting(node, categorySortFunc, 0);
return true; return true;
} }
else else
@ -1262,10 +1276,29 @@ bool FileBrowser::renameInTree(const generic_string& rootPath, HTREEITEM node, c
// found it, rename it // found it, rename it
_treeView.renameItem(foundItem, renameTo.c_str()); _treeView.renameItem(foundItem, renameTo.c_str());
SortingData4lParam* compareData = reinterpret_cast<SortingData4lParam*>(_treeView.getItemParam(foundItem));
compareData->_label = renameTo;
_treeView.customSorting(_treeView.getParent(foundItem), categorySortFunc, 0);
return true; return true;
} }
int CALLBACK FileBrowser::categorySortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM /*lParamSort*/)
{
SortingData4lParam* item1 = reinterpret_cast<SortingData4lParam*>(lParam1);
SortingData4lParam* item2 = reinterpret_cast<SortingData4lParam*>(lParam2);
if (!item1 || !item2)
return 0;
if (item1->_isFolder && !item2->_isFolder)
return -1;
else if (!item1->_isFolder && item2->_isFolder)
return 1;
else
return lstrcmpi(item1->_label.c_str(), item2->_label.c_str());
}
bool FolderInfo::addToStructure(generic_string & fullpath, std::vector<generic_string> linarPathArray) bool FolderInfo::addToStructure(generic_string & fullpath, std::vector<generic_string> linarPathArray)
{ {
if (linarPathArray.size() == 1) // could be file or folder if (linarPathArray.size() == 1) // could be file or folder
@ -1467,14 +1500,12 @@ DWORD WINAPI FolderUpdater::watching(void *params)
{ {
case FILE_ACTION_ADDED: case FILE_ACTION_ADDED:
file2Change.push_back(wstrFilename); file2Change.push_back(wstrFilename);
//thisFolderUpdater->updateTree(dwAction, file2Change);
::SendMessage((thisFolderUpdater->_pFileBrowser)->getHSelf(), FB_ADDFILE, reinterpret_cast<WPARAM>(nullptr), reinterpret_cast<LPARAM>(&file2Change)); ::SendMessage((thisFolderUpdater->_pFileBrowser)->getHSelf(), FB_ADDFILE, reinterpret_cast<WPARAM>(nullptr), reinterpret_cast<LPARAM>(&file2Change));
oldName = TEXT(""); oldName = TEXT("");
break; break;
case FILE_ACTION_REMOVED: case FILE_ACTION_REMOVED:
file2Change.push_back(wstrFilename); file2Change.push_back(wstrFilename);
//thisFolderUpdater->updateTree(dwAction, file2Change);
::SendMessage((thisFolderUpdater->_pFileBrowser)->getHSelf(), FB_RMFILE, reinterpret_cast<WPARAM>(nullptr), reinterpret_cast<LPARAM>(&file2Change)); ::SendMessage((thisFolderUpdater->_pFileBrowser)->getHSelf(), FB_RMFILE, reinterpret_cast<WPARAM>(nullptr), reinterpret_cast<LPARAM>(&file2Change));
oldName = TEXT(""); oldName = TEXT("");
break; break;

View File

@ -113,6 +113,14 @@ private:
static DWORD WINAPI watching(void *param); static DWORD WINAPI watching(void *param);
}; };
struct SortingData4lParam {
generic_string _rootPath; // Only for the root. It should be empty if it's not root
generic_string _label; // TreeView item label
bool _isFolder = false; // if it's not a folder, then it's a file
SortingData4lParam(generic_string rootPath, generic_string label, bool isFolder) : _rootPath(rootPath), _label(label), _isFolder(isFolder) {}
};
class FileBrowser : public DockingDlgInterface { class FileBrowser : public DockingDlgInterface {
public: public:
FileBrowser(): DockingDlgInterface(IDD_FILEBROWSER) {}; FileBrowser(): DockingDlgInterface(IDD_FILEBROWSER) {};
@ -168,7 +176,7 @@ protected:
HMENU _hFileMenu = NULL; HMENU _hFileMenu = NULL;
std::vector<FolderUpdater *> _folderUpdaters; std::vector<FolderUpdater *> _folderUpdaters;
std::vector<generic_string*> rootPaths; std::vector<SortingData4lParam*> sortingDataArray;
void initPopupMenus(); void initPopupMenus();
void destroyMenus(); void destroyMenus();
@ -184,4 +192,5 @@ protected:
void openSelectFile(); void openSelectFile();
void getDirectoryStructure(const TCHAR *dir, const std::vector<generic_string> & patterns, FolderInfo & directoryStructure, bool isRecursive, bool isInHiddenDir); void getDirectoryStructure(const TCHAR *dir, const std::vector<generic_string> & patterns, FolderInfo & directoryStructure, bool isRecursive, bool isInHiddenDir);
HTREEITEM createFolderItemsFromDirStruct(HTREEITEM hParentItem, const FolderInfo & directoryStructure); HTREEITEM createFolderItemsFromDirStruct(HTREEITEM hParentItem, const FolderInfo & directoryStructure);
static int CALLBACK categorySortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
}; };

View File

@ -690,3 +690,14 @@ void TreeView::sort(HTREEITEM hTreeItem, bool isRecusive)
for (HTREEITEM hItem = getChildFrom(hTreeItem); hItem != NULL; hItem = getNextSibling(hItem)) for (HTREEITEM hItem = getChildFrom(hTreeItem); hItem != NULL; hItem = getNextSibling(hItem))
sort(hItem, isRecusive); sort(hItem, isRecusive);
} }
void TreeView::customSorting(HTREEITEM hTreeItem, PFNTVCOMPARE sortingCallbackFunc, LPARAM lParam)
{
TVSORTCB treeViewSortCB;
treeViewSortCB.hParent = hTreeItem;
treeViewSortCB.lpfnCompare = sortingCallbackFunc;
treeViewSortCB.lParam = lParam;
::SendMessage(_hSelf, TVM_SORTCHILDRENCB, 0, reinterpret_cast<LPARAM>(&treeViewSortCB));
}

View File

@ -126,6 +126,7 @@ public:
bool retrieveFoldingStateTo(TreeStateNode & treeState2Construct, HTREEITEM treeviewNode); bool retrieveFoldingStateTo(TreeStateNode & treeState2Construct, HTREEITEM treeviewNode);
bool searchLeafAndBuildTree(TreeView & tree2Build, const generic_string & text2Search, int index2Search); bool searchLeafAndBuildTree(TreeView & tree2Build, const generic_string & text2Search, int index2Search);
void sort(HTREEITEM hTreeItem, bool isRecusive); void sort(HTREEITEM hTreeItem, bool isRecusive);
void customSorting(HTREEITEM hTreeItem, PFNTVCOMPARE sortingCallbackFunc, LPARAM lParam);
protected: protected:
WNDPROC _defaultProc; WNDPROC _defaultProc;