celestia/src/celestia/winlocations.cpp

1000 lines
37 KiB
C++

// winlocations.cpp
//
// Copyright (C) 2002, Chris Laurel <claurel@shatters.net>
//
// Miscellaneous utilities for Locations UI implementation.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
#include "winlocations.h"
#include "res/resource.h"
#include <celutil/winutil.h>
using namespace std;
bool dragging;
HTREEITEM hDragItem;
HTREEITEM hDropTargetItem;
POINT dragPos;
HTREEITEM PopulateLocationsTree(HWND hTree, CelestiaCore* appCore, HINSTANCE appInstance)
{
//First create an image list for the icons in the control
HIMAGELIST himlIcons;
HICON hIcon;
HTREEITEM hParent=NULL, hParentItem;
//Create a masked image list large enough to hold the icons.
himlIcons = ImageList_Create(16, 16, ILC_MASK, 3, 0);
// Load the icon resources, and add the icons to the image list.
hIcon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_CLOSEDFOLDER));
ImageList_AddIcon(himlIcons, hIcon);
hIcon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_OPENFOLDER));
ImageList_AddIcon(himlIcons, hIcon);
hIcon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_ROOTFOLDER));
ImageList_AddIcon(himlIcons, hIcon);
hIcon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_LOCATION));
ImageList_AddIcon(himlIcons, hIcon);
// Associate the image list with the tree-view control.
TreeView_SetImageList(hTree, himlIcons, TVSIL_NORMAL);
const FavoritesList* favorites = appCore->getFavorites();
if (favorites != NULL)
{
//Create a subtree item called "Locations"
TVINSERTSTRUCT tvis;
tvis.hParent = TVI_ROOT;
tvis.hInsertAfter = TVI_LAST;
tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvis.item.pszText = "Locations";
tvis.item.lParam = 1; //1 for folders, 0 for items.
tvis.item.iImage = 2;
tvis.item.iSelectedImage = 2;
if (hParent = TreeView_InsertItem(hTree, &tvis))
{
FavoritesList::const_iterator iter = favorites->begin();
while (iter != favorites->end())
{
TVINSERTSTRUCT tvis;
//Is this a folder?
if ((*iter)->isFolder)
{
//Create a subtree item
tvis.hParent = hParent;
tvis.hInsertAfter = TVI_LAST;
tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvis.item.pszText = const_cast<char*>((*iter)->name.c_str());
tvis.item.lParam = 1; //1 for folders, 0 for items.
tvis.item.iImage = 0;
tvis.item.iSelectedImage = 1;
if (hParentItem = TreeView_InsertItem(hTree, &tvis))
{
FavoritesList::const_iterator subIter = favorites->begin();
while (subIter != favorites->end())
{
if (!(*subIter)->isFolder && (*subIter)->parentFolder == (*iter)->name)
{
//Add items to sub tree
tvis.hParent = hParentItem;
tvis.hInsertAfter = TVI_LAST;
tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvis.item.pszText = const_cast<char*>((*subIter)->name.c_str());
tvis.item.lParam = 0; //1 for folders, 0 for items.
tvis.item.iImage = 3;
tvis.item.iSelectedImage = 3;
TreeView_InsertItem(hTree, &tvis);
}
subIter++;
}
//Expand each folder to display location items
TreeView_Expand(hTree, hParentItem, TVE_EXPAND);
}
}
else if((*iter)->parentFolder == "")
{
//Add item to root "Locations"
tvis.hParent = hParent;
tvis.hInsertAfter = TVI_LAST;
tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvis.item.pszText = const_cast<char*>((*iter)->name.c_str());
tvis.item.lParam = 0; //1 for folders, 0 for items.
tvis.item.iImage = 3;
tvis.item.iSelectedImage = 3;
TreeView_InsertItem(hTree, &tvis);
}
iter++;
}
}
}
dragging = false;
return hParent;
}
HTREEITEM PopulateLocationFolders(HWND hTree, CelestiaCore* appCore, HINSTANCE appInstance)
{
//First create an image list for the icons in the control
HTREEITEM hParent=NULL;
HIMAGELIST himlIcons;
HICON hIcon;
//Create a masked image list large enough to hold the icons.
himlIcons = ImageList_Create(16, 16, ILC_MASK, 3, 0);
// Load the icon resources, and add the icons to the image list.
hIcon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_CLOSEDFOLDER));
ImageList_AddIcon(himlIcons, hIcon);
hIcon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_OPENFOLDER));
ImageList_AddIcon(himlIcons, hIcon);
hIcon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_ROOTFOLDER));
ImageList_AddIcon(himlIcons, hIcon);
// Associate the image list with the tree-view control.
TreeView_SetImageList(hTree, himlIcons, TVSIL_NORMAL);
const FavoritesList* favorites = appCore->getFavorites();
if (favorites != NULL)
{
//Create a subtree item called "Locations"
TVINSERTSTRUCT tvis;
tvis.hParent = TVI_ROOT;
tvis.hInsertAfter = TVI_LAST;
tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvis.item.pszText = "Locations";
tvis.item.lParam = 1;
tvis.item.iImage = 2;
tvis.item.iSelectedImage = 2;
if (hParent = TreeView_InsertItem(hTree, &tvis))
{
FavoritesList::const_iterator iter = favorites->begin();
while (iter != favorites->end())
{
TVINSERTSTRUCT tvis;
//Is this a folder?
if ((*iter)->isFolder)
{
//Create a subtree item for the folder
tvis.hParent = hParent;
tvis.hInsertAfter = TVI_LAST;
tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvis.item.pszText = const_cast<char*>((*iter)->name.c_str());
tvis.item.lParam = 1;
tvis.item.iImage = 0;
tvis.item.iSelectedImage = 1;
TreeView_InsertItem(hTree, &tvis);
}
iter++;
}
//Select "Locations" folder
TreeView_SelectItem(hTree, hParent);
}
}
return hParent;
}
void BuildFavoritesMenu(HMENU menuBar, CelestiaCore* appCore, HINSTANCE appInstance, ODMenu* odMenu)
{
// Add favorites to locations menu
int numStaticItems = 2; //The number of items defined in the .rc file.
const FavoritesList* favorites = appCore->getFavorites();
if (favorites != NULL)
{
MENUITEMINFO menuInfo;
menuInfo.cbSize = sizeof(MENUITEMINFO);
menuInfo.fMask = MIIM_SUBMENU;
if (GetMenuItemInfo(menuBar, 4, TRUE, &menuInfo))
{
HMENU locationsMenu = menuInfo.hSubMenu;
// First, tear down existing menu beyond separator.
while (DeleteMenu(locationsMenu, numStaticItems, MF_BYPOSITION))
odMenu->DeleteItem(locationsMenu, numStaticItems);
// Don't continue if there are no items in favorites
if (favorites->size() == 0)
return;
// Insert separator
menuInfo.cbSize = sizeof MENUITEMINFO;
menuInfo.fMask = MIIM_TYPE | MIIM_STATE;
menuInfo.fType = MFT_SEPARATOR;
menuInfo.fState = MFS_UNHILITE;
if(InsertMenuItem(locationsMenu, numStaticItems, TRUE, &menuInfo))
{
odMenu->AddItem(locationsMenu, numStaticItems);
numStaticItems++;
}
// Add folders and their sub items
int rootMenuIndex = numStaticItems;
int subMenuIndex, resourceIndex = 0;
FavoritesList::const_iterator iter = favorites->begin();
while (iter != favorites->end())
{
// Is this a folder?
if ((*iter)->isFolder)
{
// Create a submenu
HMENU subMenu;
if (subMenu = CreatePopupMenu())
{
// Create a menu item that displays a popup sub menu
menuInfo.cbSize = sizeof MENUITEMINFO;
menuInfo.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
menuInfo.fType = MFT_STRING;
menuInfo.wID = ID_LOCATIONS_FIRSTLOCATION + resourceIndex;
menuInfo.hSubMenu = subMenu;
menuInfo.dwTypeData = const_cast<char*>((*iter)->name.c_str());
if (InsertMenuItem(locationsMenu, rootMenuIndex, TRUE, &menuInfo))
{
odMenu->AddItem(locationsMenu, rootMenuIndex);
odMenu->SetItemImage(appInstance, menuInfo.wID, IDB_FOLDERCLOSED);
rootMenuIndex++;
resourceIndex++;
// Now iterate through all Favorites and add items
// to this folder where parentFolder == folderName
subMenuIndex = 0;
string folderName = (*iter)->name;
iter++;
while (iter != favorites->end())
{
if (!(*iter)->isFolder && (*iter)->parentFolder == folderName)
{
// Add items to sub menu
menuInfo.cbSize = sizeof MENUITEMINFO;
menuInfo.fMask = MIIM_TYPE | MIIM_ID;
menuInfo.fType = MFT_STRING;
menuInfo.wID = ID_LOCATIONS_FIRSTLOCATION + resourceIndex;
menuInfo.dwTypeData = const_cast<char*>((*iter)->name.c_str());
if(InsertMenuItem(subMenu, subMenuIndex, TRUE, &menuInfo))
{
odMenu->AddItem(subMenu, subMenuIndex);
odMenu->SetItemImage(appInstance, menuInfo.wID, IDB_LOCATION);
subMenuIndex++;
}
}
else
break;
iter++;
resourceIndex++;
}
// Add a disabled "(empty)" item if no items
// were added to sub menu
if (subMenuIndex == 0)
{
menuInfo.cbSize = sizeof MENUITEMINFO;
menuInfo.fMask = MIIM_TYPE | MIIM_STATE;
menuInfo.fType = MFT_STRING;
menuInfo.fState = MFS_DISABLED;
menuInfo.dwTypeData = "(empty)";
if (InsertMenuItem(subMenu, subMenuIndex, TRUE, &menuInfo))
{
odMenu->AddItem(subMenu, subMenuIndex);
}
}
}
}
}
else
iter++;
}
// Add root locations items
iter = favorites->begin();
while (iter != favorites->end())
{
// Is this a non folder item?
if (!(*iter)->isFolder && (*iter)->parentFolder == "")
{
// Append to locationsMenu
AppendMenu(locationsMenu, MF_STRING,
ID_LOCATIONS_FIRSTLOCATION + resourceIndex,
const_cast<char*>((*iter)->name.c_str()));
odMenu->AddItem(locationsMenu, rootMenuIndex);
odMenu->SetItemImage(appInstance, ID_LOCATIONS_FIRSTLOCATION + resourceIndex, IDB_LOCATION);
rootMenuIndex++;
resourceIndex++;
}
iter++;
}
}
}
}
void AddNewLocationFolderInTree(HWND hTree, char* folderName)
{
//Add new item to Location item after other folders but before root items
HTREEITEM hParent, hItem, hInsertAfter;
TVINSERTSTRUCT tvis;
TVITEM tvItem;
hParent = TreeView_GetChild(hTree, TVI_ROOT);
if (hParent)
{
//Find last "folder" in children of hParent
hItem = TreeView_GetChild(hTree, hParent);
while (hItem)
{
//Is this a "folder
tvItem.hItem = hItem;
tvItem.mask = TVIF_HANDLE | TVIF_PARAM;
if (TreeView_GetItem(hTree, &tvItem))
{
if(tvItem.lParam == 1)
hInsertAfter = hItem;
}
hItem = TreeView_GetNextSibling(hTree, hItem);
}
tvis.hParent = hParent;
tvis.hInsertAfter = hInsertAfter;
tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvis.item.pszText = folderName;
tvis.item.lParam = 1;
tvis.item.iImage = 2;
tvis.item.iSelectedImage = 1;
if (hItem = TreeView_InsertItem(hTree, &tvis))
{
//Make sure root tree item is open and newly
//added item is visible.
TreeView_Expand(hTree, hParent, TVE_EXPAND);
//Select the item
TreeView_SelectItem(hTree, hItem);
}
}
}
void SyncTreeFoldersWithFavoriteFolders(HWND hTree, CelestiaCore* appCore)
{
const FavoritesList* favorites = appCore->getFavorites();
FavoritesList::const_iterator iter;
TVITEM tvItem;
HTREEITEM hItem, hParent;
char itemName[33];
bool found;
if (favorites != NULL)
{
//Scan through tree control folders and add any folder that does
//not exist in Favorites.
if (hParent = TreeView_GetChild(hTree, TVI_ROOT))
{
hItem = TreeView_GetChild(hTree, hParent);
do
{
//Get information on item
tvItem.hItem = hItem;
tvItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_HANDLE;
tvItem.pszText = itemName;
tvItem.cchTextMax = sizeof(itemName);
if (TreeView_GetItem(hTree, &tvItem))
{
//Skip non-folders.
if(tvItem.lParam == 0)
continue;
string name(itemName);
if (favorites->size() == 0)
{
//Just append the folder
appCore->addFavoriteFolder(name);
continue;
}
//Loop through favorites to find item = itemName
found = false;
iter = favorites->begin();
while (iter != favorites->end())
{
if ((*iter)->isFolder && (*iter)->name == itemName)
{
found = true;
break;
}
iter++;
}
if (!found)
{
//If not found in favorites, add it.
//We want all folders to appear before root items so this
//new folder must be inserted after the last item of the
//last folder.
//Locate position of last folder.
FavoritesList::const_iterator folderIter = favorites->begin();
iter = favorites->begin();
while (iter != favorites->end())
{
if ((*iter)->isFolder)
folderIter = iter;
iter++;
}
//Now iterate through items until end of folder found
folderIter++;
while (folderIter != favorites->end() && (*folderIter)->parentFolder != "")
folderIter++;
//Insert item
appCore->addFavoriteFolder(name, &folderIter);
}
}
} while (hItem = TreeView_GetNextSibling(hTree, hItem));
}
}
}
void InsertLocationInFavorites(HWND hTree, char* name, CelestiaCore* appCore)
{
const FavoritesList* favorites = appCore->getFavorites();
FavoritesList::const_iterator iter;
TVITEM tvItem;
HTREEITEM hItem;
char itemName[33];
string newLocation(name);
SyncTreeFoldersWithFavoriteFolders(hTree, appCore);
//Determine which tree item (folder) is selected (if any)
hItem = TreeView_GetSelection(hTree);
if (!TreeView_GetParent(hTree, hItem))
hItem = NULL;
if (hItem)
{
tvItem.hItem = hItem;
tvItem.mask = TVIF_TEXT | TVIF_HANDLE;
tvItem.pszText = itemName;
tvItem.cchTextMax = sizeof(itemName);
if (TreeView_GetItem(hTree, &tvItem))
{
//Iterate through Favorites to locate folder = selected tree item
iter = favorites->begin();
while (iter != favorites->end())
{
if ((*iter)->isFolder && (*iter)->name == itemName)
{
//To insert new item at end of folder menu, we have to iterate
//to the one item past the last item in the folder.
//vector::insert() inserts item before specified iterator.
iter++;
while (iter != favorites->end() && !((*iter)->isFolder) && (*iter)->parentFolder != "")
iter++;
//Insert new location at position in iteration.
string parentFolder(itemName);
appCore->addFavorite(newLocation, parentFolder, &iter);
break;
}
iter++;
}
}
}
else
{
//Folder not specified, add to end of favorites
appCore->addFavorite(newLocation, "");
}
}
void DeleteLocationFromFavorites(HWND hTree, CelestiaCore* appCore)
{
const FavoritesList* favorites = appCore->getFavorites();
FavoritesList::const_iterator iter;
TVITEM tvItem;
HTREEITEM hItem, hFolder;
char itemName[33], folderName[33];
//First get the selected item
if (hItem = TreeView_GetSelection(hTree))
{
//Next get this items parent (which is the folder)
if (hFolder = TreeView_GetParent(hTree, hItem))
{
//Get the item text (which is the folder name)
tvItem.hItem = hFolder;
tvItem.mask = TVIF_TEXT | TVIF_HANDLE;
tvItem.pszText = folderName;
tvItem.cchTextMax = sizeof(folderName);
if (TreeView_GetItem(hTree, &tvItem))
{
//Have we selected a root location item?
if (!TreeView_GetParent(hTree, hFolder))
folderName[0] = '\0';
//Get the selected item text (which is the location name)
tvItem.hItem = hItem;
tvItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_HANDLE;
tvItem.pszText = itemName;
tvItem.cchTextMax = sizeof(itemName);
if (TreeView_GetItem(hTree, &tvItem))
{
//tvItem.lParam == 1 if this is a folder we are trying to delete
if (tvItem.lParam == 1)
{
//Delete folder and all children
if (TreeView_DeleteItem(hTree, hItem))
{
//Delete items in favorites
iter = favorites->begin();
while (iter != favorites->end())
{
if ((*iter)->name == itemName || (*iter)->parentFolder == itemName)
{
//Delete item from favorites.
((FavoritesList*)favorites)->erase((FavoritesList::iterator)iter);
}
else
iter++;
}
}
}
else
{
//Delete the corresponding item in Favorites
iter = favorites->begin();
while (iter != favorites->end())
{
if ((*iter)->name == itemName && (*iter)->parentFolder == folderName)
{
//Delete the tree item
if (TreeView_DeleteItem(hTree, hItem))
{
//Delete item from favorites.
((FavoritesList*)favorites)->erase((FavoritesList::iterator)iter);
}
break;
}
iter++;
}
}
}
}
}
}
}
void RenameLocationInFavorites(HWND hTree, char* newName, CelestiaCore* appCore)
{
const FavoritesList* favorites = appCore->getFavorites();
FavoritesList::const_iterator iter;
TVITEM tvItem;
HTREEITEM hItem, hFolder;
char itemName[33], folderName[33];
//First get the selected item
if (hItem = TreeView_GetSelection(hTree))
{
//Next get this items parent (which is the folder)
if (hFolder = TreeView_GetParent(hTree, hItem))
{
//Get the item text (which is the folder name)
tvItem.hItem = hFolder;
tvItem.mask = TVIF_TEXT | TVIF_HANDLE;
tvItem.pszText = folderName;
tvItem.cchTextMax = sizeof(folderName);
if (TreeView_GetItem(hTree, &tvItem))
{
//Have we selected a root location item?
if (!TreeView_GetParent(hTree, hFolder))
folderName[0] = '\0';
//Get the selected item text (which is the location name)
tvItem.hItem = hItem;
tvItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_HANDLE;
tvItem.pszText = itemName;
tvItem.cchTextMax = sizeof(itemName);
if (TreeView_GetItem(hTree, &tvItem))
{
//tvItem.lParam == 1 if this is a folder we are trying to delete
if (tvItem.lParam == 1)
{
//Rename folder and update children
tvItem.hItem = hItem;
tvItem.mask = TVIF_TEXT | TVIF_HANDLE;
tvItem.pszText = newName;
if (TreeView_SetItem(hTree, &tvItem))
{
//Rename folder item in favorites, and update children
iter = favorites->begin();
while (iter != favorites->end())
{
if ((*iter)->name == itemName)
(*iter)->name = newName;
else if ((*iter)->parentFolder == itemName)
(*iter)->parentFolder = newName;
iter++;
}
}
}
else
{
//Rename the corresponding item in Favorites
iter = favorites->begin();
while (iter != favorites->end())
{
if ((*iter)->name == itemName && (*iter)->parentFolder == folderName)
{
//Rename the tree item
tvItem.hItem = hItem;
tvItem.mask = TVIF_TEXT | TVIF_HANDLE;
tvItem.pszText = newName;
if (TreeView_SetItem(hTree, &tvItem))
(*iter)->name = newName;
break;
}
iter++;
}
}
}
}
}
}
}
void MoveLocationInFavorites(HWND hTree, CelestiaCore* appCore)
{
const FavoritesList* favorites = appCore->getFavorites();
FavoritesList::const_iterator iter;
TVITEM tvItem;
TVINSERTSTRUCT tvis;
HTREEITEM hDragItemFolder, hDropItem;
char dragItemName[33], dragItemFolderName[33];
char dropFolderName[33];
bool bMovedInTree = false;
//First get the target folder name
tvItem.hItem = hDropTargetItem;
tvItem.mask = TVIF_TEXT | TVIF_HANDLE;
tvItem.pszText = dropFolderName;
tvItem.cchTextMax = sizeof(dropFolderName);
if (TreeView_GetItem(hTree, &tvItem))
{
if (!TreeView_GetParent(hTree, hDropTargetItem))
dropFolderName[0] = '\0';
//First get the dragged item text
tvItem.hItem = hDragItem;
tvItem.mask = TVIF_TEXT | TVIF_HANDLE;
tvItem.pszText = dragItemName;
tvItem.cchTextMax = sizeof(dragItemName);
if (TreeView_GetItem(hTree, &tvItem))
{
//Get the dragged item folder
if (hDragItemFolder = TreeView_GetParent(hTree, hDragItem))
{
tvItem.hItem = hDragItemFolder;
tvItem.mask = TVIF_TEXT | TVIF_HANDLE;
tvItem.pszText = dragItemFolderName;
tvItem.cchTextMax = sizeof(dragItemFolderName);
if (TreeView_GetItem(hTree, &tvItem))
{
if (!TreeView_GetParent(hTree, hDragItemFolder))
dragItemFolderName[0] = '\0';
//Make sure drag and target folders are different
if (strcmp(dragItemFolderName, dropFolderName))
{
//Delete tree item from src location
if (TreeView_DeleteItem(hTree, hDragItem))
{
//Add item to dest location
tvis.hParent = hDropTargetItem;
tvis.hInsertAfter = TVI_LAST;
tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvis.item.pszText = dragItemName;
tvis.item.lParam = 0; //1 for folders, 0 for items.
tvis.item.iImage = 3;
tvis.item.iSelectedImage = 3;
if (hDropItem = TreeView_InsertItem(hTree, &tvis))
{
TreeView_Expand(hTree, hDropTargetItem, TVE_EXPAND);
//Make the dropped item selected
TreeView_SelectItem(hTree, hDropItem);
bMovedInTree = true;
}
}
}
}
}
}
}
//Now perform the move in Favorites
if(bMovedInTree)
{
//Locate item with name == dragItemName and parentFolder == dragItemFolderName
iter = favorites->begin();
while (iter != favorites->end())
{
if ((*iter)->name == dragItemName && (*iter)->parentFolder == dragItemFolderName)
{
FavoritesList::const_iterator subIter;
FavoritesEntry* fav = new FavoritesEntry();
fav->name = dragItemName;
fav->parentFolder = dropFolderName;
fav->jd = (*iter)->jd;
fav->position = (*iter)->position;
fav->orientation = (*iter)->orientation;
fav->isFolder = false;
fav->selectionName = (*iter)->selectionName;
fav->coordSys = (*iter)->coordSys;
//Locate position to insert moved item
if (dropFolderName[0] != '\0')
{
subIter = favorites->begin();
while (subIter != favorites->end())
{
if ((*subIter)->isFolder && (*subIter)->name == dropFolderName)
{
//To insert new item at end of folder menu, we have to iterate
//to the one item past the last item in the folder.
//vector::insert() inserts item before specified iterator.
subIter++;
while (subIter != favorites->end() && !((*subIter)->isFolder) &&
(*subIter)->parentFolder != "")
subIter++;
//Insert new location at position in iteration.
((FavoritesList*)favorites)->insert((FavoritesList::iterator)subIter, fav);
break;
}
subIter++;
}
//vector::insert() likely has moved item iter was pointing at
iter = favorites->begin();
while (iter != favorites->end())
{
if ((*iter)->name == dragItemName && (*iter)->parentFolder == dragItemFolderName)
{
//Delete item from favorites.
((FavoritesList*)favorites)->erase((FavoritesList::iterator)iter);
break;
}
iter++;
}
}
else
{
//Just append item to end for root folders
((FavoritesList*)favorites)->insert((FavoritesList::iterator)favorites->end(), fav);
//Delete item from favorites.
((FavoritesList*)favorites)->erase((FavoritesList::iterator)iter);
}
break;
}
iter++;
}
}
}
bool isOrganizeLocationsDragDropActive()
{
return dragging;
}
void OrganizeLocationsOnBeginDrag(HWND hTree, LPNMTREEVIEW lpnmtv)
{
HIMAGELIST himl; // handle to image list
RECT rcItem; // bounding rectangle of item
DWORD dwLevel; // heading level of item
DWORD dwIndent; // amount that child items are indented
//Clear any selected item
TreeView_SelectItem(hTree, NULL);
// Tell the tree-view control to create an image to use
// for dragging.
hDragItem = lpnmtv->itemNew.hItem;
himl = TreeView_CreateDragImage(hTree, hDragItem);
// Get the bounding rectangle of the item being dragged.
TreeView_GetItemRect(hTree, hDragItem, &rcItem, TRUE);
// Get the heading level and the amount that the child items are
// indented.
dwLevel = lpnmtv->itemNew.lParam;
dwIndent = (DWORD) SendMessage(hTree, TVM_GETINDENT, 0, 0);
ImageList_DragShowNolock(TRUE);
// Start the drag operation.
ImageList_BeginDrag(himl, 0, 7, 7);
// Hide the mouse pointer, and direct mouse input to the
// parent window.
ShowCursor(FALSE);
SetCapture(GetParent(hTree));
dragging = true;
}
void OrganizeLocationsOnMouseMove(HWND hTree, LONG xCur, LONG yCur)
{
TVHITTESTINFO tvht; // hit test information
TVITEM tvItem;
HTREEITEM hItem;
//Store away last drag position so timer can perform auto-scrolling.
dragPos.x = xCur;
dragPos.y = yCur;
if (dragging)
{
// Drag the item to the current position of the mouse pointer.
ImageList_DragMove(xCur, yCur);
ImageList_DragLeave(hTree);
// Find out if the pointer is on the item. If it is,
// highlight the item as a drop target.
tvht.pt.x = dragPos.x;
tvht.pt.y = dragPos.y;
if(hItem = TreeView_HitTest(hTree, &tvht))
{
//Only select folder items for drop targets
tvItem.hItem = hItem;
tvItem.mask = TVIF_PARAM | TVIF_HANDLE;
if (TreeView_GetItem(hTree, &tvItem))
{
if(tvItem.lParam == 1)
{
hDropTargetItem = hItem;
TreeView_SelectDropTarget(hTree, hDropTargetItem);
}
}
}
ImageList_DragEnter(hTree, xCur, yCur);
}
}
void OrganizeLocationsOnLButtonUp(HWND hTree)
{
if (dragging)
{
ImageList_EndDrag();
ImageList_DragLeave(hTree);
ReleaseCapture();
ShowCursor(TRUE);
dragging = false;
//Remove TVIS_DROPHILITED state from drop target item
TreeView_SelectDropTarget(hTree, NULL);
}
}
void DragDropAutoScroll(HWND hTree)
{
RECT rect;
int i, count;
HTREEITEM hItem;
GetClientRect(hTree, &rect);
ImageList_DragLeave(hTree);
//See if we need to scroll.
if(dragPos.y > rect.bottom - 10)
{
//If we are down towards the bottom but have not scrolled to the last
//item, we need to scroll down.
if(dragPos.x > rect.left && dragPos.x < rect.right)
{
SendMessage(hTree, WM_VSCROLL, SB_LINEDOWN, 0);
count = TreeView_GetVisibleCount(hTree);
hItem = TreeView_GetFirstVisible(hTree);
for (i=0; i<count-1; i++)
hItem = TreeView_GetNextVisible(hTree, hItem);
if(hItem)
{
hDropTargetItem = hItem;
TreeView_SelectDropTarget(hTree, hDropTargetItem);
}
}
}
else if(dragPos.y < rect.top + 10)
{
//If we are up towards the top but have not scrolled to the first
//item, we need to scroll up.
if(dragPos.x > rect.left && dragPos.x < rect.right)
{
SendMessage(hTree, WM_VSCROLL, SB_LINEUP, 0);
hItem = TreeView_GetFirstVisible(hTree);
if(hItem)
{
hDropTargetItem = hItem;
TreeView_SelectDropTarget(hTree, hDropTargetItem);
}
}
}
ImageList_DragEnter(hTree, dragPos.x, dragPos.y);
}
/*
/////////////////////////////////////////////////////////////////////////////
// This function returns the handle of the tree item specified using standard
// path notation.
/////////////////////////////////////////////////////////////////////////////
HTREEITEM GetTreeViewItemHandle(HWND hTree, char* path, HTREEITEM hParent)
{
if (!hTree || !hParent)
return NULL;
char* cP;
char itemName[33];
char pathBuf[66];
TVITEM Item;
HTREEITEM hItem;
strcpy(pathBuf, path);
if (cP = strchr(pathBuf, '/'))
*cP = '\0';
hItem = NULL;
itemName[0] = '\0';
Item.mask = TVIF_TEXT | TVIF_HANDLE;
Item.pszText = itemName;
Item.cchTextMax = sizeof(itemName);
Item.hItem = hParent;
if (TreeView_GetItem(hTree, &Item))
{
while (strcmp(pathBuf, itemName))
{
Item.hItem = TreeView_GetNextSibling(hTree, Item.hItem);
if (!Item.hItem)
break;
TreeView_GetItem(hTree, &Item);
}
hItem = Item.hItem;
}
if (!hItem)
return NULL;
//Prepare to call recursively
if (cP)
{
strcpy(pathBuf, cP + 1);
hItem = TreeView_GetChild(hTree, hItem);
hItem = GetTreeViewItemHandle(hTree, pathBuf, hItem);
}
return hItem;
}
*/