void ProjectPanel::notified(LPNMHDR notification)
{
    if ((notification->hwndFrom == _treeView.getHSelf()))
    {
        TCHAR textBuffer[MAX_PATH];
        TVITEM tvItem;
        tvItem.mask = TVIF_TEXT | TVIF_PARAM;
        tvItem.pszText = textBuffer;
        tvItem.cchTextMax = MAX_PATH;

        switch (notification->code)
        {
        case NM_DBLCLK:
        {
            openSelectFile();
        }
        break;

        case TVN_ENDLABELEDIT:
        {
            LPNMTVDISPINFO tvnotif = (LPNMTVDISPINFO)notification;
            if (!tvnotif->item.pszText)
                return;
            if (getNodeType(tvnotif->item.hItem) == nodeType_root)
                return;

            // Processing for only File case
            if (tvnotif->item.lParam)
            {
                // Get the old label
                tvItem.hItem = _treeView.getSelection();
                ::SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0,(LPARAM)&tvItem);
                size_t len = lstrlen(tvItem.pszText);

                // Find the position of old label in File path
                generic_string *filePath = (generic_string *)tvnotif->item.lParam;
                size_t found = filePath->rfind(tvItem.pszText);

                // If found the old label, replace it with the modified one
                if (found != generic_string::npos)
                    filePath->replace(found, len, tvnotif->item.pszText);

                // Check the validity of modified file path
                tvItem.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
                if (::PathFileExists(filePath->c_str()))
                {
                    tvItem.iImage = INDEX_LEAF;
                    tvItem.iSelectedImage = INDEX_LEAF;
                }
                else
                {
                    tvItem.iImage = INDEX_LEAF_INVALID;
                    tvItem.iSelectedImage = INDEX_LEAF_INVALID;
                }
                TreeView_SetItem(_treeView.getHSelf(), &tvItem);
            }

            // For File, Folder and Project
            ::SendMessage(_treeView.getHSelf(), TVM_SETITEM, 0,(LPARAM)(&(tvnotif->item)));
            setWorkSpaceDirty(true);
        }
        break;

        case TVN_GETINFOTIP:
        {
            LPNMTVGETINFOTIP lpGetInfoTip = (LPNMTVGETINFOTIP)notification;
            generic_string *str = NULL ;

            if (_treeView.getRoot() == lpGetInfoTip->hItem)
            {
                str = &_workSpaceFilePath;
            }
            else
            {
                str = (generic_string *)lpGetInfoTip->lParam;
                if (!str)
                    return;
            }
            lpGetInfoTip->pszText = (LPTSTR)str->c_str();
            lpGetInfoTip->cchTextMax = str->size();
        }
        break;

        case TVN_KEYDOWN:
        {
            //tvItem.hItem = _treeView.getSelection();
            //::SendMessage(_treeView.getHSelf(), TVM_GETITEM, 0,(LPARAM)&tvItem);
            LPNMTVKEYDOWN ptvkd = (LPNMTVKEYDOWN)notification;

            if (ptvkd->wVKey == VK_DELETE)
            {
                HTREEITEM hItem = _treeView.getSelection();
                NodeType nType = getNodeType(hItem);
                if (nType == nodeType_project || nType == nodeType_folder)
                    popupMenuCmd(IDM_PROJECT_DELETEFOLDER);
                else if (nType == nodeType_file)
                    popupMenuCmd(IDM_PROJECT_DELETEFILE);
            }
            else if (ptvkd->wVKey == VK_RETURN)
            {
                HTREEITEM hItem = _treeView.getSelection();
                NodeType nType = getNodeType(hItem);
                if (nType == nodeType_file)
                    openSelectFile();
                else
                    _treeView.toggleExpandCollapse(hItem);
            }
            else if (ptvkd->wVKey == VK_UP)
            {
                if (0x80 & GetKeyState(VK_CONTROL))
                {
                    popupMenuCmd(IDM_PROJECT_MOVEUP);
                }
            }
            else if (ptvkd->wVKey == VK_DOWN)
            {
                if (0x80 & GetKeyState(VK_CONTROL))
                {
                    popupMenuCmd(IDM_PROJECT_MOVEDOWN);
                }
            }
            else if (ptvkd->wVKey == VK_F2)
                popupMenuCmd(IDM_PROJECT_RENAME);

        }
        break;

        case TVN_ITEMEXPANDED:
        {
            LPNMTREEVIEW nmtv = (LPNMTREEVIEW)notification;
            tvItem.hItem = nmtv->itemNew.hItem;
            tvItem.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;

            if (getNodeType(nmtv->itemNew.hItem) == nodeType_folder)
            {
                if (nmtv->action == TVE_COLLAPSE)
                {
                    _treeView.setItemImage(nmtv->itemNew.hItem, INDEX_CLOSED_NODE, INDEX_CLOSED_NODE);
                }
                else if (nmtv->action == TVE_EXPAND)
                {
                    _treeView.setItemImage(nmtv->itemNew.hItem, INDEX_OPEN_NODE, INDEX_OPEN_NODE);
                }
            }
        }
        break;

        case TVN_BEGINDRAG:
        {
            //printStr(TEXT("hello"));
            _treeView.beginDrag((LPNMTREEVIEW)notification);

        }
        break;
        }
    }
}
void FileBrowser::popupMenuCmd(int cmdID)
{
	// get selected item handle
	HTREEITEM selectedNode = _treeView.getSelection();

	switch (cmdID)
	{

		//
		// Toolbar menu commands
		//
		case IDM_FILEBROWSER_REMOVEROOTFOLDER:
		{
			if (not selectedNode) return;

			generic_string *rootPath = (generic_string *)_treeView.getItemParam(selectedNode);
			if (_treeView.getParent(selectedNode) != nullptr || rootPath == nullptr)
				return;

			size_t nbFolderUpdaters = _folderUpdaters.size();
			for (size_t i = 0; i < nbFolderUpdaters; ++i)
			{
				if (_folderUpdaters[i]->_rootFolder._rootPath == *rootPath)
				{
					_folderUpdaters[i]->stopWatcher();
					_folderUpdaters.erase(_folderUpdaters.begin() + i);
					_treeView.removeItem(selectedNode);
					break;
				}
			}
		}
		break;
		
		case IDM_FILEBROWSER_EXPLORERHERE:
		{
			if (not selectedNode) return;

			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 (not selectedNode) return;

			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_COPYEPATH:
		{
			if (not selectedNode) return;
			generic_string path = getNodePath(selectedNode);
			str2Clipboard(path, _hParent);
		}
		break;

		case IDM_FILEBROWSER_OPENINNPP:
		{
			openSelectFile();
		}
		break;

		case IDM_FILEBROWSER_REMOVEALLROOTS:
		{
			for (int i = _folderUpdaters.size() - 1; i >= 0; --i)
			{
				_folderUpdaters[i]->stopWatcher();

				HTREEITEM root =  getRootFromFullPath(_folderUpdaters[i]->_rootFolder._rootPath);
				if (root)
					_treeView.removeItem(root);

				_folderUpdaters.erase(_folderUpdaters.begin() + i);
			}
		}
		break;

		case IDM_FILEBROWSER_ADDROOT:
		{
			generic_string folderPath = folderBrowser(_hParent, TEXT("Select a folder to add in Folder as Workspace panel"));
			if (not folderPath.empty())
			{
				addRootFolder(folderPath);
			}
		}
		break;

		case IDM_FILEBROWSER_SHELLEXECUTE:
		{
			if (not selectedNode) return;
			generic_string path = getNodePath(selectedNode);

			if (::PathFileExists(path.c_str()))
				::ShellExecute(NULL, TEXT("open"), path.c_str(), NULL, NULL, SW_SHOWNORMAL);
		}
		break;

	/*
		case IDM_FILEBROWSER_RENAME :
			TreeView_EditLabel(_treeView.getHSelf(), hTreeItem);
		break;
		



		

		case IDM_FILEBROWSER_DELETEFOLDER :
		{
			HTREEITEM parent = _treeView.getParent(hTreeItem);

			if (_treeView.getChildFrom(hTreeItem) != NULL)
			{
				TCHAR str2display[MAX_PATH] = TEXT("All the sub-items will be removed.\rAre you sure you want to remove this folder from the project?");
				if (::MessageBox(_hSelf, str2display, TEXT("Remove folder from project"), MB_YESNO) == IDYES)
				{
					_treeView.removeItem(hTreeItem);
					//_folderUpdaters[0].stopWatcher();
				}
			}
			else
			{
				_treeView.removeItem(hTreeItem);
			}
			if (getNodeType(parent) == browserNodeType_folder)
				_treeView.setItemImage(parent, INDEX_CLOSED_NODE, INDEX_CLOSED_NODE);
		}
		break;

		case IDM_FILEBROWSER_DELETEFILE :
		{
			HTREEITEM parent = _treeView.getParent(hTreeItem);

			TCHAR str2display[MAX_PATH] = TEXT("Are you sure you want to remove this file from the project?");
			if (::MessageBox(_hSelf, str2display, TEXT("Remove file from project"), MB_YESNO) == IDYES)
			{
				_treeView.removeItem(hTreeItem);
				if (getNodeType(parent) == browserNodeType_folder)
					_treeView.setItemImage(parent, INDEX_CLOSED_NODE, INDEX_CLOSED_NODE);
			}
		}
		break;
		*/
	}
}