winbookmarks.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:30k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // winbookmarks.cpp
  2. // 
  3. // Copyright (C) 2002, Chris Laurel <claurel@shatters.net>
  4. //
  5. // Miscellaneous utilities for Locations UI implementation.
  6. //
  7. // This program is free software; you can redistribute it and/or
  8. // modify it under the terms of the GNU General Public License
  9. // as published by the Free Software Foundation; either version 2
  10. // of the License, or (at your option) any later version.
  11. #include "winbookmarks.h"
  12. #include "res/resource.h"
  13. #include <celutil/winutil.h>
  14. #include <iostream>
  15. using namespace std;
  16. bool dragging;
  17. HTREEITEM hDragItem;
  18. HTREEITEM hDropTargetItem;
  19. POINT dragPos;
  20. static const unsigned int StdItemMask = (TVIF_TEXT | TVIF_PARAM |
  21.                                          TVIF_IMAGE | TVIF_SELECTEDIMAGE);
  22. static bool isTopLevel(const FavoritesEntry* fav)
  23. {
  24.     return fav->parentFolder == "";
  25. }
  26. HTREEITEM PopulateBookmarksTree(HWND hTree, CelestiaCore* appCore, HINSTANCE appInstance)
  27. {
  28.     //First create an image list for the icons in the control
  29.     HIMAGELIST himlIcons;
  30.     HICON hIcon;
  31.     HTREEITEM hParent=NULL, hParentItem;
  32.     //Create a masked image list large enough to hold the icons. 
  33.     himlIcons = ImageList_Create(16, 16, ILC_MASK, 3, 0);
  34.  
  35.     // Load the icon resources, and add the icons to the image list.
  36.     hIcon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_CLOSEDFOLDER)); 
  37.     ImageList_AddIcon(himlIcons, hIcon);
  38.     hIcon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_OPENFOLDER)); 
  39.     ImageList_AddIcon(himlIcons, hIcon);
  40.     hIcon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_ROOTFOLDER)); 
  41.     ImageList_AddIcon(himlIcons, hIcon);
  42.     hIcon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_BOOKMARK)); 
  43.     ImageList_AddIcon(himlIcons, hIcon);
  44.     // Associate the image list with the tree-view control.
  45.     TreeView_SetImageList(hTree, himlIcons, TVSIL_NORMAL);
  46.     FavoritesList* favorites = appCore->getFavorites();
  47.     if (favorites != NULL)
  48.     {
  49.         // Create a subtree item called "Bookmarks"
  50.         TVINSERTSTRUCT tvis;
  51.         tvis.hParent = TVI_ROOT;
  52.         tvis.hInsertAfter = TVI_LAST;
  53.         tvis.item.mask = StdItemMask;
  54.         tvis.item.pszText = "Bookmarks";
  55.         tvis.item.lParam = NULL;
  56.         tvis.item.iImage = 2;
  57.         tvis.item.iSelectedImage = 2;
  58.         if (hParent = TreeView_InsertItem(hTree, &tvis))
  59.         {
  60.             FavoritesList::iterator iter = favorites->begin();
  61.             while (iter != favorites->end())
  62.             {
  63.                 TVINSERTSTRUCT tvis;
  64.                 FavoritesEntry* fav = *iter;
  65.                 // Is this a folder?
  66.                 if (fav->isFolder)
  67.                 {
  68.                     // Create a subtree item
  69.                     tvis.hParent = hParent;
  70.                     tvis.hInsertAfter = TVI_LAST;
  71.                     tvis.item.mask = StdItemMask;
  72.                     tvis.item.pszText = const_cast<char*>(fav->name.c_str());
  73.                     tvis.item.lParam = reinterpret_cast<LPARAM>(fav);
  74.                     tvis.item.iImage = 0;
  75.                     tvis.item.iSelectedImage = 1;
  76.                     if (hParentItem = TreeView_InsertItem(hTree, &tvis))
  77.                     {
  78.                         FavoritesList::iterator subIter = favorites->begin();
  79.                         while (subIter != favorites->end())
  80.                         {
  81.                             FavoritesEntry* child = *subIter;
  82.                             // See if this entry is a child
  83.                             if (!child->isFolder && child->parentFolder == fav->name)
  84.                             {
  85.                                 // Add items to sub tree
  86.                                 tvis.hParent = hParentItem;
  87.                                 tvis.hInsertAfter = TVI_LAST;
  88.                                 tvis.item.mask = StdItemMask;
  89.                                 tvis.item.pszText = const_cast<char*>(child->name.c_str());
  90.                                 tvis.item.lParam = reinterpret_cast<LPARAM>(child);
  91.                                 tvis.item.iImage = 3;
  92.                                 tvis.item.iSelectedImage = 3;
  93.                                 TreeView_InsertItem(hTree, &tvis);
  94.                             }
  95.                             subIter++;
  96.                         }
  97.                         // Expand each folder to display bookmark items
  98.                         TreeView_Expand(hTree, hParentItem, TVE_EXPAND);
  99.                     }
  100.                 }
  101.                 else if (isTopLevel(fav))
  102.                 {
  103.                     // Add item to root "Bookmarks"
  104.                     tvis.hParent = hParent;
  105.                     tvis.hInsertAfter = TVI_LAST;
  106.                     tvis.item.mask = StdItemMask;
  107.                     tvis.item.pszText = const_cast<char*>((*iter)->name.c_str());
  108.                     tvis.item.lParam = reinterpret_cast<LPARAM>(fav);
  109.                     tvis.item.iImage = 3;
  110.                     tvis.item.iSelectedImage = 3;
  111.                     TreeView_InsertItem(hTree, &tvis);
  112.                 }
  113.                 iter++;
  114.             }
  115.         }
  116.     }
  117.     dragging = false;
  118.     return hParent;
  119. }
  120. HTREEITEM PopulateBookmarkFolders(HWND hTree, CelestiaCore* appCore, HINSTANCE appInstance)
  121. {
  122.     // First create an image list for the icons in the control
  123.     HTREEITEM hParent=NULL;
  124.     HIMAGELIST himlIcons;
  125.     HICON hIcon;
  126.     //Create a masked image list large enough to hold the icons. 
  127.     himlIcons = ImageList_Create(16, 16, ILC_MASK, 3, 0);
  128.  
  129.     // Load the icon resources, and add the icons to the image list.
  130.     hIcon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_CLOSEDFOLDER)); 
  131.     ImageList_AddIcon(himlIcons, hIcon);
  132.     hIcon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_OPENFOLDER)); 
  133.     ImageList_AddIcon(himlIcons, hIcon);
  134.     hIcon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_ROOTFOLDER)); 
  135.     ImageList_AddIcon(himlIcons, hIcon);
  136.     // Associate the image list with the tree-view control.
  137.     TreeView_SetImageList(hTree, himlIcons, TVSIL_NORMAL);
  138.     FavoritesList* favorites = appCore->getFavorites();
  139.     if (favorites != NULL)
  140.     {
  141.         // Create a subtree item called "Bookmarks"
  142.         TVINSERTSTRUCT tvis;
  143.         tvis.hParent = TVI_ROOT;
  144.         tvis.hInsertAfter = TVI_LAST;
  145.         tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  146.         tvis.item.pszText = "Bookmarks";
  147.         tvis.item.lParam = 0;
  148.         tvis.item.iImage = 2;
  149.         tvis.item.iSelectedImage = 2;
  150.         if (hParent = TreeView_InsertItem(hTree, &tvis))
  151.         {
  152.             FavoritesList::iterator iter = favorites->begin();
  153.             while (iter != favorites->end())
  154.             {
  155.                 FavoritesEntry* fav = *iter;
  156.                 if (fav->isFolder)
  157.                 {
  158.                     // Create a subtree item for the folder
  159.                     TVINSERTSTRUCT tvis;
  160.                     tvis.hParent = hParent;
  161.                     tvis.hInsertAfter = TVI_LAST;
  162.                     tvis.item.mask = StdItemMask;
  163.                     tvis.item.pszText = const_cast<char*>(fav->name.c_str());
  164.                     tvis.item.lParam = reinterpret_cast<LPARAM>(fav);
  165.                     tvis.item.iImage = 0;
  166.                     tvis.item.iSelectedImage = 1;
  167.                     TreeView_InsertItem(hTree, &tvis);
  168.                 }
  169.                 iter++;
  170.             }
  171.             // Select "Bookmarks" folder
  172.             TreeView_SelectItem(hTree, hParent);
  173.         }
  174.     }
  175.     return hParent;
  176. }
  177. void BuildFavoritesMenu(HMENU menuBar,
  178.                         CelestiaCore* appCore,
  179.                         HINSTANCE appInstance,
  180.                         ODMenu* odMenu)
  181. {
  182.     // Add item to bookmarks menu
  183.     int numStaticItems = 2; // The number of items defined in the .rc file.
  184.     // Ugly dependence on menu defined in celestia.rc; this needs to change
  185.     // if the bookmarks menu is moved, or if another item is added to the
  186.     // menu bar.
  187.     // TODO: Fix this dependency
  188.     UINT bookmarksMenuPosition = 5;
  189.     FavoritesList* favorites = appCore->getFavorites();
  190.     if (favorites == NULL)
  191.         return;
  192.     MENUITEMINFO menuInfo;
  193.     menuInfo.cbSize = sizeof(MENUITEMINFO);
  194.     menuInfo.fMask = MIIM_SUBMENU;
  195.     if (GetMenuItemInfo(menuBar, bookmarksMenuPosition, TRUE, &menuInfo))
  196.     {
  197.         HMENU bookmarksMenu = menuInfo.hSubMenu;
  198.         // First, tear down existing menu beyond separator.
  199.         while (DeleteMenu(bookmarksMenu, numStaticItems, MF_BYPOSITION))
  200.             odMenu->DeleteItem(bookmarksMenu, numStaticItems);
  201.         // Don't continue if there are no items in favorites
  202.         if (favorites->size() == 0)
  203.             return;
  204.         // Insert separator
  205.         menuInfo.cbSize = sizeof MENUITEMINFO;
  206.         menuInfo.fMask = MIIM_TYPE | MIIM_STATE;
  207.         menuInfo.fType = MFT_SEPARATOR;
  208.         menuInfo.fState = MFS_UNHILITE;
  209.         if (InsertMenuItem(bookmarksMenu, numStaticItems, TRUE, &menuInfo))
  210.         {
  211.             odMenu->AddItem(bookmarksMenu, numStaticItems);
  212.             numStaticItems++;
  213.         }
  214.         // Add folders and their sub items
  215.         int rootMenuIndex = numStaticItems;
  216.         int rootResIndex = 0;
  217.         FavoritesList::iterator iter = favorites->begin();
  218.         while (iter != favorites->end())
  219.         {
  220.             FavoritesEntry* fav = *iter;
  221.             // Is this a folder?
  222.             if (fav->isFolder)
  223.             {
  224.                 // Create a submenu
  225.                 HMENU subMenu;
  226.                 if (subMenu = CreatePopupMenu())
  227.                 {
  228.                     // Create a menu item that displays a popup sub menu
  229.                     menuInfo.cbSize = sizeof MENUITEMINFO;
  230.                     menuInfo.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
  231.                     menuInfo.fType = MFT_STRING;
  232.                     menuInfo.wID = ID_BOOKMARKS_FIRSTBOOKMARK + rootResIndex;
  233.                     menuInfo.hSubMenu = subMenu;
  234.                     menuInfo.dwTypeData = const_cast<char*>(fav->name.c_str());
  235.                     if (InsertMenuItem(bookmarksMenu,
  236.                                        rootMenuIndex,
  237.                                        TRUE,
  238.                                        &menuInfo))
  239.                     {
  240.                         odMenu->AddItem(bookmarksMenu, rootMenuIndex);
  241.                         odMenu->SetItemImage(appInstance, menuInfo.wID,
  242.                                              IDB_FOLDERCLOSED);
  243.                         rootMenuIndex++;
  244.                         // Now iterate through all Favorites and add items
  245.                         // to this folder where parentFolder == folderName
  246.                         int subMenuIndex = 0;
  247.                         int childResIndex = 0;
  248.                         string folderName = fav->name;
  249.                         for (FavoritesList::iterator childIter = favorites->begin();
  250.                              childIter != favorites->end();
  251.                              childIter++, childResIndex++)
  252.                         {
  253.                             FavoritesEntry* child = *childIter;
  254.                             if (!child->isFolder &&
  255.                                 child->parentFolder == folderName)
  256.                             {
  257.                                 clog << "  " << child->name << 'n';
  258.                                 // Add item to sub menu
  259.                                 menuInfo.cbSize = sizeof MENUITEMINFO;
  260.                                 menuInfo.fMask = MIIM_TYPE | MIIM_ID;
  261.                                 menuInfo.fType = MFT_STRING;
  262.                                 menuInfo.wID = ID_BOOKMARKS_FIRSTBOOKMARK + childResIndex;
  263.                                 menuInfo.dwTypeData = const_cast<char*>(child->name.c_str());
  264.                                 if (InsertMenuItem(subMenu, subMenuIndex, TRUE, &menuInfo))
  265.                                 {
  266.                                     odMenu->AddItem(subMenu, subMenuIndex);
  267.                                     odMenu->SetItemImage(appInstance, menuInfo.wID, IDB_BOOKMARK);
  268.                                     subMenuIndex++;
  269.                                 }
  270.                             }
  271.                         }
  272.                         // Add a disabled "(empty)" item if no items
  273.                         // were added to sub menu
  274.                         if (subMenuIndex == 0)
  275.                         {
  276.                             menuInfo.cbSize = sizeof MENUITEMINFO;
  277.                             menuInfo.fMask = MIIM_TYPE | MIIM_STATE;
  278.                             menuInfo.fType = MFT_STRING;
  279.                             menuInfo.fState = MFS_DISABLED;
  280.                             menuInfo.dwTypeData = "(empty)";
  281.                             if (InsertMenuItem(subMenu, subMenuIndex, TRUE, &menuInfo))
  282.                             {
  283.                                 odMenu->AddItem(subMenu, subMenuIndex);
  284.                             }
  285.                         }
  286.                     }
  287.                 }
  288.             }
  289.             rootResIndex++;
  290.             iter++;
  291.         }
  292.         // Add root bookmark items
  293.         iter = favorites->begin();
  294.         rootResIndex = 0;
  295.         while (iter != favorites->end())
  296.         {
  297.             FavoritesEntry* fav = *iter;
  298.             // Is this a non folder item?
  299.             if (!fav->isFolder && isTopLevel(fav))
  300.             {
  301.                 // Append to bookmarksMenu
  302.                 AppendMenu(bookmarksMenu, MF_STRING,
  303.                            ID_BOOKMARKS_FIRSTBOOKMARK + rootResIndex,
  304.                            const_cast<char*>(fav->name.c_str()));
  305.                 odMenu->AddItem(bookmarksMenu, rootMenuIndex);
  306.                 odMenu->SetItemImage(appInstance,
  307.                                      ID_BOOKMARKS_FIRSTBOOKMARK + rootResIndex,
  308.                                      IDB_BOOKMARK);
  309.                 rootMenuIndex++;
  310.             }
  311.             iter++;
  312.             rootResIndex++;
  313.         }
  314.     }
  315. }
  316. void AddNewBookmarkFolderInTree(HWND hTree, CelestiaCore* appCore, char* folderName)
  317. {
  318.     // Add new item to bookmark item after other folders but before root items
  319.     HTREEITEM hParent, hItem, hInsertAfter;
  320.     TVINSERTSTRUCT tvis;
  321.     TVITEM tvItem;
  322.     hParent = TreeView_GetChild(hTree, TVI_ROOT);
  323.     if (hParent)
  324.     {
  325.         // Find last "folder" in children of hParent
  326.         hItem = TreeView_GetChild(hTree, hParent);
  327.         while (hItem)
  328.         {
  329.             // Is this a "folder"
  330.             tvItem.hItem = hItem;
  331.             tvItem.mask = TVIF_HANDLE | TVIF_PARAM;
  332.             if (TreeView_GetItem(hTree, &tvItem))
  333.             {
  334.                 FavoritesEntry* fav = reinterpret_cast<FavoritesEntry*>(tvItem.lParam);
  335.                 if (fav == NULL || fav->isFolder)
  336.                     hInsertAfter = hItem;
  337.             }
  338.             hItem = TreeView_GetNextSibling(hTree, hItem);
  339.         }
  340.         FavoritesEntry* folderFav = new FavoritesEntry();
  341.         folderFav->isFolder = true;
  342.         folderFav->name = folderName;
  343.         FavoritesList* favorites = appCore->getFavorites();
  344.         favorites->insert(favorites->end(), folderFav);
  345.         tvis.hParent = hParent;
  346.         tvis.hInsertAfter = hInsertAfter;
  347.         tvis.item.mask = StdItemMask;
  348.         tvis.item.pszText = folderName;
  349.         tvis.item.lParam = reinterpret_cast<LPARAM>(folderFav);
  350.         tvis.item.iImage = 2;
  351.         tvis.item.iSelectedImage = 1;
  352.         if (hItem = TreeView_InsertItem(hTree, &tvis))
  353.         {
  354.             // Make sure root tree item is open and newly
  355.             // added item is visible.
  356.             TreeView_Expand(hTree, hParent, TVE_EXPAND);
  357.             // Select the item
  358.             TreeView_SelectItem(hTree, hItem);
  359.         }
  360.     }
  361. }
  362. void SyncTreeFoldersWithFavoriteFolders(HWND hTree, CelestiaCore* appCore)
  363. {
  364.     FavoritesList* favorites = appCore->getFavorites();
  365.     FavoritesList::iterator iter;
  366.     TVITEM tvItem;
  367.     HTREEITEM hItem, hParent;
  368.     char itemName[33];
  369.     bool found;
  370.     if (favorites != NULL)
  371.     {
  372.         // Scan through tree control folders and add any folder that does
  373.         // not exist in Favorites.
  374.         if (hParent = TreeView_GetChild(hTree, TVI_ROOT))
  375.         {
  376.             hItem = TreeView_GetChild(hTree, hParent);
  377.             do
  378.             {
  379.                 // Get information on item
  380.                 tvItem.hItem = hItem;
  381.                 tvItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_HANDLE;
  382.                 tvItem.pszText = itemName;
  383.                 tvItem.cchTextMax = sizeof(itemName);
  384.                 if (TreeView_GetItem(hTree, &tvItem))
  385.                 {
  386.                     // Skip non-folders.
  387.                     if(tvItem.lParam == 0)
  388.                         continue;
  389.                     string name(itemName);
  390.                     if (favorites->size() == 0)
  391.                     {
  392.                         // Just append the folder
  393.                         appCore->addFavoriteFolder(name);
  394.                         continue;
  395.                     }
  396.                     // Loop through favorites to find item = itemName
  397.                     found = false;
  398.                     iter = favorites->begin();
  399.                     while (iter != favorites->end())
  400.                     {
  401.                         if ((*iter)->isFolder && (*iter)->name == itemName)
  402.                         {
  403.                             found = true;
  404.                             break;
  405.                         }
  406.                         iter++;
  407.                     }
  408.                     if (!found)
  409.                     {
  410.                         // If not found in favorites, add it.
  411.                         // We want all folders to appear before root items so this
  412.                         // new folder must be inserted after the last item of the 
  413.                         // last folder.
  414.                         // Locate position of last folder.
  415.                         FavoritesList::iterator folderIter = favorites->begin();
  416.                         iter = favorites->begin();
  417.                         while (iter != favorites->end())
  418.                         {
  419.                             if ((*iter)->isFolder)
  420.                                 folderIter = iter;
  421.                             iter++;
  422.                         }
  423.                         //Now iterate through items until end of folder found
  424.                         folderIter++;
  425.                         while (folderIter != favorites->end() && (*folderIter)->parentFolder != "")
  426.                             folderIter++;
  427.                         
  428.                         //Insert item
  429.                         appCore->addFavoriteFolder(name, &folderIter);
  430.                     }
  431.                 }
  432.             } while (hItem = TreeView_GetNextSibling(hTree, hItem));
  433.         }
  434.     }
  435. }
  436. void InsertBookmarkInFavorites(HWND hTree, char* name, CelestiaCore* appCore)
  437. {
  438.     FavoritesList* favorites = appCore->getFavorites();
  439.     TVITEM tvItem;
  440.     HTREEITEM hItem;
  441.     char itemName[33];
  442.     string newBookmark(name);
  443.     // SyncTreeFoldersWithFavoriteFolders(hTree, appCore);
  444.     // Determine which tree item (folder) is selected (if any)
  445.     hItem = TreeView_GetSelection(hTree);
  446.     if (!TreeView_GetParent(hTree, hItem))
  447.         hItem = NULL;
  448.     if (hItem)
  449.     {
  450.         tvItem.hItem = hItem;
  451.         tvItem.mask = TVIF_TEXT | TVIF_HANDLE;
  452.         tvItem.pszText = itemName;
  453.         tvItem.cchTextMax = sizeof(itemName);
  454.         if (TreeView_GetItem(hTree, &tvItem))
  455.         {
  456.             FavoritesEntry* fav = reinterpret_cast<FavoritesEntry*>(tvItem.lParam);
  457.             if (fav != NULL && fav->isFolder)
  458.             {
  459.                 appCore->addFavorite(newBookmark, string(itemName));
  460.             }
  461.         }
  462.     }
  463.     else
  464.     {
  465.         // Folder not specified, add to end of favorites
  466.         appCore->addFavorite(newBookmark, "");
  467.     }
  468. }
  469. void DeleteBookmarkFromFavorites(HWND hTree, CelestiaCore* appCore)
  470. {
  471.     FavoritesList* favorites = appCore->getFavorites();
  472.     TVITEM tvItem;
  473.     HTREEITEM hItem;
  474.     char itemName[33];
  475.     hItem = TreeView_GetSelection(hTree);
  476.     if (!hItem)
  477.         return;
  478.     // Get the selected item text (which is the bookmark name)
  479.     tvItem.hItem = hItem;
  480.     tvItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_HANDLE;
  481.     tvItem.pszText = itemName;
  482.     tvItem.cchTextMax = sizeof(itemName);
  483.     if (!TreeView_GetItem(hTree, &tvItem))
  484.         return;
  485.     FavoritesEntry* fav = reinterpret_cast<FavoritesEntry*>(tvItem.lParam);
  486.     if (!fav)
  487.         return;
  488.     // Delete the item from the tree view; give up if this fails for some
  489.     // reason (it shouldn't . . .)
  490.     if (!TreeView_DeleteItem(hTree, hItem))
  491.         return;
  492.     // Delete item in favorites, as well as all of it's children
  493.     FavoritesList::iterator iter = favorites->begin();
  494.     while (iter != favorites->end())
  495.     {
  496.         if (*iter == fav)
  497.         {
  498.             favorites->erase(iter);
  499.         }
  500.         else if (fav->isFolder && (*iter)->parentFolder == itemName)
  501.         {
  502.             favorites->erase(iter);
  503.             // delete *iter;
  504.         }
  505.         else
  506.         {
  507.             iter++;
  508.         }
  509.     }
  510. }
  511. void RenameBookmarkInFavorites(HWND hTree, char* newName, CelestiaCore* appCore)
  512. {
  513.     FavoritesList* favorites = appCore->getFavorites();
  514.     TVITEM tvItem;
  515.     HTREEITEM hItem;
  516.     char itemName[33];
  517.     // First get the selected item
  518.     hItem = TreeView_GetSelection(hTree);
  519.     if (!hItem)
  520.         return;
  521.     // Get the item text 
  522.     tvItem.hItem = hItem;
  523.     tvItem.mask = TVIF_TEXT | TVIF_HANDLE;
  524.     tvItem.pszText = itemName;
  525.     tvItem.cchTextMax = sizeof(itemName);
  526.     if (!TreeView_GetItem(hTree, &tvItem))
  527.         return;
  528.     FavoritesEntry* fav = reinterpret_cast<FavoritesEntry*>(tvItem.lParam);
  529.     if (fav == NULL)
  530.         return;
  531.     
  532.     tvItem.hItem = hItem;
  533.     tvItem.mask = TVIF_TEXT | TVIF_HANDLE;
  534.     tvItem.pszText = newName;
  535.     if (!TreeView_SetItem(hTree, &tvItem))
  536.         return;
  537.     string oldName = fav->name;
  538.     fav->name = newName;
  539.     if (fav->isFolder)
  540.     {
  541.         FavoritesList::iterator iter = favorites->begin();
  542.         while (iter != favorites->end())
  543.         {
  544.             if ((*iter)->parentFolder == oldName)
  545.                 (*iter)->parentFolder = newName;
  546.             iter++;
  547.         }
  548.     }
  549. }
  550. void MoveBookmarkInFavorites(HWND hTree, CelestiaCore* appCore)
  551. {
  552.     FavoritesList* favorites = appCore->getFavorites();
  553.     TVITEM tvItem;
  554.     TVINSERTSTRUCT tvis;
  555.     HTREEITEM hDragItemFolder, hDropItem;
  556.     char dragItemName[33];
  557.     char dragItemFolderName[33];
  558.     char dropFolderName[33];
  559.     bool bMovedInTree = false;
  560.     FavoritesEntry* draggedFav = NULL;
  561.     FavoritesEntry* dropFolderFav = NULL;
  562.     // First get the target folder name
  563.     tvItem.hItem = hDropTargetItem;
  564.     tvItem.mask = TVIF_TEXT | TVIF_HANDLE;
  565.     tvItem.pszText = dropFolderName;
  566.     tvItem.cchTextMax = sizeof(dropFolderName);
  567.     if (!TreeView_GetItem(hTree, &tvItem))
  568.         return;
  569.     if (!TreeView_GetParent(hTree, hDropTargetItem))
  570.         dropFolderName[0] = '';
  571.     // Get the dragged item text
  572.     tvItem.lParam = NULL;
  573.     tvItem.hItem = hDragItem;
  574.     tvItem.mask = TVIF_TEXT | TVIF_HANDLE;
  575.     tvItem.pszText = dragItemName;
  576.     tvItem.cchTextMax = sizeof(dragItemName);
  577.     if (TreeView_GetItem(hTree, &tvItem))
  578.     {
  579.         draggedFav = reinterpret_cast<FavoritesEntry*>(tvItem.lParam);
  580.             
  581.         // Get the dragged item folder
  582.         if (hDragItemFolder = TreeView_GetParent(hTree, hDragItem))
  583.         {
  584.             tvItem.hItem = hDragItemFolder;
  585.             tvItem.mask = TVIF_TEXT | TVIF_HANDLE;
  586.             tvItem.pszText = dragItemFolderName;
  587.             tvItem.cchTextMax = sizeof(dragItemFolderName);
  588.             if (TreeView_GetItem(hTree, &tvItem))
  589.             {
  590.                 if (!TreeView_GetParent(hTree, hDragItemFolder))
  591.                     dragItemFolderName[0] = '';
  592.                 // Make sure drag and target folders are different
  593.                 if (strcmp(dragItemFolderName, dropFolderName))
  594.                 {
  595.                     // Delete tree item from source bookmark
  596.                     if (TreeView_DeleteItem(hTree, hDragItem))
  597.                     {
  598.                         // Add item to dest bookmark
  599.                         tvis.hParent = hDropTargetItem;
  600.                         tvis.hInsertAfter = TVI_LAST;
  601.                         tvis.item.mask = StdItemMask;
  602.                         tvis.item.pszText = dragItemName;
  603.                         tvis.item.lParam = reinterpret_cast<LPARAM>(draggedFav);
  604.                         tvis.item.iImage = 3;
  605.                         tvis.item.iSelectedImage = 3;
  606.                         if (hDropItem = TreeView_InsertItem(hTree, &tvis))
  607.                         {
  608.                             TreeView_Expand(hTree, hDropTargetItem, TVE_EXPAND);
  609.                                 
  610.                             // Make the dropped item selected
  611.                             TreeView_SelectItem(hTree, hDropItem);
  612.                             bMovedInTree = true;
  613.                         }
  614.                     }
  615.                 }
  616.             }
  617.         }
  618.     }
  619.     // Now perform the move in favorites
  620.     if (bMovedInTree && draggedFav != NULL)
  621.     {
  622.         draggedFav->parentFolder = dropFolderName;
  623.     }
  624. }
  625. bool isOrganizeBookmarksDragDropActive()
  626. {
  627.     return dragging;
  628. }
  629. void OrganizeBookmarksOnBeginDrag(HWND hTree, LPNMTREEVIEW lpnmtv)
  630. {
  631.     HIMAGELIST himl;    // handle to image list
  632.     RECT rcItem;        // bounding rectangle of item
  633.     DWORD dwLevel;      // heading level of item
  634.     DWORD dwIndent;     // amount that child items are indented
  635.     //Clear any selected item
  636.     TreeView_SelectItem(hTree, NULL);
  637.     // Tell the tree-view control to create an image to use
  638.     // for dragging.
  639.     hDragItem = lpnmtv->itemNew.hItem;
  640.     himl = TreeView_CreateDragImage(hTree, hDragItem);
  641.     // Get the bounding rectangle of the item being dragged.
  642.     TreeView_GetItemRect(hTree, hDragItem, &rcItem, TRUE);
  643.     // Get the heading level and the amount that the child items are
  644.     // indented.
  645.     dwLevel = lpnmtv->itemNew.lParam;
  646.     dwIndent = (DWORD) SendMessage(hTree, TVM_GETINDENT, 0, 0);
  647.     ImageList_DragShowNolock(TRUE);
  648.     // Start the drag operation.
  649.     ImageList_BeginDrag(himl, 0, 7, 7);
  650.     // Hide the mouse pointer, and direct mouse input to the
  651.     // parent window.
  652.     ShowCursor(FALSE);
  653.     SetCapture(GetParent(hTree));
  654.     dragging = true;
  655. }
  656. void OrganizeBookmarksOnMouseMove(HWND hTree, LONG xCur, LONG yCur)
  657. {
  658.     TVHITTESTINFO tvht;  // hit test information
  659.     TVITEM tvItem;
  660.     HTREEITEM hItem;
  661.     //Store away last drag position so timer can perform auto-scrolling.
  662.     dragPos.x = xCur;
  663.     dragPos.y = yCur;
  664.     if (dragging)
  665.     {
  666.         // Drag the item to the current position of the mouse pointer.
  667.         ImageList_DragMove(xCur, yCur);
  668.         ImageList_DragLeave(hTree);
  669.         // Find out if the pointer is on the item. If it is,
  670.         // highlight the item as a drop target.
  671.         tvht.pt.x = dragPos.x;
  672.         tvht.pt.y = dragPos.y;
  673.         if(hItem = TreeView_HitTest(hTree, &tvht))
  674.         {
  675.             // Only select folder items for drop targets
  676.             tvItem.hItem = hItem;
  677.             tvItem.mask = TVIF_PARAM | TVIF_HANDLE;
  678.             if (TreeView_GetItem(hTree, &tvItem))
  679.             {
  680.                 FavoritesEntry* fav = reinterpret_cast<FavoritesEntry*>(tvItem.lParam);
  681.                 if (fav != NULL && fav->isFolder)
  682.                 {
  683.                     hDropTargetItem = hItem;
  684.                     TreeView_SelectDropTarget(hTree, hDropTargetItem);
  685.                 }
  686.             }
  687.         }
  688.         ImageList_DragEnter(hTree, xCur, yCur);
  689.     }
  690. }
  691. void OrganizeBookmarksOnLButtonUp(HWND hTree)
  692. {
  693.     if (dragging)
  694.     {
  695.         ImageList_EndDrag();
  696.         ImageList_DragLeave(hTree);
  697.         ReleaseCapture();
  698.         ShowCursor(TRUE);
  699.         dragging = false;
  700.         // Remove TVIS_DROPHILITED state from drop target item
  701.         TreeView_SelectDropTarget(hTree, NULL);
  702.     }
  703. }
  704. void DragDropAutoScroll(HWND hTree)
  705. {
  706.     RECT rect;
  707.     int i, count;
  708.     HTREEITEM hItem;
  709.     GetClientRect(hTree, &rect);
  710.     ImageList_DragLeave(hTree);
  711.     // See if we need to scroll.
  712.     if (dragPos.y > rect.bottom - 10)
  713.     {
  714.         // If we are down towards the bottom but have not scrolled to the last
  715.         // item, we need to scroll down.
  716.         if (dragPos.x > rect.left && dragPos.x < rect.right)
  717.         {
  718.             SendMessage(hTree, WM_VSCROLL, SB_LINEDOWN, 0);
  719.             count = TreeView_GetVisibleCount(hTree);
  720.             hItem = TreeView_GetFirstVisible(hTree);
  721.             for (i = 0; i < count - 1; i++)
  722.                 hItem = TreeView_GetNextVisible(hTree, hItem);
  723.             if (hItem)
  724.             {
  725.                 hDropTargetItem = hItem;
  726.                 TreeView_SelectDropTarget(hTree, hDropTargetItem);
  727.             }
  728.         }
  729.     }
  730.     else if (dragPos.y < rect.top + 10)
  731.     {
  732.         // If we are up towards the top but have not scrolled to the first
  733.         // item, we need to scroll up.
  734.         if (dragPos.x > rect.left && dragPos.x < rect.right)
  735.         {
  736.             SendMessage(hTree, WM_VSCROLL, SB_LINEUP, 0);
  737.             hItem = TreeView_GetFirstVisible(hTree);
  738.             if(hItem)
  739.             {
  740.                 hDropTargetItem = hItem;
  741.                 TreeView_SelectDropTarget(hTree, hDropTargetItem);
  742.             }
  743.         }
  744.     }
  745.     ImageList_DragEnter(hTree, dragPos.x, dragPos.y);
  746. }
  747. /*
  748. /////////////////////////////////////////////////////////////////////////////
  749. // This function returns the handle of the tree item specified using standard
  750. // path notation.
  751. /////////////////////////////////////////////////////////////////////////////
  752. HTREEITEM GetTreeViewItemHandle(HWND hTree, char* path, HTREEITEM hParent)
  753. {
  754.     if (!hTree || !hParent)
  755.         return NULL;
  756.     char* cP;
  757.     char itemName[33];
  758.     char pathBuf[66];
  759.     TVITEM Item;
  760.     HTREEITEM hItem;
  761.     strcpy(pathBuf, path);
  762.     if (cP = strchr(pathBuf, '/'))
  763.     *cP = '';
  764.     hItem = NULL;
  765.     itemName[0] = '';
  766.     Item.mask = TVIF_TEXT | TVIF_HANDLE;
  767.     Item.pszText = itemName;
  768.     Item.cchTextMax = sizeof(itemName);
  769.     Item.hItem = hParent;
  770.     if (TreeView_GetItem(hTree, &Item))
  771.     {
  772.     while (strcmp(pathBuf, itemName))
  773.     {
  774.             Item.hItem = TreeView_GetNextSibling(hTree, Item.hItem);
  775.             if (!Item.hItem)
  776.                 break;
  777.             TreeView_GetItem(hTree, &Item);
  778.         }
  779.         hItem = Item.hItem;
  780.     }
  781.     if (!hItem)
  782.         return NULL;
  783.     //Prepare to call recursively
  784.     if (cP)
  785.     {
  786.         strcpy(pathBuf, cP + 1);
  787.         hItem = TreeView_GetChild(hTree, hItem);
  788.         hItem = GetTreeViewItemHandle(hTree, pathBuf, hItem);
  789.     }
  790.     return hItem;
  791. }
  792. */