File Browser (In progress)

1. Memorize the opened folders for the next session.
2. Add tip infos.
3. Add "Explorer from here" & "Command from here" context menu.
This commit is contained in:
Don Ho 2016-02-02 19:06:23 +01:00
parent fb189fa247
commit 81deab0554
13 changed files with 228 additions and 60 deletions

View File

@ -795,6 +795,17 @@ bool Notepad_plus::saveProjectPanelsParams()
return (NppParameters::getInstance())->writeProjectPanelsSettings();
}
bool Notepad_plus::saveFileBrowserParam()
{
if (_pFileBrowser)
{
vector<generic_string> rootPaths = _pFileBrowser->getRoots();
generic_string selectedItemPath = _pFileBrowser->getSelectedItemPath();
return (NppParameters::getInstance())->writeFileBrowserSettings(rootPaths, selectedItemPath);
}
return true; // nothing to save so true is returned
}
void Notepad_plus::saveDockingParams()
{
NppGUI & nppGUI = (NppGUI &)(NppParameters::getInstance())->getNppGUI();
@ -2997,7 +3008,9 @@ void Notepad_plus::dropFiles(HDROP hdrop)
if (test != BUFFER_INVALID)
lastOpened = test;
}
if (lastOpened != BUFFER_INVALID) {
if (lastOpened != BUFFER_INVALID)
{
switchToFile(lastOpened);
}
}
@ -3007,14 +3020,8 @@ void Notepad_plus::dropFiles(HDROP hdrop)
}
else if (not isOldMode && (folderPaths.size() != 0 && filePaths.size() == 0)) // new mode && only folders
{
launchFileBrowser();
// process new mode
for (int i = 0; i < filesDropped; ++i)
{
_pFileBrowser->addRootFolder(folderPaths[i]);
}
launchFileBrowser(folderPaths);
/*
for (int i = 0; i < filesDropped; ++i)
@ -5352,7 +5359,7 @@ void Notepad_plus::launchAnsiCharPanel()
_pAnsiCharPanel->display();
}
void Notepad_plus::launchFileBrowser()
void Notepad_plus::launchFileBrowser(const vector<generic_string> & folders)
{
if (!_pFileBrowser)
{
@ -5370,6 +5377,11 @@ void Notepad_plus::launchFileBrowser()
data.hIconTab = (HICON)::LoadImage(_pPublicInterface->getHinst(), MAKEINTRESOURCE(IDR_PROJECTPANEL_ICO), IMAGE_ICON, 14, 14, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT);
data.pszModuleName = NPP_INTERNAL_FUCTION_STR;
// the dlgDlg should be the index of funcItem where the current function pointer is
// in this case is DOCKABLE_DEMO_INDEX
// In the case of Notepad++ internal function, it'll be the command ID which triggers this dialog
data.dlgID = IDM_VIEW_FILEBROWSER;
NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker();
generic_string title_temp = pNativeSpeaker->getAttrNameStr(FB_PROJECTPANELTITLE, "FileBrowser", "PanelTitle");
@ -5388,6 +5400,11 @@ void Notepad_plus::launchFileBrowser()
_pFileBrowser->setForegroundColor(fgColor);
}
for (size_t i = 0; i <folders.size(); ++i)
{
_pFileBrowser->addRootFolder(folders[i]);
}
_pFileBrowser->display();
}
@ -5400,7 +5417,7 @@ void Notepad_plus::launchProjectPanel(int cmdID, ProjectPanel ** pProjPanel, int
(*pProjPanel) = new ProjectPanel;
(*pProjPanel)->init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf());
(*pProjPanel)->setWorkSpaceFilePath(pNppParam->getworkSpaceFilePath(panelID));
(*pProjPanel)->setWorkSpaceFilePath(pNppParam->getWorkSpaceFilePath(panelID));
tTbData data;
memset(&data, 0, sizeof(data));

View File

@ -255,6 +255,7 @@ public:
bool saveGUIParams();
bool saveProjectPanelsParams();
bool saveFileBrowserParam();
void saveDockingParams();
void saveUserDefineLangs();
void saveShortcuts();
@ -621,7 +622,7 @@ private:
void launchProjectPanel(int cmdID, ProjectPanel ** pProjPanel, int panelID);
void launchDocMap();
void launchFunctionList();
void launchFileBrowser();
void launchFileBrowser(const std::vector<generic_string> & folders);
void showAllQuotes() const;
static DWORD WINAPI threadTextPlayer(void *text2display);
static DWORD WINAPI threadTextTroller(void *params);

View File

@ -1590,6 +1590,7 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa
saveScintillaParams(); //writeScintillaParams
saveGUIParams(); //writeGUIParams
saveProjectPanelsParams(); //writeProjectPanelsSettings
saveFileBrowserParam();
//
// saving config.xml
//

View File

@ -512,6 +512,13 @@ void Notepad_plus::command(int id)
}
break;
case IDM_VIEW_FILEBROWSER:
{
NppParameters *pNppParam = NppParameters::getInstance();
launchFileBrowser(pNppParam->getFileBrowserRoots());
}
break;
case IDM_VIEW_DOC_MAP:
{
if (_pDocMap && (!_pDocMap->isClosed()))

View File

@ -1592,6 +1592,9 @@ bool NppParameters::getUserParametersFromXmlTree()
//Get Project Panel parameters
feedProjectPanelsParameters(root);
//Get File browser parameters
feedFileBrowserParameters(root);
return true;
}
@ -2069,6 +2072,23 @@ void NppParameters::feedFileListParameters(TiXmlNode *node)
}
void NppParameters::feedProjectPanelsParameters(TiXmlNode *node)
{
TiXmlNode *fileBrowserRoot = node->FirstChildElement(TEXT("FileBrowser"));
if (!fileBrowserRoot) return;
for (TiXmlNode *childNode = fileBrowserRoot->FirstChildElement(TEXT("root"));
childNode;
childNode = childNode->NextSibling(TEXT("root")) )
{
const TCHAR *filePath = (childNode->ToElement())->Attribute(TEXT("foldername"));
if (filePath)
{
_fileBrowserRoot.push_back(filePath);
}
}
}
void NppParameters::feedFileBrowserParameters(TiXmlNode *node)
{
TiXmlNode *projPanelRoot = node->FirstChildElement(TEXT("ProjectPanels"));
if (!projPanelRoot) return;
@ -3397,7 +3417,7 @@ bool NppParameters::writeProjectPanelsSettings() const
TiXmlElement projPanelRootNode{TEXT("ProjectPanels")};
// Add 3 Project Panel parameters
for (int i = 0 ; i < 3 ; ++i)
for (size_t i = 0 ; i < 3 ; ++i)
{
TiXmlElement projPanelNode{TEXT("ProjectPanel")};
(projPanelNode.ToElement())->SetAttribute(TEXT("id"), i);
@ -3411,6 +3431,43 @@ bool NppParameters::writeProjectPanelsSettings() const
return true;
}
bool NppParameters::writeFileBrowserSettings(const vector<generic_string> & rootPaths, const generic_string & latestSelectedItemPath) const
{
if (!_pXmlUserDoc) return false;
TiXmlNode *nppRoot = _pXmlUserDoc->FirstChild(TEXT("NotepadPlus"));
if (!nppRoot) return false;
TiXmlNode *oldFileBrowserRootNode = nppRoot->FirstChildElement(TEXT("FileBrowser"));
if (oldFileBrowserRootNode != nullptr)
{
// Erase the file broser root
nppRoot->RemoveChild(oldFileBrowserRootNode);
}
// Create the file browser root
TiXmlElement fileBrowserRootNode{ TEXT("FileBrowser") };
if (rootPaths.size() != 0)
{
fileBrowserRootNode.SetAttribute(TEXT("latestSelectedItem"), latestSelectedItemPath.c_str());
// add roots
size_t len = rootPaths.size();
for (size_t i = 0; i < len; ++i)
{
TiXmlElement fbRootNode{ TEXT("root") };
(fbRootNode.ToElement())->SetAttribute(TEXT("foldername"), rootPaths[i].c_str());
(fileBrowserRootNode.ToElement())->InsertEndChild(fbRootNode);
}
}
// (Re)Insert the file browser root
(nppRoot->ToElement())->InsertEndChild(fileBrowserRootNode);
return true;
}
bool NppParameters::writeHistory(const TCHAR *fullpath)
{
TiXmlNode *nppRoot = _pXmlUserDoc->FirstChild(TEXT("NotepadPlus"));

View File

@ -1342,6 +1342,7 @@ public:
bool writeHistory(const TCHAR *fullpath);
bool writeProjectPanelsSettings() const;
bool writeFileBrowserSettings(const std::vector<generic_string> & rootPath, const generic_string & latestSelectedItemPath) const;
TiXmlNode* getChildElementByAttribut(TiXmlNode *pere, const TCHAR *childName, const TCHAR *attributName, const TCHAR *attributVal) const;
@ -1459,12 +1460,11 @@ public:
generic_string getContextMenuPath() const {return _contextMenuPath;};
const TCHAR * getAppDataNppDir() const {return _appdataNppDir.c_str();};
const TCHAR * getWorkingDir() const {return _currentDirectory.c_str();};
const TCHAR * getworkSpaceFilePath(int i) const
{
const TCHAR * getWorkSpaceFilePath(int i) const {
if (i < 0 || i > 2) return nullptr;
return _workSpaceFilePathes[i].c_str();
}
const std::vector<generic_string> getFileBrowserRoots() const { return _fileBrowserRoot; };
void setWorkSpaceFilePath(int i, const TCHAR *wsFile);
void setWorkingDir(const TCHAR * newPath);
@ -1478,8 +1478,7 @@ public:
int langTypeToCommandID(LangType lt) const;
WNDPROC getEnableThemeDlgTexture() const {return _enableThemeDialogTextureFuncAddr;};
struct FindDlgTabTitiles final
{
struct FindDlgTabTitiles final {
generic_string _find;
generic_string _replace;
generic_string _findInFiles;
@ -1490,8 +1489,7 @@ public:
bool asNotepadStyle() const {return _asNotepadStyle;};
bool reloadPluginCmds()
{
bool reloadPluginCmds() {
return getPluginCmdsFromXmlTree();
}
@ -1664,6 +1662,8 @@ private:
generic_string _currentDirectory;
generic_string _workSpaceFilePathes[3];
std::vector<generic_string> _fileBrowserRoot;
Accelerator *_pAccelerator;
ScintillaAccelerator * _pScintAccelerator;
@ -1704,6 +1704,7 @@ private:
void feedDockingManager(TiXmlNode *node);
void feedFindHistoryParameters(TiXmlNode *node);
void feedProjectPanelsParameters(TiXmlNode *node);
void feedFileBrowserParameters(TiXmlNode *node);
bool feedStylerArray(TiXmlNode *node);
void getAllWordStyles(TCHAR *lexerName, TiXmlNode *lexerNode);

View File

@ -32,6 +32,7 @@
#include "FileDialog.h"
#include "localization.h"
#include "Parameters.h"
#include "RunDlg.h"
#include "ReadDirectoryChanges.h"
#define CX_BITMAP 16
@ -262,13 +263,17 @@ void FileBrowser::initPopupMenus()
_hRootMenu = ::CreatePopupMenu();
::InsertMenu(_hRootMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_REMOVEROOTFOLDER, edit_removeFolderFromFileBrowser.c_str());
::InsertMenu(_hRootMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_EXPLORERHERE, TEXT("Explorer here"));
::InsertMenu(_hRootMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_CMDHERE, TEXT("CMD here"));
_hFolderMenu = ::CreatePopupMenu();
::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_EXPLORERHERE, TEXT("Explorer here"));
::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_CMDHERE, TEXT("CMD here"));
//::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_NEWFOLDER, edit_addfolder.c_str());
//::InsertMenu(_hFolderMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_ADDFILES, edit_addfiles.c_str());
_hFileMenu = ::CreatePopupMenu();
::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_EXPLORERHERE, TEXT("Explorer here"));
::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_CMDHERE, TEXT("CMD here"));
//::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_RENAME, edit_rename.c_str());
//::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_DELETEFILE, edit_remove.c_str());
//::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_MODIFYFILEPATH, edit_modifyfile.c_str());
@ -391,17 +396,15 @@ generic_string FileBrowser::getRelativePath(const generic_string & filePath, con
return relativeFile;
}
void FileBrowser::openSelectFile()
generic_string FileBrowser::getNodePath(HTREEITEM node) const
{
// Get the selected item
HTREEITEM selectedNode = _treeView.getSelection();
if (not selectedNode) return;
if (not node) return TEXT("");
vector<generic_string> fullPathArray;
generic_string fullPath;
// go up until to root, then get the full path
HTREEITEM parent = selectedNode;
HTREEITEM parent = node;
for (; parent != nullptr;)
{
generic_string folderName = _treeView.getItemDisplayName(parent);
@ -424,6 +427,17 @@ void FileBrowser::openSelectFile()
fullPath += TEXT("\\");
}
return fullPath;
}
void FileBrowser::openSelectFile()
{
// Get the selected item
HTREEITEM selectedNode = _treeView.getSelection();
if (not selectedNode) return;
generic_string fullPath = getNodePath(selectedNode);
// test the path - if it's a file, open it, otherwise just fold or unfold it
if (not ::PathFileExists(fullPath.c_str()))
return;
@ -507,6 +521,27 @@ void FileBrowser::notified(LPNMHDR notification)
}
break;
case TVN_GETINFOTIP:
{
LPNMTVGETINFOTIP lpGetInfoTip = (LPNMTVGETINFOTIP)notification;
static generic_string tipStr;
BrowserNodeType nType = getNodeType(lpGetInfoTip->hItem);
if (nType == browserNodeType_root)
{
tipStr = *((generic_string *)lpGetInfoTip->lParam);
}
else if (nType == browserNodeType_file)
{
tipStr = getNodePath(lpGetInfoTip->hItem);
}
else
return;
lpGetInfoTip->pszText = (LPTSTR)tipStr.c_str();
lpGetInfoTip->cchTextMax = tipStr.size();
}
break;
case TVN_KEYDOWN:
{
LPNMTVKEYDOWN ptvkd = (LPNMTVKEYDOWN)notification;
@ -632,11 +667,9 @@ void FileBrowser::showContextMenu(int x, int y)
if (nodeType == browserNodeType_root)
hMenu = _hRootMenu;
else if (nodeType == browserNodeType_folder)
//hMenu = _hFolderMenu;
return;
hMenu = _hFolderMenu;
else //nodeType_file
//hMenu = _hFileMenu;
return;
hMenu = _hFileMenu;
TrackPopupMenu(hMenu, TPM_LEFTALIGN, x, y, 0, _hSelf, NULL);
}
@ -658,8 +691,8 @@ HTREEITEM FileBrowser::createNewFolder(HTREEITEM hTreeItem, const TCHAR *folderN
void FileBrowser::popupMenuCmd(int cmdID)
{
// get selected item handle
HTREEITEM hTreeItem = _treeView.getSelection();
if (!hTreeItem)
HTREEITEM selectedNode = _treeView.getSelection();
if (not selectedNode)
return;
switch (cmdID)
@ -670,7 +703,6 @@ void FileBrowser::popupMenuCmd(int cmdID)
//
case IDM_FILEBROWSER_REMOVEROOTFOLDER:
{
HTREEITEM selectedNode = _treeView.getSelection();
generic_string *rootPath = (generic_string *)_treeView.getItemParam(selectedNode);
if (_treeView.getParent(selectedNode) != nullptr || rootPath == nullptr)
return;
@ -688,6 +720,36 @@ void FileBrowser::popupMenuCmd(int cmdID)
}
}
break;
case IDM_FILEBROWSER_EXPLORERHERE:
{
generic_string path = getNodePath(selectedNode);
if (::PathFileExists(path.c_str()))
{
TCHAR cmdStr[1024];
wsprintf(cmdStr, TEXT("explorer /select,%s"), path.c_str());
Command cmd(cmdStr);
cmd.run(nullptr);
}
}
break;
case IDM_FILEBROWSER_CMDHERE:
{
if (getNodeType(selectedNode) == browserNodeType_file)
selectedNode = _treeView.getParent(selectedNode);
generic_string path = getNodePath(selectedNode);
if (::PathFileExists(path.c_str()))
{
TCHAR cmdStr[1024];
wsprintf(cmdStr, TEXT("cmd /K cd /d %s"), path.c_str());
Command cmd(cmdStr);
cmd.run(nullptr);
}
}
break;
/*
case IDM_FILEBROWSER_RENAME :
TreeView_EditLabel(_treeView.getHSelf(), hTreeItem);
@ -701,17 +763,7 @@ void FileBrowser::popupMenuCmd(int cmdID)
}
break;
case IDM_FILEBROWSER_MOVEDOWN :
{
_treeView.moveDown(hTreeItem);
}
break;
case IDM_FILEBROWSER_MOVEUP :
{
_treeView.moveUp(hTreeItem);
}
break;
case IDM_FILEBROWSER_DELETEFOLDER :
@ -856,7 +908,6 @@ void FileBrowser::addRootFolder(generic_string rootFolderPath)
if (pos == 0)
{
printStr(TEXT("do nothing, go down to select the dir."));
return;
}
@ -918,7 +969,7 @@ HTREEITEM FileBrowser::createFolderItemsFromDirStruct(HTREEITEM hParentItem, con
return hFolderItem;
}
HTREEITEM FileBrowser::getRootFromFullPath(generic_string rootPath)
HTREEITEM FileBrowser::getRootFromFullPath(const generic_string & rootPath) const
{
HTREEITEM node = nullptr;
for (HTREEITEM hItemNode = _treeView.getRoot();
@ -961,6 +1012,37 @@ HTREEITEM FileBrowser::findChildNodeFromName(HTREEITEM parent, generic_string la
return childNodeFound;
}
vector<generic_string> FileBrowser::getRoots() const
{
vector<generic_string> roots;
HTREEITEM node = nullptr;
for (HTREEITEM hItemNode = _treeView.getRoot();
hItemNode != nullptr && node == nullptr;
hItemNode = _treeView.getNextSibling(hItemNode))
{
TVITEM tvItem;
tvItem.mask = TVIF_PARAM;
tvItem.cchTextMax = MAX_PATH;
tvItem.hItem = hItemNode;
SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0, (LPARAM)&tvItem);
roots.push_back(*((generic_string *)tvItem.lParam));
}
return roots;
}
generic_string FileBrowser::getSelectedItemPath() const
{
generic_string itemPath;
HTREEITEM hItemNode = _treeView.getSelection();
if (hItemNode)
{
itemPath = getNodePath(hItemNode);
}
return itemPath;
}
bool FileBrowser::addInTree(generic_string rootPath, generic_string addItemFullPath, HTREEITEM node, vector<generic_string> linarPathArray)
{
if (node == nullptr) // it's a root. Search the right root with rootPath

View File

@ -122,10 +122,8 @@ public:
private:
FolderInfo _rootFolder;
FileBrowser *_pFileBrowser = nullptr;
HANDLE _watchThreadHandle = nullptr;
HANDLE _EventHandle = nullptr;
static DWORD WINAPI watching(void *param);
};
@ -153,15 +151,19 @@ public:
TreeView_SetTextColor(_treeView.getHSelf(), fgColour);
};
generic_string getNodePath(HTREEITEM node) const;
void addRootFolder(generic_string);
HTREEITEM getRootFromFullPath(generic_string rootPath);
HTREEITEM getRootFromFullPath(const generic_string & rootPath) const;
HTREEITEM FileBrowser::findChildNodeFromName(HTREEITEM parent, generic_string);
bool addInTree(generic_string rootPath, generic_string addItemFullPath, HTREEITEM node, std::vector<generic_string> linarPathArray);
bool deleteFromTree(generic_string rootPath, HTREEITEM node, std::vector<generic_string> linarPathArray);
bool renameInTree(generic_string rootPath, HTREEITEM node, std::vector<generic_string> linarPathArrayFrom, std::vector<generic_string> linarPathArrayTo);
std::vector<generic_string> getRoots() const;
generic_string getSelectedItemPath() const;
protected:
TreeView _treeView;
HIMAGELIST _hImaLst;

View File

@ -41,10 +41,12 @@
#define IDM_FILEBROWSER_DELETEFILE (IDD_FILEBROWSER_MENU + 5)
#define IDM_FILEBROWSER_MODIFYFILEPATH (IDD_FILEBROWSER_MENU + 6)
#define IDM_FILEBROWSER_MOVEUP (IDD_FILEBROWSER_MENU + 8)
#define IDM_FILEBROWSER_MOVEDOWN (IDD_FILEBROWSER_MENU + 9)
*/
//#define IDM_FILEBROWSER_MODIFYFILEPATH (IDD_FILEBROWSER_MENU + 6)
#define IDM_FILEBROWSER_EXPLORERHERE (IDD_FILEBROWSER_MENU + 8)
#define IDM_FILEBROWSER_CMDHERE (IDD_FILEBROWSER_MENU + 9)
#define IDD_FILEBROWSER_CTRL (IDD_FILEBROWSER + 30)
#define ID_FILEBROWSERTREEVIEW (IDD_FILEBROWSER_CTRL + 1)

View File

@ -101,7 +101,7 @@ bool TreeView::setItemParam(HTREEITEM Item2Set, const TCHAR *paramStr)
return true;
}
LPARAM TreeView::getItemParam(HTREEITEM Item2Get)
LPARAM TreeView::getItemParam(HTREEITEM Item2Get) const
{
if (not Item2Get)
return false;
@ -115,7 +115,7 @@ LPARAM TreeView::getItemParam(HTREEITEM Item2Get)
return tvItem.lParam;
}
generic_string TreeView::getItemDisplayName(HTREEITEM Item2Set)
generic_string TreeView::getItemDisplayName(HTREEITEM Item2Set) const
{
if (not Item2Set)
return false;

View File

@ -51,8 +51,8 @@ public:
virtual void destroy();
HTREEITEM addItem(const TCHAR *itemName, HTREEITEM hParentItem, int iImage, const TCHAR *filePath = NULL);
bool setItemParam(HTREEITEM Item2Set, const TCHAR *paramStr);
LPARAM getItemParam(HTREEITEM Item2Get);
generic_string getItemDisplayName(HTREEITEM Item2Set);
LPARAM getItemParam(HTREEITEM Item2Get) const;
generic_string getItemDisplayName(HTREEITEM Item2Set) const;
HTREEITEM searchSubItemByName(const TCHAR *itemName, HTREEITEM hParentItem);
void removeItem(HTREEITEM hTreeItem);
void removeAllItems();

View File

@ -59,10 +59,7 @@ public :
RunDlg() : StaticDialog() {};
void doDialog(bool isRTL = false);
virtual void destroy() {
};
virtual void destroy() {};
protected :
virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam);

View File

@ -319,6 +319,7 @@
#define IDM_VIEW_PROJECT_PANEL_3 (IDM_VIEW + 83)
#define IDM_VIEW_FUNC_LIST (IDM_VIEW + 84)
#define IDM_VIEW_FILEBROWSER (IDM_VIEW + 85)
#define IDM_VIEW_TAB1 (IDM_VIEW + 86)
#define IDM_VIEW_TAB2 (IDM_VIEW + 87)