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;
}
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);
if (temp == nullptr)
{
LPARAM param = _treeView.getItemParam(parent);
folderName = (param == 0) ? TEXT("") : *((generic_string *)param);
SortingData4lParam* customData = reinterpret_cast<SortingData4lParam*>(_treeView.getItemParam(parent));
folderName = customData->_rootPath;
}
parent = temp;
fullPathArray.push_back(folderName);
@ -564,7 +564,8 @@ void FileBrowser::notified(LPNMHDR notification)
size_t len = lstrlen(tvItem.pszText);
// 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);
// If found the old label, replace it with the modified one
@ -708,7 +709,7 @@ BrowserNodeType FileBrowser::getNodeType(HTREEITEM hItem)
return browserNodeType_file;
}
// Root
else if (tvItem.lParam != NULL)
else if (tvItem.lParam != NULL && !reinterpret_cast<SortingData4lParam*>(tvItem.lParam)->_rootPath.empty())
{
return browserNodeType_root;
}
@ -1049,14 +1050,17 @@ HTREEITEM FileBrowser::createFolderItemsFromDirStruct(HTREEITEM hParentItem, con
if (rootPath[len - 1] == '\\')
rootPath[len - 1] = '\0';
generic_string* rootPathStr = new generic_string(rootPath);
rootPaths.push_back(rootPathStr);
LPARAM lParamRootPath = reinterpret_cast<LPARAM>(rootPathStr);
hFolderItem = _treeView.addItem(directoryStructure._name.c_str(), TVI_ROOT, INDEX_CLOSE_ROOT, lParamRootPath);
SortingData4lParam* customData = new SortingData4lParam(rootPath, TEXT(""), true);
sortingDataArray.push_back(customData);
hFolderItem = _treeView.addItem(directoryStructure._name.c_str(), TVI_ROOT, INDEX_CLOSE_ROOT, reinterpret_cast<LPARAM>(customData));
}
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)
@ -1066,7 +1070,10 @@ HTREEITEM FileBrowser::createFolderItemsFromDirStruct(HTREEITEM hParentItem, con
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);
@ -1087,7 +1094,7 @@ HTREEITEM FileBrowser::getRootFromFullPath(const generic_string & rootPath) cons
tvItem.hItem = hItemNode;
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;
}
return node;
@ -1131,7 +1138,7 @@ vector<generic_string> FileBrowser::getRoots() const
tvItem.hItem = hItemNode;
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;
}
@ -1170,13 +1177,20 @@ bool FileBrowser::addInTree(const generic_string& rootPath, const generic_string
// No found, good - Action
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
{
_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;
}
else
@ -1262,10 +1276,29 @@ bool FileBrowser::renameInTree(const generic_string& rootPath, HTREEITEM node, c
// found it, rename it
_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;
}
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)
{
if (linarPathArray.size() == 1) // could be file or folder
@ -1467,14 +1500,12 @@ DWORD WINAPI FolderUpdater::watching(void *params)
{
case FILE_ACTION_ADDED:
file2Change.push_back(wstrFilename);
//thisFolderUpdater->updateTree(dwAction, file2Change);
::SendMessage((thisFolderUpdater->_pFileBrowser)->getHSelf(), FB_ADDFILE, reinterpret_cast<WPARAM>(nullptr), reinterpret_cast<LPARAM>(&file2Change));
oldName = TEXT("");
break;
case FILE_ACTION_REMOVED:
file2Change.push_back(wstrFilename);
//thisFolderUpdater->updateTree(dwAction, file2Change);
::SendMessage((thisFolderUpdater->_pFileBrowser)->getHSelf(), FB_RMFILE, reinterpret_cast<WPARAM>(nullptr), reinterpret_cast<LPARAM>(&file2Change));
oldName = TEXT("");
break;

View File

@ -113,6 +113,14 @@ private:
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 {
public:
FileBrowser(): DockingDlgInterface(IDD_FILEBROWSER) {};
@ -168,7 +176,7 @@ protected:
HMENU _hFileMenu = NULL;
std::vector<FolderUpdater *> _folderUpdaters;
std::vector<generic_string*> rootPaths;
std::vector<SortingData4lParam*> sortingDataArray;
void initPopupMenus();
void destroyMenus();
@ -184,4 +192,5 @@ protected:
void openSelectFile();
void getDirectoryStructure(const TCHAR *dir, const std::vector<generic_string> & patterns, FolderInfo & directoryStructure, bool isRecursive, bool isInHiddenDir);
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))
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 searchLeafAndBuildTree(TreeView & tree2Build, const generic_string & text2Search, int index2Search);
void sort(HTREEITEM hTreeItem, bool isRecusive);
void customSorting(HTREEITEM hTreeItem, PFNTVCOMPARE sortingCallbackFunc, LPARAM lParam);
protected:
WNDPROC _defaultProc;