home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / gui / CPersonalToolbarManager.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  10.5 KB  |  316 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. //
  20. // CPersonalToolbarManager.cp
  21. //
  22. // Implementation of the CPersonalToolbarManager class which handles keeping all the
  23. // personal toolbars in sync. This reads all its info from RDF, not the old BM UI.
  24. //
  25. // I REALLY dislike that most of this code is in Hungarian notation, but the Windows
  26. // code that it originally came from was like that and instead of doing a slew of
  27. // global replaces, I'll just complain about it.
  28. //
  29.  
  30. #include "CPersonalToolbarManager.h"
  31. #include "CPersonalToolbarTable.h"
  32. #include "URDFUtilities.h"
  33.  
  34. #include "prefapi.h"
  35.  
  36. #pragma mark ÑÑ CPersonalToolbarManager
  37. #pragma mark -- Public Methods
  38.  
  39.  
  40. const char* CPersonalToolbarManager::kMaxButtonCharsPref = "browser.personal_toolbar_button.max_chars";
  41. const char* CPersonalToolbarManager::kMinButtonCharsPref = "browser.personal_toolbar_button.min_chars";
  42.  
  43.  
  44. //
  45. // Constructor
  46. //
  47. // Setup. Assumes that preferences and RDF have been initialized fully by this point.
  48. //
  49. CPersonalToolbarManager :: CPersonalToolbarManager ( )
  50.     : mUserButtonInfoArray ( sizeof(CUserButtonInfo*) )
  51. {
  52.     // setup our window into the RDF world and register this class as the one to be notified
  53.     // when the personal toolbar changes.
  54.     HT_Notification notifyStruct = CreateNotificationStruct();
  55.     mToolbarView = HT_GetSelectedView ( HT_NewPersonalToolbarPane(notifyStruct) );
  56.     Assert_(mToolbarView != NULL);
  57.     mToolbarRoot = HT_TopNode ( mToolbarView );
  58.     Assert_(mToolbarRoot != NULL);
  59.     HT_SetOpenState ( mToolbarRoot, PR_TRUE );    // ensure container is open so we can see its contents
  60.     
  61.     // read in the maximum size we're allowing for personal toolbar items. If not
  62.     // found in prefs, use our own
  63.     int32 maxToolbarButtonChars, minToolbarButtonChars;
  64.     if ( PREF_GetIntPref(kMaxButtonCharsPref, &maxToolbarButtonChars ) == PREF_ERROR )
  65.         mMaxToolbarButtonChars = CPersonalToolbarManager::kMaxPersonalToolbarChars;
  66.     else
  67.         mMaxToolbarButtonChars = maxToolbarButtonChars;
  68.     if ( PREF_GetIntPref(kMinButtonCharsPref, &minToolbarButtonChars ) == PREF_ERROR )
  69.         mMinToolbarButtonChars = CPersonalToolbarManager::kMinPersonalToolbarChars;
  70.     else
  71.         mMinToolbarButtonChars = minToolbarButtonChars;
  72.  
  73.     InitializeButtonInfo();
  74.     
  75. } // constructor
  76.  
  77.  
  78. //
  79. // Destructor
  80. //
  81. // The toolbars in individual windows will delete themselves when the window dies and
  82. // unregister themselves as listeners. We don't need to do anything along those
  83. // lines here.
  84. //
  85. CPersonalToolbarManager :: ~CPersonalToolbarManager ( )
  86. {
  87.     //ÑÑÑ delete the contents of the button list
  88. } // destructor
  89.  
  90.  
  91. //
  92. // RegisterNewToolbar
  93. //
  94. // This must be called for each new toolbar created in a browser window. It fills in
  95. // the toolbar with the correct items and registers it as a listener to the messages
  96. // we emit.
  97. //
  98. void
  99. CPersonalToolbarManager :: RegisterNewToolbar ( CPersonalToolbarTable* inBar )
  100. {
  101.     AddListener ( inBar );
  102.     BroadcastMessage ( k_PTToolbarChanged );
  103.     
  104. } // RegisterNewToolbar
  105.  
  106.  
  107. //
  108. // ToolbarChanged
  109. //
  110. // The user has just made some change to the toolbar, such as manipulating items in the nav center
  111. // or changing the personal toolbar folder. Since these changes could be quite extensive, we
  112. // just clear out the whole thing and start afresh. Tell all the toolbars that they have to
  113. // clear themselves and grab the new information. Changes to the toolbar directly, such as by
  114. // drag and drop, are handled elsewhere.
  115. //
  116. void 
  117. CPersonalToolbarManager :: ToolbarChanged ( )
  118. {
  119.     RemoveToolbarButtons();            // out with the old...
  120.     InitializeButtonInfo();            // ...in with the new
  121.     BroadcastMessage ( k_PTToolbarChanged );
  122.  
  123. } // ToolbarHeaderChanged
  124.  
  125.  
  126. //
  127. // AddButton
  128. //
  129. // Given a pre-created HT item, add it to the personal toolbar folder before the
  130. // given id and tell all the toolbars to update. This is called when the user
  131. // drops an item from another RDF source on a personal toolbar
  132. //
  133. void 
  134. CPersonalToolbarManager :: AddButton ( HT_Resource inBookmark, Uint32 inIndex )
  135. {
  136.     // Add this to RDF.
  137.     if ( GetButtons().GetCount() ) {
  138.         // If we get back a null resource then we must be trying to drop after
  139.         // the last element, or there just plain aren't any in the toolbar. Re-fetch the last element
  140.         // (using the correct index) and add the new bookmark AFTER instead of before or just add
  141.         // it to the parent for the case of an empty toolbar
  142.         PRBool before = PR_TRUE;
  143.         HT_Resource dropOn = HT_GetNthItem( mToolbarView, URDFUtilities::PPRowToHTRow(inIndex) );
  144.         if ( ! dropOn ) {
  145.             dropOn = HT_GetNthItem( mToolbarView, URDFUtilities::PPRowToHTRow(inIndex) - 1 );
  146.             before = PR_FALSE;
  147.         }
  148.         HT_DropHTRAtPos ( dropOn, inBookmark, before );
  149.     } // if items in toolbar
  150.     else
  151.         HT_DropHTROn ( mToolbarRoot, inBookmark );
  152.         
  153.     // no need to tell toolbars to refresh because we will get an HT node added event and
  154.     // refresh at that time.
  155.     
  156. } // Addbutton
  157.  
  158.  
  159. //
  160. // AddButton
  161. //
  162. // Given just a URL, add it to the personal toolbar folder before the
  163. // given id and tell all the toolbars to update. This is called when the user
  164. // drops an item from another RDF source on a personal toolbar
  165. //
  166. void 
  167. CPersonalToolbarManager :: AddButton ( const string & inURL, const string & inTitle, Uint32 inIndex )
  168. {
  169.     // Add this to RDF.
  170.     if ( GetButtons().GetCount() ) {
  171.         // If we get back a null resource then we must be trying to drop after
  172.         // the last element, or there just plain aren't any in the toolbar. Re-fetch the last element
  173.         // (using the correct index) and add the new bookmark AFTER instead of before or just add
  174.         // it to the parent for the case of an empty toolbar
  175.         PRBool before = PR_TRUE;
  176.         HT_Resource dropOn = HT_GetNthItem( mToolbarView, URDFUtilities::PPRowToHTRow(inIndex) );
  177.         if ( ! dropOn ) {
  178.             dropOn = HT_GetNthItem( mToolbarView, URDFUtilities::PPRowToHTRow(inIndex) - 1 );
  179.             before = PR_FALSE;
  180.         }
  181.         HT_DropURLAndTitleAtPos ( dropOn, const_cast<char*>(inURL.c_str()), 
  182.                                     const_cast<char*>(inTitle.c_str()), before );
  183.     } // if items in toolbar
  184.     else
  185.         HT_DropURLAndTitleOn ( mToolbarRoot, const_cast<char*>(inURL.c_str()), 
  186.                                     const_cast<char*>(inTitle.c_str()) );  
  187.         
  188.     // no need to tell toolbars to refresh because we will get an HT node added event and
  189.     // refresh at that time.
  190.     
  191. } // Addbutton
  192.  
  193.  
  194. //
  195. // RemoveButton
  196. //
  197. // The user has explicitly removed a button from the toolbar in one of the windows (probably
  198. // by dragging it to the trash). Tell all the other toolbars about it, remove it from our
  199. // own bookkeeping list, then let RDF get rid of it.
  200. //
  201. void 
  202. CPersonalToolbarManager :: RemoveButton ( Uint32 inIndex )
  203. {
  204.     CUserButtonInfo* deadBookmark;
  205.     GetButtons().FetchItemAt ( inIndex, &deadBookmark );
  206.     
  207.     // remove it from RDF
  208.     HT_Resource deadNode = HT_GetNthItem ( GetHTView(), URDFUtilities::PPRowToHTRow(inIndex) );
  209.     HT_RemoveChild ( mToolbarRoot, deadNode );
  210.  
  211.     delete deadBookmark;
  212.  
  213.     // no need to tell toolbars to refresh because we will get an HT view update event and
  214.     // refresh at that time.
  215.     
  216. } // RemoveButton
  217.  
  218.  
  219. //
  220. // RemoveToolbarButtons
  221. //
  222. // Clears out our own internal list of toolbar button information.
  223. //
  224. void 
  225. CPersonalToolbarManager :: RemoveToolbarButtons (void)
  226. {
  227.     mUserButtonInfoArray.RemoveItemsAt(mUserButtonInfoArray.GetCount(), LArray::index_First);
  228.  
  229. } // RemoveToolbarButtons
  230.  
  231.  
  232. #pragma mark -- Protected Utility Methods
  233. ///////////////////////////////////////////////////////////////////////////////////
  234. //                        CPersonalToolbarManager Helpers
  235. ///////////////////////////////////////////////////////////////////////////////////
  236.  
  237.  
  238. //
  239. // InitializeButtonInfo
  240. //
  241. // Create our list of information for each bookmark that belongs in the toolbar. This
  242. // involves iterating over the RDF data in the folder pre-selected to be the personal
  243. // toolbar folder, compiling some info about it, and adding to an internal list which
  244. // will be used by each toolbar to build their tables.
  245. //
  246. // ÑÑÑNOTE: this will put folders in the bar if they exist. Strange things may happen if the
  247. // user clicks on them....
  248. //
  249. void 
  250. CPersonalToolbarManager :: InitializeButtonInfo(void)
  251. {
  252.     HT_Cursor cursor = HT_NewCursor( mToolbarRoot );
  253.     if ( cursor ) {
  254.         HT_Resource currNode = HT_GetNextItem(cursor);
  255.         while ( currNode ) {
  256.             CUserButtonInfo *info = new CUserButtonInfo ( HT_GetNodeName(currNode), HT_GetNodeURL(currNode),
  257.                                                             0, 0, HT_IsContainer(currNode));
  258.             mUserButtonInfoArray.InsertItemsAt(1, LArray::index_Last, &info);
  259.             currNode = HT_GetNextItem(cursor);
  260.         } // for each top-level node
  261.     }
  262.     
  263. } // InitializeButtonInfo
  264.  
  265.  
  266. //
  267. // HandleNotification
  268. //
  269. // Called when the user makes a change to the personal toolbar folder from some other
  270. // place (like the bookmarks view). Reset our internal list and tell our listeners
  271. // that things are now different.
  272. //
  273. void
  274. CPersonalToolbarManager  :: HandleNotification(
  275.     HT_Notification    /*notifyStruct*/,
  276.     HT_Resource        node,
  277.     HT_Event        event)
  278. {
  279.     switch (event)
  280.     {
  281.         case HT_EVENT_NODE_ADDED:
  282.         case HT_EVENT_VIEW_REFRESH:
  283.         case HT_EVENT_NODE_VPROP_CHANGED:
  284.         {
  285.             // only update toolbar if the quickfile view changes
  286.             if ( HT_GetView(node) == mToolbarView )                        
  287.                 ToolbarChanged();
  288.             break;
  289.         }        
  290.     }
  291. }
  292.  
  293.  
  294. #pragma mark ÑÑ class CUserButtonInfo
  295.  
  296. ///////////////////////////////////////////////////////////////////////////////////
  297. //                                    Class CUserButtonInfo
  298. ///////////////////////////////////////////////////////////////////////////////////
  299.  
  300. CUserButtonInfo::CUserButtonInfo( const string & pName, const string & pURL, Uint32 nBitmapID,
  301.                                      Uint32 nBitmapIndex, bool bIsFolder)
  302. : mName(pName), mURL(pURL), mBitmapID(nBitmapID), mBitmapIndex(nBitmapIndex), 
  303.         mIsResourceID(true), mIsFolder(bIsFolder)
  304. {
  305. }
  306.  
  307.  
  308. CUserButtonInfo::~CUserButtonInfo()
  309. {
  310.     // string destructor takes care of everything...
  311. }
  312.  
  313.  
  314.  
  315.  
  316.