home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / notebvac.zip / inotebk.cpp
C/C++ Source or Header  |  2002-11-05  |  266KB  |  6,871 lines

  1. // Revision: 18 1.39.1.4 source/ui/basectl/inotebk.cpp, notebook, ioc.v400, 001113 
  2. /*******************************************************************************
  3. * FILE NAME: inotebk.cpp                                                       *
  4. *                                                                              *
  5. * DESCRIPTION:                                                                 *
  6. *   Implementation of the class(es):                                           *
  7. *     IPageHandle                                                              *
  8. *     INotebook                                                                *
  9. *                                                                              *
  10. *   See inotebk0.cpp for the implementation of the platform independent        *
  11. *   nested classes:                                                            *
  12. *     INotebook::Cursor                                                        *
  13. *     INotebook::PageSettings                                                  *
  14. *                                                                              *
  15. * COPYRIGHT:                                                                   *
  16. *   IBM Open Class Library                                                     *
  17. *   (C) Copyright International Business Machines Corporation 1992, 1997       *
  18. *   Licensed Material - Program-Property of IBM - All Rights Reserved.         *
  19. *   US Government Users Restricted Rights - Use, duplication, or disclosure    *
  20. *   restricted by GSA ADP Schedule Contract with IBM Corp.                     *
  21. *                                                                              *
  22. *******************************************************************************/
  23. #pragma priority( -2147481524 )
  24.  
  25. extern "C" {
  26.   #define INCL_DOSMODULEMGR
  27.   #define INCL_WINSYS
  28.   #define INCL_WINENTRYFIELDS
  29.   #define INCL_WINCLIPBOARD
  30.   #define INCL_WININPUT             // WM_CHAR, etc.
  31.   #define INCL_WINMESSAGEMGR        // for WNDPARAM struct
  32.   #define INCL_NLS                  // ES_ANY, ES_SBCS, ES_DBCS, ES_MIXED
  33.   #define INCL_WINSTDDRAG
  34.   #define INCL_WINWINDOWMGR         // WinQueryWindowULong
  35.   #define INCL_WINSTDBOOK
  36.   #define INCL_WINDIALOGS           // Needed for PDLGTEMPLATE in BOOKPAGEINFO
  37.   #define INCL_GPI
  38.   #include <iwindefs.h>
  39. }
  40.  
  41. #ifdef IC_MOTIF
  42. #include <notebk.h>
  43. #include <Xm/Label.h>
  44. #include <Xm/PushB.h>
  45. #endif
  46.  
  47. #ifdef IC_WIN
  48.   #ifndef _ICLNOTEBOOKW_
  49.     #include <iclnbw.h>
  50.   #endif
  51.   #include <icctlsta.hpp>         // Statics to load dll.
  52.   #include <ibmpctl.hpp>
  53. #endif
  54.   #include <inotebk.hpp>
  55.   #include <inotebk0.hpp>
  56.   #include <icconst.h>
  57.   #include <icolor.hpp>
  58.   #include <iexcept.hpp>
  59.   #include <iframe.hpp>
  60.   #include <imphdr.hpp>
  61.   #include <inotifev.hpp>
  62.   #include <irect.hpp>
  63.   #include <ireslib.hpp>
  64.   #include <istring.hpp>
  65.   #include <itrace.hpp>
  66.  
  67. #ifdef IC_PMWIN
  68.   #include <inotehdr.hpp>
  69.   #include <isizehdr.hpp>
  70.   #include <iwcname.hpp>
  71.   #include <ibmpstat.hpp>
  72. #endif // IC_PMWIN
  73.  
  74. #ifdef IC_WIN
  75.     #include <ifont.hpp>
  76.     #include <ipagehdr.hpp>
  77.     #include <ipainhdr.hpp>
  78.     #include <ipainevt.hpp>
  79.     #include <ikeyevt.hpp>
  80.     #include <igimage.hpp>
  81. #endif //IC_WIN
  82.  
  83. #ifdef IC_MOTIF
  84.   #include <ifont.hpp>
  85.   #include <imstring.hpp>
  86.   #include <iwinpriv.hpp>
  87.   #include <ixmlabel.hpp>
  88. #endif // IC_MOTIF
  89.  
  90. #ifdef IC_MOTIFWIN
  91. #pragma info(none)
  92.   #include <ies2.h>
  93. #pragma info(restore)
  94. #endif // IC_MOTIFWIN
  95.  
  96. // Segment definitions.
  97. #ifdef IC_PAGETUNE
  98.   #define _INOTEBK_CPP_
  99.   #include <ipagetun.h>
  100. #endif
  101.  
  102. #ifdef IC_WIN
  103. extern unsigned long propagationInProgress;
  104. #endif
  105.  
  106. /*------------------------------------------------------------------------------
  107. | Public notebook styles.                                                      |
  108. ------------------------------------------------------------------------------*/
  109. const INotebook::Style
  110.   INotebook::backPagesBottomRight = BKS_BACKPAGESBR,            // 0x00000001
  111.   INotebook::backPagesBottomLeft  = BKS_BACKPAGESBL,            // 0x00000002
  112.   INotebook::backPagesTopRight    = BKS_BACKPAGESTR,            // 0x00000004
  113.   INotebook::backPagesTopLeft     = BKS_BACKPAGESTL,            // 0x00000008
  114.   INotebook::majorTabsRight       = BKS_MAJORTABRIGHT,          // 0x00000010
  115.   INotebook::majorTabsLeft        = BKS_MAJORTABLEFT,           // 0x00000020
  116.   INotebook::majorTabsTop         = BKS_MAJORTABTOP,            // 0x00000040
  117.   INotebook::majorTabsBottom      = BKS_MAJORTABBOTTOM,         // 0x00000080
  118.   INotebook::squareTabs           ( 0, IBKS_SQUARETABS ),       // 0x00000001 *
  119.   INotebook::roundedTabs          = BKS_ROUNDEDTABS,            // 0x00000100
  120.   INotebook::polygonTabs          = BKS_POLYGONTABS,            // 0x00000200
  121.   INotebook::solidBinding         ( 0, IBKS_SOLIDBIND ),        // 0x00000002 *
  122.   INotebook::spiralBinding        = BKS_SPIRALBIND,             // 0x00000400
  123.   INotebook::statusTextLeft       ( 0, IBKS_STATUSTEXTLEFT ),   // 0x00000004 *
  124.   INotebook::statusTextRight      = BKS_STATUSTEXTRIGHT,        // 0x00001000
  125.   INotebook::statusTextCenter     = BKS_STATUSTEXTCENTER,       // 0x00002000
  126.   INotebook::tabTextLeft          ( 0, IBKS_TABTEXTLEFT ),      // 0x00000008 *
  127.   INotebook::pmCompatible        ( 0, IBKS_PMCOMPATIBLE),       // 0x00000010 *
  128.   INotebook::allTabsVisible      ( 0, IBKS_ALLTABSVISIBLE),     // 0x00000020 *
  129.   INotebook::handleDrawTabs      ( 0, IBKS_HANDLEDRAWTABS),     // 0x00000040 *
  130.   INotebook::tabTextRight         = BKS_TABTEXTRIGHT,           // 0x00004000
  131.   INotebook::tabTextCenter        = BKS_TABTEXTCENTER,          // 0x00008000
  132.   INotebook::classDefaultStyle  ( BKS_BACKPAGESBR |
  133.                                   BKS_MAJORTABRIGHT |
  134.                                   BKS_TABTEXTCENTER |
  135.                                   WS_VISIBLE ,
  136.                                   IBKS_SQUARETABS |
  137.                                   IBKS_SOLIDBIND |
  138.                                   IBKS_STATUSTEXTLEFT );
  139.                                // 0x00000001 backPagesBottomRight
  140.                                // 0x00000010 majorTabsRight
  141.                                // 0x00008000 tabTextCenter
  142.                                // 0x80000000 visible
  143.                                              // 0x00000001 squareTabs
  144.                                              // 0x00000002 solidBinding
  145.                                              // 0x00000004 statusTextLeft
  146.  
  147. const INotebook::PageSettings::Attribute
  148.   INotebook::PageSettings::noAttribute  = 0,                    // 0x00000000
  149.   INotebook::PageSettings::statusTextOn = BKA_STATUSTEXTON,     // 0x00000001
  150.   INotebook::PageSettings::majorTab     = BKA_MAJOR,            // 0x00000040
  151.   INotebook::PageSettings::minorTab     = BKA_MINOR,            // 0x00000080
  152.   INotebook::PageSettings::autoPageSize = BKA_AUTOPAGESIZE;     // 0x00000100
  153.  
  154. const INotebook::clrFlags
  155.   INotebook::bgnPageColor  = IBKA_BACKGROUNDPAGECOLOR,          // 0x00000001 *
  156.   INotebook::bgnMajorColor = IBKA_BACKGROUNDMAJORCOLOR,         // 0x00000002 *
  157.   INotebook::bgnMinorColor = IBKA_BACKGROUNDMINORCOLOR,         // 0x00000004 *
  158.   INotebook::fgnMajorColor = IBKA_FOREGROUNDMAJORCOLOR,         // 0x00000008 *
  159.   INotebook::fgnMinorColor = IBKA_FOREGROUNDMINORCOLOR;         // 0x00000010 *
  160.  
  161. /*------------------------------------------------------------------------------
  162. | Default style for new notebook objects (initial value).                      |
  163. ------------------------------------------------------------------------------*/
  164.   INotebook::Style
  165.        INotebook::currentDefaultStyle ( BKS_BACKPAGESBR |
  166.                                         BKS_MAJORTABRIGHT |
  167.                                         BKS_TABTEXTCENTER |
  168.                                         WS_VISIBLE ,
  169.                                         IBKS_SQUARETABS |
  170.                                         IBKS_SOLIDBIND |
  171.                                         IBKS_STATUSTEXTLEFT );
  172. #ifdef IC_WIN
  173.   bool  INotebook::hasBeenRegistered = false;
  174. #endif
  175.  
  176. #ifdef IC_WIN
  177.   #define UPAGE   (unsigned long)(void*)page
  178. #endif // IC_WIN
  179. #ifdef IC_PM
  180.   #define UPAGE   (unsigned long)page
  181. #endif // IC_PM
  182.  
  183. #ifdef IC_WIN
  184.   #define WC_PAGECLIP "IOC Page Clipping Window"
  185.   #define ID_PAGECLIP 8000
  186. #endif // IC_WIN
  187.  
  188. #ifdef IC_MOTIF
  189. // In INotebookData we maintain two arrays that for each colorArea
  190. // define the following info respectively:
  191. //   colorSet - whether this color has been set by the user
  192. //   curColor - what this color has been set to
  193. // We use PrivateColorArea enum as the index to these arrays.
  194.  
  195. enum PrivateColorArea {
  196.   pcaPageBackground,
  197.   pcaMajorTabBackground,
  198.   pcaMajorTabForeground,
  199.   pcaMinorTabBackground,
  200.   pcaMinorTabForeground
  201. };
  202. static const int numColorAreas = pcaMinorTabForeground + 1;
  203.  
  204. #pragma enum(4)
  205. #pragma pack(push,4)
  206.  
  207. // Note:  In order to keep this struct declaration out of the public
  208. //        interface and to avoid creating a new file for just this
  209. //        struct, this declaration appears here and in ipageevt.cpp.
  210. //        Any changes made here MUST be made in that file as well.
  211. struct PageData
  212. {
  213.   unsigned long userData;
  214.   unsigned long pageHandle;
  215.   bool          isAutoSize;
  216. };
  217. #pragma pack(pop)
  218. #pragma enum(pop)
  219. #endif // IC_MOTIF
  220.  
  221. /*------------------------------------------------------------------------------
  222. | ITabBitmapMgr                                                                |
  223. |                                                                              |
  224. | This class is used to manage the tab bitmaps for a notebook's pages.         |
  225. ------------------------------------------------------------------------------*/
  226. #pragma enum(4)
  227. #pragma pack(push,4)
  228.  
  229. class ITabBitmapMgr {
  230. public:
  231.   ITabBitmapMgr ( const IBitmapHandle& tabBitmap,
  232.                   const IPageHandle&   pgHandle );
  233. void
  234.   setNext ( ITabBitmapMgr* );
  235. ITabBitmapMgr
  236.  *next    ( );
  237. private:
  238. IBitmapHandle
  239.   bitmapHandle;
  240. IPageHandle
  241.   pageHandle;
  242. ITabBitmapMgr
  243.  *nextInList;
  244. };
  245.  
  246. #pragma pack(pop)
  247. #pragma enum(pop)
  248.  
  249. /*------------------------------------------------------------------------------
  250. | ITabBitmapMgr::ITabBitmapMgr                                                 |
  251. ------------------------------------------------------------------------------*/
  252. ITabBitmapMgr :: ITabBitmapMgr ( const IBitmapHandle& tabBitmap,
  253.                                  const IPageHandle&   pgHandle )
  254. {
  255.   bitmapHandle = tabBitmap;
  256.   pageHandle = pgHandle;
  257.   nextInList = 0;
  258. }
  259.  
  260. /*------------------------------------------------------------------------------
  261. | ITabBitmapMgr::setNext                                                       |
  262. ------------------------------------------------------------------------------*/
  263. void ITabBitmapMgr :: setNext ( ITabBitmapMgr* nextOne )
  264. {
  265.   nextInList = nextOne;
  266. }
  267.  
  268. /*------------------------------------------------------------------------------
  269. | ITabBitmapMgr::next                                                          |
  270. ------------------------------------------------------------------------------*/
  271. ITabBitmapMgr* ITabBitmapMgr :: next ( )
  272. {
  273.   return nextInList;
  274. }
  275.  
  276.  
  277. #ifdef IC_WIN
  278. /*------------------------------------------------------------------------------
  279. | IPageClipPaintHandler                                                        |
  280. |                                                                              |
  281. | Handle paint requests for the page clipping window.                          |
  282. ------------------------------------------------------------------------------*/
  283. #pragma enum(4)
  284. #pragma pack(push,4)
  285.  
  286. class IPageClipPaintHandler : public IPaintHandler
  287. {
  288. typedef IPaintHandler
  289.   Inherited;
  290. public:
  291.   IPageClipPaintHandler  ( );
  292. virtual
  293.   ~IPageClipPaintHandler ( );
  294.  
  295. protected:
  296. virtual bool
  297.   paintWindow          ( IPaintEvent& event );
  298. };
  299.  
  300. #pragma pack(pop)
  301. #pragma enum(pop)
  302.  
  303. /*------------------------------------------------------------------------------
  304. | IPageClipPaintHandler::IPageClipPaintHandler                                 |
  305. | Constructor                                                                  |
  306. ------------------------------------------------------------------------------*/
  307. IPageClipPaintHandler :: IPageClipPaintHandler( )
  308. {}
  309.  
  310. /*------------------------------------------------------------------------------
  311. | IPageClipPaintHandler::~IPageClipPaintHandler                                |
  312. | Destructor                                                                   |
  313. ------------------------------------------------------------------------------*/
  314. IPageClipPaintHandler :: ~IPageClipPaintHandler( )
  315. {}
  316.  
  317. /*------------------------------------------------------------------------------
  318. | IPageClipPaintHandler::paintWindow                                           |
  319. |                                                                              |
  320. ------------------------------------------------------------------------------*/
  321. bool IPageClipPaintHandler :: paintWindow ( IPaintEvent& event )
  322. {
  323.   IMODTRACE_DEVELOP( "IPageClipPaintHandler::paintWindow" );
  324.  
  325.   INotebook*
  326.     pNotebook = (INotebook *)event.window()->parent();
  327.  
  328.   if (pNotebook)
  329.   {
  330.     IPresSpaceHandle hps = event.presSpaceHandle();
  331.     event.clearBackground( pNotebook->pageBackgroundColor() );
  332.     return( true );
  333.   }
  334.  
  335.   return( false );
  336. }
  337.  
  338. /*------------------------------------------------------------------------------
  339. | IPageClipEraseHandler                                                        |
  340. |                                                                              |
  341. | Handle background erase requests for the page clipping window.               |
  342. ------------------------------------------------------------------------------*/
  343. #pragma enum(4)
  344. #pragma pack(push,4)
  345.  
  346. class IPageClipEraseHandler : public IHandler
  347. {
  348. typedef IHandler
  349.   Inherited;
  350. public:
  351.   IPageClipEraseHandler  ( );
  352. virtual
  353.   ~IPageClipEraseHandler ( );
  354.  
  355. protected:
  356. virtual bool
  357.   dispatchHandlerEvent ( IEvent& event );
  358. };
  359.  
  360. #pragma pack(pop)
  361. #pragma enum(pop)
  362.  
  363. /*------------------------------------------------------------------------------
  364. | IPageClipEraseHandler::IPageClipEraseHandler                                 |
  365. | Constructor                                                                  |
  366. ------------------------------------------------------------------------------*/
  367. IPageClipEraseHandler :: IPageClipEraseHandler( )
  368. {}
  369.  
  370. /*------------------------------------------------------------------------------
  371. | IPageClipEraseHandler::~IPageClipEraseHandler                                |
  372. | Destructor                                                                   |
  373. ------------------------------------------------------------------------------*/
  374. IPageClipEraseHandler :: ~IPageClipEraseHandler( )
  375. {}
  376.  
  377. /*------------------------------------------------------------------------------
  378. | IPageClipEraseHandler::dispatchHandlerEvent                                  |
  379. |                                                                              |
  380. ------------------------------------------------------------------------------*/
  381. bool IPageClipEraseHandler :: dispatchHandlerEvent( IEvent& event )
  382. {
  383.   /****************************************************************************/
  384.   /* Only processes WM_ERASEBKGND to prevent default processing               */
  385.   /****************************************************************************/
  386.   switch( event.eventId() )
  387.   {
  388.     case WM_ERASEBKGND:
  389.       event.setResult( true );
  390.       return( true );
  391.  
  392.     default:
  393.       break;
  394.   }
  395.  
  396.   return( false );
  397. }
  398.  
  399. /*------------------------------------------------------------------------------
  400. | IPageClipWindow                                                              |
  401. |                                                                              |
  402. | Page clipping window class for the Windows tab control implementation.       |
  403. | Clips the application page window to the allowable display area within the   |
  404. | tab control to prevent it from painting over areas of the control.           |
  405. ------------------------------------------------------------------------------*/
  406. #pragma enum(4)
  407. #pragma pack(push,4)
  408.  
  409. class IPageClipWindow : public IWindow
  410. {
  411. public:
  412.   IPageClipWindow  ( INotebook*             parentNbk );
  413. virtual
  414.   ~IPageClipWindow ( );
  415.  
  416. private:
  417.   IPageClipWindow  ( const IPageClipWindow& pageClipWindow );
  418. IPageClipWindow
  419.  &operator =       ( const IPageClipWindow& pageClipWindow );
  420.  
  421. IPageClipPaintHandler
  422.   fPaintHandler;
  423. IPageClipEraseHandler
  424.   fEraseHandler;
  425. };
  426.  
  427. #pragma pack(pop)
  428. #pragma enum(pop)
  429.  
  430.  
  431. /*------------------------------------------------------------------------------
  432. | IPageClipWindow::IPageClipWindow                                             |
  433. | Constructor                                                                  |
  434. ------------------------------------------------------------------------------*/
  435. IPageClipWindow :: IPageClipWindow( INotebook* parentNbk )
  436.   : fPaintHandler(),
  437.     fEraseHandler()
  438. {
  439.   if ( !parentNbk->hasBeenRegistered )
  440.   {
  441.     WNDCLASS wndClass;
  442.     wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
  443.     wndClass.lpfnWndProc = DefWindowProc;
  444.     wndClass.cbClsExtra = 0;
  445.     wndClass.cbWndExtra = 0;
  446.     wndClass.hInstance = GetModuleHandle( 0 );
  447.     wndClass.hIcon = 0;
  448.     wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
  449.     wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
  450.     wndClass.lpszMenuName = 0;
  451.     wndClass.lpszClassName = WC_PAGECLIP;
  452.  
  453.     if ( RegisterClass( &wndClass ) )
  454.     {
  455.       parentNbk->hasBeenRegistered = true;
  456.     }
  457.     else
  458.     {
  459.       ITHROWGUIERROR("RegisterClass");
  460.     }
  461.   }
  462.  
  463.   if ( parentNbk->hasBeenRegistered )
  464.   {
  465.     IWindowHandle
  466.       handlePage = create( ID_PAGECLIP,
  467.                            0,
  468.                            WS_CHILD | WS_CLIPCHILDREN,
  469.                            WC_PAGECLIP,
  470.                            parentNbk->handle(),
  471.                            IWindowHandle(0),
  472.                            IRectangle(),
  473.                            0,
  474.                            0 );
  475.  
  476.     if ( handlePage.isValid() )
  477.     {
  478.       setAutoDestroyWindow( true );
  479.       startHandlingEventsFor( handlePage );
  480.       fPaintHandler.handleEventsFor( this );
  481.       fEraseHandler.handleEventsFor( this );
  482.     }
  483.     else
  484.     {
  485.       ITHROWGUIERROR("CreateWindow");
  486.     }
  487.   }
  488. }
  489.  
  490. /*------------------------------------------------------------------------------
  491. | IPageClipWindow::IPageClipWindow                                             |
  492. | Copy constructor                                                             |
  493. ------------------------------------------------------------------------------*/
  494. IPageClipWindow :: IPageClipWindow( const IPageClipWindow& pageClipWindow )
  495. {
  496. }
  497.  
  498. /*------------------------------------------------------------------------------
  499. | IPageClipWindow::operator =                                                  |
  500. | Assignment                                                                   |
  501. ------------------------------------------------------------------------------*/
  502. IPageClipWindow& IPageClipWindow ::
  503.                       operator = ( const IPageClipWindow& pageClipWindow )
  504. {
  505.   return( *this );
  506. }
  507.  
  508. /*------------------------------------------------------------------------------
  509. | IPageClipWindow::~IPageClipWindow                                            |
  510. | Destructor                                                                   |
  511. ------------------------------------------------------------------------------*/
  512. IPageClipWindow :: ~IPageClipWindow( )
  513. {
  514.   fPaintHandler.stopHandlingEventsFor( this );
  515.   fEraseHandler.stopHandlingEventsFor( this );
  516. }
  517.  
  518.  
  519. /*------------------------------------------------------------------------------
  520. | ITopPageKeyboardHandler                                                      |
  521. |                                                                              |
  522. | Process Alt+PageUp, Alt+PageDown, and Alt+UpArrow keys for the application   |
  523. | page window that is on top.  This handler is only attached to the            |
  524. | application page window that is on top.  When a new page becomes the top     |
  525. | page this handler is removed from the current page and attached to the new   |
  526. | top page.                                                                    |
  527. ------------------------------------------------------------------------------*/
  528. #pragma enum(4)
  529. #pragma pack(push,4)
  530.  
  531. class ITopPageKeyboardHandler : public IHandler
  532. {
  533. typedef IHandler
  534.   Inherited;
  535. public:
  536.   ITopPageKeyboardHandler  ( );
  537. virtual
  538.   ~ITopPageKeyboardHandler ( );
  539.  
  540. protected:
  541. bool
  542.   dispatchHandlerEvent ( IEvent& event );
  543. };
  544.  
  545. #pragma pack(pop)
  546. #pragma enum(pop)
  547.  
  548.  
  549. /*------------------------------------------------------------------------------
  550. | ITopPageKeyboardHandler::ITopPageKeyboardHandler                             |
  551. | Constructor                                                                  |
  552. ------------------------------------------------------------------------------*/
  553. ITopPageKeyboardHandler :: ITopPageKeyboardHandler( )
  554. {}
  555.  
  556. /*------------------------------------------------------------------------------
  557. | ITopPageKeyboardHandler::~ITopPageKeyboardHandler                            |
  558. | Destructor                                                                   |
  559. ------------------------------------------------------------------------------*/
  560. ITopPageKeyboardHandler :: ~ITopPageKeyboardHandler( )
  561. {}
  562.  
  563. /*------------------------------------------------------------------------------
  564. | ITopPageKeyboardHandler::dispatchHandlerEvent                                |
  565. |                                                                              |
  566. ------------------------------------------------------------------------------*/
  567. bool ITopPageKeyboardHandler :: dispatchHandlerEvent( IEvent& event )
  568. {
  569.   bool stopProcessingEvent = false;
  570.  
  571.   /****************************************************************************/
  572.   /* Only processes WM_SYSKEYDOWN to simulate CUA '91 notebook behavior.      */
  573.   /****************************************************************************/
  574.   switch( event.eventId() )
  575.   {
  576.     case WM_SYSKEYDOWN:
  577.       {
  578.         /**********************************************************************/
  579.         /* Get a pointer to the notebook object.  The parent of the top       */
  580.         /* application page window is always the page clipping window, and    */
  581.         /* the parent of the page clipping window is always the notebook.     */
  582.         /**********************************************************************/
  583.         IWindowHandle
  584.           hwndControl( event.window()->parent()->parent()->handle() );
  585.         if ( !hwndControl )
  586.           break;
  587.  
  588.         /**********************************************************************/
  589.         /* Only process Windows tab control keyboard events of interest.      */
  590.         /**********************************************************************/
  591.         if ( IWindowClassName( hwndControl ) != WC_TABCONTROL )
  592.           break;
  593.  
  594.         /**********************************************************************/
  595.         /* Process key events for the Windows tab control.                    */
  596.         /**********************************************************************/
  597.         IKeyboardEvent keyevt( event );
  598.         if ( !keyevt.isVirtual() || !keyevt.isAltDown() ||
  599.              keyevt.isShiftDown() || keyevt.isCtrlDown() )
  600.         {
  601.           break;
  602.         }
  603.  
  604.         /**********************************************************************/
  605.         /* Obtain pointer to notebook object.                                 */
  606.         /**********************************************************************/
  607.         INotebook*
  608.           pNotebk = (INotebook*)IWindow::windowWithHandle( hwndControl );
  609.  
  610.         /**********************************************************************/
  611.         /* If Alt+PageUp or Alt+PageDown was pressed, send to the notebook    */
  612.         /* for processing.                                                    */
  613.         /**********************************************************************/
  614.         if ( (keyevt.virtualKey() == IKeyboardEvent::pageUp)  ||
  615.              (keyevt.virtualKey() == IKeyboardEvent::pageDown) )
  616.         {
  617.           HWND hwndOldFocus = IQUERYFOCUS(HWND_DESKTOP);
  618.  
  619.           pNotebk->sendEvent( event );
  620.  
  621.           /********************************************************************/
  622.           /* If the focus hasn't changed after the page-turn, the application */
  623.           /* left it on the old page, so put it on the tab control            */
  624.           /********************************************************************/
  625.           if ( IQUERYFOCUS(HWND_DESKTOP) == hwndOldFocus )
  626.             pNotebk->setFocus();
  627.  
  628.           stopProcessingEvent = true;
  629.         }
  630.         /**********************************************************************/
  631.         /* Alt+Up:  set the focus to the tab control                          */
  632.         /**********************************************************************/
  633.         else if ( keyevt.virtualKey() == IKeyboardEvent::up )
  634.         {
  635.           pNotebk->setFocus();
  636.           stopProcessingEvent = true;
  637.         }
  638.       } //WM_SYSKEYDOWN
  639.       break;
  640.  
  641.     default:
  642.       break;
  643.   }
  644.  
  645.   return( stopProcessingEvent );
  646. }
  647.  
  648. #endif // IC_WIN
  649.  
  650.  
  651. #ifdef IC_PM
  652. /*------------------------------------------------------------------------------
  653. | IPageResizeHandler                                                           |
  654. |                                                                              |
  655. | This handler is used to workaround a PM problem. The problem manifests       |
  656. | itself when a page window is resized subsequent to its being set as a page   |
  657. | window in the notebook.  When this occurs, the notebook doesn't correctly    |
  658. | manage the geometry for the resized page unless it is the page window for    |
  659. | the current top page.  The fix for this is to add a resize handler to the    |
  660. | page windows as they are set in the notebook.  The resize handler will reset |
  661. | the page window for the corresponding page if and when the page window is    |
  662. | resized.  This resetting of the page window causes the PM notebook to        |
  663. | correctly cache the new page size and manage the page window geometry before |
  664. | it becomes the top page.                                                     |
  665. ------------------------------------------------------------------------------*/
  666. #pragma enum(4)
  667. #pragma pack(push,4)
  668.  
  669. class IPageResizeHandler : public IResizeHandler
  670. {
  671. public:
  672.   IPageResizeHandler ( ) { };
  673. virtual
  674.   ~IPageResizeHandler ( ) { };
  675.  
  676. protected:
  677. bool
  678.   windowResize ( IResizeEvent& event );
  679. };
  680.  
  681. #pragma pack(pop)
  682. #pragma enum(pop)
  683.  
  684. /*------------------------------------------------------------------------------
  685. | IPageResizeHandler :: windowResize                                           |
  686. ------------------------------------------------------------------------------*/
  687. bool IPageResizeHandler :: windowResize( IResizeEvent& event )
  688. {
  689.    // Get the notebook for this page window.
  690.    IWindow   *pageWindow = event.controlWindow();
  691.    INotebook *notebook = 0;
  692.    if (pageWindow)
  693.       notebook = dynamic_cast<INotebook*>(pageWindow->parent());
  694.    if (notebook)
  695.    {
  696.       // If the top page window is being resized, just return.
  697.       if (pageWindow == notebook->window( notebook->topPage()))
  698.          return false;
  699.  
  700.       // Reset the page window for the first page found that has this window as
  701.       // its page window.
  702.       INotebook::Cursor cursor( *notebook );
  703.       bool pageFound = false;
  704.       for (cursor.setToFirst();
  705.            cursor.isValid() && !pageFound;
  706.            cursor.setToNext())
  707.       {
  708.          IPageHandle pageHandle = cursor.current();
  709.          if (notebook->window( pageHandle ) == pageWindow)
  710.          {
  711.             notebook->sendEvent( BKM_SETPAGEWINDOWHWND,
  712.                                  (unsigned long)pageHandle,
  713.                                  (unsigned long)pageWindow->handle() );
  714.             pageFound = true;
  715.          }
  716.       }
  717.    }
  718.    return false;
  719. }
  720. #endif // IC_PM
  721.  
  722. #ifdef IC_MOTIFWIN
  723. /*------------------------------------------------------------------------------
  724. | INotebookPageSequence                                                        |
  725. ------------------------------------------------------------------------------*/
  726. #pragma enum(4)
  727. #pragma pack(push,4)
  728.  
  729. class INotebookPageSequence : public IEqualitySequence< IPageHandle > {
  730. public:
  731.   INotebookPageSequence ( );
  732.  ~INotebookPageSequence ( );
  733. };
  734.  
  735. #pragma pack(pop)
  736. #pragma enum(pop)
  737.  
  738. /*------------------------------------------------------------------------------
  739. | INotebookPageSequence::INotebookPageSequence                                 |
  740. | Constructor                                                                  |
  741. ------------------------------------------------------------------------------*/
  742. INotebookPageSequence :: INotebookPageSequence( )
  743.   : IEqualitySequence< IPageHandle >( 20 )
  744. {
  745. }
  746.  
  747. /*------------------------------------------------------------------------------
  748. | INotebookPageSequence::~INotebookPageSequence                                |
  749. | Destructor                                                                   |
  750. ------------------------------------------------------------------------------*/
  751. INotebookPageSequence :: ~INotebookPageSequence( )
  752. {
  753. }
  754. #endif // IC_MOTIFWIN
  755.  
  756. /*------------------------------------------------------------------------------
  757. | INotebookData class definition                                               |
  758. ------------------------------------------------------------------------------*/
  759. #pragma enum(4)
  760. #pragma pack(push,4)
  761.  
  762. class INotebookData
  763. {
  764. public:
  765.   INotebookData  ( );
  766.  
  767.   ~INotebookData ( );
  768.  
  769. #ifdef IC_PMWIN
  770.   INotebookHandler
  771.     fdefaultHandler;
  772.   IMousePointerHandler
  773.     fMousePointerHandler;
  774. #endif
  775. #ifdef IC_PM
  776. IPageResizeHandler
  777.    fPageResizeHandler;
  778. #endif // IC_PM
  779. #ifdef IC_WIN
  780. IPageClipWindow
  781.  *pPageClipWindow;
  782.  
  783. HIMAGELIST
  784.   hWndImageList;        // Image list window handle
  785.  
  786. long
  787.   lMajorTabHeight;
  788.  
  789. ITopPageKeyboardHandler
  790.   fTopPageKeyboardHandler;
  791. #endif
  792.  
  793. #ifdef IC_MOTIF
  794.   void registerCallbacks();
  795.   void unregisterCallbacks();
  796.   IColor getColor(PrivateColorArea);
  797.   void setColor(PrivateColorArea, Pixel value);
  798.   void refreshTabs();
  799.   void refreshStatus();
  800.   void adjustPages(int firstPage, int lastPage,
  801.                    int adjustment);
  802.   int  pagesToTab(int startPage, bool gotMajor);
  803.   void deletePages(int startPage,
  804.                    int endPage,
  805.                    bool removeGaps = true);
  806.   int pageNumber( IPageHandle page );
  807.   IPageHandle pageHandle( int pageNumber );
  808.  
  809.   // Data members
  810.   Widget notebook;   // the notebook widget itself
  811.   unsigned char statusAlignment;
  812.   unsigned char tabAlignment;
  813.  
  814.   // Arrays mentioned above for tracking what ColorAreas have been set and
  815.   // what they have been set to.
  816.   bool colorSet[numColorAreas];
  817.   Pixel curColor[numColorAreas];
  818.  
  819.   // Sizes of major and minor tabs
  820.   ISize majorTabSize;
  821.   ISize minorTabSize;
  822.  
  823.   // Sequence of page handles and member to maintain next available page
  824.   // handle.
  825.   INotebookPageSequence
  826.     *fPageSequence;
  827.   unsigned long
  828.     fNextPageHandle;
  829.  
  830.   IString
  831.     xlfdString;
  832. #endif // IC_MOTIF
  833.  
  834. };
  835.  
  836. #pragma pack(pop)
  837. #pragma enum(pop)
  838.  
  839. /*------------------------------------------------------------------------------
  840. | INotebookData::INotebookData                                                 |
  841. |                                                                              |
  842. | This class contains the private data and functions necessary for the         |
  843. | implementation of the INotebook class.                                       |
  844. ------------------------------------------------------------------------------*/
  845. INotebookData::INotebookData()
  846. #ifdef IC_PMWIN
  847.   : fdefaultHandler()
  848.   , fMousePointerHandler()
  849. #endif
  850. #ifdef IC_PM
  851.   , fPageResizeHandler()
  852. #endif // IC_PM
  853. #ifdef IC_WIN
  854.   , pPageClipWindow (0)
  855.   , hWndImageList (0)
  856.   , lMajorTabHeight (0)
  857.   , fTopPageKeyboardHandler()
  858. #endif // IC_WIN
  859. #ifdef IC_MOTIF
  860.   : notebook(0)
  861.   , colorSet()
  862.   , curColor()
  863.   , majorTabSize()
  864.   , minorTabSize()
  865.   , statusAlignment(XmALIGNMENT_BEGINNING)
  866.   , tabAlignment(XmALIGNMENT_CENTER)
  867.   , fPageSequence( 0 )
  868.   , fNextPageHandle( 1 )
  869.   , xlfdString( "" )
  870. #endif // IC_MOTIF
  871. {
  872. #ifdef IC_MOTIF
  873.   int i;
  874.   // Indicate that no colorAreas have been set yet
  875.   for(i=0;i<numColorAreas;i++)
  876.     colorSet[i] = false;
  877. #endif
  878. }
  879.  
  880.  
  881. /*------------------------------------------------------------------------------
  882. | INotebookData::~INotebookData                                                |
  883. |                                                                              |
  884. | Destructor here for page tuning.                                             |
  885. ------------------------------------------------------------------------------*/
  886. INotebookData::~INotebookData()
  887. {
  888. #ifdef IC_WIN
  889.   // Destroy the page clipping window if it exists
  890.   if ( this->pPageClipWindow )
  891.     delete this->pPageClipWindow;
  892.  
  893.   // Destroy the image list if it exists
  894.   if ( this->hWndImageList )
  895.   {
  896.     if ( !ImageList_Destroy( this->hWndImageList ) )
  897.       ITHROWGUIERROR("ImageList_Destroy");
  898.   }
  899. #endif // IC_WIN
  900.  
  901. #ifdef IC_MOTIF
  902.   // Delete the sequence of page handles.
  903.   delete fPageSequence;
  904. #endif // IC_MOTIF
  905. }
  906.  
  907. #ifdef IC_MOTIF
  908. /*------------------------------------------------------------------------------
  909. | INotebookData :: getColor()                                                  |
  910. ------------------------------------------------------------------------------*/
  911. IColor INotebookData :: getColor(PrivateColorArea colorArea)
  912. {
  913.   if (colorSet[colorArea])
  914.     return IColor(curColor[colorArea]);
  915.  
  916.   // Color has never been set, have to retrieve pixel values from widgets
  917.  
  918.   // Cruise notebook pages till we find a page with what we're looking for
  919.   int firstPage, lastPage;
  920.   XtVaGetValues(notebook,
  921.                 XmNfirstPageNumber, &firstPage,
  922.                 XmNlastPageNumber, &lastPage,
  923.                 NULL);
  924.  
  925.   XmNotebookPageStatus pageStatus;
  926.   XmNotebookPageInfo   pageInfo;
  927.   bool                 keepLooking = true;
  928.   Pixel                value;
  929.  
  930.   for (int i=firstPage;(i<=lastPage && keepLooking); i++) {
  931.     pageStatus = XmNotebookGetPageInfo(notebook, i, &pageInfo);
  932.     switch (colorArea) {
  933.       case pcaPageBackground:
  934.         if (pageInfo.page_widget != 0) {
  935.           XtVaGetValues(pageInfo.page_widget,
  936.                         XmNbackground, &value,
  937.                         NULL);
  938.           keepLooking = false;
  939.         }
  940.         break;
  941.       case pcaMajorTabBackground:
  942.         if (pageInfo.major_tab_widget != 0) {
  943.           XtVaGetValues(pageInfo.major_tab_widget,
  944.                         XmNbackground, &value,
  945.                         NULL);
  946.           keepLooking = false;
  947.         }
  948.         break;
  949.       case pcaMajorTabForeground:
  950.         if (pageInfo.major_tab_widget != 0) {
  951.           XtVaGetValues(pageInfo.major_tab_widget,
  952.                         XmNforeground, &value,
  953.                         NULL);
  954.           keepLooking = false;
  955.         }
  956.         break;
  957.       case pcaMinorTabBackground:
  958.         if (pageInfo.minor_tab_widget != 0) {
  959.           XtVaGetValues(pageInfo.minor_tab_widget,
  960.                         XmNbackground, &value,
  961.                         NULL);
  962.           keepLooking = false;
  963.         }
  964.         break;
  965.       case pcaMinorTabForeground:
  966.         if (pageInfo.minor_tab_widget != 0) {
  967.           XtVaGetValues(pageInfo.minor_tab_widget,
  968.                         XmNforeground, &value,
  969.                         NULL);
  970.           keepLooking = false;
  971.         }
  972.         break;
  973.       default:
  974.         ITHROWLIBRARYERROR(IC_INVALIDENUMVALUE,IBaseErrorInfo::invalidParameter,
  975.                            IException::recoverable);
  976.         break;
  977.     }   // end switch
  978.   }    //  end for
  979.   if (keepLooking)
  980.     // Looked at all the pages and didn't find a widget that matches
  981.     // what this hoser wants, so return black same as IWindow functions
  982.     return IColor(0,0,0);
  983.   else
  984.     return IColor(value);
  985. }
  986.  
  987. /*------------------------------------------------------------------------------
  988. | INotebookData :: setColor()                                                  |
  989. ------------------------------------------------------------------------------*/
  990. void INotebookData :: setColor(PrivateColorArea colorArea,
  991.                                       Pixel value)
  992. {
  993.   // Record that this color area was set and what it was set to
  994.   // Future calls to addPageAt() will honor this setting
  995.   colorSet[colorArea] = true;
  996.   curColor[colorArea] = value;
  997.  
  998.   // Now set this color area on all existing pages of the notebook
  999.   int firstPage, lastPage;
  1000.   XtVaGetValues(notebook,
  1001.                 XmNfirstPageNumber, &firstPage,
  1002.                 XmNlastPageNumber, &lastPage,
  1003.                 NULL);
  1004.  
  1005.   XmNotebookPageStatus pageStatus;
  1006.   XmNotebookPageInfo   pageInfo;
  1007.   int pcaPageBackgroundSet = 0;
  1008.   int pcaMajorTabBackgroundSet = 0;
  1009.   int pcaMajorTabForegroundSet = 0;
  1010.   int pcaMinorTabBackgroundSet = 0;
  1011.   int pcaMinorTabForegroundSet = 0;
  1012.  
  1013.   for (int i=firstPage;i<=lastPage; i++) {
  1014.     pageStatus = XmNotebookGetPageInfo(notebook, i, &pageInfo);
  1015.     switch (colorArea) {
  1016.       case pcaPageBackground:
  1017.         if (pageInfo.page_widget != 0) {
  1018.           IXmColor::setBackgroundColor( pageInfo.page_widget, value );
  1019.           pcaPageBackgroundSet++;
  1020.         }
  1021.         if (pageInfo.status_area_widget != 0) {
  1022.           IXmColor::setBackgroundColor( pageInfo.status_area_widget, value );
  1023.         }
  1024.         break;
  1025.       case pcaMajorTabBackground:
  1026.         if (pageInfo.major_tab_widget != 0) {
  1027.           if ( colorSet[pcaMajorTabForeground] ) // This is a bit faster.
  1028.             IXmColor::setColor( pageInfo.major_tab_widget,
  1029.                                 true, value, curColor[pcaMajorTabForeground] );
  1030.           else
  1031.             IXmColor::setBackgroundColor( pageInfo.major_tab_widget, value );
  1032.           pcaMajorTabBackgroundSet++;
  1033.         }
  1034.         break;
  1035.       case pcaMajorTabForeground:
  1036.         if (pageInfo.major_tab_widget != 0) {
  1037.           XtVaSetValues(pageInfo.major_tab_widget,
  1038.                         XmNforeground, value,
  1039.                         NULL);
  1040.           pcaMajorTabForegroundSet++;
  1041.         }
  1042.         break;
  1043.       case pcaMinorTabBackground:
  1044.         if (pageInfo.minor_tab_widget != 0) {
  1045.           if ( colorSet[pcaMinorTabForeground] ) // This is a bit faster.
  1046.             IXmColor::setColor( pageInfo.minor_tab_widget,
  1047.                                 true, value, curColor[pcaMinorTabForeground] );
  1048.           else
  1049.             IXmColor::setBackgroundColor( pageInfo.minor_tab_widget, value );
  1050.           pcaMinorTabBackgroundSet++;
  1051.         }
  1052.         break;
  1053.       case pcaMinorTabForeground:
  1054.         if (pageInfo.minor_tab_widget != 0) {
  1055.           XtVaSetValues(pageInfo.minor_tab_widget,
  1056.                         XmNforeground, value,
  1057.                         NULL);
  1058.           pcaMinorTabForegroundSet++;
  1059.         }
  1060.         break;
  1061.       default:
  1062.         ITHROWLIBRARYERROR(IC_INVALIDENUMVALUE,IBaseErrorInfo::invalidParameter,
  1063.                            IException::recoverable);
  1064.         break;
  1065.     }   // end switch
  1066.   }    //  end for
  1067.   IWindow* thisWindow = IWindow::windowWithHandle(notebook);
  1068.   if (thisWindow) {
  1069.     if (pcaPageBackgroundSet > 0)
  1070.       thisWindow->notifyObservers(INotificationEvent(
  1071.         INotebook::pageBackgroundColorId, *thisWindow));
  1072.     if (pcaMajorTabBackgroundSet > 0)
  1073.       thisWindow->notifyObservers(INotificationEvent(
  1074.         INotebook::majorTabBackgroundColorId, *thisWindow));
  1075.     if (pcaMajorTabForegroundSet > 0)
  1076.       thisWindow->notifyObservers(INotificationEvent(
  1077.         INotebook::majorTabForegroundColorId, *thisWindow));
  1078.     if (pcaMinorTabBackgroundSet > 0)
  1079.       thisWindow->notifyObservers(INotificationEvent(
  1080.         INotebook::minorTabBackgroundColorId, *thisWindow));
  1081.     if (pcaMinorTabForegroundSet > 0)
  1082.       thisWindow->notifyObservers(INotificationEvent(
  1083.         INotebook::minorTabForegroundColorId, *thisWindow));
  1084.   }
  1085. }
  1086.  
  1087. /*------------------------------------------------------------------------------
  1088. | INotebookData :: refreshStatus                                               |
  1089. ------------------------------------------------------------------------------*/
  1090. void INotebookData :: refreshStatus()
  1091. {
  1092.   // Change all existing status alignment
  1093.   int firstPage, lastPage;
  1094.   XtVaGetValues(notebook,
  1095.                 XmNfirstPageNumber, &firstPage,
  1096.                 XmNlastPageNumber, &lastPage,
  1097.                 NULL);
  1098.  
  1099.   XmNotebookPageStatus pageStatus;
  1100.   XmNotebookPageInfo   pageInfo;
  1101.  
  1102.   for (int i=firstPage;i<=lastPage; i++) {
  1103.     pageStatus = XmNotebookGetPageInfo(notebook, i, &pageInfo);
  1104.     if (pageInfo.status_area_widget != 0)
  1105.       XtVaSetValues(pageInfo.status_area_widget,
  1106.                     XmNalignment, statusAlignment,
  1107.                     NULL);
  1108.   }    //  end for
  1109. }
  1110.  
  1111. /*------------------------------------------------------------------------------
  1112. | INotebookData :: refreshTabs                                                 |
  1113. ------------------------------------------------------------------------------*/
  1114. void INotebookData :: refreshTabs()
  1115. {
  1116.   // Change all existing tab alignment and size
  1117.   int firstPage, lastPage;
  1118.   XtVaGetValues(notebook,
  1119.                 XmNfirstPageNumber, &firstPage,
  1120.                 XmNlastPageNumber, &lastPage,
  1121.                 NULL);
  1122.  
  1123.   XmNotebookPageStatus pageStatus;
  1124.   XmNotebookPageInfo   pageInfo;
  1125.   Widget               tabWidget;
  1126.   Arg                  args[10];
  1127.   int                  n;
  1128.  
  1129.   for (int i=firstPage;i<=lastPage; i++) {
  1130.     n = 0;
  1131.     pageStatus = XmNotebookGetPageInfo(notebook, i, &pageInfo);
  1132.     if (pageInfo.major_tab_widget != 0) {
  1133.       tabWidget = pageInfo.major_tab_widget;
  1134.       if (majorTabSize != ISize()) {
  1135.         XtSetArg(args[n],XmNresizable, True);
  1136.         n++;
  1137.         XtSetArg(args[n],XmNwidth, majorTabSize.width());
  1138.         n++;
  1139.         XtSetArg(args[n],XmNheight, majorTabSize.height());
  1140.         n++;
  1141.       }
  1142.     }
  1143.     else {
  1144.       tabWidget = pageInfo.minor_tab_widget;
  1145.       if (minorTabSize != ISize()) {
  1146.         XtSetArg(args[n],XmNresizable, True);
  1147.         n++;
  1148.         XtSetArg(args[n],XmNwidth, minorTabSize.width());
  1149.         n++;
  1150.         XtSetArg(args[n],XmNheight, minorTabSize.height());
  1151.         n++;
  1152.       }
  1153.     }
  1154.  
  1155.     if (tabWidget != 0) {
  1156.       XtSetArg(args[n], XmNalignment, tabAlignment);
  1157.       n++;
  1158.       XtSetValues(tabWidget, args, n);
  1159.     }
  1160.   }    //  end for
  1161. }
  1162.  
  1163. /*------------------------------------------------------------------------------
  1164. | INotebookData :: adjustPages                                                 |
  1165. |                                                                              |
  1166. | private  function for making pages contiguous after add or remove            |
  1167. ------------------------------------------------------------------------------*/
  1168. void INotebookData :: adjustPages(int firstPage, int lastPage,
  1169.                                   int adjustment)
  1170. {
  1171.   // The interface to this function is a little tricky, but it is private.
  1172.   // If you had a notebook with pages 1 to 5 and you:
  1173.   //    Add a new page 3:
  1174.   //       firstPage = 3
  1175.   //       lastPage  = 5
  1176.   //       adjustment = +1
  1177.   //    RESULT: pages 3-5 become pages 4-6 and the new page will be pg. 3
  1178.   //
  1179.   //    Delete pages 2-3:
  1180.   //       first page = 4
  1181.   //       last page  = 5
  1182.   //       adjustment = -2
  1183.   //    RESULT: pages 4-5 become pages 2-3
  1184.  
  1185.   // addPageAt call this function BEFORE adding a page.
  1186.   // deletePages calls this function AFTER deleting the page(s)
  1187.  
  1188.   XmNotebookPageInfo pageInfo;
  1189.   XmNotebookPageStatus pageStatus;
  1190.   int startPage, finishPage, increment;
  1191.  
  1192.   if (adjustment > 0) {   // adjust after an add of one page
  1193.     startPage = lastPage;
  1194.     finishPage = firstPage-1;
  1195.     increment = -1;      // adjust working from end to start - avoid duplicates
  1196.     // so last page is valid in loop below
  1197.     XtVaSetValues(notebook, XmNlastPageNumber, lastPage+adjustment, NULL);
  1198.   }
  1199.   else {                 // adjust after removing one or more pages
  1200.     startPage = firstPage;
  1201.     finishPage = lastPage+1;
  1202.     increment = 1;
  1203.   }
  1204.  
  1205.  
  1206.   // loop to change pageNumber for affected pages
  1207.   for (int i = startPage; i != finishPage; i+=increment)
  1208.   {
  1209.     pageStatus = XmNotebookGetPageInfo(notebook, i, &pageInfo);
  1210.     if (pageInfo.page_widget != 0)
  1211.       XtVaSetValues(pageInfo.page_widget, XmNpageNumber, i+adjustment, NULL);
  1212.     if (pageInfo.status_area_widget != 0)
  1213.       XtVaSetValues(pageInfo.status_area_widget, XmNpageNumber, i+adjustment, NULL);
  1214.     if (pageInfo.major_tab_widget != 0)
  1215.       XtVaSetValues(pageInfo.major_tab_widget, XmNpageNumber, i+adjustment, NULL);
  1216.     if (pageInfo.minor_tab_widget != 0)
  1217.       XtVaSetValues(pageInfo.minor_tab_widget, XmNpageNumber, i+adjustment, NULL);
  1218.   }
  1219.  
  1220.   // if we filled in a gap now set new last page number
  1221.   // Couldn't do this before above loop because we would have then
  1222.   // tried to access an invalid page
  1223.   if (adjustment < 0)
  1224.     XtVaSetValues(notebook, XmNlastPageNumber, lastPage+adjustment, NULL);
  1225. }
  1226.  
  1227. /*------------------------------------------------------------------------------
  1228. | INotebookData :: pagesToTab                                                  |
  1229. |                                                                              |
  1230. | private  function called by pagesToMajorTab() and pagesToMinorTab()          |
  1231. ------------------------------------------------------------------------------*/
  1232. int INotebookData :: pagesToTab(int startPage, bool gotMajor)
  1233. {
  1234.   bool keepGoing = true;
  1235.   int origLast, pageCount = 0;
  1236.   XmNotebookPageInfo pageInfo;
  1237.   XmNotebookPageStatus pageStatus;
  1238.   XtVaGetValues(notebook, XmNlastPageNumber, &origLast, NULL);
  1239.  
  1240.   for(int i = startPage+1; i<=origLast && keepGoing; i++) {
  1241.     pageStatus = XmNotebookGetPageInfo(notebook, i, &pageInfo);
  1242.     switch (pageStatus) {
  1243.       case XmPAGE_FOUND:
  1244.       case XmPAGE_EMPTY:    // empty page could have tab or status area
  1245.         pageCount++;
  1246.         if ( (gotMajor && pageInfo.major_tab_widget !=0) ||
  1247.             (!gotMajor && pageInfo.minor_tab_widget != 0) )
  1248.           keepGoing = false;
  1249.         break;
  1250.       case XmPAGE_INVALID:
  1251.         ITHROWGUIERROR("Found invalid page");
  1252.         break;
  1253.       case XmPAGE_DUPLICATED:
  1254.         ITHROWGUIERROR("Duplicate pages found in INotebook");
  1255.         break;
  1256.       default:
  1257.         ITHROWGUIERROR("Unexpected pageStatus from XmNotebookGetPageInfo");
  1258.     }   // end switch
  1259.   }     // end for
  1260.   return pageCount;
  1261. }
  1262.  
  1263. /*------------------------------------------------------------------------------
  1264. | INotebookData :: deletePages                                                 |
  1265. |                                                                              |
  1266. | private function that removes pages                                          |
  1267. ------------------------------------------------------------------------------*/
  1268. void INotebookData :: deletePages(int startPage,
  1269.                                   int endPage,
  1270.                                   bool removeGaps)
  1271. {
  1272.   int origFirst, origLast;
  1273.   XmNotebookPageInfo pageInfo;
  1274.   XmNotebookPageStatus pageStatus;
  1275.   XtVaGetValues(notebook,
  1276.                 XmNfirstPageNumber, &origFirst,
  1277.                 XmNlastPageNumber, &origLast,
  1278.                 NULL);
  1279.  
  1280.   for(int i = startPage; i<=endPage; i++) {
  1281.     pageStatus = XmNotebookGetPageInfo(notebook, i, &pageInfo);
  1282.     switch (pageStatus) {
  1283.       case XmPAGE_FOUND:
  1284.       case XmPAGE_EMPTY:    // empty page could have tab or status area
  1285.         if (pageInfo.page_widget != 0)
  1286.           // setting pageNumber to -1 effectively removes the page because
  1287.           // it can no longer be accessed by the user
  1288.           XtVaSetValues(pageInfo.page_widget,
  1289.                         XmNpageNumber, -1,
  1290.                         NULL);
  1291.         // Destroy tab and status widgets associated with the removed page.
  1292.         // If the page is added back, these will be re created based on the
  1293.         // PageSettings passed on the add call.
  1294.         if (pageInfo.status_area_widget != 0)
  1295.         {
  1296.            // First delete the page data structure pointer to by the status
  1297.            // widget's user data.
  1298.            unsigned long userData;
  1299.            XtVaGetValues( pageInfo.status_area_widget,
  1300.                           XmNuserData, &userData,
  1301.                           NULL );
  1302.            delete ((PageData*)userData);
  1303.            XtDestroyWidget(pageInfo.status_area_widget);
  1304.         }
  1305.         if (pageInfo.major_tab_widget != 0)
  1306.           XtDestroyWidget(pageInfo.major_tab_widget);
  1307.         if (pageInfo.minor_tab_widget != 0)
  1308.           XtDestroyWidget(pageInfo.minor_tab_widget);
  1309.         break;
  1310.       case XmPAGE_INVALID:
  1311.         ITHROWGUIERROR("Tried to delete invalid page");
  1312.         break;
  1313.       case XmPAGE_DUPLICATED:
  1314.         ITHROWGUIERROR("Duplicate pages found in INotebook");
  1315.         break;
  1316.       default:
  1317.         ITHROWGUIERROR("Unexpected pageStatus from XmNotebookGetPageInfo");
  1318.     }   // end switch
  1319.   }     // end for
  1320.  
  1321.   // Get rid of empty pages created by above.
  1322.   // How we do this depends on where the pages were deleted from.
  1323.   // But, we don't get rid of gaps when called by setWindow() since
  1324.   // it will be immediately filling in the gap with a page with the
  1325.   // new IWindow* value that was passed to it.
  1326.  
  1327.   if (removeGaps) {
  1328.     // Deleted all the pages
  1329.     if (startPage == origFirst && endPage == origLast)
  1330.     {
  1331.        XtVaSetValues( notebook,
  1332.                       XmNfirstPageNumber, 0,
  1333.                       XmNlastPageNumber, 0,
  1334.                       NULL );
  1335.        fPageSequence->removeAll();
  1336.     }
  1337.  
  1338.     // Deleted up to the last page
  1339.     else if (endPage == origLast)
  1340.     {
  1341.        XtVaSetValues( notebook,
  1342.                       XmNlastPageNumber, startPage - 1,
  1343.                       NULL );
  1344.        int removeCnt = endPage - startPage + 1;
  1345.        for (int i = 1; i <= removeCnt; i++)
  1346.        {
  1347.           fPageSequence->removeLast();
  1348.        }
  1349.     }
  1350.  
  1351.     // Deleted somewhere in the middle
  1352.     else {
  1353.       int removeCnt = endPage - startPage + 1;
  1354.       // have to fill in the "hole" left by deleting pages from the middle
  1355.       adjustPages(endPage+1, origLast,
  1356.                   -removeCnt);
  1357.       for (int i = 1; i <= removeCnt; i++)
  1358.       {
  1359.          fPageSequence->removeAtPosition( startPage );
  1360.       }
  1361.     }
  1362.   }  // if removeGaps
  1363. }
  1364.  
  1365. /*------------------------------------------------------------------------------
  1366. | INotebookData :: pageNumber                                                  |
  1367. |                                                                              |
  1368. | Determine the page number for this page handle.                              |
  1369. ------------------------------------------------------------------------------*/
  1370. int INotebookData :: pageNumber( IPageHandle page )
  1371. {
  1372.   int pageNumber = 0;
  1373.  
  1374.   if (!fPageSequence->isEmpty())
  1375.   {
  1376.      INotebookPageSequence::Cursor cursor( *fPageSequence );
  1377.      if (fPageSequence->locate( page, cursor ))
  1378.      {
  1379.         pageNumber = fPageSequence->position( cursor );
  1380.      }
  1381.   }
  1382.  
  1383.   return pageNumber;
  1384. }
  1385.  
  1386. /*------------------------------------------------------------------------------
  1387. | INotebookData :: pageHandle                                                  |
  1388. |                                                                              |
  1389. | Determine the page handle for this page number.                              |
  1390. ------------------------------------------------------------------------------*/
  1391. IPageHandle INotebookData :: pageHandle( int pageNumber )
  1392. {
  1393.   IPageHandle page( 0 );
  1394.   XmNotebookPageInfo pageInfo;
  1395.  
  1396.   XmNotebookPageStatus
  1397.      pageStatus = XmNotebookGetPageInfo( notebook, pageNumber, &pageInfo );
  1398.   if ((pageStatus == XmPAGE_FOUND || pageStatus == XmPAGE_EMPTY) &&
  1399.       pageInfo.status_area_widget)
  1400.   {
  1401.      unsigned long userData;
  1402.      XtVaGetValues( pageInfo.status_area_widget,
  1403.                     XmNuserData, &userData,
  1404.                     NULL );
  1405.      page = IPageHandle( ((PageData*)userData)->pageHandle );
  1406.   }
  1407.  
  1408.   return page;
  1409. }
  1410. #endif // IC_MOTIF
  1411.  
  1412.  
  1413. /*------------------------------------------------------------------------------
  1414. | IPageHandle::IPageHandle                                                     |
  1415. |                                                                              |
  1416. | Class constructor                                                            |
  1417. ------------------------------------------------------------------------------*/
  1418. IPageHandle :: IPageHandle ( Value pageId )
  1419.   : IHandle( pageId )
  1420. {}
  1421.  
  1422.  
  1423.  
  1424. /*------------------------------------------------------------------------------
  1425. | INotebook::INotebook                                                         |
  1426. |                                                                              |
  1427. | Construct a notebook from a window id, parent, and owner window handles,     |
  1428. | and initial size rectangle, and a style.                                     |
  1429. ------------------------------------------------------------------------------*/
  1430. INotebook :: INotebook ( unsigned long windowId,
  1431.                          IWindow* parent,
  1432.                          IWindow* pOwner,
  1433.                          const IRectangle& initial,
  1434.                          const Style& style )
  1435.   : fNotebookData( new INotebookData( ) )
  1436.   , bmClTabBitmapMgr( 0 )
  1437.   , pnotebookColors( 0 )
  1438.   , colorFlags( 0 )
  1439.   , ulClValidate( 0 )
  1440. #ifdef IC_WIN
  1441.   , pTabCtrlPageSeqCl( 0 )
  1442.   , ulClPagesInserted( 0 )
  1443. #endif
  1444. {
  1445.   // assertions on input parms
  1446.   IASSERTPARM(parent != 0);
  1447.  
  1448.   // Save the extended style to make sure we have a copy of it stored
  1449.   setExtendedStyle( extendedStyle() | style.asExtendedUnsignedLong() );
  1450.  
  1451. #ifdef IC_PMWIN
  1452.   IWindowHandle owner = (pOwner == 0) ? IWindowHandle(0) : pOwner->handle();
  1453.  
  1454.   // Default notebook window class name
  1455.   char* windowClass = WC_NOTEBOOK;
  1456.  
  1457. #ifdef IC_WIN
  1458.   if ( isPMCompatible() )
  1459.   {
  1460.     // Use CUA '91 notebook control.
  1461.     // If needed, load the DLL containing the control code.
  1462.     IControlStatics::loadControlDLL();
  1463.   }
  1464.   else
  1465.   {
  1466.     //Use native tab control
  1467.     InitCommonControls();
  1468.     windowClass = WC_TABCONTROL;
  1469.   }
  1470. #endif
  1471.  
  1472.   IWindowHandle whNB =
  1473.       this -> create( windowId,
  1474.                       0,
  1475.                       convertToGUIStyle( style ),
  1476.                       windowClass,
  1477.                       parent->handleForChildCreation(),
  1478.                       owner,
  1479.                       initial,
  1480.                       0,
  1481.                       0,
  1482.                       defaultOrdering(),
  1483.                       convertToGUIStyle( style, true ) );
  1484.  
  1485.   startHandlingEventsFor( whNB );
  1486.   fNotebookData->fdefaultHandler.handleEventsFor( this );
  1487.   fNotebookData->fMousePointerHandler.handleEventsFor( this );
  1488.  
  1489.   /********************************************************************/
  1490.   /* pmCompatible style is set for CUA '91 notebook in both PM and    */
  1491.   /* Windows.  If this style is not set, treat the notebook as a      */
  1492.   /* Windows tab control.                                             */
  1493.   /********************************************************************/
  1494.   if ( isPMCompatible() )
  1495.   {
  1496.     // Set Default Major Tab Dimensions
  1497.     SHORT MajorTabWidth  = 50;
  1498.     SHORT MajorTabHeight = 30;
  1499.     setMajorTabSize( ISize(MajorTabWidth,MajorTabHeight) );
  1500.  
  1501.     // Set Default Minor Tab Dimensions
  1502.     SHORT MinorTabWidth  = 50;
  1503.     SHORT MinorTabHeight = 30;
  1504.     setMinorTabSize( ISize(MinorTabWidth,MinorTabHeight) );
  1505.  
  1506.     // Set Default DogEar Dimensions
  1507.     SHORT DogEarWidth   = 30;
  1508.     SHORT DogEarHeight  = 20;
  1509.     setPageButtonSize( ISize(DogEarWidth,DogEarHeight) );
  1510.   }
  1511. #ifdef IC_WIN
  1512.   else
  1513.   {
  1514.     //Create the page clipping window
  1515.     fNotebookData->pPageClipWindow = new IPageClipWindow( this );
  1516.  
  1517.     //Since we have defined our own tab control item structure, we must
  1518.     //indicate the number of extra bytes in addition to the TC_ITEMHEADER
  1519.     //structure.  The TC_ITEMHEADER structure must be the first field in
  1520.     //the new item structure.
  1521.     if ( !TabCtrl_SetItemExtra( whNB,
  1522.                                 sizeof(IOC_ITEM) - sizeof(TC_ITEMHEADER) ) )
  1523.     {
  1524.       ITHROWGUIERROR("TabCtrl_SetItemExtra");
  1525.     }
  1526.  
  1527.     //Create the tab page sequence collection
  1528.     pTabCtrlPageSeqCl = new INotebookPageSequence( );
  1529.  
  1530.     //The tab control automatically sizes the tabs based upon the
  1531.     //tab text and/or bitmap size.  We do not need to set a default
  1532.     //size.
  1533.   }
  1534. #endif //IC_WIN
  1535. #endif // IC_PMWIN
  1536.  
  1537. #ifdef IC_MOTIF
  1538.   Arg            args[9];
  1539.   int            n = 0;
  1540.   IRectangle     activeRect = initial;
  1541.  
  1542.   // Signals addPageAt() that it's got an empty notebook
  1543.   // Need this to prevent getting a blank first page
  1544.   XtSetArg(args[n], XmNfirstPageNumber, 0); n++;
  1545.   XtSetArg(args[n], XmNlastPageNumber, 0); n++;
  1546.  
  1547.   // There are geometry problems in the Notebook widget if it has
  1548.   // no size, so give it a default. It will be sized to its parent
  1549.   // anyway.
  1550.   if (initial == IRectangle())
  1551.     activeRect.sizeTo(ISize(200,200));
  1552.  
  1553.   IWindowHandle notebook =
  1554.          Inherited::create(
  1555.             windowId,
  1556.             NULL,
  1557.             style.asUnsignedLong(),
  1558.             (IXmCreateFunction)XmCreateNotebook,
  1559.             parent->handleForChildCreation(),
  1560.             pOwner ? pOwner->handle() : desktopWindow()->handle(),
  1561.             activeRect,
  1562.             args,
  1563.             n);
  1564.  
  1565.   // Save Widget in private data and use this rather than
  1566.   // always calling handle()
  1567.   fNotebookData->notebook = notebook;
  1568.  
  1569.   // Create a page sequence used to store unique page handles for the
  1570.   // notebook.
  1571.   fNotebookData->fPageSequence = new INotebookPageSequence();
  1572.  
  1573.   startHandlingEventsFor( notebook );
  1574.   fNotebookData->registerCallbacks();
  1575.  
  1576.   // Set appearance programmatically
  1577.   if ( style != IWindow::noStyle ) {
  1578.     // Binding
  1579.     if (style & spiralBinding)
  1580.       setBinding(spiral);
  1581.  
  1582.    // Orientation
  1583.    if (style & backPagesBottomLeft)
  1584.      if (style & majorTabsLeft)
  1585.        setOrientation(backpagesBottomTabsLeft);
  1586.      else
  1587.        setOrientation(backpagesLeftTabsBottom);
  1588.  
  1589.    else if (style & backPagesBottomRight)
  1590.      if (style & majorTabsRight)
  1591.        setOrientation(backpagesBottomTabsRight);
  1592.      else
  1593.        setOrientation(backpagesRightTabsBottom);
  1594.  
  1595.    else if (style & backPagesTopLeft)
  1596.      if (style & majorTabsLeft)
  1597.        setOrientation(backpagesTopTabsLeft);
  1598.      else
  1599.        setOrientation(backpagesLeftTabsBottom);
  1600.  
  1601.    else if (style & backPagesTopRight)
  1602.      if (style & majorTabsRight)
  1603.        setOrientation(backpagesTopTabsRight);
  1604.      else
  1605.        setOrientation(backpagesRightTabsTop);
  1606.  
  1607.    // Tab shape
  1608.       // noop for now
  1609.  
  1610.    // Status alignment
  1611.    if (style & statusTextLeft)
  1612.      setStatusTextAlignment(left);
  1613.    else if (style & statusTextCenter)
  1614.      setStatusTextAlignment(center);
  1615.    else if (style & statusTextRight)
  1616.      setStatusTextAlignment(right);
  1617.  
  1618.    // Tab alignment
  1619.    if (style & tabTextLeft)
  1620.      setTabTextAlignment(left);
  1621.    else if (style & tabTextCenter)
  1622.      setTabTextAlignment(center);
  1623.    else if (style & tabTextRight)
  1624.      setTabTextAlignment(right);
  1625.  
  1626.   }  // if noStyle off
  1627.  
  1628.   // Default Tab Dimensions from the PM version
  1629.   int MajorTabWidth  = 50;
  1630.   int MajorTabHeight = 30;
  1631.   int MinorTabWidth  = 50;
  1632.   int MinorTabHeight = 30;
  1633.  
  1634. #if 0
  1635.   // Default DogEar Dimensions from the PM version
  1636.   int DogEarWidth   = 30;
  1637.   int DogEarHeight  = 20;
  1638.  
  1639.   // Set the various notebook dimensions
  1640.   // Need a fix to the notebook widget itself for this to have
  1641.   // any effect.
  1642.   setPageButtonSize( ISize(DogEarWidth,DogEarHeight) );
  1643.   setMajorTabSize( ISize(MajorTabWidth,MajorTabHeight) );
  1644.   setMinorTabSize( ISize(MinorTabWidth,MinorTabHeight) );
  1645. #endif
  1646. #endif // IC_MOTIF
  1647. }
  1648.  
  1649.  
  1650. #ifdef IC_PMWIN
  1651. /*------------------------------------------------------------------------------
  1652. | INotebook::INotebook                                                         |
  1653. |                                                                              |
  1654. | Construct a notebook from a window id and the window handle which serves     |
  1655. | as both parent and owner.                                                    |
  1656. ------------------------------------------------------------------------------*/
  1657. INotebook :: INotebook( unsigned long windowId,
  1658.                         IWindow* parentAndOwner )
  1659.   : fNotebookData( new INotebookData( ) )
  1660.   , bmClTabBitmapMgr( 0 )
  1661.   , pnotebookColors( 0 )
  1662.   , colorFlags( 0 )
  1663.   , ulClValidate( 0 )
  1664. #ifdef IC_WIN
  1665.   , pTabCtrlPageSeqCl( 0 )
  1666.   , ulClPagesInserted( 0 )
  1667. #endif
  1668. {
  1669.   IASSERTPARM(parentAndOwner != 0);
  1670.  
  1671.   setAutoDestroyWindow(false);
  1672.   reserveUserWindowWord( false );
  1673.   startHandlingEventsFor(windowId, parentAndOwner);
  1674.  
  1675. #ifdef IC_PMWIN
  1676.   fNotebookData->fdefaultHandler.handleEventsFor( this );
  1677.   fNotebookData->fMousePointerHandler.handleEventsFor( this );
  1678.  
  1679. #ifdef IC_WIN
  1680.   /********************************************************************/
  1681.   /* Get the window class of the control window to determine if       */
  1682.   /* we're dealing with a tab control.                                */
  1683.   /********************************************************************/
  1684.   IWindowHandle
  1685.     hwndControl = IWindow::handleWithParent( windowId,
  1686.                                              parentAndOwner->handle() );
  1687.   if ( IWindowClassName( hwndControl ) == WC_TABCONTROL )
  1688.   {
  1689.     //Create the page clipping window
  1690.     fNotebookData->pPageClipWindow = new IPageClipWindow( this );
  1691.  
  1692.     //Since we have defined our own tab control item structure, we must
  1693.     //indicate the number of extra bytes in addition to the TC_ITEMHEADER
  1694.     //structure.  The TC_ITEMHEADER structure must be the first field in
  1695.     //the new item structure.
  1696.     if ( !TabCtrl_SetItemExtra( hwndControl,
  1697.                                 sizeof(IOC_ITEM) - sizeof(TC_ITEMHEADER) ) )
  1698.     {
  1699.       ITHROWGUIERROR("TabCtrl_SetItemExtra");
  1700.     }
  1701.  
  1702.     //Create the tab page sequence collection
  1703.     pTabCtrlPageSeqCl = new INotebookPageSequence( );
  1704.  
  1705.     //The tab control automatically sizes the tabs based upon the
  1706.     //tab text and/or bitmap size.  We do not need to set a default
  1707.     //size, so we return.
  1708.     return;
  1709.   }
  1710. #endif
  1711.  
  1712.   // Set Default Major Tab Dimensions
  1713.   SHORT MajorTabWidth  = 50;
  1714.   SHORT MajorTabHeight = 30;
  1715.   setMajorTabSize( ISize(MajorTabWidth,MajorTabHeight) );
  1716.  
  1717.   // Set Default Minor Tab Dimensions
  1718.   SHORT MinorTabWidth  = 50;
  1719.   SHORT MinorTabHeight = 30;
  1720.   setMinorTabSize( ISize(MinorTabWidth,MinorTabHeight) );
  1721.  
  1722.   // Set Default DogEar Dimensions
  1723.   SHORT DogEarWidth   = 30;
  1724.   SHORT DogEarHeight  = 20;
  1725.   setPageButtonSize( ISize(DogEarWidth,DogEarHeight) );
  1726. #endif // IC_PMWIN
  1727. #ifdef IC_MOTIF
  1728.   fNotebookData->notebook = handleWithId(windowId, parentAndOwner->handle());
  1729. #endif
  1730. }
  1731. #endif
  1732.  
  1733. #ifdef IC_PMWIN
  1734. /*------------------------------------------------------------------------------
  1735. | INotebook::INotebook                                                         |
  1736. |                                                                              |
  1737. | Constructor to instantiate from an existing notebook control.                |
  1738. ------------------------------------------------------------------------------*/
  1739. INotebook :: INotebook ( const IWindowHandle& handle )
  1740.  
  1741.   : fNotebookData( new INotebookData( ) )
  1742.   , bmClTabBitmapMgr( 0 )
  1743.   , pnotebookColors( 0 )
  1744.   , colorFlags( 0 )
  1745.   , ulClValidate( 0 )
  1746. #ifdef IC_WIN
  1747.   , pTabCtrlPageSeqCl( 0 )
  1748.   , ulClPagesInserted( 0 )
  1749. #endif
  1750. {
  1751.   setAutoDestroyWindow(false);
  1752.   reserveUserWindowWord( false );
  1753.   startHandlingEventsFor(handle);
  1754.   fNotebookData->fdefaultHandler.handleEventsFor( this );
  1755.   fNotebookData->fMousePointerHandler.handleEventsFor( this );
  1756.  
  1757. #ifdef IC_WIN
  1758.   /********************************************************************/
  1759.   /* Get the window class of the control window to determine if       */
  1760.   /* we're dealing with a tab control.                                */
  1761.   /********************************************************************/
  1762.   if ( IWindowClassName( handle ) == WC_TABCONTROL )
  1763.   {
  1764.     //Create the page clipping window
  1765.     fNotebookData->pPageClipWindow = new IPageClipWindow( this );
  1766.  
  1767.     //Since we have defined our own tab control item structure, we must
  1768.     //indicate the number of extra bytes in addition to the TC_ITEMHEADER
  1769.     //structure.  The TC_ITEMHEADER structure must be the first field in
  1770.     //the new item structure.
  1771.     if ( !TabCtrl_SetItemExtra( handle,
  1772.                                 sizeof(IOC_ITEM) - sizeof(TC_ITEMHEADER) ) )
  1773.     {
  1774.       ITHROWGUIERROR("TabCtrl_SetItemExtra");
  1775.     }
  1776.  
  1777.     //Create the tab page sequence collection
  1778.     pTabCtrlPageSeqCl = new INotebookPageSequence( );
  1779.   }
  1780. #endif
  1781. }
  1782. #endif // IC_PMWIN
  1783.  
  1784. /*------------------------------------------------------------------------------
  1785. | INotebook::~INotebook                                                        |
  1786. |                                                                              |
  1787. ------------------------------------------------------------------------------*/
  1788. INotebook :: ~INotebook ( )
  1789. {
  1790. #ifdef IC_PMWIN
  1791.   fNotebookData->fdefaultHandler.stopHandlingEventsFor( this );
  1792.   fNotebookData->fMousePointerHandler.stopHandlingEventsFor( this );
  1793.   delete (pnotebookColors);
  1794.  
  1795.   while (bmClTabBitmapMgr)            // Remove the associated bitmap managers
  1796.   {
  1797.     ITabBitmapMgr *tmpTabBitmapMgr = bmClTabBitmapMgr;
  1798.     bmClTabBitmapMgr = bmClTabBitmapMgr->next();
  1799.     delete tmpTabBitmapMgr;
  1800.   }
  1801.  
  1802. #ifdef IC_WIN
  1803.   if ( !isPMCompatible() )
  1804.   {
  1805.     if (pTabCtrlPageSeqCl)
  1806.       delete pTabCtrlPageSeqCl;
  1807.   }
  1808. #endif
  1809. #endif // IC_PMWIN
  1810.  
  1811. #ifdef IC_MOTIF
  1812.   while (bmClTabBitmapMgr)            // Remove the associated bitmap managers
  1813.   {
  1814.     ITabBitmapMgr *tmpTabBitmapMgr = bmClTabBitmapMgr;
  1815.     delete tmpTabBitmapMgr;
  1816.     bmClTabBitmapMgr = bmClTabBitmapMgr->next();
  1817.   }
  1818.   if (fNotebookData && isValid())
  1819.      fNotebookData->unregisterCallbacks();
  1820. #endif
  1821.   delete fNotebookData;
  1822. }
  1823.  
  1824.  
  1825. /*------------------------------------------------------------------------------
  1826. | INotebook::defaultStyle                                                      |
  1827. |                                                                              |
  1828. | Return the default style for new notebook objects.                           |
  1829. ------------------------------------------------------------------------------*/
  1830. INotebook::Style INotebook :: defaultStyle ( )
  1831. {
  1832.   return currentDefaultStyle;
  1833. }
  1834.  
  1835. #ifdef IC_WIN
  1836. /*------------------------------------------------------------------------------
  1837. | INotebook::setDefaultStyle                                                   |
  1838. |                                                                              |
  1839. | Sets the default style.                                                      |
  1840. |                                                                              |
  1841. | Note: This function is inlined on all platforms except Windows due to        |
  1842. |       variables it references not being exported.                            |
  1843. ------------------------------------------------------------------------------*/
  1844. void INotebook::setDefaultStyle ( const INotebook::Style& style )
  1845. {
  1846.   currentDefaultStyle = style;
  1847. }
  1848. #endif //IC_WIN
  1849.  
  1850. /*------------------------------------------------------------------------------
  1851. | INotebook::convertToGUIStyle                                                 |
  1852. |                                                                              |
  1853. | Returns base style for the control by default, or extended style if          |
  1854. | extended flag (bExtOnly) is set.                                             |
  1855. ------------------------------------------------------------------------------*/
  1856. unsigned long INotebook::convertToGUIStyle ( const IBitFlag& guiStyle,
  1857.                                              bool bExtOnly ) const
  1858. {
  1859.   // Obtain the style from the class (IControl) that we inherit from
  1860.   unsigned long ulStyle = Inherited::convertToGUIStyle( guiStyle, bExtOnly );
  1861.  
  1862.   if (bExtOnly)
  1863.   {
  1864.     // Use mask to only return extended styles in the user defined range
  1865.     ulStyle |= guiStyle.asExtendedUnsignedLong() & IS_EXTMASK;
  1866.   }
  1867.   else
  1868.   {
  1869. #ifdef IC_WIN
  1870.     if ( !isPMCompatible() )
  1871.     {
  1872.        // Add the new styles required by the tab control
  1873.        ulStyle |= TCS_TABS | TCS_SINGLELINE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
  1874.  
  1875.        // Set the multiple row tab style if requested
  1876.        ulStyle |= ( guiStyle.asExtendedUnsignedLong() &
  1877.                    allTabsVisible.asExtendedUnsignedLong() ) ? TCS_MULTILINE : 0;
  1878.  
  1879.        // Set the owner draw tab style if requested
  1880.        ulStyle |= ( guiStyle.asExtendedUnsignedLong() &
  1881.                  handleDrawTabs.asExtendedUnsignedLong() ) ? TCS_OWNERDRAWFIXED
  1882.                                                            : 0;
  1883.     }
  1884.     else
  1885.     {
  1886. #endif // IC_WIN
  1887.        // BKS_ styles use all but one of their available bits in the lower
  1888.        // word of the base GUI style.  Therefore, obtain that portion asis,
  1889.        // masking out the upper word. Four of the styles were denoted as
  1890.        // 0 (OS/2 PM), due to the lack of available bits.  We are representing
  1891.        // those as extended bits so we or the developer can accurately test
  1892.        // for them later.  Since their native values are 0, we do not have to
  1893.        // do any additional processing here.
  1894.        ulStyle |= guiStyle.asUnsignedLong() & IBKS_MASK;
  1895. #ifdef IC_WIN
  1896.     }
  1897.     ulStyle |= WS_CHILD;
  1898. #endif // IC_WIN
  1899.   }
  1900.  
  1901.   return( ulStyle );
  1902. }
  1903.  
  1904. #ifdef IC_MOTIF
  1905. // Bitmaps used for spiral binding in setBinding()
  1906.  
  1907. #define spiral_width 24
  1908. #define spiral_height 18
  1909. static char spiral_bits[] = {
  1910.    0x00, 0x0c, 0x00, 0xc0, 0x0f, 0x00, 0xe0, 0x0c, 0x00, 0x38, 0x0c, 0x00,
  1911.    0x8c, 0x0f, 0x00, 0xc6, 0x0d, 0x00, 0x66, 0x0c, 0x00, 0x62, 0x0c, 0x00,
  1912.    0x66, 0x0c, 0x00, 0xc6, 0x0c, 0x1e, 0x8c, 0x0d, 0x3f, 0x18, 0x8e, 0x7f,
  1913.    0x70, 0xf8, 0x73, 0xc0, 0x01, 0x70, 0x00, 0x0f, 0x7c, 0x00, 0xfc, 0x3f,
  1914.    0x00, 0x0c, 0x1e, 0x00, 0x0c, 0x00};
  1915.  
  1916. #define spiral90_width 18
  1917. #define spiral90_height 24
  1918. static char spiral90_bits[] = {
  1919.  0x00,0x00,0x00,0xe0,0x03,0x00,0x70,0x07,0x00,0x18,0x0c,0x00,0x08,0x18,0x00,
  1920.  0xcc,0x11,0x00,0xe6,0x33,0x00,0x36,0x26,0x00,0x32,0x64,0x00,0x12,0x48,0x00,
  1921.  0xff,0xcf,0x03,0xff,0xdf,0x03,0x00,0x90,0x00,0x00,0x90,0x00,0x00,0x90,0x00,
  1922.  0x00,0x98,0x00,0x00,0x9c,0x00,0x00,0x9e,0x01,0x00,0xce,0x01,0x00,0xce,0x01,
  1923.  0x00,0xfe,0x01,0x00,0xfc,0x00,0x00,0x78,0x00,0x00,0x00,0x00};
  1924.  
  1925. #define spiral180_width 24
  1926. #define spiral180_height 18
  1927. static char spiral180_bits[] = {
  1928.  0x00,0x30,0x00,0x00,0xf0,0x03,0x00,0x30,0x07,0x00,0x30,0x1c,0x00,0xf0,0x31,
  1929.  0x00,0xb0,0x63,0x00,0x30,0x66,0x00,0x30,0x46,0x00,0x30,0x66,0x78,0x30,0x63,
  1930.  0xfc,0xb0,0x31,0xfe,0x71,0x18,0xce,0x1f,0x0e,0x0e,0x80,0x03,0x3e,0xf0,0x00,
  1931.  0xfc,0x3f,0x00,0x78,0x30,0x00,0x00,0x30,0x00};
  1932.  
  1933. #define spiral270_width 18
  1934. #define spiral270_height 24
  1935. static char spiral270_bits[] = {
  1936.  0x00,0x00,0x00,0x00,0x78,0x00,0x00,0xfc,0x00,0x00,0xfe,0x01,0x00,0xce,0x01,
  1937.  0x00,0xce,0x01,0x00,0x9e,0x01,0x00,0x9c,0x00,0x00,0x98,0x00,0x00,0x90,0x00,
  1938.  0x00,0x90,0x00,0x00,0x90,0x00,0xff,0xdf,0x03,0xff,0xcf,0x03,0x12,0x48,0x00,
  1939.  0x32,0x64,0x00,0x36,0x26,0x00,0xe6,0x33,0x00,0xcc,0x11,0x00,0x08,0x18,0x00,
  1940.  0x18,0x0c,0x00,0x70,0x07,0x00,0xe0,0x03,0x00,0x00,0x00,0x00};
  1941.  
  1942.  
  1943. #endif // IC_MOTIF
  1944.  
  1945. /*------------------------------------------------------------------------------
  1946. | INotebook::setBinding                                                        |
  1947. |                                                                              |
  1948. | Set the binding style of the notebook.                                       |
  1949. ------------------------------------------------------------------------------*/
  1950. INotebook& INotebook :: setBinding ( Binding binding )
  1951. {
  1952.   ITRACE_WIN_NOP();
  1953.  
  1954. #ifdef IC_PMWIN
  1955.   if ( isPMCompatible() )
  1956.   {
  1957.     unsigned long ulStyle = style();
  1958.     unsigned long ulOldStyle = ulStyle;
  1959.     unsigned long ulExtStyle = extendedStyle();
  1960.  
  1961.     if (binding == spiral)
  1962.     {
  1963.       ulStyle |= spiralBinding.asUnsignedLong();
  1964.       ulExtStyle &= ~solidBinding.asExtendedUnsignedLong();
  1965.     }
  1966.     else if (binding == solid)
  1967.     {
  1968.       ulStyle &= ~spiralBinding.asUnsignedLong();
  1969.       ulExtStyle |= solidBinding.asExtendedUnsignedLong();
  1970.     }
  1971.     else
  1972.     {
  1973.       ITHROWLIBRARYERROR(IC_INVALIDENUMVALUE,
  1974.                          IBaseErrorInfo::invalidParameter,
  1975.                          IException::recoverable);
  1976.     }
  1977.  
  1978.     if (ulStyle != ulOldStyle)
  1979.     {
  1980.       setStyle(ulStyle);
  1981.       refresh();
  1982.  
  1983.       // Update extended style ...
  1984.       setExtendedStyle(ulExtStyle);
  1985.     }
  1986.   }
  1987. #endif // IC_PMWIN
  1988. #ifdef IC_MOTIF
  1989.   if (binding == solid)
  1990.     XtVaSetValues(fNotebookData->notebook,
  1991.                   XmNbindingType, XmSOLID,
  1992.                   NULL);
  1993.   else
  1994.   {
  1995.     Pixel fg, bg;
  1996.     Pixmap tile;
  1997.     unsigned int width, height;
  1998.     char* bitData;
  1999.     Display* display = XtDisplay(fNotebookData->notebook);
  2000.     XtVaGetValues(fNotebookData->notebook,
  2001.                   XmNforeground, &fg,
  2002.                   XmNbackground, &bg,
  2003.                   XmNbindingPixmap, &tile,
  2004.                   NULL);
  2005.  
  2006.     if (tile != XmUNSPECIFIED_PIXMAP)
  2007.        XFreePixmap(display, tile);
  2008.  
  2009.     switch(orientation())
  2010.     {
  2011.       case backpagesLeftTabsBottom:
  2012.       case backpagesRightTabsBottom:
  2013.         bitData = spiral90_bits;
  2014.         width = spiral90_width;
  2015.         height = spiral90_height;
  2016.         break;
  2017.  
  2018.       case backpagesRightTabsTop:
  2019.       case backpagesLeftTabsTop:
  2020.         bitData = spiral270_bits;
  2021.         width = spiral270_width;
  2022.         height = spiral270_height;
  2023.         break;
  2024.  
  2025.       case backpagesBottomTabsRight:
  2026.       case backpagesTopTabsRight:
  2027.         bitData = spiral_bits;
  2028.         width = spiral_width;
  2029.         height = spiral_height;
  2030.         break;
  2031.  
  2032.       case backpagesBottomTabsLeft:
  2033.       case backpagesTopTabsLeft:
  2034.         bitData = spiral180_bits;
  2035.         width = spiral180_width;
  2036.         height = spiral180_height;
  2037.         break;
  2038.     }  // end switch
  2039.  
  2040.     tile = XCreatePixmapFromBitmapData(display,
  2041.                RootWindow(display, DefaultScreen(display)),
  2042.                bitData,
  2043.                width, height,
  2044.                fg, bg,
  2045.                DefaultDepthOfScreen(XtScreen(fNotebookData->notebook)));
  2046.  
  2047.     XtVaSetValues(fNotebookData->notebook,
  2048.                   XmNbindingType, XmPIXMAP,
  2049.                   XmNbindingPixmap, tile,
  2050.                   NULL);
  2051.   }
  2052.  
  2053. #endif // IC_MOTIF
  2054.   return( *this );
  2055. }
  2056.  
  2057.  
  2058. /*------------------------------------------------------------------------------
  2059. | INotebook::setOrientation                                                    |
  2060. |                                                                              |
  2061. | Set the orientation style of the notebook.                                   |
  2062. ------------------------------------------------------------------------------*/
  2063. INotebook& INotebook :: setOrientation ( Orientation orientation )
  2064. {
  2065.   ITRACE_WIN_NOP();
  2066.  
  2067. #ifdef IC_PMWIN
  2068.   if ( isPMCompatible() )
  2069.   {
  2070.     unsigned long ulStyle = style();
  2071.     unsigned long ulOldStyle = ulStyle;
  2072.     unsigned long ulMask = ~(backPagesBottomRight.asUnsignedLong()  |
  2073.                              backPagesBottomLeft.asUnsignedLong()   |
  2074.                              backPagesTopRight.asUnsignedLong()     |
  2075.                              backPagesTopLeft.asUnsignedLong()      |
  2076.                              majorTabsRight.asUnsignedLong()        |
  2077.                              majorTabsLeft.asUnsignedLong()         |
  2078.                              majorTabsTop.asUnsignedLong()          |
  2079.                              majorTabsBottom.asUnsignedLong());
  2080.     ulStyle &= ulMask;
  2081.     switch (orientation)
  2082.     {
  2083.       case backpagesBottomTabsRight:
  2084.         ulStyle |= (backPagesBottomRight.asUnsignedLong() |
  2085.                     majorTabsRight.asUnsignedLong());
  2086.         break;
  2087.       case backpagesTopTabsRight:
  2088.         ulStyle |= (backPagesTopRight.asUnsignedLong() |
  2089.                     majorTabsRight.asUnsignedLong());
  2090.         break;
  2091.       case backpagesBottomTabsLeft:
  2092.         ulStyle |= (backPagesBottomLeft.asUnsignedLong() |
  2093.                     majorTabsLeft.asUnsignedLong());
  2094.         break;
  2095.       case backpagesTopTabsLeft:
  2096.         ulStyle |= (backPagesTopLeft.asUnsignedLong() |
  2097.                     majorTabsLeft.asUnsignedLong());
  2098.         break;
  2099.       case backpagesRightTabsTop:
  2100.         ulStyle |= (backPagesTopRight.asUnsignedLong() |
  2101.                     majorTabsTop.asUnsignedLong());
  2102.         break;
  2103.       case backpagesLeftTabsTop:
  2104.         ulStyle |= (backPagesTopLeft.asUnsignedLong() |
  2105.                     majorTabsTop.asUnsignedLong());
  2106.         break;
  2107.       case backpagesRightTabsBottom:
  2108.         ulStyle |= (backPagesBottomRight.asUnsignedLong() |
  2109.                     majorTabsBottom.asUnsignedLong());
  2110.         break;
  2111.       case backpagesLeftTabsBottom:
  2112.         ulStyle |= (backPagesBottomLeft.asUnsignedLong() |
  2113.                     majorTabsBottom.asUnsignedLong());
  2114.         break;
  2115.       default:
  2116.         ITHROWLIBRARYERROR(IC_INVALIDENUMVALUE,
  2117.                            IBaseErrorInfo::invalidParameter,
  2118.                            IException::recoverable);
  2119.         break;
  2120.     }
  2121.  
  2122.     if (ulStyle != ulOldStyle)
  2123.     {
  2124.       setStyle(ulStyle);
  2125.       refresh();
  2126.       notifyObservers(INotificationEvent(INotebook::orientationId,
  2127.                                          *this, true, (void*)orientation));
  2128.     }
  2129.   }
  2130. #endif // IC_PMWIN
  2131. #ifdef IC_MOTIF
  2132.   unsigned char pagePlacement = XmBOTTOM_RIGHT,
  2133.                 nbOrientation = XmHORIZONTAL;
  2134.  
  2135.   switch (orientation)
  2136.   {
  2137.     case backpagesBottomTabsRight:
  2138.       pagePlacement = XmBOTTOM_RIGHT;
  2139.       nbOrientation = XmHORIZONTAL;
  2140.       break;
  2141.     case backpagesTopTabsRight:
  2142.       pagePlacement = XmTOP_RIGHT;
  2143.       nbOrientation = XmHORIZONTAL;
  2144.       break;
  2145.     case backpagesBottomTabsLeft:
  2146.       pagePlacement = XmBOTTOM_LEFT;
  2147.       nbOrientation = XmHORIZONTAL;
  2148.       break;
  2149.     case backpagesTopTabsLeft:
  2150.       pagePlacement = XmTOP_LEFT;
  2151.       nbOrientation = XmHORIZONTAL;
  2152.       break;
  2153.     case backpagesRightTabsTop:
  2154.       pagePlacement = XmTOP_RIGHT;
  2155.       nbOrientation = XmVERTICAL;
  2156.       break;
  2157.     case backpagesLeftTabsTop:
  2158.       pagePlacement = XmTOP_LEFT;
  2159.       nbOrientation = XmVERTICAL;
  2160.       break;
  2161.     case backpagesRightTabsBottom:
  2162.       pagePlacement = XmBOTTOM_RIGHT;
  2163.       nbOrientation = XmVERTICAL;
  2164.       break;
  2165.     case backpagesLeftTabsBottom:
  2166.       pagePlacement = XmBOTTOM_LEFT;
  2167.       nbOrientation = XmVERTICAL;
  2168.       break;
  2169.   }
  2170.   XtVaSetValues(fNotebookData->notebook,
  2171.                 XmNbackPagePlacement, pagePlacement,
  2172.                 XmNorientation, nbOrientation,
  2173.                 NULL);
  2174.  
  2175.   // May need a new binding pixmap if using spiral binding
  2176.   if (binding() == spiral)
  2177.     setBinding(spiral);
  2178.  
  2179.   this->notifyObservers(INotificationEvent(INotebook::orientationId,
  2180.     *this, true, (void*)orientation));
  2181.  
  2182. #endif // IC_MOTIF
  2183.   return( *this );
  2184. }
  2185.  
  2186.  
  2187. /*------------------------------------------------------------------------------
  2188. | INotebook::setTabShape                                                       |
  2189. ------------------------------------------------------------------------------*/
  2190. INotebook& INotebook :: setTabShape ( TabShape tabShape )
  2191. {
  2192.   ITRACE_MOTIF_NOP();
  2193.   ITRACE_WIN_NOP();
  2194.  
  2195. #ifdef IC_PMWIN
  2196.   if ( isPMCompatible() )
  2197.   {
  2198.     unsigned long ulStyle = style();
  2199.     unsigned long ulOldStyle = ulStyle;
  2200.     unsigned long ulExtStyle = extendedStyle();
  2201.     unsigned long ulMask = ~(roundedTabs.asUnsignedLong()  |
  2202.                              polygonTabs.asUnsignedLong());
  2203.     ulStyle &= ulMask;
  2204.     ulExtStyle &= ~squareTabs.asExtendedUnsignedLong();
  2205.  
  2206.     switch (tabShape)
  2207.     {
  2208.       case square:
  2209.         ulExtStyle |= squareTabs.asExtendedUnsignedLong();
  2210.         break;
  2211.       case rounded:
  2212.         ulStyle |= roundedTabs.asUnsignedLong();
  2213.         break;
  2214.       case polygon:
  2215.         ulStyle |= polygonTabs.asUnsignedLong();
  2216.         break;
  2217.       default:
  2218.         ITHROWLIBRARYERROR(IC_INVALIDENUMVALUE,
  2219.                            IBaseErrorInfo::invalidParameter,
  2220.                            IException::recoverable);
  2221.         break;
  2222.     }
  2223.  
  2224.     if (ulStyle != ulOldStyle)
  2225.     {
  2226.       setStyle(ulStyle);
  2227.       refresh();
  2228.  
  2229.       // Update extended style ...
  2230.       setExtendedStyle(ulExtStyle);
  2231.     }
  2232.   }
  2233. #endif
  2234.   return( *this );
  2235. }
  2236.  
  2237.  
  2238. /*------------------------------------------------------------------------------
  2239. | INotebook::setStatusTextAlignment                                            |
  2240. |                                                                              |
  2241. | Set the alignment style of the text in the notebook's status line.           |
  2242. ------------------------------------------------------------------------------*/
  2243. INotebook& INotebook :: setStatusTextAlignment ( TextAlignment align )
  2244. {
  2245.   ITRACE_WIN_NOP();
  2246.  
  2247. #ifdef IC_PMWIN
  2248.   if ( isPMCompatible() )
  2249.   {
  2250.     unsigned long ulStyle = style();
  2251.     unsigned long ulOldStyle = ulStyle;
  2252.     unsigned long ulExtStyle = extendedStyle();
  2253.     unsigned long ulMask = ~(statusTextRight.asUnsignedLong()  |
  2254.                              statusTextCenter.asUnsignedLong());
  2255.     ulStyle &= ulMask;
  2256.     ulExtStyle &= ~statusTextLeft.asExtendedUnsignedLong();
  2257.  
  2258.     switch (align)
  2259.     {
  2260.       case left:
  2261.         ulExtStyle |= statusTextLeft.asExtendedUnsignedLong();
  2262.         break;
  2263.       case right:
  2264.         ulStyle |= statusTextRight.asUnsignedLong();
  2265.         break;
  2266.       case center:
  2267.         ulStyle |= statusTextCenter.asUnsignedLong();
  2268.         break;
  2269.       default:
  2270.         ITHROWLIBRARYERROR(IC_INVALIDENUMVALUE,
  2271.                            IBaseErrorInfo::invalidParameter,
  2272.                            IException::recoverable);
  2273.         break;
  2274.     }
  2275.  
  2276.     if (ulStyle != ulOldStyle)
  2277.     {
  2278.       setStyle(ulStyle);
  2279.       refresh();
  2280.  
  2281.       // Update extended style ...
  2282.       setExtendedStyle(ulExtStyle);
  2283.     }
  2284.   }
  2285. #endif // IC_PMWIN
  2286. #ifdef IC_MOTIF
  2287.   switch (align)
  2288.   {
  2289.     case left:
  2290.       if (fNotebookData->statusAlignment == XmALIGNMENT_BEGINNING)
  2291.         return *this;
  2292.       fNotebookData->statusAlignment = XmALIGNMENT_BEGINNING;
  2293.       break;
  2294.  
  2295.     case right:
  2296.       if (fNotebookData->statusAlignment == XmALIGNMENT_END)
  2297.         return *this;
  2298.       fNotebookData->statusAlignment = XmALIGNMENT_END;
  2299.       break;
  2300.  
  2301.     case center:
  2302.       if (fNotebookData->statusAlignment == XmALIGNMENT_CENTER)
  2303.         return *this;
  2304.       fNotebookData->statusAlignment = XmALIGNMENT_CENTER;
  2305.       break;
  2306.   }
  2307.   fNotebookData->refreshStatus();
  2308. #endif // IC_MOTIF
  2309.   return( *this );
  2310. }
  2311.  
  2312. /*------------------------------------------------------------------------------
  2313. | INotebook::setTabTextAlignment                                               |
  2314. |                                                                              |
  2315. | Set the alignment of the text in the notebook's tabs.                        |
  2316. ------------------------------------------------------------------------------*/
  2317. INotebook& INotebook :: setTabTextAlignment ( TextAlignment align )
  2318. {
  2319.   ITRACE_WIN_NOP();
  2320.  
  2321. #ifdef IC_PMWIN
  2322.   if ( isPMCompatible() )
  2323.   {
  2324.     unsigned long ulStyle = style();
  2325.     unsigned long ulOldStyle = ulStyle;
  2326.     unsigned long ulExtStyle = extendedStyle();
  2327.     unsigned long ulMask = ~(tabTextRight.asUnsignedLong()  |
  2328.                              tabTextCenter.asUnsignedLong());
  2329.     ulStyle &= ulMask;
  2330.     ulExtStyle &= ~statusTextLeft.asExtendedUnsignedLong();
  2331.  
  2332.     switch (align)
  2333.     {
  2334.       case left:
  2335.         ulExtStyle |= tabTextLeft.asExtendedUnsignedLong();
  2336.         break;
  2337.       case right:
  2338.         ulStyle |= tabTextRight.asUnsignedLong();
  2339.         break;
  2340.       case center:
  2341.         ulStyle |= tabTextCenter.asUnsignedLong();
  2342.         break;
  2343.       default:
  2344.         ITHROWLIBRARYERROR(IC_INVALIDENUMVALUE,
  2345.                            IBaseErrorInfo::invalidParameter,
  2346.                            IException::recoverable);
  2347.         break;
  2348.     }
  2349.  
  2350.     if (ulStyle != ulOldStyle)
  2351.     {
  2352.       setStyle(ulStyle);
  2353.       refresh();
  2354.  
  2355.       // Update extended style ...
  2356.       setExtendedStyle(ulExtStyle);
  2357.     }
  2358.   }
  2359. #endif // IC_PMWIN
  2360. #ifdef IC_MOTIF
  2361.   switch (align)
  2362.   {
  2363.     case left:
  2364.       if (fNotebookData->tabAlignment == XmALIGNMENT_BEGINNING)
  2365.         return *this;
  2366.       fNotebookData->tabAlignment = XmALIGNMENT_BEGINNING;
  2367.       break;
  2368.  
  2369.     case right:
  2370.       if (fNotebookData->tabAlignment == XmALIGNMENT_END)
  2371.         return *this;
  2372.       fNotebookData->tabAlignment = XmALIGNMENT_END;
  2373.       break;
  2374.  
  2375.     case center:
  2376.       if (fNotebookData->tabAlignment == XmALIGNMENT_CENTER)
  2377.         return *this;
  2378.       fNotebookData->tabAlignment = XmALIGNMENT_CENTER;
  2379.       break;
  2380.   }
  2381.   fNotebookData->refreshTabs();
  2382. #endif // IC_MOTIF
  2383.   return( *this );
  2384. }
  2385.  
  2386.  
  2387. /*------------------------------------------------------------------------------
  2388. | INotebook::binding                                                           |
  2389. ------------------------------------------------------------------------------*/
  2390. INotebook::Binding INotebook :: binding ( ) const
  2391. {
  2392.   ITRACE_WIN_NOP();
  2393.  
  2394. #ifdef IC_PMWIN
  2395.   if ( isPMCompatible() )
  2396.   {
  2397.     return( (style() & spiralBinding.asUnsignedLong()) ?  INotebook::spiral
  2398.                                                        :  INotebook::solid );
  2399.   }
  2400.   else
  2401.   {
  2402.     return( INotebook::solid );                            //return default
  2403.   }
  2404. #endif // IC_PMWIN
  2405. #ifdef IC_MOTIF
  2406.   unsigned char bindingType;
  2407.  
  2408.   XtVaGetValues(fNotebookData->notebook,
  2409.                 XmNbindingType, &bindingType,
  2410.                 NULL);
  2411.  
  2412.   // For a spiral binding we set the Pixmap in setBinding()
  2413.   if (bindingType == XmPIXMAP)
  2414.       return INotebook::spiral;
  2415.   return INotebook::solid;
  2416. #endif
  2417. }
  2418.  
  2419.  
  2420. /*------------------------------------------------------------------------------
  2421. | INotebook::orientation                                                       |
  2422. ------------------------------------------------------------------------------*/
  2423. INotebook::Orientation INotebook :: orientation ( ) const
  2424. {
  2425.   ITRACE_WIN_NOP();
  2426.  
  2427. #ifdef IC_PMWIN
  2428.   if ( isPMCompatible() )
  2429.   {
  2430.     unsigned long ulStyle = style();
  2431.     INotebook::Orientation currentOrientation(backpagesRightTabsBottom);
  2432.  
  2433.     if (ulStyle & majorTabsRight.asUnsignedLong())
  2434.     {
  2435.       if (ulStyle & backPagesBottomRight.asUnsignedLong())
  2436.         currentOrientation = INotebook::backpagesBottomTabsRight;
  2437.       else
  2438.         currentOrientation = INotebook::backpagesTopTabsRight;
  2439.     }
  2440.     else if (ulStyle & majorTabsLeft.asUnsignedLong())
  2441.     {
  2442.       if (ulStyle & backPagesBottomLeft.asUnsignedLong())
  2443.         currentOrientation = INotebook::backpagesBottomTabsLeft;
  2444.       else
  2445.         currentOrientation = INotebook::backpagesTopTabsLeft;
  2446.     }
  2447.     else if (ulStyle & majorTabsTop.asUnsignedLong())
  2448.     {
  2449.       if (ulStyle & backPagesTopLeft.asUnsignedLong())
  2450.         currentOrientation = INotebook::backpagesLeftTabsTop;
  2451.       else
  2452.         currentOrientation = INotebook::backpagesRightTabsTop;
  2453.     }
  2454.     else if (ulStyle & majorTabsBottom.asUnsignedLong())
  2455.     {
  2456.       if (ulStyle & backPagesBottomLeft.asUnsignedLong())
  2457.         currentOrientation = INotebook::backpagesLeftTabsBottom;
  2458.       else
  2459.         currentOrientation = INotebook::backpagesRightTabsBottom;
  2460.     }
  2461.     return currentOrientation;
  2462.   }
  2463.   else
  2464.   {
  2465.     return( INotebook::backpagesRightTabsTop );
  2466.   }
  2467. #endif
  2468. #ifdef IC_MOTIF
  2469.   unsigned char bPP, ornt;
  2470.   XtVaGetValues(fNotebookData->notebook,
  2471.                 XmNbackPagePlacement, &bPP,
  2472.                 XmNorientation, &ornt,
  2473.                 NULL);
  2474.   INotebook::Orientation currentOrientation(backpagesRightTabsBottom);
  2475.  
  2476.   if (bPP == XmBOTTOM_RIGHT)
  2477.   {
  2478.     if (ornt == XmHORIZONTAL)
  2479.       currentOrientation = INotebook::backpagesBottomTabsRight;
  2480.     else
  2481.       currentOrientation = INotebook::backpagesRightTabsBottom;
  2482.   }
  2483.   else if (bPP == XmBOTTOM_LEFT)
  2484.   {
  2485.     if (ornt == XmHORIZONTAL)
  2486.       currentOrientation = INotebook::backpagesBottomTabsLeft;
  2487.     else
  2488.       currentOrientation = INotebook::backpagesLeftTabsBottom;
  2489.   }
  2490.   else if (bPP == XmTOP_RIGHT)
  2491.   {
  2492.     if (ornt == XmHORIZONTAL)
  2493.       currentOrientation = INotebook::backpagesTopTabsRight;
  2494.     else
  2495.       currentOrientation = INotebook::backpagesRightTabsTop;
  2496.   }
  2497.   else if (bPP == XmTOP_LEFT)
  2498.   {
  2499.     if (ornt == XmHORIZONTAL)
  2500.       currentOrientation = INotebook::backpagesTopTabsLeft;
  2501.     else
  2502.       currentOrientation = INotebook::backpagesLeftTabsTop;
  2503.   }
  2504.   return currentOrientation;
  2505. #endif
  2506. }
  2507.  
  2508.  
  2509. /*------------------------------------------------------------------------------
  2510. | INotebook::tabShape                                                          |
  2511. ------------------------------------------------------------------------------*/
  2512. INotebook::TabShape INotebook :: tabShape ( ) const
  2513. {
  2514. #ifdef IC_PMWIN
  2515.   if ( isPMCompatible() )
  2516.   {
  2517.     unsigned long ulStyle = style();
  2518.     if (ulStyle & roundedTabs.asUnsignedLong())
  2519.       return( INotebook::rounded );
  2520.     else if (ulStyle & polygonTabs.asUnsignedLong())
  2521.       return( INotebook::polygon );
  2522.     else
  2523.       return( INotebook::square );
  2524.   }
  2525.   else
  2526.   {
  2527.     return( INotebook::rounded );
  2528.   }
  2529. #endif // IC_PMWIN
  2530. #ifdef IC_MOTIF
  2531.   // Only square is currently supported
  2532.   return INotebook::square;
  2533. #endif
  2534. }
  2535.  
  2536.  
  2537. /*------------------------------------------------------------------------------
  2538. | INotebook::statusTextAlignment                                               |
  2539. |                                                                              |
  2540. | Return the alignment of the status text of the notebook.                     |
  2541. ------------------------------------------------------------------------------*/
  2542. INotebook::TextAlignment INotebook :: statusTextAlignment ( ) const
  2543. {
  2544.   ITRACE_WIN_NOP();
  2545.  
  2546. #ifdef IC_PMWIN
  2547.   if ( isPMCompatible() )
  2548.   {
  2549.     unsigned long ulStyle = style();
  2550.     if (ulStyle & statusTextRight.asUnsignedLong())
  2551.       return( INotebook::right );
  2552.     else if (ulStyle & statusTextCenter.asUnsignedLong())
  2553.       return( INotebook::center );
  2554.     else
  2555.       return( INotebook::left );
  2556.   }
  2557.   else
  2558.   {
  2559.     return( INotebook::left );                             //return default
  2560.   }
  2561. #endif // IC_PMWIN
  2562. #ifdef IC_MOTIF
  2563.   if (fNotebookData->statusAlignment == XmALIGNMENT_END)
  2564.     return INotebook::right;
  2565.   else if (fNotebookData->statusAlignment == XmALIGNMENT_CENTER)
  2566.     return INotebook::center;
  2567.   else
  2568.     return INotebook::left;
  2569. #endif
  2570. }
  2571.  
  2572.  
  2573. /*------------------------------------------------------------------------------
  2574. | INotebook::tabTextAlignment                                                  |
  2575. |                                                                              |
  2576. | Return the alignment of the tab text of the notebook.                        |
  2577. ------------------------------------------------------------------------------*/
  2578. INotebook::TextAlignment INotebook :: tabTextAlignment ( ) const
  2579. {
  2580. #ifdef IC_PMWIN
  2581.   if ( isPMCompatible() )
  2582.   {
  2583.     unsigned long ulStyle = style();
  2584.     if (ulStyle & tabTextRight.asUnsignedLong())
  2585.       return( INotebook::right );
  2586.     else if (ulStyle & tabTextCenter.asUnsignedLong())
  2587.       return( INotebook::center );
  2588.     else
  2589.       return( INotebook::left );
  2590.   }
  2591.   else
  2592.   {
  2593.     return( INotebook::center );
  2594.   }
  2595. #endif // IC_PMWIN
  2596. #ifdef IC_MOTIF
  2597.   if (fNotebookData->tabAlignment == XmALIGNMENT_END)
  2598.     return INotebook::right;
  2599.   else if (fNotebookData->tabAlignment == XmALIGNMENT_CENTER)
  2600.     return INotebook::center;
  2601.   else
  2602.     return INotebook::left;
  2603. #endif // IC_MOTIF
  2604. }
  2605.  
  2606.  
  2607. /*------------------------------------------------------------------------------
  2608. | INotebook::setMajorTabSize                                                   |
  2609. ------------------------------------------------------------------------------*/
  2610. INotebook& INotebook :: setMajorTabSize ( const ISize& sizeMajorTab )
  2611. {
  2612. #ifdef IC_PMWIN
  2613.   IMODTRACE_DEVELOP( "INotebook::setMajorTabSize" );
  2614.  
  2615.   if ( isPMCompatible() )
  2616.   {
  2617.     IEventResult
  2618.        retVal = sendEvent( BKM_SETDIMENSIONS,
  2619.                            MPFROM2SHORT(sizeMajorTab.width(),
  2620.                                         sizeMajorTab.height()),
  2621.                            BKA_MAJORTAB );
  2622.     if (retVal.asUnsignedLong() == false)
  2623.     {
  2624.       ITHROWGUIERROR("BKM_SETDIMENSIONS");
  2625.     }
  2626.   }
  2627. #ifdef IC_WIN
  2628.   else
  2629.   {
  2630.     unsigned long ulStyle = style();
  2631.     if ( !(ulStyle & TCS_FIXEDWIDTH) )
  2632.     {
  2633.       setStyle( ulStyle | TCS_FIXEDWIDTH );
  2634.     }
  2635.  
  2636.     if ( isDrawTabsEnabled() )
  2637.     {
  2638.       fNotebookData->lMajorTabHeight = sizeMajorTab.height();
  2639.       tabControlResize( size() );
  2640.     }
  2641.  
  2642.     sendEvent( TCM_SETITEMSIZE,
  2643.                0,
  2644.                MPFROM2SHORT(sizeMajorTab.width(),
  2645.                             sizeMajorTab.height()) );
  2646.  
  2647.     /**************************************************************************/
  2648.     /* Simulate a resizing event to force repainting of the client area       */
  2649.     /**************************************************************************/
  2650.     if ( !isDrawTabsEnabled() )
  2651.       parent()->sizeTo( parent()->size() );
  2652.   }
  2653. #endif //IC_WIN
  2654. #endif // IC_PMWIN
  2655. #ifdef IC_MOTIF
  2656.   fNotebookData->majorTabSize = sizeMajorTab;
  2657.   fNotebookData->refreshTabs();
  2658. #endif // IC_MOTIF
  2659.   return *this;
  2660. }
  2661.  
  2662.  
  2663. /*------------------------------------------------------------------------------
  2664. | INotebook::setMinorTabSize                                                   |
  2665. ------------------------------------------------------------------------------*/
  2666. INotebook& INotebook :: setMinorTabSize ( const ISize& sizeMinorTab )
  2667. {
  2668. #ifdef IC_PMWIN
  2669.   if ( isPMCompatible() )
  2670.   {
  2671.     IEventResult
  2672.        retVal = sendEvent( BKM_SETDIMENSIONS,
  2673.                            MPFROM2SHORT(sizeMinorTab.width(),
  2674.                                         sizeMinorTab.height()),
  2675.                            BKA_MINORTAB );
  2676.     if (retVal.asUnsignedLong() == false)
  2677.     {
  2678.       ITHROWGUIERROR("BKM_SETDIMENSIONS");
  2679.     }
  2680.   }
  2681. #endif // IC_PMWIN
  2682. #ifdef IC_MOTIF
  2683.   fNotebookData->minorTabSize = sizeMinorTab;
  2684.   fNotebookData->refreshTabs();
  2685. #endif
  2686.   return *this;
  2687. }
  2688.  
  2689.  
  2690. /*------------------------------------------------------------------------------
  2691. | INotebook::setPageButtonSize                                                 |
  2692. |                                                                              |
  2693. | Set the size of the arrow buttons used to turn the notebook's pages, in      |
  2694. | pixels.                                                                      |
  2695. ------------------------------------------------------------------------------*/
  2696. INotebook& INotebook :: setPageButtonSize ( const ISize& sizePageButton )
  2697. {
  2698.   ITRACE_MOTIF_NOP();
  2699.   ITRACE_WIN_NOP();
  2700.  
  2701. #ifdef IC_PMWIN
  2702.   if ( isPMCompatible() )
  2703.   {
  2704.     IEventResult
  2705.        retVal = sendEvent( BKM_SETDIMENSIONS,
  2706.                            MPFROM2SHORT(sizePageButton.width(),
  2707.                                         sizePageButton.height()),
  2708.                            BKA_PAGEBUTTON );
  2709.     if (retVal.asUnsignedLong() == false)
  2710.     {
  2711.       ITHROWGUIERROR("BKM_SETDIMENSIONS");
  2712.     }
  2713.   }
  2714. #endif // IC_PMWIN
  2715. #ifdef IC_MOTIF
  2716.   // Setting the height and width resources will be ignored by the Notebook
  2717.   // widget until a fix is made. Once that fix is made and this function
  2718.   // starts working, then...
  2719.   // This code will break if OSF changes the name of NextPageButton or
  2720.   // PrevPageButton. If this happens, this function will harmlessly return
  2721.   // with no action having been taken.
  2722.   // The widget names aren't really a documented interface, used editres
  2723.   // to find the names.
  2724.   Widget nextPageButton
  2725.                 = XtNameToWidget(fNotebookData->notebook, "NextPageButton");
  2726.   Widget prevPageButton
  2727.                 = XtNameToWidget(fNotebookData->notebook, "PrevPageButton");
  2728.  
  2729.   if (nextPageButton != 0)
  2730.     XtVaSetValues(nextPageButton,
  2731.                   XmNresizable, True,
  2732.                   XmNwidth, sizePageButton.width(),
  2733.                   XmNheight, sizePageButton.height(),
  2734.                   NULL);
  2735.  
  2736.   if (prevPageButton != 0)
  2737.     XtVaSetValues(prevPageButton,
  2738.                   XmNresizable, True,
  2739.                   XmNwidth, sizePageButton.width(),
  2740.                   XmNheight, sizePageButton.height(),
  2741.                   NULL);
  2742.  
  2743. #endif // IC_MOTIF
  2744.   return *this;
  2745. }
  2746.  
  2747.  
  2748. /*------------------------------------------------------------------------------
  2749. | INotebook::refreshTabs                                                       |
  2750. |                                                                              |
  2751. | Causes all tabs in the notebook to be invalidated (and thus repainted).      |
  2752. ------------------------------------------------------------------------------*/
  2753. INotebook& INotebook :: refreshTabs ( )
  2754. {
  2755. #ifdef IC_PMWIN
  2756.   if ( isPMCompatible() )
  2757.   {
  2758.     IEventResult
  2759.        retVal = sendEvent( BKM_INVALIDATETABS, 0, 0 );
  2760.     if (retVal.asUnsignedLong() == false)
  2761.     {
  2762.       ITHROWGUIERROR("BKM_INVALIDATETABS");
  2763.     }
  2764.   }
  2765. #ifdef IC_WIN
  2766.   else
  2767.   {
  2768.     RECT firstTab,
  2769.          lastTab,
  2770.          updateRect;
  2771.  
  2772.     if (( TabCtrl_GetItemRect( handle(), 0, &firstTab ) )  &&
  2773.         ( TabCtrl_GetItemRect( handle(), (totalPages() - 1), &lastTab ) ))
  2774.     {
  2775.       updateRect.left = firstTab.left;
  2776.       updateRect.top = firstTab.top;
  2777.       updateRect.right = lastTab.right;
  2778.       updateRect.bottom = lastTab.bottom;
  2779.  
  2780.       InvalidateRect( handle(), &updateRect, false );
  2781.     }
  2782.     else
  2783.     {
  2784.       ITHROWGUIERROR("TabCtrl_GetItemRect");
  2785.     }
  2786.   }
  2787. #endif //IC_WIN
  2788. #endif // IC_PMWIN
  2789. #ifdef IC_MOTIF
  2790.   fNotebookData->refreshTabs();
  2791. #endif
  2792.   return *this;
  2793. }
  2794.  
  2795. /*------------------------------------------------------------------------------
  2796. | WIN32 Color Support                                                          |
  2797. |                                                                              |
  2798. | Windows has no API equivalent for Presentation Parameters.  The following    |
  2799. | notebook color functions are NOPed for Windows.  The query functions return  |
  2800. | an appropriate default IColor object.                                        |
  2801. ------------------------------------------------------------------------------*/
  2802. /*------------------------------------------------------------------------------
  2803. | INoteBook::backgroundColor                                                   |
  2804. |                                                                              |
  2805. | Returns the background color of the notebook.                                |
  2806. ------------------------------------------------------------------------------*/
  2807. IColor INotebook::backgroundColor ( ) const
  2808. {
  2809. #ifdef IC_PM
  2810.   return (IWindow::color(PP_BACKGROUNDCOLOR,
  2811.                          IGUIColor(IGUIColor::defaultControl)));
  2812. #endif // IC_PM
  2813. #ifdef IC_WIN
  2814.   return IGUIColor( IGUIColor::defaultControl );
  2815. #endif //IC_WIN
  2816. #ifdef IC_MOTIF
  2817.   return Inherited::backgroundColor();
  2818. #endif
  2819. }
  2820.  
  2821. /*------------------------------------------------------------------------------
  2822. | INoteBook::hiliteBackgroundColor                                             |
  2823. |                                                                              |
  2824. | Returns the hilite background color of the notebook.                         |
  2825. ------------------------------------------------------------------------------*/
  2826. IColor INotebook::hiliteBackgroundColor ( ) const
  2827. {
  2828. #ifdef IC_PM
  2829.   return (IWindow::color(PP_HILITEBACKGROUNDCOLOR,
  2830.                          IGUIColor(IGUIColor::defaultButton)));
  2831. #endif //IC_PM
  2832. #ifdef IC_WIN
  2833.   return IGUIColor( IGUIColor::defaultButton );
  2834. #endif //IC_WIN
  2835. #ifdef IC_MOTIF
  2836.   return Inherited::hiliteBackgroundColor();
  2837. #endif
  2838. }
  2839.  
  2840. /*------------------------------------------------------------------------------
  2841. | INoteBook::pageBackgroundColor                                               |
  2842. |                                                                              |
  2843. | Returns the background page color of the notebook.                           |
  2844. ------------------------------------------------------------------------------*/
  2845. IColor INotebook::pageBackgroundColor ( ) const
  2846. {
  2847. #ifdef IC_PMWIN
  2848.   if ( isPMCompatible() )
  2849.   {
  2850.     /********************************************************************/
  2851.     /* If this color was set previously, retrieve it from where we saved*/
  2852.     /* it and return it.  Otherwise, if a color has not been previously */
  2853.     /* set, return the default.                                         */
  2854.     /********************************************************************/
  2855.     if (colorFlags & INotebook::bgnPageColor)
  2856.     {
  2857.       if (pnotebookColors)
  2858.       {
  2859.         return (UnsignedLongAsRGB(pnotebookColors->pageBackgroundColor));
  2860.       }
  2861.     }
  2862.   }
  2863.  
  2864.   return( IGUIColor(IGUIColor::notebookPageBgnd) );
  2865. #endif // IC_PMWIN
  2866. #ifdef IC_MOTIF
  2867.   return fNotebookData->getColor(pcaPageBackground);
  2868. #endif // IC_MOTIF
  2869. }
  2870.  
  2871. /*------------------------------------------------------------------------------
  2872. | INoteBook::majorTabBackgroundColor                                           |
  2873. |                                                                              |
  2874. | Returns the major tab background color.                                      |
  2875. ------------------------------------------------------------------------------*/
  2876. IColor INotebook::majorTabBackgroundColor ( ) const
  2877. {
  2878. #ifdef IC_PMWIN
  2879.   if ( isPMCompatible() )
  2880.   {
  2881.     /********************************************************************/
  2882.     /* If this color was set previously, retrieve it from where we saved*/
  2883.     /* it and return it.  Otherwise, if a color has not been previously */
  2884.     /* set, return the default.                                         */
  2885.     /********************************************************************/
  2886.     if (colorFlags & INotebook::bgnMajorColor)
  2887.     {
  2888.       if (pnotebookColors)
  2889.       {
  2890.         return (UnsignedLongAsRGB(pnotebookColors->majorTabBackgroundColor));
  2891.       }
  2892.     }
  2893.   }
  2894.  
  2895.   return( IGUIColor(IGUIColor::notebookPageBgnd) );
  2896. #endif // IC_PMWIN
  2897. #ifdef IC_MOTIF
  2898.   return fNotebookData->getColor(pcaMajorTabBackground);
  2899. #endif // IC_MOTIF
  2900. }
  2901.  
  2902. /*------------------------------------------------------------------------------
  2903. | INoteBook::minorTabBackgroundColor                                           |
  2904. |                                                                              |
  2905. | Returns the minor tab background color.                                      |
  2906. ------------------------------------------------------------------------------*/
  2907. IColor INotebook::minorTabBackgroundColor ( ) const
  2908. {
  2909.   ITRACE_WIN_NOP();
  2910.  
  2911. #ifdef IC_PMWIN
  2912.   if ( isPMCompatible() )
  2913.   {
  2914.     /********************************************************************/
  2915.     /* If this color was set previously, retrieve it from where we saved*/
  2916.     /* it and return it.  Otherwise, if a color has not been previously */
  2917.     /* set, return the default.                                         */
  2918.     /********************************************************************/
  2919.     if (colorFlags & INotebook::bgnMinorColor)
  2920.     {
  2921.       if (pnotebookColors)
  2922.       {
  2923.         return (UnsignedLongAsRGB(pnotebookColors->minorTabBackgroundColor));
  2924.       }
  2925.     }
  2926.   }
  2927.  
  2928.   return( IGUIColor(IGUIColor::notebookPageBgnd) );
  2929. #endif // IC_PMWIN
  2930. #ifdef IC_MOTIF
  2931.   return fNotebookData->getColor(pcaMinorTabBackground);
  2932. #endif // IC_MOTIF
  2933. }
  2934.  
  2935. /*------------------------------------------------------------------------------
  2936. | INoteBook::majorTabForegroundColor                                           |
  2937. |                                                                              |
  2938. | Returns the major tab foreground color.                                      |
  2939. ------------------------------------------------------------------------------*/
  2940. IColor INotebook::majorTabForegroundColor ( ) const
  2941. {
  2942. #ifdef IC_PMWIN
  2943.   if ( isPMCompatible() )
  2944.   {
  2945.     /********************************************************************/
  2946.     /* If this color was set previously, retrieve it from where we saved*/
  2947.     /* it and return it.  Otherwise, if a color has not been previously */
  2948.     /* set, return the default.                                         */
  2949.     /********************************************************************/
  2950.     if (colorFlags & INotebook::fgnMajorColor)
  2951.     {
  2952.       if (pnotebookColors)
  2953.       {
  2954.         return (UnsignedLongAsRGB(pnotebookColors->majorTabForegroundColor));
  2955.       }
  2956.     }
  2957.   }
  2958.  
  2959.   return( IGUIColor(IGUIColor::windowText) );
  2960. #endif // IC_PMWIN
  2961. #ifdef IC_MOTIF
  2962.   return fNotebookData->getColor(pcaMajorTabForeground);
  2963. #endif // IC_MOTIF
  2964. }
  2965.  
  2966. /*------------------------------------------------------------------------------
  2967. | INoteBook::minorTabForegroundColor                                           |
  2968. |                                                                              |
  2969. | Returns the minor tab foreground color.                                      |
  2970. ------------------------------------------------------------------------------*/
  2971. IColor INotebook::minorTabForegroundColor ( ) const
  2972. {
  2973. #ifdef IC_PMWIN
  2974.   if ( isPMCompatible() )
  2975.   {
  2976.     /********************************************************************/
  2977.     /* If this color was set previously, retrieve it from where we saved*/
  2978.     /* it and return it.  Otherwise, if a color has not been previously */
  2979.     /* set, return the default.                                         */
  2980.     /********************************************************************/
  2981.     if (colorFlags & INotebook::fgnMinorColor)
  2982.     {
  2983.       if (pnotebookColors)
  2984.       {
  2985.         return (UnsignedLongAsRGB(pnotebookColors->minorTabForegroundColor));
  2986.       }
  2987.     }
  2988.   }
  2989.  
  2990.   return IGUIColor(IGUIColor::windowText);
  2991. #endif // IC_PMWIN
  2992. #ifdef IC_MOTIF
  2993.   return fNotebookData->getColor(pcaMinorTabForeground);
  2994. #endif // IC_MOTIF
  2995. }
  2996.  
  2997. #ifdef IC_MOTIF
  2998. /*------------------------------------------------------------------------------
  2999. | INotebook::setBackgroundColor                                                |
  3000. |                                                                              |
  3001. ------------------------------------------------------------------------------*/
  3002. INotebook& INotebook :: setBackgroundColor (const IColor& color )
  3003. {
  3004.   // the inherited setForegroundColor calls setColor, so the code
  3005.   // to set color of binding can be moved to setColor.
  3006.   Inherited::setBackgroundColor(color);
  3007.  
  3008.   return *this;
  3009. }
  3010.  
  3011. /*------------------------------------------------------------------------------
  3012. | INotebook::setForegroundColor                                                |
  3013. |                                                                              |
  3014. ------------------------------------------------------------------------------*/
  3015. INotebook& INotebook :: setForegroundColor (const IColor& color )
  3016. {
  3017.   // the inherited setForegroundColor calls setColor, so the code
  3018.   // to set color of binding can be moved to setColor.
  3019.   Inherited::setForegroundColor(color);
  3020.  
  3021.   return *this;
  3022. }
  3023.  
  3024. /*------------------------------------------------------------------------------
  3025. | INotebook::setColor                                                          |
  3026. |                                                                              |
  3027. | setColor is used for propagating colors down to children. Calling the        |
  3028. | inherited version will assure that the colors are inherited by children.
  3029. ------------------------------------------------------------------------------*/
  3030. INotebook& INotebook :: setColor (unsigned long colorArea,
  3031.                                   const IColor& color )
  3032. {
  3033.   Inherited::setColor(colorArea, color);
  3034.   // update color of spiral binding pixmap
  3035.   if ( (colorArea == PP_FOREGROUNDCOLOR) ||
  3036.        (colorArea == PP_BACKGROUNDCOLOR) )
  3037.   {
  3038.     if (binding() == spiral)
  3039.       setBinding(spiral);
  3040.   }
  3041.  
  3042.   return *this;
  3043. }
  3044.  
  3045. #endif
  3046.  
  3047. /*------------------------------------------------------------------------------
  3048. | INoteBook::setPageBackgroundColor                                            |
  3049. |                                                                              |
  3050. | Sets the page background color in a notebook.                                |
  3051. ------------------------------------------------------------------------------*/
  3052. INotebook& INotebook::setPageBackgroundColor ( const IColor &color )
  3053. {
  3054.   ITRACE_WIN_NOP();
  3055.  
  3056. #ifdef IC_PMWIN
  3057.   if ( isPMCompatible() )
  3058.   {
  3059.     setNotebookColors (color.asRGBLong(), BKA_BACKGROUNDPAGECOLOR);
  3060.   }
  3061.  
  3062. #endif // IC_PMWIN
  3063. #ifdef IC_MOTIF
  3064.  fNotebookData->setColor(pcaPageBackground, color.index());
  3065. #endif
  3066.   return *this;
  3067. }
  3068.  
  3069. /*------------------------------------------------------------------------------
  3070. | INoteBook::setMajorTabBackgroundColor                                        |
  3071. |                                                                              |
  3072. | Sets the major tab background color.                                         |
  3073. ------------------------------------------------------------------------------*/
  3074. INotebook& INotebook::setMajorTabBackgroundColor ( const IColor &color )
  3075. {
  3076.   ITRACE_WIN_NOP();
  3077.  
  3078. #ifdef IC_PMWIN
  3079.   if ( isPMCompatible() )
  3080.   {
  3081.     setNotebookColors (color.asRGBLong(), BKA_BACKGROUNDMAJORCOLOR);
  3082.   }
  3083. #endif // IC_PMWIN
  3084. #ifdef IC_MOTIF
  3085.   fNotebookData->setColor(pcaMajorTabBackground, color.index());
  3086. #endif // IC_MOTIF
  3087.  
  3088.   return *this;
  3089. }
  3090.  
  3091. /*------------------------------------------------------------------------------
  3092. | INoteBook::setMinorTabBackgroundColor                                        |
  3093. |                                                                              |
  3094. | Sets the minor tab background color.                                         |
  3095. ------------------------------------------------------------------------------*/
  3096. INotebook& INotebook::setMinorTabBackgroundColor ( const IColor &color )
  3097. {
  3098.   ITRACE_WIN_NOP();
  3099.  
  3100. #ifdef IC_PMWIN
  3101.   if ( isPMCompatible() )
  3102.   {
  3103.     setNotebookColors (color.asRGBLong(), BKA_BACKGROUNDMINORCOLOR);
  3104.   }
  3105.  
  3106.   /********************************************************************/
  3107.   /* Windows tab control has no concept of minor tabs.  Therefore,    */
  3108.   /* this function is a no-op.                                        */
  3109.   /********************************************************************/
  3110. #endif // IC_PMWIN
  3111. #ifdef IC_MOTIF
  3112.   fNotebookData->setColor(pcaMinorTabBackground, color.index());
  3113. #endif // IC_MOTIF
  3114.   return *this;
  3115. }
  3116.  
  3117. /*------------------------------------------------------------------------------
  3118. | INoteBook::setMajorTabForegroundColor                                        |
  3119. |                                                                              |
  3120. | Sets the major tab foreground color.                                         |
  3121. ------------------------------------------------------------------------------*/
  3122. INotebook& INotebook::setMajorTabForegroundColor ( const IColor &color )
  3123. {
  3124.   ITRACE_WIN_NOP();
  3125.  
  3126. #ifdef IC_PMWIN
  3127.   if ( isPMCompatible() )
  3128.   {
  3129.     setNotebookColors (color.asRGBLong(), BKA_FOREGROUNDMAJORCOLOR);
  3130.   }
  3131. #endif // IC_PMWIN
  3132. #ifdef IC_MOTIF
  3133.   fNotebookData->setColor(pcaMajorTabForeground, color.index());
  3134. #endif // IC_MOTIF
  3135.   return *this;
  3136. }
  3137.  
  3138. /*------------------------------------------------------------------------------
  3139. | INoteBook::setMinorTabForegroundColor                                        |
  3140. |                                                                              |
  3141. | Sets the minor tab foreground color.                                         |
  3142. ------------------------------------------------------------------------------*/
  3143. INotebook& INotebook::setMinorTabForegroundColor ( const IColor &color )
  3144. {
  3145.   ITRACE_WIN_NOP();
  3146.  
  3147. #ifdef IC_PMWIN
  3148.   if ( isPMCompatible() )
  3149.   {
  3150.     setNotebookColors (color.asRGBLong(), BKA_FOREGROUNDMINORCOLOR);
  3151.   }
  3152.  
  3153.   /********************************************************************/
  3154.   /* Windows tab control has no concept of minor tabs.  Therefore,    */
  3155.   /* this function is a no-op.                                        */
  3156.   /********************************************************************/
  3157. #endif // IC_PMWIN
  3158. #ifdef IC_MOTIF
  3159.   fNotebookData->setColor(pcaMinorTabForeground, color.index());
  3160. #endif // IC_MOTIF
  3161.   return *this;
  3162. }
  3163.  
  3164. /*------------------------------------------------------------------------------
  3165. | INoteBook::resetPageBackgroundColor                                          |
  3166. |                                                                              |
  3167. | Resets the page background color by undoing a previous set.                  |
  3168. ------------------------------------------------------------------------------*/
  3169. INotebook& INotebook::resetPageBackgroundColor ( )
  3170. {
  3171.   ITRACE_MOTIF_NOP();
  3172.   ITRACE_WIN_NOP();
  3173.  
  3174. #ifdef IC_PMWIN
  3175.   colorFlags &= ~bgnPageColor;
  3176. #endif // IC_PMWIN
  3177.   return *this;
  3178. }
  3179.  
  3180. /*------------------------------------------------------------------------------
  3181. | INoteBook::resetMajorTabBackgroundColor                                      |
  3182. |                                                                              |
  3183. | Resets the major tab background color by undoing a previous set.             |
  3184. ------------------------------------------------------------------------------*/
  3185. INotebook& INotebook::resetMajorTabBackgroundColor ( )
  3186. {
  3187.   ITRACE_MOTIF_NOP();
  3188.   ITRACE_WIN_NOP();
  3189.  
  3190. #ifdef IC_PMWIN
  3191.   colorFlags &= ~bgnMajorColor;
  3192. #endif // IC_PMWIN
  3193.   return *this;
  3194. }
  3195.  
  3196. /*------------------------------------------------------------------------------
  3197. | INoteBook::resetMinorTabBackgroundColor                                      |
  3198. |                                                                              |
  3199. | Resets the minor tab background color by undoing a previous set.             |
  3200. ------------------------------------------------------------------------------*/
  3201. INotebook& INotebook::resetMinorTabBackgroundColor ( )
  3202. {
  3203.   ITRACE_MOTIF_NOP();
  3204.   ITRACE_WIN_NOP();
  3205.  
  3206. #ifdef IC_PMWIN
  3207.   colorFlags &= ~bgnMinorColor;
  3208. #endif // IC_PMWIN
  3209.   return *this;
  3210. }
  3211.  
  3212. /*------------------------------------------------------------------------------
  3213. | INoteBook::resetMajorTabForegroundColor                                      |
  3214. |                                                                              |
  3215. | Resets the major tab foreground color by undoing a previous set.             |
  3216. ------------------------------------------------------------------------------*/
  3217. INotebook& INotebook::resetMajorTabForegroundColor ( )
  3218. {
  3219.   ITRACE_MOTIF_NOP();
  3220.   ITRACE_WIN_NOP();
  3221.  
  3222. #ifdef IC_PMWIN
  3223.   colorFlags &= ~fgnMajorColor;
  3224. #endif // IC_PMWIN
  3225.   return *this;
  3226. }
  3227.  
  3228. /*------------------------------------------------------------------------------
  3229. | INoteBook::resetMinorTabForegroundColor                                      |
  3230. |                                                                              |
  3231. | Resets the minor tab foreground color by undoing a previous set.             |
  3232. ------------------------------------------------------------------------------*/
  3233. INotebook& INotebook::resetMinorTabForegroundColor ( )
  3234. {
  3235.   ITRACE_MOTIF_NOP();
  3236.   ITRACE_WIN_NOP();
  3237.  
  3238. #ifdef IC_PMWIN
  3239.   colorFlags &= ~fgnMinorColor;
  3240. #endif // IC_PMWIN
  3241.   return *this;
  3242. }
  3243.  
  3244. #ifdef IC_MOTIF
  3245. /*------------------------------------------------------------------------------
  3246. | INotebook::setFont                                                           |
  3247. |                                                                              |
  3248. | Sets the font for the notebook.                                              |
  3249. ------------------------------------------------------------------------------*/
  3250. INotebook& INotebook::setFont ( const IFont& fm )
  3251. {
  3252.   // cache X Windows Logical Font Descriptor (XLFD) string
  3253.   fNotebookData->xlfdString = fm.qualifiedName();
  3254.   Inherited::setFont( fm );
  3255.   return *this;
  3256. }
  3257.  
  3258. /*------------------------------------------------------------------------------
  3259. | INotebook::font                                                              |
  3260. |                                                                              |
  3261. | Returns the font used for the notebook.                                      |
  3262. ------------------------------------------------------------------------------*/
  3263. IFont INotebook::font () const
  3264. {
  3265.   if (fNotebookData->xlfdString.length() > 0)
  3266.     // construct font based on cached XLFD string
  3267.     return IFont(fNotebookData->xlfdString);
  3268.   else
  3269.     return Inherited::font();
  3270. }
  3271. #endif //IC_MOTIF
  3272.  
  3273.  
  3274. /*------------------------------------------------------------------------------
  3275. | INoteBook::areAllTabsVisible                                                 |
  3276. |                                                                              |
  3277. | Returns true if multiple rows of tabs can be displayed on the tab control.   |
  3278. ------------------------------------------------------------------------------*/
  3279. bool INotebook::areAllTabsVisible ( ) const
  3280. {
  3281.   ITRACE_MOTIF_NOP();
  3282.   ITRACE_PM_NOP();
  3283.  
  3284. #ifdef IC_WIN
  3285.   if ( !isPMCompatible() )
  3286.   {
  3287.     return( (style() & TCS_MULTILINE) ? true : false );
  3288.   }
  3289.   else
  3290. #endif
  3291.   {
  3292.     return( false );
  3293.   }
  3294. }
  3295.  
  3296. /*------------------------------------------------------------------------------
  3297. | INoteBook::isDrawTabsEnabled                                                 |
  3298. |                                                                              |
  3299. | Returns true if owner draw tabs style is specified.                          |
  3300. ------------------------------------------------------------------------------*/
  3301. bool INotebook::isDrawTabsEnabled ( ) const
  3302. {
  3303. #ifdef IC_WIN
  3304.   if ( !isPMCompatible() )
  3305.   {
  3306.     return( (style() & TCS_OWNERDRAWFIXED) ? true : false );
  3307.   }
  3308.   else
  3309. #endif
  3310.   {
  3311.     return( false );
  3312.   }
  3313. }
  3314.  
  3315.  
  3316. /*------------------------------------------------------------------------------
  3317. | INoteBook::isPMCompatible                                                    |
  3318. |                                                                              |
  3319. | Returns true if the notebook is displayed as the CUA '91 notebook.           |
  3320. ------------------------------------------------------------------------------*/
  3321. bool INotebook::isPMCompatible ( ) const
  3322. {
  3323.   ITRACE_MOTIF_NOP();
  3324.  
  3325. #ifdef IC_MOTIFPM
  3326.   return( true );
  3327. #else
  3328.   return( (extendedStyle() &
  3329.            pmCompatible.asExtendedUnsignedLong()) ? true : false );
  3330. #endif
  3331. }
  3332.  
  3333. //
  3334. // PageSettings and Cursor classes now implemented in inotebk0.cpp
  3335. //
  3336.  
  3337. #ifdef IC_PMWIN
  3338. /*------------------------------------------------------------------------------
  3339. | INotebook::insertPageInfo                                                    |
  3340. |                                                                              |
  3341. | Set the values in the PageSettings into the notebook.                        |
  3342. ------------------------------------------------------------------------------*/
  3343. IPageHandle INotebook :: insertPageInfo ( const PageSettings& pageInfo,
  3344.                                           const IPageHandle&  referencePage,
  3345.                                           IWindow*            window,
  3346.                                           unsigned long       fPosition )
  3347. {
  3348.   IMODTRACE_DEVELOP( "INotebook::insertPageInfo" );
  3349.  
  3350.   IPageHandle pageHandle( 0 );
  3351. #ifdef IC_WIN
  3352.   if ( isPMCompatible() )
  3353.   {
  3354.     /**************************************************************************/
  3355.     /* Insert page in the CUA '91 notebook.                                   */
  3356.     /**************************************************************************/
  3357.     pageHandle =
  3358.         (void*)insertPage( MPFROMLONG( ((void*)referencePage) ),
  3359.                     MPFROM2SHORT( (USHORT)pageInfo.pageStyle.asUnsignedLong(),
  3360.                                   fPosition) );
  3361.   }
  3362.   else
  3363.   {
  3364.     /**************************************************************************/
  3365.     /* Handle the tab control page in a separate function to increase         */
  3366.     /* readability/maintainability of the code.                               */
  3367.     /**************************************************************************/
  3368.     return( insertPageInfo2( pageInfo, referencePage, window, fPosition ) );
  3369.   }
  3370. #else
  3371.   pageHandle =
  3372.         insertPage( MPFROMLONG( referencePage ),
  3373.                     MPFROM2SHORT( (USHORT)pageInfo.pageStyle.asUnsignedLong(),
  3374.                                   fPosition) );
  3375. #endif
  3376.  
  3377.   if (window && pageHandle)
  3378.   {
  3379.     IRectangle pageRect;
  3380.  
  3381.     /**************************************************************************/
  3382.     /* If the page window is a frame, we need to set the owner to NULL.  The  */
  3383.     /* notebook will set the parent to the page window (id 8006) and then we  */
  3384.     /* can set the owner to the notebook.  (We cannot set the owner to the    */
  3385.     /* notebook initially because this might cause the frame to have the same */
  3386.     /* parent and owner and cause problems).  If the owner of the frame is    */
  3387.     /* not the notebook, a focus loop problem will occur.                     */
  3388.     /**************************************************************************/
  3389. #ifndef IC_WIN
  3390.     if ( window->isFrameWindow() )
  3391.       window->setOwner( NULL );
  3392. #endif
  3393.  
  3394.     /**************************************************************************/
  3395.     /* save the page window rect                                              */
  3396.     /**************************************************************************/
  3397.     if ( pageInfo.isAutoSize() )
  3398.       pageRect = window->rect();
  3399.  
  3400.     /**************************************************************************/
  3401.     /* Set (associate) the application page window with the notebook page     */
  3402.     /**************************************************************************/
  3403.     IEventResult
  3404.       retVal = sendEvent( BKM_SETPAGEWINDOWHWND,
  3405. #ifdef IC_WIN
  3406.                           (unsigned long)(void*)pageHandle,
  3407.                           (unsigned long)(void*)(window->handle()) );
  3408. #else
  3409.                           (unsigned long)pageHandle,
  3410.                           (unsigned long)window->handle() );
  3411. #endif
  3412.  
  3413.     if (retVal.asUnsignedLong() == false)
  3414.     {
  3415.       ITHROWGUIERROR("BKM_SETPAGEWINDOWHWND");
  3416.     }
  3417.     else
  3418.     {
  3419.       /************************************************************************/
  3420.       /* restore the page window size                                         */
  3421.       /************************************************************************/
  3422.       if ( pageInfo.isAutoSize() )
  3423.         window->sizeTo( ISize( pageRect.width(), pageRect.height() ));
  3424.  
  3425.       /************************************************************************/
  3426.       /* If there is no owner for the page, set it to the notebook.           */
  3427.       /************************************************************************/
  3428. #ifdef IC_PM
  3429.       if ( window->owner() == NULL )
  3430.         window->setOwner( this );
  3431.  
  3432.       // Add the page window resize handler for PM.  Only add it if this page
  3433.       // window is not already a page window for another page.
  3434.       Cursor cursor( *this );
  3435.       bool isHandled = false;
  3436.       for (cursor.setToFirst();
  3437.            cursor.isValid() && !isHandled;
  3438.            cursor.setToNext())
  3439.       {
  3440.          IPageHandle currentHandle = cursor.current();
  3441.          if (currentHandle != pageHandle &&
  3442.              this->window( currentHandle ) == window)
  3443.             isHandled = true;
  3444.       }
  3445.       if (!isHandled)
  3446.          fNotebookData->fPageResizeHandler.handleEventsFor( window );
  3447. #endif // IC_PM
  3448.     }
  3449.   }
  3450.  
  3451.   if (pageHandle)
  3452.   {
  3453.     if (pageInfo.savedStatusText.size() != 0)
  3454.       setStatusText(pageHandle, pageInfo.savedStatusText);
  3455.  
  3456.     if (pageInfo.savedTabText.size() != 0)
  3457.       setTabText(pageHandle, pageInfo.savedTabText);
  3458.  
  3459.     if (pageInfo.savedTabBitmap != 0)
  3460.       setTabBitmap(pageHandle, pageInfo.savedTabBitmap);
  3461.  
  3462.     setUserData(pageHandle, pageInfo.savedUserData);
  3463.   }
  3464.   return pageHandle;
  3465. }
  3466. #endif // IC_PMWIN
  3467.  
  3468. #ifdef IC_WIN
  3469. /*------------------------------------------------------------------------------
  3470. | INotebook::insertPageInfo2                                                   |
  3471. |                                                                              |
  3472. | Set the values in the PageSettings into the notebook.                        |
  3473. ------------------------------------------------------------------------------*/
  3474. IPageHandle INotebook :: insertPageInfo2 ( const PageSettings& pageInfo,
  3475.                                            const IPageHandle&  referencePage,
  3476.                                            IWindow*            window,
  3477.                                            unsigned long       fPosition )
  3478. {
  3479.   IMODTRACE_DEVELOP( "INotebook::insertPageInfo2" );
  3480.  
  3481.   /****************************************************************************/
  3482.   /* Update the page styles so we can store them in our extended tab control  */
  3483.   /* item.                                                                    */
  3484.   /****************************************************************************/
  3485.   if ( pageInfo.isAutoSize() )
  3486.   {
  3487.     pageInfo.fPageSettingsData->tabCtrlItem.ulPageStyle |=
  3488.                                    PageSettings::autoPageSize.asUnsignedLong();
  3489.   }
  3490.   else
  3491.   {
  3492.     pageInfo.fPageSettingsData->tabCtrlItem.ulPageStyle &=
  3493.                                   ~PageSettings::autoPageSize.asUnsignedLong();
  3494.   }
  3495.  
  3496.   /****************************************************************************/
  3497.   /* Add the application page window handle and its parent's handle to our    */
  3498.   /* extended tab control item, as well as any application user-defined data  */
  3499.   /* to our extended tab control item.                                        */
  3500.   /****************************************************************************/
  3501.   if (window)
  3502.   {
  3503.     pageInfo.fPageSettingsData->tabCtrlItem.hPageWindow = window->handle();
  3504.     pageInfo.fPageSettingsData->tabCtrlItem.hPageWindowParent =
  3505.         ( window->parent() ? window->parent()->handle() : IWindowHandle(0) );
  3506.   }
  3507.   else
  3508.   {
  3509.     pageInfo.fPageSettingsData->tabCtrlItem.hPageWindow = 0;
  3510.     pageInfo.fPageSettingsData->tabCtrlItem.hPageWindowParent = 0;
  3511.   }
  3512.   pageInfo.fPageSettingsData->tabCtrlItem.ulUserData = pageInfo.userData();
  3513.  
  3514.   /****************************************************************************/
  3515.   /* Insert the tab page into the tab control, and associate the application  */
  3516.   /* page window to it if one is supplied.                                    */
  3517.   /****************************************************************************/
  3518.   IPageHandle
  3519.     pageHandle = insertTabPage( pageInfo, referencePage, fPosition );
  3520.  
  3521.   /****************************************************************************/
  3522.   /* If we have an application page window and if the tab page was inserted   */
  3523.   /* successfully then do the following:                                      */
  3524.   /****************************************************************************/
  3525.   if (window && pageHandle)
  3526.   {
  3527.     IRectangle pageRect;
  3528.  
  3529.     /**************************************************************************/
  3530.     /* Make the page clipping window the parent of the application page       */
  3531.     /* window.                                                                */
  3532.     /**************************************************************************/
  3533.     window->setParent( pageClippingWindow() );
  3534.  
  3535.     /**************************************************************************/
  3536.     /* Simulate CUA notebook's processing of the addition of the first page   */
  3537.     /* in the notebook.                                                       */
  3538.     /**************************************************************************/
  3539.     if ( pageHandle.asUnsigned() == 1 )
  3540.     {
  3541.       PAGESELECTNOTIFY pageSelectNotify;
  3542.       pageSelectNotify.hwndBook = handle();
  3543.       pageSelectNotify.ulPageIdNew = 1;
  3544.       pageSelectNotify.ulPageIdCur = 1;
  3545.  
  3546.       /************************************************************************/
  3547.       /* Set tab selection on the first tab in the tab control.               */
  3548.       /************************************************************************/
  3549.       processTabSelect( &pageSelectNotify, false );
  3550.     }
  3551.     else
  3552.       window->hide();
  3553.   }
  3554.  
  3555.   if (pageHandle)
  3556.   {
  3557.     if (pageInfo.savedTabBitmap != 0)
  3558.       setTabBitmap(pageHandle, pageInfo.savedTabBitmap);
  3559.   }
  3560.  
  3561.   return( pageHandle );
  3562. }
  3563. #endif
  3564.  
  3565. #ifdef IC_MOTIF
  3566. /*------------------------------------------------------------------------------
  3567. | INotebook :: addPageAt                                                       |
  3568. |                                                                              |
  3569. | private member function for actually doing the add of a page                 |
  3570. ------------------------------------------------------------------------------*/
  3571. IPageHandle INotebook :: addPageAt( int                 pageNumber,
  3572.                                     const PageSettings& settings,
  3573.                                     IWindow*            newPage,
  3574.                                     bool                replacePage )
  3575. {
  3576.   IPageHandle page( 0 );
  3577.  
  3578.   // Adjust the page numbers if needed then add the page
  3579.   int firstPage, lastPage;
  3580.   XtVaGetValues(fNotebookData->notebook,
  3581.                 XmNfirstPageNumber, &firstPage,
  3582.                 XmNlastPageNumber, &lastPage,
  3583.                 NULL);
  3584.  
  3585.   // If called from addAsLast, the page number will be 0.
  3586.   // Set it to the correct value.
  3587.   if (pageNumber == 0)
  3588.      pageNumber = lastPage + 1;
  3589.  
  3590.   XmNotebookPageInfo pageInfo;
  3591.   XmNotebookPageStatus pageStatus;
  3592.   pageStatus = XmNotebookGetPageInfo(
  3593.                         fNotebookData->notebook, pageNumber, &pageInfo);
  3594.  
  3595.   switch (pageStatus) {
  3596.     case XmPAGE_FOUND:
  3597.       fNotebookData->adjustPages(pageNumber, lastPage, 1);
  3598.  
  3599.       // Create a unique page handle for this new page.
  3600.       page = IPageHandle( fNotebookData->fNextPageHandle++ );
  3601.       fNotebookData->fPageSequence->addAtPosition( pageNumber, page );
  3602.       break;
  3603.     case XmPAGE_INVALID:
  3604.       if (pageNumber = lastPage + 1)
  3605.       {
  3606.         // Create a unique page handle for this new page.
  3607.         page = IPageHandle( fNotebookData->fNextPageHandle++ );
  3608.         fNotebookData->fPageSequence->addAsLast( page );
  3609.       }
  3610.       else
  3611.         ITHROWGUIERROR(IString("Tried to add notebook page ") +
  3612.                        IString(pageNumber) +
  3613.                        IString(" with lastPage ") +
  3614.                        IString(lastPage) );
  3615.       break;
  3616.     case XmPAGE_EMPTY:
  3617.       // If we are replacing a page (ie, called from setWindow) then we should
  3618.       // use the existing page handle; otherwise, create a unique page handle for
  3619.       // the new page.
  3620.       if (replacePage)
  3621.          page = fNotebookData->fPageSequence->elementAtPosition( pageNumber );
  3622.       else
  3623.       {
  3624.          fNotebookData->adjustPages( pageNumber, lastPage, 1 );
  3625.          page = IPageHandle( fNotebookData->fNextPageHandle++ );
  3626.          fNotebookData->fPageSequence->addAtPosition( pageNumber, page );
  3627.       }
  3628.       break;
  3629.     case XmPAGE_DUPLICATED:
  3630.       ITHROWGUIERROR("Duplicate pages found in INotebook");
  3631.       break;
  3632.     default:
  3633.       ITHROWGUIERROR("Unexpected pageStatus from XmNotebookGetPageInfo");
  3634.   }  // end switch
  3635.  
  3636.   // Used on XtSetArg calls below
  3637.   Arg args[20];
  3638.   int n;
  3639.  
  3640.   if (newPage != 0) {
  3641.      if (newPage->size() != ISize() || settings.isAutoSize())
  3642.      {
  3643.         // Make sure the page window is managed at this point.  We'll let the
  3644.         // notebook widget handle it from herein.
  3645.         XtManageChild( newPage->handle() );
  3646.      }
  3647.  
  3648.     n = 0;
  3649.     XtSetArg(args[n], XmNpageNumber, pageNumber); n++;
  3650.     XtSetArg(args[n], XmNnotebookChildType, XmPAGE); n++;
  3651.  
  3652.     // Note that the notebook widget's handling of resizable children was
  3653.     // not what we wanted for autoPageSize page windows.  The resizable resource
  3654.     // indicates whether size requests from the child widget should be honored.
  3655.     // The notebook widget has been modified to allow a different usage of the
  3656.     // resizable constraint resource for XmPAGE children.  If the resizable
  3657.     // resource is set to True for XmPAGE children, the page window will be
  3658.     // auto sized.  If this resource is set to False for XmPAGE children, the
  3659.     // page window will still be allowed to resize; it won't, however, be auto
  3660.     // sized by the notebook widget.
  3661.     XtSetArg(args[n], XmNresizable, settings.isAutoSize() ? True : False); n++;
  3662.  
  3663.     if(fNotebookData->colorSet[pcaPageBackground]) {
  3664.       IXmColor::setBackgroundColor( newPage->handle(),
  3665.                                     fNotebookData->curColor[pcaPageBackground]);
  3666.     }
  3667.     XtSetValues(newPage->handle(), args, n);
  3668.   }
  3669.  
  3670.   // Create status
  3671.   // The notebook widget can't properly calculate its height
  3672.   // before it is shown if there's no statusText.
  3673.   // It doesn't create the pageScroller until it's shown, so
  3674.   // its NewPreferredGeometry will return a height that lacks the
  3675.   // height of the pageScroller.
  3676.   // So to get around this we always create a status text LabelWidget
  3677.   // Note: at one point we tried using a LabelGadget. This caused a
  3678.   // segmentation violation when we called XtCreateManagedWidget when
  3679.   // we created the same notebook a second time in the same app.
  3680.  
  3681.   n = 0;
  3682.   XtSetArg(args[n], XmNnotebookChildType, XmSTATUS_AREA); n++;
  3683.   XtSetArg(args[n], XmNpageNumber, pageNumber); n++;
  3684.   XtSetArg(args[n], XmNalignment, fNotebookData->statusAlignment); n++;
  3685.   IString statusText;
  3686.   IMString imStatusText;
  3687.   if (settings.isStatusTextOn())
  3688.     statusText = settings.statusText();
  3689.   if ( statusText.size() != 0 ) {
  3690.     imStatusText += statusText;
  3691.     XtSetArg( args[n], XmNlabelString, (XmString)imStatusText ); n++;
  3692.   }
  3693.  
  3694.   // Create a page data structure to save the user data and auto size preference.
  3695.   // We don't always create the page window when the page is added and this
  3696.   // information must be available when the page window is set later.
  3697.   // It is necessary to store this with the status text since it is the only
  3698.   // widget associated with the page that is created unconditionally.
  3699.   PageData *pageData = new PageData;
  3700.   pageData->userData = settings.userData() ? settings.userData() : 0;
  3701.   pageData->pageHandle = page;
  3702.   pageData->isAutoSize = settings.isAutoSize() ? true : false;
  3703.   XtSetArg( args[n], XmNuserData, pageData ); n++;
  3704.  
  3705.   Widget theStatusArea = XtCreateManagedWidget("IC_NB_STATUS",
  3706.                                                xmLabelWidgetClass,
  3707.                                                fNotebookData->notebook, args,n);
  3708.   //
  3709.   // If we did not set the status text, check to see if the text was set
  3710.   // from a resource file.  If not, set to blank.
  3711.   //
  3712.   if ( statusText.size() == 0 ) { // We did not set the text.
  3713.     IXmLabel::initializeXmLabelString( theStatusArea, IString("IC_NB_STATUS") );
  3714.   }
  3715.  
  3716.   // Create tab
  3717.   Widget theTab = 0;
  3718.   if ((settings.isMajorTab()) || (settings.isMinorTab())) {
  3719.     n = 0;
  3720.     IString label = settings.tabText();
  3721.     // Strip any PM accelerator that we can't support
  3722.     IXmLabel::removeMnemonic( label );
  3723.     IMString labelString;
  3724.  
  3725.     // Set up label string or pixmap
  3726.     if (label.size() != 0) {      // use a string
  3727.       labelString += label;
  3728.       XtSetArg(args[n], XmNlabelType, XmSTRING); n++;
  3729.       XtSetArg(args[n], XmNlabelString, (XmString)labelString); n++;
  3730.       XtSetArg(args[n], XmNalignment, fNotebookData->tabAlignment); n++;
  3731.     }
  3732.     else if (settings.tabBitmap() != 0) {     // use a Pixmap
  3733.       XtSetArg(args[n], XmNlabelType, XmPIXMAP); n++;
  3734.       XtSetArg(args[n], XmNlabelPixmap, settings.tabBitmap()); n++;
  3735.     }
  3736.  
  3737.     // Set tab type and pageNumber
  3738.     unsigned char tabType =
  3739.       (settings.isMajorTab()) ?
  3740.       (unsigned char)XmMAJOR_TAB : (unsigned char)XmMINOR_TAB;
  3741.     XtSetArg(args[n], XmNnotebookChildType, tabType); n++;
  3742.     XtSetArg(args[n], XmNpageNumber, pageNumber); n++;
  3743.  
  3744.     // Set size
  3745.     Dimension tabWidth = fNotebookData->minorTabSize.width();
  3746.     Dimension tabHeight = fNotebookData->minorTabSize.height();
  3747.     if (tabType == XmMAJOR_TAB) {
  3748.       tabWidth = fNotebookData->majorTabSize.width();
  3749.       tabHeight = fNotebookData->majorTabSize.height();
  3750.     }
  3751.     if ( tabWidth && tabHeight ) {
  3752.       XtSetArg(args[n],XmNresizable, True); n++;
  3753.       XtSetArg(args[n],XmNwidth, tabWidth); n++;
  3754.       XtSetArg(args[n],XmNheight, tabHeight); n++;
  3755.     }
  3756.     //
  3757.     // Set foreground color only if background is not going to be set.
  3758.     //
  3759.     PrivateColorArea bgColorArea = pcaMinorTabBackground;
  3760.     PrivateColorArea fgColorArea = pcaMinorTabForeground;
  3761.     if (tabType == XmMAJOR_TAB) {
  3762.       bgColorArea = pcaMajorTabBackground;
  3763.       fgColorArea = pcaMajorTabForeground;
  3764.     }
  3765.     if ( !fNotebookData->colorSet[bgColorArea]
  3766.       &&  fNotebookData->colorSet[fgColorArea] ) {
  3767.       XtSetArg(args[n], XmNforeground, fNotebookData->curColor[fgColorArea]);
  3768.       n++;
  3769.     }
  3770.  
  3771.     // Create the tab widget.
  3772.     theTab = XtCreateManagedWidget("IC_NB_TAB",
  3773.                                    xmPushButtonWidgetClass,
  3774.                                    fNotebookData->notebook,
  3775.                                    args, n);
  3776.     //
  3777.     // Set background and foreground colors
  3778.     // Do this after it is created, so XmChangeColor can be used to
  3779.     // adjust the shadow colors.
  3780.     //
  3781.     if (fNotebookData->colorSet[bgColorArea]) {
  3782.       if (fNotebookData->colorSet[fgColorArea]) {
  3783.         IXmColor::setColor( theTab,
  3784.                             true,
  3785.                             fNotebookData->curColor[bgColorArea],
  3786.                             fNotebookData->curColor[fgColorArea] ); // Slightly faster.
  3787.       }
  3788.       else {
  3789.         IXmColor::setBackgroundColor( theTab,
  3790.                                       fNotebookData->curColor[bgColorArea] );
  3791.       }
  3792.     }
  3793.     //
  3794.     // If we did not set the tab text, check to see if the text was set
  3795.     // from a resource file.  If so, remove mnemonic.  If not, set to blank.
  3796.     //
  3797.     if ( label.size() == 0 ) { // We did not set the text.
  3798.       IXmLabel::initializeXmLabelString( theTab, IString("IC_NB_TAB"), true );
  3799.     }
  3800.   }
  3801.  
  3802.   // Set the font of the status and tab widgets if we previously stored a font
  3803.   // for the widget.
  3804.   if (fNotebookData->xlfdString != IString( "" ))
  3805.   {
  3806.      IString xFontName = fNotebookData->xlfdString;
  3807.      xFontName.stripLeading( IString( "IOC:" ));
  3808.      XFontStruct *xfont  = XLoadQueryFont( XtDisplay( fNotebookData->notebook ),
  3809.                                            xFontName );
  3810.      if (xfont)
  3811.      {
  3812.         // We found the font.  Create a font list resource.
  3813.         XmFontListEntry
  3814.           entry = XmFontListEntryCreate( XmFONTLIST_DEFAULT_TAG,
  3815.                                          XmFONT_IS_FONT,
  3816.                                          xfont );
  3817.         XmFontList fontList = 0;
  3818.         fontList = XmFontListAppendEntry(fontList, entry);
  3819.         XmFontListEntryFree( &entry );
  3820.  
  3821.         // Set the font resources.
  3822.         XtVaSetValues( theStatusArea,
  3823.                        XmNfontList, fontList,
  3824.                        NULL );
  3825.         if (theTab)
  3826.         {
  3827.            XtVaSetValues( theTab,
  3828.                           XmNfontList, fontList,
  3829.                           NULL );
  3830.         }
  3831.  
  3832.         XmFontListFree( fontList );
  3833.      }
  3834.   }
  3835.  
  3836.   // Now adjust the first and last page numbers in the notebook if necessary.
  3837.   // If the first and last pages numbers are adjusted before the widgets are
  3838.   // created, a selection event may be generated for an invalid page.  We also
  3839.   // want to make sure the status widget is created before any selection event
  3840.   // is generated to ensure access to the page handle contained therein.
  3841.   n = 0;
  3842.   if (firstPage == 0)
  3843.   {
  3844.      XtSetArg( args[n], XmNfirstPageNumber, 1 ); n++;
  3845.   }
  3846.   if (pageNumber > lastPage)
  3847.   {
  3848.      XtSetArg( args[n], XmNlastPageNumber, pageNumber ); n++;
  3849.   }
  3850.   if (n)
  3851.   {
  3852.      XtSetValues( fNotebookData->notebook,
  3853.                   args,
  3854.                   n );
  3855.   }
  3856.  
  3857.   return page;
  3858. }
  3859. #endif // IC_MOTIF
  3860.  
  3861. /*------------------------------------------------------------------------------
  3862. | INotebook::addFirstPage                                                      |
  3863. |                                                                              |
  3864. | Add a given window to the notebook as the first page, using the given        |
  3865. | page settings.                                                               |
  3866. ------------------------------------------------------------------------------*/
  3867. IPageHandle INotebook :: addFirstPage ( const PageSettings& pageInfo,
  3868.                                         IWindow* window )
  3869. {
  3870. #ifdef IC_PMWIN
  3871.   return insertPageInfo(pageInfo, IPageHandle(0), window, BKA_FIRST);
  3872. #endif
  3873. #ifdef IC_MOTIF
  3874.   return addPageAt(1, pageInfo, window);
  3875. #endif // IC_MOTIF
  3876. }
  3877.  
  3878.  
  3879. /*------------------------------------------------------------------------------
  3880. | INotebook::addLastPage                                                       |
  3881. |                                                                              |
  3882. | Add a given window to the notebook as the last page, using the given         |
  3883. | page settings.                                                               |
  3884. ------------------------------------------------------------------------------*/
  3885. IPageHandle INotebook :: addLastPage ( const PageSettings& pageInfo,
  3886.                                        IWindow* window )
  3887. {
  3888. #ifdef IC_PMWIN
  3889.   return insertPageInfo(pageInfo, IPageHandle(0), window, BKA_LAST);
  3890. #endif // IC_PMWIN
  3891. #ifdef IC_MOTIF
  3892.   return addPageAt(0, pageInfo, window);
  3893. #endif // IC_MOTIF
  3894. }
  3895.  
  3896.  
  3897. /*------------------------------------------------------------------------------
  3898. | INotebook::addPageBefore                                                     |
  3899. |                                                                              |
  3900. | Add a given window to the notebook before the referenced page, using the     |
  3901. | given page settings.                                                         |
  3902. ------------------------------------------------------------------------------*/
  3903. IPageHandle INotebook :: addPageBefore ( const PageSettings& newPageInfo,
  3904.                                          const IPageHandle& referencePage,
  3905.                                          IWindow* window )
  3906. {
  3907. #ifdef IC_PMWIN
  3908.   return insertPageInfo(newPageInfo, referencePage, window, BKA_PREV);
  3909. #endif // IC_PMWIN
  3910. #ifdef IC_MOTIF
  3911.   return addPageAt( fNotebookData->pageNumber( referencePage ),
  3912.                     newPageInfo,
  3913.                     window );
  3914. #endif // IC_MOTIF
  3915. }
  3916.  
  3917.  
  3918. /*------------------------------------------------------------------------------
  3919. | INotebook::addPageBefore                                                     |
  3920. |                                                                              |
  3921. | Add a given window to the notebook before the referenced page, using the     |
  3922. | given page settings.                                                         |
  3923. ------------------------------------------------------------------------------*/
  3924. IPageHandle INotebook :: addPageBefore ( const PageSettings& newPageInfo,
  3925.                                          const Cursor& cursor,
  3926.                                          IWindow* window )
  3927. {
  3928. #ifdef IC_PMWIN
  3929.   return insertPageInfo(newPageInfo, cursor.current(), window, BKA_PREV);
  3930. #endif // IC_PMWIN
  3931. #ifdef IC_MOTIF
  3932.   return addPageAt( fNotebookData->pageNumber( cursor.current() ),
  3933.                     newPageInfo,
  3934.                     window );
  3935. #endif // IC_MOTIF
  3936. }
  3937.  
  3938.  
  3939. /*------------------------------------------------------------------------------
  3940. | INotebook::addPageAfter                                                      |
  3941. |                                                                              |
  3942. | Add a given window to the notebook after the referenced page, using the      |
  3943. | given page settings.                                                         |
  3944. ------------------------------------------------------------------------------*/
  3945. IPageHandle INotebook :: addPageAfter ( const PageSettings& newPageInfo,
  3946.                                         const IPageHandle& referencePage,
  3947.                                         IWindow* window )
  3948. {
  3949. #ifdef IC_PMWIN
  3950.   return insertPageInfo(newPageInfo, referencePage, window, BKA_NEXT);
  3951. #endif // IC_PMWIN
  3952. #ifdef IC_MOTIF
  3953.   return addPageAt( fNotebookData->pageNumber( referencePage ) + 1,
  3954.                     newPageInfo,
  3955.                     window );
  3956. #endif // IC_MOTIF
  3957. }
  3958.  
  3959.  
  3960. /*------------------------------------------------------------------------------
  3961. | INotebook::addPageAfter                                                      |
  3962. |                                                                              |
  3963. | Add a given window to the notebook after the referenced page, using the      |
  3964. | given page settings.                                                         |
  3965. ------------------------------------------------------------------------------*/
  3966. IPageHandle INotebook :: addPageAfter ( const PageSettings& newPageInfo,
  3967.                                         const Cursor& cursor,
  3968.                                         IWindow* window )
  3969. {
  3970. #ifdef IC_PMWIN
  3971.   return insertPageInfo(newPageInfo, cursor.current(), window, BKA_NEXT);
  3972. #endif // IC_PMWIN
  3973. #ifdef IC_MOTIF
  3974.   return addPageAt( fNotebookData->pageNumber( cursor.current() ) + 1,
  3975.                     newPageInfo,
  3976.                     window );
  3977. #endif // IC_MOTIF
  3978. }
  3979.  
  3980.  
  3981. #ifdef IC_PMWIN
  3982. /*------------------------------------------------------------------------------
  3983. | INotebook::insertPage                                                        |
  3984. ------------------------------------------------------------------------------*/
  3985. unsigned long INotebook :: insertPage ( void* mp1, void* mp2 )
  3986. {
  3987.   unsigned long retVal = sendEvent(BKM_INSERTPAGE, mp1, mp2);
  3988.   if (!retVal)
  3989.   {
  3990.     ITHROWGUIERROR("BKM_INSERTPAGE");
  3991.   }
  3992.   ulClValidate++;
  3993.   return retVal;
  3994. }
  3995. #endif
  3996.  
  3997.  
  3998. /*------------------------------------------------------------------------------
  3999. | INotebook::removePage                                                        |
  4000. ------------------------------------------------------------------------------*/
  4001. INotebook& INotebook :: removePage ( const IPageHandle& page )
  4002. {
  4003. #ifdef IC_WIN
  4004.   deletePage( MPFROMLONG( ((void*)page)), MPFROMSHORT (BKA_SINGLE) );
  4005. #endif // IC_WIN
  4006. #ifdef IC_PM
  4007.   deletePage (MPFROMLONG (page), MPFROMSHORT (BKA_SINGLE));
  4008. #endif // IC_PM
  4009. #ifdef IC_MOTIF
  4010.   int pageNumber = fNotebookData->pageNumber( page );
  4011.   fNotebookData->deletePages( pageNumber, pageNumber );
  4012. #endif
  4013.   return( *this );
  4014. }
  4015.  
  4016.  
  4017. /*------------------------------------------------------------------------------
  4018. | INotebook::removePage                                                        |
  4019. ------------------------------------------------------------------------------*/
  4020. INotebook& INotebook :: removePage ( const Cursor& cursor )
  4021. {
  4022.   return removePage(cursor.current());
  4023. }
  4024.  
  4025.  
  4026. /*------------------------------------------------------------------------------
  4027. | INotebook::removeAllPages                                                    |
  4028. ------------------------------------------------------------------------------*/
  4029. INotebook& INotebook :: removeAllPages ( )
  4030. {
  4031. #ifdef IC_PMWIN
  4032.   if ( isPMCompatible() )
  4033.   {
  4034.     deletePage (0, MPFROMSHORT (BKA_ALL));
  4035.   }
  4036. #ifdef IC_WIN
  4037.   else
  4038.   {
  4039.     /**************************************************************************/
  4040.     /* We cannot use the tab control's delete all functions if we want to     */
  4041.     /* send a page deleted notification.  Instead we have to loop thru        */
  4042.     /* every page to simulate the PM behavior, since the tab control does     */
  4043.     /* not have a TCN_ notification defined for page deletion.                */
  4044.     /**************************************************************************/
  4045.  
  4046.     /**************************************************************************/
  4047.     /* Hide the page clipping window if we're deleting all of the pages.      */
  4048.     /**************************************************************************/
  4049.     pageClippingWindow()->hide();
  4050.  
  4051.     /**************************************************************************/
  4052.     /* This is the hack to simulate the PM page deleted notification that     */
  4053.     /* was mentioned above.                                                   */
  4054.     /**************************************************************************/
  4055.     unsigned long
  4056.       ulTotalPages = totalPages();
  4057.     for ( unsigned i = 1; i <= ulTotalPages; i++ )
  4058.     {
  4059.       deletePage( MPFROMLONG ((void*)tabPageHandle( 0 )),
  4060.                   MPFROMSHORT (BKA_ALL) );
  4061.     }
  4062.  
  4063.     /**************************************************************************/
  4064.     /* Reset pages inserted count to 0, since we have just deleted all of     */
  4065.     /* the pages.                                                             */
  4066.     /**************************************************************************/
  4067.     ulClPagesInserted = 0;
  4068.  
  4069.     /******************************************************************/
  4070.     /* Also clear the equality sequence of all its entries            */
  4071.     /******************************************************************/
  4072.     tabPageHandleCollection()->removeAll();
  4073.   }
  4074. #endif //IC_WIN
  4075. #endif // IC_PMWIN
  4076. #ifdef IC_MOTIF
  4077.   int firstPage, lastPage;
  4078.   XtVaGetValues(fNotebookData->notebook,
  4079.                 XmNfirstPageNumber, &firstPage,
  4080.                 XmNlastPageNumber, &lastPage,
  4081.                 NULL);
  4082.  
  4083.   fNotebookData->deletePages (firstPage, lastPage);
  4084. #endif
  4085.   return( *this );
  4086. }
  4087.  
  4088.  
  4089. /*------------------------------------------------------------------------------
  4090. | INotebook::removeTabSection                                                  |
  4091. |                                                                              |
  4092. | If the page specified is a major tab page, the specified page and all        |
  4093. | subsequent pages up to the next major tab page are removed.                  |
  4094. | If the page specified is a minor tab page, the specified page and all        |
  4095. | subsequent pages up to the next page with any tab are removed.               |
  4096. ------------------------------------------------------------------------------*/
  4097. INotebook& INotebook :: removeTabSection ( const IPageHandle& page )
  4098. {
  4099.   ITRACE_WIN_NOP();
  4100.  
  4101. #ifdef IC_PMWIN
  4102.   if ( isPMCompatible() )
  4103.   {
  4104.     unsigned short pageStyle = sendEvent( BKM_QUERYPAGESTYLE,
  4105.                                           MPFROMLONG( UPAGE ),
  4106.                                           0 );
  4107.  
  4108.     IASSERTSTATE( ( pageStyle & (BKA_MAJOR | BKA_MINOR) ) != 0 );
  4109.  
  4110.     deletePage (MPFROMLONG( UPAGE ), MPFROMSHORT( BKA_TAB ));
  4111.   }
  4112. #endif // IC_PMWIN
  4113. #ifdef IC_MOTIF
  4114.   int startPage = fNotebookData->pageNumber( page );
  4115.   bool keepGoing = true;
  4116.   bool gotMajor;
  4117.   int origLast;
  4118.   XmNotebookPageInfo pageInfo;
  4119.   XmNotebookPageStatus pageStatus;
  4120.   XtVaGetValues(fNotebookData->notebook, XmNlastPageNumber, &origLast, NULL);
  4121.   pageStatus = XmNotebookGetPageInfo(
  4122.                         fNotebookData->notebook, startPage, &pageInfo);
  4123.  
  4124.   if (pageStatus == XmPAGE_FOUND || pageStatus == XmPAGE_EMPTY) {
  4125.     if (pageInfo.major_tab_widget != 0)
  4126.        gotMajor = true;
  4127.     else if (pageInfo.minor_tab_widget != 0)
  4128.        gotMajor = false;
  4129.     else
  4130.        ITHROWGUIERROR("Invalid Page");
  4131.   }
  4132.   else
  4133.     ITHROWGUIERROR("Invalid Page");
  4134.  
  4135.   for(int i = startPage+1; i<=origLast && keepGoing; i++) {
  4136.     pageStatus = XmNotebookGetPageInfo(fNotebookData->notebook, i, &pageInfo);
  4137.     switch (pageStatus) {
  4138.       case XmPAGE_FOUND:
  4139.       case XmPAGE_EMPTY:    // empty page could have tab or status area
  4140.         if ( (gotMajor && pageInfo.major_tab_widget !=0) ||
  4141.            (!gotMajor && (pageInfo.major_tab_widget != 0 ||
  4142.                                pageInfo.minor_tab_widget != 0)) ) {
  4143.           keepGoing = false;
  4144.           i--;
  4145.         }
  4146.         break;
  4147.       case XmPAGE_INVALID:
  4148.         ITHROWGUIERROR("Found invalid page while removing tab section");
  4149.         break;
  4150.       case XmPAGE_DUPLICATED:
  4151.         ITHROWGUIERROR("Duplicate pages found in INotebook");
  4152.         break;
  4153.       default:
  4154.         ITHROWGUIERROR("Unexpected pageStatus from XmNotebookGetPageInfo");
  4155.     }   // end switch
  4156.   }     // end for
  4157.  
  4158.   fNotebookData->deletePages(startPage, --i);
  4159. #endif
  4160.   return( *this );
  4161. }
  4162.  
  4163.  
  4164. /*------------------------------------------------------------------------------
  4165. | INotebook::removeTabSection                                                  |
  4166. |                                                                              |
  4167. | If the page cursored is a major tab page, remove the cursored page and       |
  4168. | all subsequent pages up to the next major tab page.                          |
  4169. | If the page cursored is a minor tab page, remove the cursored page and       |
  4170. | all subsequent pages up to the next page with any tab.                       |
  4171. ------------------------------------------------------------------------------*/
  4172. INotebook& INotebook :: removeTabSection ( const Cursor& cursor )
  4173. {
  4174.   return removeTabSection(cursor.current());
  4175. }
  4176.  
  4177.  
  4178. #ifdef IC_PMWIN
  4179. /*------------------------------------------------------------------------------
  4180. | INotebook::deletePage                                                        |
  4181. ------------------------------------------------------------------------------*/
  4182. bool INotebook :: deletePage ( void* mp1, void* mp2 )
  4183. {
  4184.   if ( isPMCompatible() )
  4185.   {
  4186. #ifdef IC_PM
  4187.      // Remove the page window resize handler for PM.  Only remove it if
  4188.      // this page window is not the page window for another page.
  4189.      IWindow *pageWindow = window( (IPageHandle)(unsigned long)mp1 );
  4190.      if (pageWindow)
  4191.      {
  4192.         Cursor cursor( *this );
  4193.         bool pageWindowFound = false;
  4194.         for (cursor.setToFirst();
  4195.              cursor.isValid() && !pageWindowFound;
  4196.              cursor.setToNext())
  4197.         {
  4198.            IPageHandle currentHandle = cursor.current();
  4199.            if (currentHandle != (IPageHandle)(unsigned long)mp1 &&
  4200.                this->window( currentHandle ) == pageWindow)
  4201.               pageWindowFound = true;
  4202.         }
  4203.         if (!pageWindowFound)
  4204.            fNotebookData->fPageResizeHandler.stopHandlingEventsFor( pageWindow );
  4205.      }
  4206. #endif // IC_PM
  4207.     IEventResult
  4208.        retVal = sendEvent(BKM_DELETEPAGE, mp1, mp2);
  4209.     if (retVal.asUnsignedLong() == false)
  4210.     {
  4211.       ITHROWGUIERROR("BKM_DELETEPAGE");
  4212.     }
  4213.   }
  4214. #ifdef IC_WIN
  4215.   else
  4216.   {
  4217.     /**************************************************************************/
  4218.     /* Windows tab control processing                                         */
  4219.     /* ---------------------------------------------------------------------- */
  4220.     /* Query the tab item's information                                       */
  4221.     /**************************************************************************/
  4222.     IOC_ITEM tabCtrlItem;
  4223.     tabCtrlItem.itemHeader.mask = TCIF_PARAM | TCIF_IMAGE;
  4224.  
  4225.     long
  4226.       iPageIndex = tabPageIndex( mp1 );
  4227.  
  4228.     if ( !TabCtrl_GetItem( handle(), iPageIndex, &tabCtrlItem ) )
  4229.     {
  4230.       if ( (unsigned long)mp2 == BKA_SINGLE )
  4231.         ITHROWGUIERROR("TabCtrl_GetItem");
  4232.       else
  4233.         return( false );
  4234.     }
  4235.  
  4236.     /**************************************************************************/
  4237.     /* If we have created an image list, then check to see if an image exists */
  4238.     /* for the specified page.  If an image exists, then remove it from the   */
  4239.     /* image list.                                                            */
  4240.     /**************************************************************************/
  4241.     IMAGEINFO imageInfo;
  4242.     if ( fNotebookData->hWndImageList )
  4243.     {
  4244.       if ( tabCtrlItem.itemHeader.iImage != -1 )
  4245.       {
  4246.         /**********************************************************************/
  4247.         /* Get the bitmap's handle before we delete it from the image list,   */
  4248.         /* so we can pass it as part of the page deleted notification.        */
  4249.         /**********************************************************************/
  4250.         ImageList_GetImageInfo( fNotebookData->hWndImageList,
  4251.                                 tabCtrlItem.itemHeader.iImage,
  4252.                                 &imageInfo );
  4253.  
  4254.         TabCtrl_RemoveImage( handle(), tabCtrlItem.itemHeader.iImage );
  4255.       }
  4256.     }
  4257.  
  4258.     /**************************************************************************/
  4259.     /* If the delete request is for the current top page, we must select a    */
  4260.     /* new top page, unless the notebook is empty.                            */
  4261.     /**************************************************************************/
  4262.     if ( ((unsigned long)mp2 == BKA_SINGLE) &&
  4263.          (IPageHandle( mp1 ) == topPage()) )
  4264.     {
  4265.       /************************************************************************/
  4266.       /* Reset the top page to the next page if it exists, or the previous    */
  4267.       /* page if it exists.                                                   */
  4268.       /************************************************************************/
  4269.       long
  4270.         iNewPageIndex = iPageIndex + 1;
  4271.       long
  4272.         retVal = TabCtrl_SetCurSel( handle(), iNewPageIndex );
  4273.       if ( retVal == -1 )
  4274.       {
  4275.         if ( iPageIndex )
  4276.         {
  4277.           iNewPageIndex = iPageIndex - 1;
  4278.           retVal = TabCtrl_SetCurSel( handle(), iNewPageIndex );
  4279.         }
  4280.       }
  4281.  
  4282.       if ( retVal != -1 )
  4283.       {
  4284.         /**********************************************************************/
  4285.         /* Notify the parent (i.e. owner) that a new page is now the top      */
  4286.         /* page. because the current top page is being deleted.               */
  4287.         /**********************************************************************/
  4288.         PAGESELECTNOTIFY pageSelectNotify;
  4289.         pageSelectNotify.hwndBook = handle();
  4290.         pageSelectNotify.ulPageIdNew =
  4291.                            tabPageHandle( iNewPageIndex ).asUnsigned();
  4292.         pageSelectNotify.ulPageIdCur = (long)mp1;
  4293.  
  4294.         processTabSelect( &pageSelectNotify, false );
  4295.       }
  4296.     }
  4297.  
  4298.     /**************************************************************************/
  4299.     /* Delete the specified page.                                             */
  4300.     /**************************************************************************/
  4301.     if ( !TabCtrl_DeleteItem( handle(), iPageIndex ) )
  4302.     {
  4303.       ITHROWGUIERROR("TabCtrl_DeleteItem");
  4304.     }
  4305.  
  4306.     /**************************************************************************/
  4307.     /* Send the page deleted notification to simulate PM behavior             */
  4308.     /**************************************************************************/
  4309.     DELETENOTIFY deleteNotify;
  4310.     deleteNotify.hwndBook = handle();
  4311.     deleteNotify.hwndPage = tabCtrlItem.hPageWindow;
  4312.     deleteNotify.ulAppPageData = tabCtrlItem.ulUserData;
  4313.     if ( fNotebookData->hWndImageList )
  4314.       deleteNotify.hbmTab = imageInfo.hbmImage;
  4315.     else
  4316.       deleteNotify.hbmTab = NULL;
  4317.  
  4318.     parent()->handle().sendEvent( WM_COMMAND,
  4319.                                   IEventParameter1( (unsigned short)id(),
  4320.                                                     BKN_PAGEDELETED ),
  4321.                                   IEventParameter2( &deleteNotify ) );
  4322.  
  4323.     /**************************************************************************/
  4324.     /* Reset the parent of the application page window for the tab page we    */
  4325.     /* just deleted.  We only want to do this if this if the application page */
  4326.     /* isn't associated with any other tab page.                              */
  4327.     /**************************************************************************/
  4328.     bool bResetParent = true;
  4329.     if ( (unsigned long)mp2 == BKA_SINGLE )
  4330.     {
  4331.       IOC_ITEM tempTabCtrlItem;
  4332.       unsigned long
  4333.         ulTotalPages = totalPages();
  4334.       for ( unsigned i = 0; i < ulTotalPages; i++ )
  4335.       {
  4336.         tempTabCtrlItem.itemHeader.mask = TCIF_PARAM;
  4337.         if ( TabCtrl_GetItem( handle(), i, &tempTabCtrlItem ) )
  4338.         {
  4339.           if ( tempTabCtrlItem.hPageWindow == tabCtrlItem.hPageWindow )
  4340.           {
  4341.             bResetParent = false;
  4342.             break;
  4343.           }
  4344.         }
  4345.       }
  4346.     }
  4347.  
  4348.     /**************************************************************************/
  4349.     /* If we didn't find a page (other than the one being freed) that has the */
  4350.     /* same application page window as the one being freed, reset the         */
  4351.     /* application page window's parent to its original parent.               */
  4352.     /**************************************************************************/
  4353.     if ( bResetParent )
  4354.     {
  4355.       IWindow* pPageWindow = windowWithHandle( tabCtrlItem.hPageWindow );
  4356.       if ( pPageWindow )
  4357.       {
  4358.         SetParent( tabCtrlItem.hPageWindow, tabCtrlItem.hPageWindowParent );
  4359.         pPageWindow->hide();
  4360.       }
  4361.     }
  4362.  
  4363.     /**************************************************************************/
  4364.     /* Remove the tab control page handle from our tab page sequence          */
  4365.     /* collection.                                                            */
  4366.     /**************************************************************************/
  4367.     if ( (unsigned long)mp2 == BKA_SINGLE )
  4368.       removeTabPage( mp1 );
  4369.   } //tab control
  4370. #endif //IC_WIN
  4371.  
  4372.   ulClValidate--;
  4373.   return( true );
  4374. }
  4375. #endif //IC_PMWIN
  4376.  
  4377.  
  4378. /*------------------------------------------------------------------------------
  4379. | INotebook::turnToPage                                                        |
  4380. ------------------------------------------------------------------------------*/
  4381. INotebook& INotebook :: turnToPage ( const IPageHandle& page )
  4382. {
  4383. #ifdef IC_PMWIN
  4384.   IMODTRACE_DEVELOP( "INotebook::turnToPage" );
  4385.  
  4386.   if ( isPMCompatible() )
  4387.   {
  4388.     IEventResult
  4389.        retVal = sendEvent(BKM_TURNTOPAGE, UPAGE, 0);
  4390.     if (retVal.asUnsignedLong() == false)
  4391.     {
  4392.       ITHROWGUIERROR("BKM_TURNTOPAGE");
  4393.     }
  4394.   }
  4395. #ifdef IC_WIN
  4396.   else
  4397.   {
  4398.     /**************************************************************************/
  4399.     /* Verify that pages exist in the Windows tab control.                    */
  4400.     /**************************************************************************/
  4401.     if ( !totalPages() )
  4402.     {
  4403.       return( *this );
  4404.     }
  4405.     else
  4406.     {
  4407.       /************************************************************************/
  4408.       /* Fill in the PAGESELECTNOTIFY structure that we use in Windows        */
  4409.       /************************************************************************/
  4410.       PAGESELECTNOTIFY pageSelectNotify;
  4411.       pageSelectNotify.hwndBook = handle();
  4412.       pageSelectNotify.ulPageIdNew = page.asUnsigned();
  4413.       pageSelectNotify.ulPageIdCur = (DWORD)topPage().asUnsigned();
  4414.  
  4415.       /************************************************************************/
  4416.       /* The tab selection is now in progress (pending).  Do our required     */
  4417.       /* processing and issue the selection pending notification.  If the     */
  4418.       /* new page selection is rejected, cancel the page turn request.        */
  4419.       /************************************************************************/
  4420.       if ( processTabSelect( &pageSelectNotify, true ) )
  4421.         return( *this );
  4422.  
  4423.       /************************************************************************/
  4424.       /* Set the index of the tab page we're turning to.                      */
  4425.       /************************************************************************/
  4426.       long
  4427.         iPageIndex = tabPageIndex( page );
  4428.       long
  4429.         retVal = TabCtrl_SetCurSel( handle(), iPageIndex );
  4430.       if ( retVal == -1 )
  4431.       {
  4432.         ITHROWGUIERROR("TabCtrl_SetCurSel");
  4433.       }
  4434.  
  4435.       /************************************************************************/
  4436.       /* The tab selection has already occurred and the new tab is now the    */
  4437.       /* top page in the tab control.  Do our required processing and issue   */
  4438.       /* the selection notification.                                          */
  4439.       /************************************************************************/
  4440.       processTabSelect( &pageSelectNotify, false );
  4441.  
  4442.     }
  4443.   }
  4444. #endif //IC_WIN
  4445. #endif // IC_PMWIN
  4446. #ifdef IC_MOTIF
  4447.   XtVaSetValues( fNotebookData->notebook,
  4448.                  XmNcurrentPageNumber, fNotebookData->pageNumber( page ),
  4449.                  NULL );
  4450. #endif
  4451.   return( *this );
  4452. }
  4453.  
  4454.  
  4455. /*------------------------------------------------------------------------------
  4456. | INotebook::turnToPage                                                        |
  4457. ------------------------------------------------------------------------------*/
  4458. INotebook& INotebook :: turnToPage ( const Cursor& cursor )
  4459. {
  4460.   return turnToPage(cursor.current());
  4461. }
  4462.  
  4463.  
  4464. /*------------------------------------------------------------------------------
  4465. | INotebook::topPage                                                           |
  4466. |                                                                              |
  4467. | Returns an IPageHandle object that references the current top page of the    |
  4468. | notebook.                                                                    |
  4469. ------------------------------------------------------------------------------*/
  4470. IPageHandle INotebook :: topPage ( ) const
  4471. {
  4472. #ifdef IC_PMWIN
  4473.   IPageHandle topPageHandle (0);
  4474.  
  4475.   if ( isPMCompatible() )
  4476.   {
  4477.     /**************************************************************************/
  4478.     /* CUA '91 notebook                                                       */
  4479.     /**************************************************************************/
  4480.     unsigned long
  4481.       retVal = queryPage (0, MPFROM2SHORT (BKA_TOP, 0));
  4482.     if (retVal)
  4483. #ifdef IC_WIN
  4484.       topPageHandle = (void*)retVal;
  4485. #else
  4486.       topPageHandle = retVal;
  4487. #endif
  4488.   }
  4489. #ifdef IC_WIN
  4490.   else
  4491.   {
  4492.     /**************************************************************************/
  4493.     /* Windows tab control                                                    */
  4494.     /**************************************************************************/
  4495.     long
  4496.       iPageIndex = TabCtrl_GetCurSel( handle() );
  4497.     if ( iPageIndex == -1 )
  4498.     {
  4499.       ITHROWGUIERROR("TabCtrl_GetCurSel");
  4500.     }
  4501.  
  4502.     /**************************************************************************/
  4503.     /* We must increment the index since the tab control uses a 0-based index */
  4504.     /* and sequence collection positions are 1-based.                         */
  4505.     /**************************************************************************/
  4506.     topPageHandle = tabPageHandle( iPageIndex );
  4507.   }
  4508. #endif //IC_WIN
  4509.  
  4510.   return( topPageHandle );
  4511. #endif // IC_PMWIN
  4512. #ifdef IC_MOTIF
  4513.   int curPage;
  4514.   XtVaGetValues(fNotebookData->notebook, XmNcurrentPageNumber, &curPage, NULL);
  4515.   return fNotebookData->pageHandle( curPage );
  4516. #endif // IC_MOTIF
  4517. }
  4518.  
  4519.  
  4520. /*------------------------------------------------------------------------------
  4521. | INotebook::firstPage                                                         |
  4522. |                                                                              |
  4523. | Returns an IPageHandle object that references the first page of the notebook.|
  4524. ------------------------------------------------------------------------------*/
  4525. IPageHandle INotebook :: firstPage ( ) const
  4526. {
  4527. #ifdef IC_PMWIN
  4528.   unsigned long retVal;
  4529.   IPageHandle firstPageHandle (0);
  4530.  
  4531.   if ( isPMCompatible() )
  4532.   {
  4533.     retVal = queryPage (0, MPFROM2SHORT (BKA_FIRST, 0));
  4534.     if (retVal)
  4535. #ifdef IC_WIN
  4536.       firstPageHandle = (void*)retVal;
  4537. #else
  4538.       firstPageHandle = retVal;
  4539. #endif
  4540.   }
  4541. #ifdef IC_WIN
  4542.   else
  4543.   {
  4544.     /**************************************************************************/
  4545.     /* Value of the first page is always the first element in the tab page    */
  4546.     /* sequence collection.                                                   */
  4547.     /**************************************************************************/
  4548.     if ( totalPages() )
  4549.       firstPageHandle = tabPageHandle( 0 );
  4550.   }
  4551. #endif //IC_WIN
  4552.  
  4553.   return( firstPageHandle );
  4554. #endif // IC_PMWIN
  4555. #ifdef IC_MOTIF
  4556.   int firstPage;
  4557.   XtVaGetValues(fNotebookData->notebook, XmNfirstPageNumber, &firstPage, NULL);
  4558.   return fNotebookData->pageHandle( firstPage );
  4559. #endif
  4560. }
  4561.  
  4562.  
  4563. /*------------------------------------------------------------------------------
  4564. | INotebook::lastPage                                                          |
  4565. |                                                                              |
  4566. | Returns an IPageHandle object that references the last page of the notebook. |
  4567. ------------------------------------------------------------------------------*/
  4568. IPageHandle INotebook :: lastPage ( ) const
  4569. {
  4570. #ifdef IC_PMWIN
  4571.   unsigned long retVal;
  4572.   IPageHandle lastPageHandle (0);
  4573.  
  4574.   if ( isPMCompatible() )
  4575.   {
  4576.     retVal = queryPage (0, MPFROM2SHORT (BKA_LAST, 0));
  4577.     if (retVal)
  4578. #ifdef IC_WIN
  4579.       lastPageHandle = (void*)retVal;
  4580. #else
  4581.       lastPageHandle = retVal;
  4582. #endif
  4583.   }
  4584. #ifdef IC_WIN
  4585.   else
  4586.   {
  4587.     /**************************************************************************/
  4588.     /* Value of the last page is always the last element in the tab page      */
  4589.     /* sequence collection.                                                   */
  4590.     /**************************************************************************/
  4591.     lastPageHandle = tabPageHandle( totalPages()-1 );
  4592.   }
  4593. #endif //IC_WIN
  4594.   return( lastPageHandle );
  4595. #endif // IC_PMWIN
  4596. #ifdef IC_MOTIF
  4597.   int lastPage;
  4598.   XtVaGetValues(fNotebookData->notebook, XmNlastPageNumber, &lastPage, NULL);
  4599.   return fNotebookData->pageHandle( lastPage );
  4600. #endif // iC_MOTIF
  4601. }
  4602.  
  4603.  
  4604. /*------------------------------------------------------------------------------
  4605. | INotebook::nextPage                                                          |
  4606. |                                                                              |
  4607. | Returns an IPageHandle object that references the next page of the notebook. |
  4608. ------------------------------------------------------------------------------*/
  4609. IPageHandle INotebook :: nextPage ( const IPageHandle& page ) const
  4610. {
  4611. #ifdef IC_PMWIN
  4612.   IPageHandle nextPageHandle (0);
  4613.  
  4614.   if (page)
  4615.   {
  4616.     if ( isPMCompatible() )
  4617.     {
  4618.       unsigned long retVal = queryPage( MPFROMLONG( UPAGE ),
  4619.                                         MPFROM2SHORT( BKA_NEXT, 0 ));
  4620.       if (retVal)
  4621. #ifdef IC_WIN
  4622.         nextPageHandle = (void*)retVal;
  4623. #else
  4624.         nextPageHandle = retVal;
  4625. #endif
  4626.     }
  4627. #ifdef IC_WIN
  4628.     else
  4629.     {
  4630.       /************************************************************************/
  4631.       /* Verify the reference page.  If it does not exist, throw an exception.*/
  4632.       /************************************************************************/
  4633.       INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
  4634.       if ( tabPageHandleCollection()->locate( page, cursor ) )
  4635.       {
  4636.         /**********************************************************************/
  4637.         /* Value of the next page is always the position of the reference     */
  4638.         /* page's element + 1 (in the tab page sequence collection).          */
  4639.         /**********************************************************************/
  4640.         unsigned long
  4641.           ulPosition = tabPageHandleCollection()->position( cursor ) + 1;
  4642.         if ( ulPosition <= tabPageHandleCollection()->numberOfElements() )
  4643.         {
  4644.           // Note:  tabPageHandle takes a 0-based index.
  4645.           nextPageHandle = tabPageHandle( ulPosition-1 );
  4646.         }
  4647.       }
  4648.       else
  4649.       {
  4650.         ITHROWLIBRARYERROR( IC_INVALIDHANDLE,
  4651.                             IBaseErrorInfo::invalidParameter,
  4652.                             IException::recoverable);
  4653.       }
  4654.     }
  4655. #endif //IC_WIN
  4656.   }
  4657.  
  4658.   return( nextPageHandle );
  4659. #endif // IC_PMWIN
  4660. #ifdef IC_MOTIF
  4661.   IPageHandle nextPageHandle (0);
  4662.   int pageNumber = fNotebookData->pageNumber( page ),
  4663.                    lastPage;
  4664.   XtVaGetValues(fNotebookData->notebook, XmNlastPageNumber, &lastPage, NULL);
  4665.   if (++pageNumber <= lastPage)
  4666.       nextPageHandle = fNotebookData->pageHandle( pageNumber );
  4667.   return nextPageHandle;
  4668. #endif
  4669.  
  4670. }
  4671.  
  4672.  
  4673. /*------------------------------------------------------------------------------
  4674. | INotebook::previousPage                                                      |
  4675. |                                                                              |
  4676. | Returns an IPageHandle object that references the page preceding the         |
  4677. | referenced page.                                                             |
  4678. ------------------------------------------------------------------------------*/
  4679. IPageHandle INotebook :: previousPage ( const IPageHandle& page ) const
  4680. {
  4681. #ifdef IC_PMWIN
  4682.   IPageHandle prevPageHandle (0);
  4683.  
  4684.   if (page)
  4685.   {
  4686.     if ( isPMCompatible() )
  4687.     {
  4688.       unsigned long retVal = queryPage( MPFROMLONG( UPAGE ),
  4689.                                         MPFROM2SHORT( BKA_PREV, 0 ));
  4690.       if (retVal)
  4691. #ifdef IC_WIN
  4692.         prevPageHandle = (void*)retVal;
  4693. #else
  4694.         prevPageHandle = retVal;
  4695. #endif
  4696.     }
  4697. #ifdef IC_WIN
  4698.     else
  4699.     {
  4700.       /************************************************************************/
  4701.       /* Verify the reference page.  If it does not exist, throw an exception.*/
  4702.       /************************************************************************/
  4703.       INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
  4704.       if ( tabPageHandleCollection()->locate( page, cursor ) )
  4705.       {
  4706.         /**********************************************************************/
  4707.         /* Value of the previous page is always the position of the reference */
  4708.         /* page's element - 1 (in the tab page sequence collection).          */
  4709.         /**********************************************************************/
  4710.         unsigned long
  4711.           ulPosition = tabPageHandleCollection()->position( cursor ) - 1;
  4712.         if ( ulPosition >= 1 )
  4713.         {
  4714.           // Note:  tabPageHandle takes a 0-based index.
  4715.           prevPageHandle = tabPageHandle( ulPosition-1 );
  4716.         }
  4717.       }
  4718.       else
  4719.       {
  4720.         ITHROWLIBRARYERROR( IC_INVALIDHANDLE,
  4721.                             IBaseErrorInfo::invalidParameter,
  4722.                             IException::recoverable);
  4723.       }
  4724.     }
  4725. #endif //IC_WIN
  4726.   }
  4727.  
  4728.   return( prevPageHandle );
  4729. #endif // IC_PMWIN
  4730. #ifdef IC_MOTIF
  4731.   IPageHandle prevPageHandle (0);
  4732.   int pageNumber = fNotebookData->pageNumber( page ),
  4733.       firstPage;
  4734.   XtVaGetValues(fNotebookData->notebook, XmNfirstPageNumber, &firstPage, NULL);
  4735.   if (--pageNumber >= firstPage)
  4736.       prevPageHandle = fNotebookData->pageHandle( pageNumber );
  4737.   return prevPageHandle;
  4738. #endif
  4739. }
  4740.  
  4741.  
  4742. #ifdef IC_PMWIN
  4743. /*------------------------------------------------------------------------------
  4744. | INotebook::queryPage                                                         |
  4745. ------------------------------------------------------------------------------*/
  4746. unsigned long INotebook :: queryPage ( void* mp1, void* mp2 ) const
  4747. {
  4748.   long retVal = (long)sendEvent(BKM_QUERYPAGEID, mp1, mp2);
  4749.  
  4750.   if (retVal == BOOKERR_INVALID_PARAMETERS)
  4751.   {
  4752.     ITHROWGUIERROR("BKM_QUERYPAGEID:INVALID_PARAMETERS");
  4753.   }
  4754.   return (unsigned long)retVal;
  4755. }
  4756. #endif // IC_PMWIN
  4757.  
  4758. /*------------------------------------------------------------------------------
  4759. | INotebook::window                                                            |
  4760. |                                                                              |
  4761. | Returns the window used by the notebook page.                                |
  4762. ------------------------------------------------------------------------------*/
  4763. IWindow* INotebook :: window ( const INotebook::Cursor& cursor ) const
  4764. {
  4765.   return window(cursor.current());     // Return window for current page
  4766. }
  4767.  
  4768.  
  4769. /*------------------------------------------------------------------------------
  4770. | INotebook::window                                                            |
  4771. |                                                                              |
  4772. | Returns the window used by the notebook page.                                |
  4773. ------------------------------------------------------------------------------*/
  4774. IWindow* INotebook :: window ( const IPageHandle& page ) const
  4775. {
  4776. #ifdef IC_PMWIN
  4777.   IWindow* pwinReturn = 0;             // Assume no window
  4778.  
  4779.   if ( isPMCompatible() )
  4780.   {
  4781.     IWindowHandle wh = (IWindowHandle::Value)
  4782.              this->sendEvent( BKM_QUERYPAGEWINDOWHWND, UPAGE, 0 );
  4783.     if ( (long)(IWindowHandle::Value) wh == BOOKERR_INVALID_PARAMETERS )
  4784.     {
  4785.       ITHROWGUIERROR("BKM_QUERYPAGEWINDOWHWND");
  4786.     }
  4787.     else if (wh != 0)
  4788.     {
  4789.       pwinReturn = windowWithHandle(wh);
  4790.     }
  4791.   }
  4792. #ifdef IC_WIN
  4793.   else
  4794.   {
  4795.     /**************************************************************************/
  4796.     /* Locate the notebook page.  If it does not exist, throw an exception.   */
  4797.     /**************************************************************************/
  4798.     INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
  4799.     if ( tabPageHandleCollection()->locate( page, cursor ) )
  4800.     {
  4801.       /************************************************************************/
  4802.       /* Get the pointer to the application page window from the extended tab */
  4803.       /* control item.                                                        */
  4804.       /************************************************************************/
  4805.       IOC_ITEM tabCtrlItem;
  4806.       tabCtrlItem.itemHeader.mask = TCIF_PARAM;
  4807.       if ( TabCtrl_GetItem( handle(), tabPageIndex( page ), &tabCtrlItem ) )
  4808.       {
  4809.         pwinReturn = windowWithHandle( tabCtrlItem.hPageWindow );
  4810.       }
  4811.       else
  4812.       {
  4813.         ITHROWGUIERROR("TabCtrl_GetItem");
  4814.       }
  4815.     }
  4816.     else
  4817.     {
  4818.       ITHROWLIBRARYERROR( IC_INVALIDHANDLE,
  4819.                           IBaseErrorInfo::invalidParameter,
  4820.                           IException::recoverable);
  4821.     }
  4822.   }
  4823. #endif //IC_WIN
  4824.  
  4825.   return( pwinReturn );
  4826. #endif // IC_PMWIN
  4827. #ifdef IC_MOTIF
  4828.   IWindow* pwinReturn = 0;             // Assume no window
  4829.  
  4830.   XmNotebookPageStatus pageStatus;
  4831.   XmNotebookPageInfo   pageInfo;
  4832.  
  4833.   pageStatus = XmNotebookGetPageInfo( fNotebookData->notebook,
  4834.                                       fNotebookData->pageNumber( page ),
  4835.                                       &pageInfo );
  4836.  
  4837.   IWindowHandle wh = pageInfo.page_widget;
  4838.  
  4839.   if (wh != 0)
  4840.   {
  4841.      pwinReturn = windowWithHandle(wh);
  4842.   }
  4843.  
  4844.   return pwinReturn;
  4845. #endif
  4846. }
  4847.  
  4848.  
  4849. /*------------------------------------------------------------------------------
  4850. | INotebook::pageSettings                                                      |
  4851. |                                                                              |
  4852. | Create and return a PageSettings object representing the page.               |
  4853. ------------------------------------------------------------------------------*/
  4854. INotebook::PageSettings INotebook :: pageSettings
  4855.                           ( const INotebook::Cursor& cursor ) const
  4856. {
  4857.    return pageSettings(cursor.current());
  4858. }
  4859.  
  4860. /*------------------------------------------------------------------------------
  4861. | INotebook::pageSettings                                                      |
  4862. |                                                                              |
  4863. | Create and return a PageSettings object representing the page.               |
  4864. ------------------------------------------------------------------------------*/
  4865. INotebook::PageSettings INotebook :: pageSettings
  4866.                           ( const IPageHandle& page ) const
  4867. {
  4868. #ifdef IC_PMWIN
  4869.   INotebook::PageSettings newPageSettings (0);
  4870.   char bookBuffer [100];
  4871.  
  4872.   if ( isPMCompatible() )
  4873.   {
  4874.     /**************************************************************************/
  4875.     /* CUA '91 notebook processing                                            */
  4876.     /**************************************************************************/
  4877.     BOOKTEXT bookText;
  4878.  
  4879.     unsigned long ulStyle =
  4880.            (unsigned long)sendEvent(BKM_QUERYPAGESTYLE, UPAGE, 0);
  4881.  
  4882.     if (ulStyle & PageSettings::autoPageSize.asUnsignedLong())
  4883.       newPageSettings.pageStyle |= (PageSettings::autoPageSize);
  4884.     if (ulStyle & PageSettings::statusTextOn.asUnsignedLong())
  4885.       newPageSettings.pageStyle |= (PageSettings::statusTextOn);
  4886.     if (ulStyle & PageSettings::majorTab.asUnsignedLong())
  4887.       newPageSettings.pageStyle |= (PageSettings::majorTab);
  4888.     if (ulStyle & PageSettings::minorTab.asUnsignedLong())
  4889.       newPageSettings.pageStyle |= (PageSettings::minorTab);
  4890.  
  4891.     newPageSettings.savedUserData =
  4892.                   sendEvent(BKM_QUERYPAGEDATA, UPAGE, 0);
  4893.  
  4894.     bookText.textLen = sizeof (bookBuffer);
  4895.     bookText.pString = bookBuffer;
  4896.     short usRetVal   = sendEvent( BKM_QUERYSTATUSLINETEXT,
  4897.                                   UPAGE,
  4898.                                   &bookText );
  4899.  
  4900.     if (usRetVal && (usRetVal != (short)BOOKERR_INVALID_PARAMETERS))
  4901.       newPageSettings.savedStatusText = IString (bookBuffer);
  4902.  
  4903.     usRetVal = sendEvent(BKM_QUERYTABTEXT, UPAGE, &bookText);
  4904.     if (usRetVal && (usRetVal != (short)BOOKERR_INVALID_PARAMETERS))
  4905.       newPageSettings.savedTabText = IString (bookBuffer);
  4906.  
  4907.     HBITMAP hTabBitmap =
  4908.                  sendEvent(BKM_QUERYTABBITMAP, UPAGE, 0);
  4909. #ifdef IC_WIN
  4910.     if (hTabBitmap && (hTabBitmap != (void*)BOOKERR_INVALID_PARAMETERS))
  4911. #else
  4912.     if (hTabBitmap && ((long)hTabBitmap != BOOKERR_INVALID_PARAMETERS))
  4913. #endif
  4914.     {
  4915.       newPageSettings.savedTabBitmap = IBitmapHandle (hTabBitmap);
  4916.     }
  4917.   }
  4918. #ifdef IC_WIN
  4919.   else
  4920.   {
  4921.     /**************************************************************************/
  4922.     /* Windows tab control processing                                         */
  4923.     /* ---------------------------------------------------------------------- */
  4924.     /* Locate the notebook page.  If it does not exist, throw an exception.   */
  4925.     /**************************************************************************/
  4926.     INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
  4927.     if ( !tabPageHandleCollection()->locate( page, cursor ) )
  4928.     {
  4929.       ITHROWLIBRARYERROR( IC_INVALIDHANDLE,
  4930.                           IBaseErrorInfo::invalidParameter,
  4931.                           IException::recoverable);
  4932.     }
  4933.  
  4934.     /**************************************************************************/
  4935.     /* Get tab text for the tab page and any user-defined data.  Get page     */
  4936.     /* settings attributes from the extended tab control item.                */
  4937.     /**************************************************************************/
  4938.     IOC_ITEM tabCtrlItem;
  4939.     tabCtrlItem.itemHeader.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM;
  4940.     tabCtrlItem.itemHeader.pszText = bookBuffer;
  4941.     tabCtrlItem.itemHeader.cchTextMax = sizeof(bookBuffer);
  4942.     if ( !TabCtrl_GetItem( handle(), tabPageIndex( page ), &tabCtrlItem ) )
  4943.     {
  4944.       ITHROWGUIERROR("TabCtrl_GetItem");
  4945.     }
  4946.  
  4947.     if ( tabCtrlItem.ulPageStyle & PageSettings::autoPageSize.asUnsignedLong() )
  4948.       newPageSettings.pageStyle |= (PageSettings::autoPageSize);
  4949.     if ( tabCtrlItem.ulPageStyle & PageSettings::statusTextOn.asUnsignedLong())
  4950.       newPageSettings.pageStyle |= (PageSettings::statusTextOn);
  4951.     if ( tabCtrlItem.ulPageStyle & PageSettings::majorTab.asUnsignedLong())
  4952.       newPageSettings.pageStyle |= (PageSettings::majorTab);
  4953.     if ( tabCtrlItem.ulPageStyle & PageSettings::minorTab.asUnsignedLong())
  4954.       newPageSettings.pageStyle |= (PageSettings::minorTab);
  4955.  
  4956.     newPageSettings.savedUserData = tabCtrlItem.ulUserData;
  4957.  
  4958.     if ( tabCtrlItem.itemHeader.cchTextMax )
  4959.       newPageSettings.savedTabText = IString( tabCtrlItem.itemHeader.pszText );
  4960.  
  4961.     /**************************************************************************/
  4962.     /* Get tab bitmap for the tab page.                                       */
  4963.     /**************************************************************************/
  4964.     if ( fNotebookData->hWndImageList )
  4965.     {
  4966.       IMAGEINFO imageInfo;
  4967.       if ( ImageList_GetImageInfo( fNotebookData->hWndImageList,
  4968.                                    tabCtrlItem.itemHeader.iImage,
  4969.                                    &imageInfo ) )
  4970.       {
  4971.         newPageSettings.savedTabBitmap = IBitmapHandle( imageInfo.hbmImage );
  4972.       }
  4973.       else
  4974.       {
  4975.         ITHROWGUIERROR("ImageList_GetImageInfo");
  4976.       }
  4977.     }
  4978.   } //isPMCompatible()
  4979. #endif //IC_WIN
  4980.  
  4981.   return newPageSettings;
  4982. #endif // IC_PMWIN
  4983. #ifdef IC_MOTIF
  4984.   XmNotebookPageStatus pageStatus;
  4985.   XmNotebookPageInfo pageInfo;
  4986.   INotebook::PageSettings newPageSettings (0);
  4987.  
  4988.   pageStatus = XmNotebookGetPageInfo( fNotebookData->notebook,
  4989.                                       fNotebookData->pageNumber( page ),
  4990.                                       &pageInfo );
  4991.   if (pageStatus == XmPAGE_INVALID)
  4992.     ITHROWGUIERROR("Tried to construct pageSettings for invalid page");
  4993.   if (pageStatus == XmPAGE_DUPLICATED)
  4994.     ITHROWGUIERROR("Tried to construct pageSettings for duplicated page");
  4995.  
  4996.   unsigned long userData = 0;
  4997.   if (pageInfo.status_area_widget != 0)
  4998.   {
  4999.      // The status area widget should always be present.  Get the auto size
  5000.      // and user data information for the page from the page data structure.
  5001.      XtVaGetValues( pageInfo.status_area_widget,
  5002.                     XmNuserData, &userData,
  5003.                     NULL );
  5004.      PageData *pageData = (PageData*)userData;
  5005.      if (pageData->isAutoSize)
  5006.         newPageSettings.pageStyle |= PageSettings::autoPageSize;
  5007.      newPageSettings.savedUserData = pageData->userData;
  5008.  
  5009.      // Get the status text.
  5010.      newPageSettings.savedStatusText =
  5011.         IMString( pageInfo.status_area_widget, XmNlabelString ).asString();
  5012.  
  5013.      newPageSettings.pageStyle |= PageSettings::statusTextOn;
  5014.   }
  5015.  
  5016.   if (pageInfo.major_tab_widget != 0)
  5017.     newPageSettings.pageStyle |= (PageSettings::majorTab);
  5018.   if (pageInfo.minor_tab_widget != 0)
  5019.     newPageSettings.pageStyle |= (PageSettings::minorTab);
  5020.  
  5021.   // Get tab text or bitmap
  5022.   Widget tabWidget = (pageInfo.major_tab_widget != 0) ?
  5023.                         pageInfo.major_tab_widget :
  5024.                         pageInfo.minor_tab_widget;
  5025.   if (tabWidget != 0) {
  5026.     unsigned char labelType;
  5027.     Pixmap pixmap;
  5028.     XtVaGetValues(tabWidget,
  5029.                   XmNlabelType, &labelType,
  5030.                   XmNlabelPixmap, &pixmap,
  5031.                   NULL);
  5032.     if (labelType == XmSTRING) {
  5033.       newPageSettings.savedTabText =
  5034.          IMString( tabWidget, XmNlabelString).asString();
  5035.       //
  5036.       // When the XmNlabelString text was set, the first mnemonic was removed.
  5037.       // Any other mnemonics are left to be displayed.
  5038.       // So if we find a mnemonic in the text now, it should not be removed
  5039.       // the next time the settings are used to set the XmNlabelString text.
  5040.       // In that case, insert a tilde at the beginning of the string.
  5041.       // It will be removed when the XmNlabelString text is set again,
  5042.       // leaving the existing mnemonic unchanged.
  5043.       //
  5044.       IString temp(newPageSettings.savedTabText);
  5045.       if ( IXmLabel::removeMnemonic( temp ) ) {
  5046.         newPageSettings.savedTabText.insert( IString('~') );
  5047.       }
  5048.     }
  5049.     else if (labelType == XmPIXMAP) {
  5050.       newPageSettings.savedTabBitmap = IBitmapHandle (pixmap);
  5051.     }
  5052.   }
  5053.  
  5054.   return newPageSettings;
  5055. #endif
  5056. }
  5057.  
  5058.  
  5059. /*------------------------------------------------------------------------------
  5060. | INotebook::setStatusText                                                     |
  5061. |                                                                              |
  5062. | Change the status text of the specified page in the notebook.                |
  5063. ------------------------------------------------------------------------------*/
  5064. INotebook& INotebook :: setStatusText ( const IPageHandle& page,
  5065.                                         const char* text )
  5066. {
  5067.   ITRACE_WIN_NOP();
  5068.  
  5069. #ifdef IC_PMWIN
  5070.   PageSettings settings = this->pageSettings( page );
  5071.  
  5072.   if ( ! settings.isStatusTextOn() )
  5073.   {           // Ensure the page has a status text area.
  5074.      ITHROWLIBRARYERROR( IC_NOSTATUSTEXTLINE,
  5075.                          IBaseErrorInfo::invalidRequest,
  5076.                          IException::recoverable );
  5077.   }
  5078.   else if ( settings.statusText() != text )
  5079.   {
  5080.     if ( isPMCompatible() )
  5081.     {
  5082.       IString strText( text );         //Avoid compiler warning!
  5083.       IEventResult retVal =
  5084.          this->sendEvent( BKM_SETSTATUSLINETEXT, UPAGE, (char*)strText );
  5085.       if (retVal.asUnsignedLong() == false)
  5086.       {
  5087.          ITHROWGUIERROR( "BKM_SETSTATUSLINETEXT" );
  5088.       }
  5089.     }
  5090.   }
  5091.  
  5092. #endif // IC_PMWIN
  5093. #ifdef IC_MOTIF
  5094.   XmNotebookPageStatus pageStatus;
  5095.   XmNotebookPageInfo   pageInfo;
  5096.  
  5097.   pageStatus = XmNotebookGetPageInfo( fNotebookData->notebook,
  5098.                                       fNotebookData->pageNumber( page ),
  5099.                                       &pageInfo );
  5100.  
  5101.   if (pageStatus == XmPAGE_FOUND || pageStatus == XmPAGE_EMPTY) {
  5102.     if (pageInfo.status_area_widget != 0) {
  5103.       IMString statusText = IMString( text );
  5104.       XtVaSetValues(pageInfo.status_area_widget,
  5105.                     XmNlabelString, (XmString)statusText,
  5106.                     NULL);
  5107.     }
  5108.     else
  5109.       ITHROWGUIERROR("Page not added with statusTextOn");
  5110.   }
  5111.   else
  5112.     ITHROWGUIERROR("Invalid page");
  5113.  
  5114. #endif
  5115.   return *this;
  5116. }
  5117.  
  5118.  
  5119. /*------------------------------------------------------------------------------
  5120. | INotebook::setStatusText                                                     |
  5121. |                                                                              |
  5122. | Change the status text of the specified page in the notebook.                |
  5123. ------------------------------------------------------------------------------*/
  5124. INotebook& INotebook :: setStatusText ( const IPageHandle& page,
  5125.                                           const IResourceId& resId )
  5126. {
  5127.   ITRACE_WIN_NOP();
  5128.  
  5129.   return setStatusText(page,
  5130.                        resId.resourceLibrary().loadString(resId.id()));
  5131. }
  5132.  
  5133.  
  5134. /*------------------------------------------------------------------------------
  5135. | INotebook::setTabText                                                        |
  5136. |                                                                              |
  5137. | Change the tab text of the specified notebook page.                          |
  5138. ------------------------------------------------------------------------------*/
  5139. INotebook& INotebook :: setTabText ( const IPageHandle& page,
  5140.                                      const char* text )
  5141. {
  5142. #ifdef IC_PMWIN
  5143.   IString strText( text );               //Avoid compiler warning!
  5144.  
  5145.   if ( isPMCompatible() )
  5146.   {
  5147.     IEventResult
  5148.        retVal = sendEvent( BKM_SETTABTEXT, UPAGE, (char *)strText );
  5149.     if (retVal.asUnsignedLong() == false)
  5150.     {
  5151.       ITHROWGUIERROR("BKM_SETTABTEXT");
  5152.     }
  5153.   }
  5154. #ifdef IC_WIN
  5155.   else
  5156.   {
  5157.     /**************************************************************************/
  5158.     /* Windows tab control processing                                         */
  5159.     /* ---------------------------------------------------------------------- */
  5160.     /* Locate the notebook page.  If it does not exist, throw an exception.   */
  5161.     /**************************************************************************/
  5162.     INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
  5163.     if ( !tabPageHandleCollection()->locate( page, cursor ) )
  5164.     {
  5165.       ITHROWLIBRARYERROR( IC_INVALIDHANDLE,
  5166.                           IBaseErrorInfo::invalidParameter,
  5167.                           IException::recoverable);
  5168.     }
  5169.  
  5170.     /**************************************************************************/
  5171.     /* Set tab text for the tab page.                                         */
  5172.     /**************************************************************************/
  5173.     IOC_ITEM tabCtrlItem;
  5174.     tabCtrlItem.itemHeader.mask = TCIF_TEXT;
  5175.     tabCtrlItem.itemHeader.pszText = strText;
  5176.     if ( !TabCtrl_SetItem( handle(), tabPageIndex( page ), &tabCtrlItem ) )
  5177.     {
  5178.       ITHROWGUIERROR("TabCtrl_SetItem");
  5179.     }
  5180.   }
  5181. #endif //IC_WIN
  5182. #endif // IC_PMWIN
  5183.  
  5184. #ifdef IC_MOTIF
  5185.   XmNotebookPageStatus pageStatus;
  5186.   XmNotebookPageInfo   pageInfo;
  5187.   Widget tabWidget;
  5188.  
  5189.   pageStatus = XmNotebookGetPageInfo( fNotebookData->notebook,
  5190.                                       fNotebookData->pageNumber( page ),
  5191.                                       &pageInfo );
  5192.  
  5193.   if (pageStatus == XmPAGE_FOUND || pageStatus == XmPAGE_EMPTY) {
  5194.     if ((tabWidget = pageInfo.major_tab_widget) == 0)
  5195.       tabWidget = pageInfo.minor_tab_widget;
  5196.     if (tabWidget == 0)
  5197.       ITHROWGUIERROR("Page not added with a tab");
  5198.  
  5199.     IString itext(text);
  5200.     IXmLabel::removeMnemonic( itext );
  5201.     IMString statusText( itext );
  5202.     XtVaSetValues(tabWidget,
  5203.                   XmNlabelString, (XmString)statusText,
  5204.                   NULL);
  5205.   }
  5206.   else
  5207.     ITHROWGUIERROR("Invalid page");
  5208.  
  5209. #endif // IC_MOTIF
  5210.   return( *this );
  5211. }
  5212.  
  5213.  
  5214. /*------------------------------------------------------------------------------
  5215. | INotebook::setTabText                                                        |
  5216. |                                                                              |
  5217. | Change the tab text of the specified notebook page.                          |
  5218. ------------------------------------------------------------------------------*/
  5219. INotebook& INotebook :: setTabText ( const IPageHandle& page,
  5220.                                      const IResourceId& resId )
  5221. {
  5222.   return setTabText(page,
  5223.                     resId.resourceLibrary().loadString(resId.id()));
  5224. }
  5225.  
  5226.  
  5227. /*------------------------------------------------------------------------------
  5228. | INotebook::setTabBitmap                                                      |
  5229. |                                                                              |
  5230. | Change the tab bitmap for the specified notebook page.                       |
  5231. ------------------------------------------------------------------------------*/
  5232. INotebook& INotebook :: setTabBitmap ( const IPageHandle& page,
  5233.                                        const IBitmapHandle& bitmap )
  5234. {
  5235. #ifdef IC_PMWIN
  5236.   IEventResult retVal;
  5237.  
  5238. #ifdef IC_PM
  5239.   IBitmapHandle desktopBitmap = IBitmapStaticPtr::desktopCompatibleBitmap(bitmap);
  5240. #endif //IC_PM
  5241.  
  5242.   if ( isPMCompatible() )
  5243.   {
  5244.     retVal = sendEvent( BKM_SETTABBITMAP, UPAGE,
  5245. #if defined(IC_WIN)
  5246.                         (unsigned long)(void*)bitmap );
  5247. #elif defined(IC_PM)
  5248.                         (unsigned long)desktopBitmap );
  5249. #elif defined(IC_MOTIF)
  5250.                         (unsigned long)bitmap );
  5251. #endif
  5252.     if (retVal.asUnsignedLong() == false)
  5253.     {
  5254.       ITHROWGUIERROR("BKM_SETTABBITMAP");
  5255.     }
  5256.   }
  5257. #ifdef IC_WIN
  5258.   else
  5259.   {
  5260.     /**************************************************************************/
  5261.     /* Windows tab control processing                                         */
  5262.     /* ---------------------------------------------------------------------- */
  5263.     /* Locate the notebook page.  If it does not exist, throw an exception.   */
  5264.     /**************************************************************************/
  5265.     INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
  5266.     if ( !tabPageHandleCollection()->locate( page, cursor ) )
  5267.     {
  5268.       ITHROWLIBRARYERROR( IC_INVALIDHANDLE,
  5269.                           IBaseErrorInfo::invalidParameter,
  5270.                           IException::recoverable);
  5271.     }
  5272.  
  5273.     /**************************************************************************/
  5274.     /* Get icon/bitmap dimensions.                                            */
  5275.     /**************************************************************************/
  5276.     //SHAJI
  5277.     long lCXIcon = GetSystemMetrics( SM_CXICON );
  5278.     long lCYIcon = GetSystemMetrics( SM_CYICON );
  5279.  
  5280.     IGImage bmpImage( bitmap );
  5281.  
  5282.     IGRect2D cur_rect = IGImage::imageBounds(bmpImage);
  5283.  
  5284.     long lCXIcon_actual = cur_rect.width();
  5285.     long lCYIcon_actual = cur_rect.height();
  5286.  
  5287.     if ( (lCXIcon_actual <= lCXIcon) || (lCYIcon_actual <= lCYIcon) )
  5288.     {
  5289.         lCXIcon = lCXIcon_actual;
  5290.         lCYIcon = lCYIcon_actual;
  5291.     }
  5292.                                  
  5293.     //SHAJI
  5294.  
  5295.     /**************************************************************************/
  5296.     /* We must use an image list per the tab control's requirements.  Create  */
  5297.     /* it if it does not exist.                                               */
  5298.     /**************************************************************************/
  5299.     if ( !fNotebookData->hWndImageList )
  5300.     {
  5301.       /************************************************************************/
  5302.       /* Create the image list to initially contain 10 bitmaps and grow it    */
  5303.       /* by an increment of 10 whenever the current increment list size is    */
  5304.       /* exceeded.  Also, set the bitmap to the system icon size.             */
  5305.       /************************************************************************/
  5306.       fNotebookData->hWndImageList =
  5307.         ImageList_Create( (int)lCXIcon, (int)lCYIcon, ILC_COLOR24, 10, 10 );
  5308.        
  5309.       if ( !fNotebookData->hWndImageList )
  5310.         ITHROWGUIERROR("ImageList_Create");
  5311.  
  5312.       /************************************************************************/
  5313.       /* Set the tab control's image list.                                    */
  5314.       /************************************************************************/
  5315.       TabCtrl_SetImageList( handle(), fNotebookData->hWndImageList );
  5316.     }
  5317.  
  5318.     /**************************************************************************/
  5319.     /* Set the image index in the tab control item that identifies the        */
  5320.     /* bitmap's index in the image list.  Query the tab control item for      */
  5321.     /* the specified page.                                                    */
  5322.     /**************************************************************************/
  5323.     long iPageIndex = tabPageIndex( page );
  5324.     IOC_ITEM tabCtrlItem;
  5325.     tabCtrlItem.itemHeader.mask = TCIF_PARAM | TCIF_IMAGE;
  5326.     if ( !TabCtrl_GetItem( handle(), iPageIndex, &tabCtrlItem ) )
  5327.     {
  5328.       ITHROWGUIERROR("TabCtrl_GetItem");
  5329.     }
  5330.  
  5331.     /**************************************************************************/
  5332.     /* Use an IGBitmap object to size the bitmap to the system icon size.     */
  5333.     /**************************************************************************/
  5334.     //IGImage bmpImage( bitmap );
  5335.     //SHAJI 30397.
  5336.     bmpImage.sizeTo(IGPoint2D((GCoordinate)lCXIcon, (GCoordinate)lCYIcon));
  5337.    
  5338.     /**************************************************************************/
  5339.     /* If the image for the specified page does not exist, add the bitmap     */
  5340.     /* to the image list.                                                     */
  5341.     /**************************************************************************/
  5342.     if ( tabCtrlItem.itemHeader.iImage == -1 )
  5343.     {
  5344.       long
  5345.         retVal = ImageList_Add( fNotebookData->hWndImageList,
  5346.                                 bmpImage.handle(),
  5347.                                 NULL );
  5348.  
  5349.       //If add was not successful, throw an exception
  5350.       if ( retVal == -1 )
  5351.       {
  5352.         ITHROWGUIERROR("ImageList_Add");
  5353.       }
  5354.  
  5355.       /************************************************************************/
  5356.       /* Use the index returned from the add to update the tab control item.  */
  5357.       /************************************************************************/
  5358.       tabCtrlItem.itemHeader.iImage = (int)retVal;
  5359.     }
  5360.     else
  5361.     {
  5362.       /************************************************************************/
  5363.       /* If the image for the specified page exists,  replace it with the     */
  5364.       /* specified bitmap.                                                    */
  5365.       /************************************************************************/
  5366.       if ( !ImageList_Replace( fNotebookData->hWndImageList,
  5367.                                tabCtrlItem.itemHeader.iImage,
  5368.                                bmpImage.handle(),
  5369.                                NULL ) )
  5370.       {
  5371.         ITHROWGUIERROR("ImageList_Replace");
  5372.       }
  5373.     }
  5374.  
  5375.     /**************************************************************************/
  5376.     /* Set the image index in the tab control item that identifies the        */
  5377.     /* bitmap's index in the image list.                                      */
  5378.     /**************************************************************************/
  5379.     if ( !TabCtrl_SetItem( handle(), iPageIndex, &tabCtrlItem ) )
  5380.     {
  5381.       ITHROWGUIERROR("TabCtrl_SetItem");
  5382.     }
  5383.   }
  5384. #endif //IC_WIN
  5385.  
  5386.   ITabBitmapMgr *tmpBitmapMgr = new ITabBitmapMgr(bitmap, page);
  5387.   tmpBitmapMgr->setNext(bmClTabBitmapMgr);
  5388.   bmClTabBitmapMgr = tmpBitmapMgr;
  5389. #endif // IC_PMWIN
  5390.  
  5391. #ifdef IC_MOTIF
  5392.   XmNotebookPageStatus pageStatus;
  5393.   XmNotebookPageInfo   pageInfo;
  5394.   Widget tabWidget;
  5395.  
  5396.   pageStatus = XmNotebookGetPageInfo( fNotebookData->notebook,
  5397.                                       fNotebookData->pageNumber( page ),
  5398.                                       &pageInfo );
  5399.  
  5400.   if (pageStatus == XmPAGE_FOUND || pageStatus == XmPAGE_EMPTY) {
  5401.     if ((tabWidget = pageInfo.major_tab_widget) == 0)
  5402.       tabWidget = pageInfo.minor_tab_widget;
  5403.     if (tabWidget == 0)
  5404.       ITHROWGUIERROR("Page not added with a tab");
  5405.  
  5406.       XtVaSetValues(tabWidget,
  5407.                     XmNlabelType, XmPIXMAP,
  5408.                     XmNlabelPixmap, bitmap,
  5409.                     NULL);
  5410.   }
  5411.   else
  5412.     ITHROWGUIERROR("Invalid page");
  5413.  
  5414.   ITabBitmapMgr *tmpBitmapMgr = new ITabBitmapMgr(bitmap, page);
  5415.   tmpBitmapMgr->setNext(bmClTabBitmapMgr);
  5416.   bmClTabBitmapMgr = tmpBitmapMgr;
  5417.  
  5418. #endif // IC_MOTIF
  5419.   return *this;
  5420. }
  5421.  
  5422.  
  5423. /*------------------------------------------------------------------------------
  5424. | INotebook::setTabBitmap                                                      |
  5425. |                                                                              |
  5426. | Change the tab bitmap for the specified notebook page.                       |
  5427. ------------------------------------------------------------------------------*/
  5428. INotebook& INotebook :: setTabBitmap ( const IPageHandle& page,
  5429.                                        const IResourceId& resId )
  5430. {
  5431.   return setTabBitmap(page,
  5432.                       resId.resourceLibrary().loadBitmap(resId.id()));
  5433. }
  5434.  
  5435.  
  5436. /*------------------------------------------------------------------------------
  5437. | INotebook::setUserData                                                       |
  5438. |                                                                              |
  5439. | Change the user data in the specified notebook page.                         |
  5440. ------------------------------------------------------------------------------*/
  5441. INotebook& INotebook :: setUserData ( const IPageHandle& page,
  5442.                                       unsigned long ulData )
  5443. {
  5444. #ifdef IC_PMWIN
  5445.   if ( isPMCompatible() )
  5446.   {
  5447.     IEventResult
  5448.        retVal = sendEvent( BKM_SETPAGEDATA, UPAGE, ulData );
  5449.     if (retVal.asUnsignedLong() == false)
  5450.     {
  5451.       ITHROWGUIERROR("BKM_SETPAGEDATA");
  5452.     }
  5453.   }
  5454. #ifdef IC_WIN
  5455.   else
  5456.   {
  5457.     /**************************************************************************/
  5458.     /* Windows tab control processing                                         */
  5459.     /* ---------------------------------------------------------------------- */
  5460.     /* Locate the notebook page.  If it does not exist, throw an exception.   */
  5461.     /**************************************************************************/
  5462.     INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
  5463.     if ( !tabPageHandleCollection()->locate( page, cursor ) )
  5464.     {
  5465.       ITHROWLIBRARYERROR( IC_INVALIDHANDLE,
  5466.                           IBaseErrorInfo::invalidParameter,
  5467.                           IException::recoverable);
  5468.     }
  5469.  
  5470.     /**************************************************************************/
  5471.     /* Get the extended tab item data for the tab page.                       */
  5472.     /**************************************************************************/
  5473.     long iPageIndex = tabPageIndex( page );
  5474.     IOC_ITEM tabCtrlItem;
  5475.     tabCtrlItem.itemHeader.mask = TCIF_PARAM;
  5476.     if ( !TabCtrl_GetItem( handle(), iPageIndex, &tabCtrlItem ) )
  5477.     {
  5478.       ITHROWGUIERROR("TabCtrl_GetItem");
  5479.     }
  5480.  
  5481.     /**************************************************************************/
  5482.     /* Set the user data for the tab page.                                    */
  5483.     /**************************************************************************/
  5484.     tabCtrlItem.ulUserData = ulData;
  5485.     if ( !TabCtrl_SetItem( handle(), iPageIndex, &tabCtrlItem ) )
  5486.     {
  5487.       ITHROWGUIERROR("TabCtrl_SetItem");
  5488.     }
  5489.   }
  5490. #endif //IC_WIN
  5491. #endif // IC_PMWIN
  5492. #ifdef IC_MOTIF
  5493.   // Store the user data with the status widget since it is always created
  5494.   // when the page is inserted.
  5495.   XmNotebookPageStatus pageStatus;
  5496.   XmNotebookPageInfo   pageInfo;
  5497.  
  5498.   pageStatus = XmNotebookGetPageInfo( fNotebookData->notebook,
  5499.                                       fNotebookData->pageNumber( page ),
  5500.                                       &pageInfo );
  5501.   if (pageStatus == XmPAGE_FOUND && pageInfo.status_area_widget != 0)
  5502.   {
  5503.      unsigned long userData;
  5504.      XtVaGetValues( pageInfo.status_area_widget,
  5505.                     XmNuserData, &userData,
  5506.                     NULL );
  5507.      PageData *pageData = (PageData*)userData;
  5508.      pageData->userData = ulData;
  5509.   }
  5510. #endif // IC_MOTIF
  5511.   return( *this );
  5512. }
  5513.  
  5514.  
  5515. /*------------------------------------------------------------------------------
  5516. | INotebook::setWindow                                                         |
  5517. |                                                                              |
  5518. | Associates the specified page with the window.                               |
  5519. ------------------------------------------------------------------------------*/
  5520. INotebook& INotebook :: setWindow ( const IPageHandle& page,
  5521.                                     IWindow*           window )
  5522. {
  5523. #ifdef IC_PMWIN
  5524.   IMODTRACE_DEVELOP( "INotebook::setWindow" );
  5525.  
  5526.   /****************************************************************************/
  5527.   /* Throw assertion if window is 0                                           */
  5528.   /****************************************************************************/
  5529.   IASSERTPARM(window != 0);
  5530.  
  5531.   INotebook::PageSettings pageInfo = this->pageSettings( page );
  5532.  
  5533.   if ( isPMCompatible() )
  5534.   {
  5535.     /**************************************************************************/
  5536.     /* CUA '91 notebook processing                                            */
  5537.     /**************************************************************************/
  5538.  
  5539. #ifdef IC_PM
  5540.      // Remove the page window resize handler for the previous page window if
  5541.      // one exists.  Only remove it if the page window is not also the page
  5542.      // window for another page.
  5543.      IWindow *pageWindow = 0;
  5544.      IWindowHandle hwndPageWindow = sendEvent( BKM_QUERYPAGEWINDOWHWND,
  5545.                                                UPAGE,
  5546.                                                0).asUnsignedLong();
  5547.      if (hwndPageWindow)
  5548.         pageWindow = windowWithHandle( hwndPageWindow );
  5549.      if (pageWindow)
  5550.      {
  5551.         Cursor cursor( *this );
  5552.         bool pageWindowFound = false;
  5553.         for (cursor.setToFirst();
  5554.              cursor.isValid() && !pageWindowFound;
  5555.              cursor.setToNext())
  5556.         {
  5557.            IPageHandle currentHandle = cursor.current();
  5558.            if (currentHandle != page &&
  5559.                this->window( currentHandle ) == pageWindow)
  5560.               pageWindowFound = true;
  5561.         }
  5562.         if (!pageWindowFound)
  5563.            fNotebookData->fPageResizeHandler.stopHandlingEventsFor( pageWindow );
  5564.      }
  5565. #endif // IC_PM
  5566.  
  5567. #ifndef IC_WIN
  5568.     /****************************************************************************/
  5569.     /* If the page window is a frame, we need to set the owner to NULL.  The  */
  5570.     /* notebook will set the parent to the page window (id 8006) and then we  */
  5571.     /* can set the owner to the notebook.  (We cannot set the owner to the    */
  5572.     /* notebook initially because this might cause the frame to have the same */
  5573.     /* parent and owner and cause problems).  If the owner of the frame is    */
  5574.     /* not the notebook, a focus loop problem will occur.                     */
  5575.     /**************************************************************************/
  5576.     if ( window->isFrameWindow() )
  5577.       window->setOwner( NULL );
  5578. #endif
  5579.  
  5580. #ifdef IC_WIN
  5581.     unsigned long temphwnd = 0;
  5582.     if (window)
  5583.       temphwnd = (unsigned long)(void*)window->handle();
  5584. #else
  5585.     unsigned long temphwnd = (window ? (unsigned long)window->handle() : 0);
  5586. #endif
  5587.     IEventResult
  5588.        retVal = sendEvent(BKM_SETPAGEWINDOWHWND, UPAGE, temphwnd );
  5589.     if (retVal.asUnsignedLong() == false)
  5590.     {
  5591.       ITHROWGUIERROR("BKM_SETPAGEWINDOWHWND");
  5592.     }
  5593. #ifdef IC_PM
  5594.     else
  5595.     {
  5596.        /***********************************************************************/
  5597.        /* If there is no owner for the page, set it to the notebook.          */
  5598.        /***********************************************************************/
  5599.        if ( window->owner() == NULL )
  5600.          window->setOwner( this );
  5601.     }
  5602.  
  5603.     // Add the page window resize handler for PM.  Only add it if this page
  5604.     // window is not already a page window for another page.
  5605.     Cursor cursor( *this );
  5606.     bool isHandled = false;
  5607.     hwndPageWindow = window->handle();
  5608.     for (cursor.setToFirst();
  5609.          cursor.isValid() && !isHandled;
  5610.          cursor.setToNext())
  5611.     {
  5612.        IPageHandle currentHandle = cursor.current();
  5613.        if (currentHandle != page &&
  5614.            this->window( currentHandle ) == window)
  5615.           isHandled = true;
  5616.     }
  5617.     if (!isHandled)
  5618.        fNotebookData->fPageResizeHandler.handleEventsFor( window );
  5619. #endif // IC_PM
  5620.  
  5621.   }
  5622. #ifdef IC_WIN
  5623.   else
  5624.   {
  5625.     /**************************************************************************/
  5626.     /* Windows tab control processing                                         */
  5627.     /**************************************************************************/
  5628.     if ( pageInfo.isAutoSize() )
  5629.     {
  5630.       pageInfo.fPageSettingsData->tabCtrlItem.ulPageStyle |=
  5631.                                   PageSettings::autoPageSize.asUnsignedLong();
  5632.     }
  5633.     else
  5634.     {
  5635.       pageInfo.fPageSettingsData->tabCtrlItem.ulPageStyle &=
  5636.                                  ~PageSettings::autoPageSize.asUnsignedLong();
  5637.     }
  5638.  
  5639.     /**************************************************************************/
  5640.     /* Add the application page window handle and its parent's handle to our  */
  5641.     /* extended tab control item in addition to any user-defined data.        */
  5642.     /**************************************************************************/
  5643.     pageInfo.fPageSettingsData->tabCtrlItem.hPageWindow = window->handle();
  5644.     pageInfo.fPageSettingsData->tabCtrlItem.hPageWindowParent =
  5645.         ( window->parent() ? window->parent()->handle() : IWindowHandle(0) );
  5646.     pageInfo.fPageSettingsData->tabCtrlItem.ulUserData = pageInfo.userData();
  5647.  
  5648.     pageInfo.fPageSettingsData->tabCtrlItem.itemHeader.mask = TCIF_PARAM;
  5649.     if ( !TabCtrl_SetItem( handle(),
  5650.                            tabPageIndex( page ),
  5651.                            &pageInfo.fPageSettingsData->tabCtrlItem ) )
  5652.     {
  5653.       ITHROWGUIERROR("TabCtrl_SetItem");
  5654.     }
  5655.  
  5656.     /**************************************************************************/
  5657.     /* Make the page clipping window the parent of the application page       */
  5658.     /* window.                                                                */
  5659.     /**************************************************************************/
  5660.     window->setParent( pageClippingWindow() );
  5661.  
  5662.     /**************************************************************************/
  5663.     /* Size and show the application page window if it is on the top page.    */
  5664.     /**************************************************************************/
  5665.     if ( page == topPage() )
  5666.     {
  5667.       /************************************************************************/
  5668.       /* Get the tab control's client area                                    */
  5669.       /************************************************************************/
  5670.       RECTL tabCtrlRect = rect().asRECTL();
  5671.  
  5672.       /************************************************************************/
  5673.       /* Calculate the display rectangle based upon the tab                   */
  5674.       /* control's client area, adjusted                                      */
  5675.       /************************************************************************/
  5676.       adjustRect( false, &tabCtrlRect );
  5677.  
  5678.       /************************************************************************/
  5679.       /* Show the top page window.                                            */
  5680.       /************************************************************************/
  5681.       showTopPage( tabPageIndex( page ), &tabCtrlRect );
  5682.     }
  5683.     else
  5684.     {
  5685.       /************************************************************************/
  5686.       /* Hide the application window since it is not on the top page.          */
  5687.       /************************************************************************/
  5688.       window->hide();
  5689.     }
  5690.   }
  5691. #endif //IC_WIN
  5692. #endif // IC_PMWIN
  5693. #ifdef IC_MOTIF
  5694.   // The Motif Notebook widget isn't really designed to support
  5695.   // setWindow(). Tried to implement this efficiently by setting the
  5696.   // pageNumber resource of the current page_widget to -1 and then
  5697.   // setting window->handle's pageNumber to this page.
  5698.   // That gives us a duplicate page and a null page_widget.
  5699.   // So for now, just:
  5700.  
  5701.   // Save the pageSettings for page whose window will be set
  5702.   INotebook::PageSettings pageSettings = this->pageSettings( page );
  5703.  
  5704.   // Delete the page, but use false flag to leave a "hole" for the page
  5705.   int pageNumber = fNotebookData->pageNumber( page );
  5706.   fNotebookData->deletePages( pageNumber, pageNumber, false);
  5707.  
  5708.   // Add the page using saved settings and new window, put it in the
  5709.   // "hole" left when we deleted original page.
  5710.   addPageAt( pageNumber, pageSettings, window, true );
  5711.  
  5712. #endif
  5713.   return( *this );
  5714. }
  5715.  
  5716.  
  5717. /*------------------------------------------------------------------------------
  5718. | INotebook::setWindow                                                         |
  5719. |                                                                              |
  5720. | Associates the specified page with the window.                               |
  5721. ------------------------------------------------------------------------------*/
  5722. INotebook& INotebook :: setWindow ( const Cursor&  cursor,
  5723.                                     IWindow*       window )
  5724. {
  5725.   return setWindow(cursor.current(), window);
  5726. }
  5727.  
  5728.  
  5729. /*------------------------------------------------------------------------------
  5730. | INotebook::notebookSize                                                      |
  5731. |                                                                              |
  5732. | Return the size of the notebook needed to display a page.                    |
  5733. ------------------------------------------------------------------------------*/
  5734. ISize INotebook :: notebookSize ( const IPageHandle& page ) const
  5735. {
  5736.   ISize pageSize;
  5737.   IWindow *pageWindow = window( page );
  5738.  
  5739.   // If there is no page window set, use the default minimum window size.
  5740.   if (pageWindow == 0)
  5741.   {
  5742.      pageSize = Inherited::calcMinimumSize();
  5743.   }
  5744.   else
  5745.   {
  5746. #ifdef IC_PMWIN
  5747.      // Try a dynamic cast to determine whether the page window is a frame
  5748.      // window.
  5749.      if (dynamic_cast<IFrameWindow*>(pageWindow))
  5750.      {
  5751.         // For dialog page windows, use their actual size.
  5752.         pageSize = pageWindow->size();
  5753.      }
  5754.      else
  5755. #endif // IC_PMWIN
  5756.      {
  5757.         PageSettings settings = pageSettings( page );
  5758.         if (!settings.isAutoSize())
  5759.         {
  5760.            // If the page window is not auto sized, then use its actual
  5761.            // size.
  5762.            pageSize = pageWindow->size();
  5763.         }
  5764.         if (pageSize == ISize())
  5765.         {
  5766.            // if the page window has not been sized yet or it is to be
  5767.            // auto sized, then use its minimum size.
  5768.            pageSize = pageWindow->minimumSize();
  5769.         }
  5770.      }
  5771.   }
  5772.  
  5773. #ifdef IC_PMWIN
  5774.   IRectangle pageRect;
  5775.   RECTL rectlSize;
  5776.  
  5777.   pageRect.sizeTo( pageSize );
  5778.   rectlSize = pageRect.asRECTL();
  5779.  
  5780.   if (isPMCompatible())
  5781.   {
  5782.      IEventResult retVal = handle().sendEvent( BKM_CALCPAGERECT,
  5783.                                                &rectlSize,
  5784.                                                false );
  5785.      if (retVal.asUnsignedLong() == false)
  5786.      {
  5787.         ITHROWGUIERROR( "BKM_CALCPAGERECT" );
  5788.      }
  5789.   }
  5790. #ifdef IC_WIN
  5791.   else
  5792.   {
  5793.      adjustRect( true, &rectlSize );
  5794.   }
  5795. #endif //IC_WIN
  5796.  
  5797.   return ISize( rectlSize );
  5798. #endif // IC_PMWIN
  5799.  
  5800. #ifdef IC_MOTIF
  5801.   // Call widget function to determine the notebook size.
  5802.   Dimension width,
  5803.             height;
  5804.   XuiclMinSize( fNotebookData->notebook,
  5805.                 pageSize.width(),
  5806.                 pageSize.height(),
  5807.                 &width,
  5808.                 &height );
  5809.  
  5810.   return ISize( width, height );
  5811. #endif // IC_MOTIF
  5812. }
  5813.  
  5814. /*------------------------------------------------------------------------------
  5815. | INotebook::pageSize                                                          |
  5816. |                                                                              |
  5817. | Return the size of the "viewport" in which the notebook draws the pages      |
  5818. | it contains.                                                                 |
  5819. ------------------------------------------------------------------------------*/
  5820. ISize INotebook :: pageSize ( ) const
  5821. {
  5822. #ifdef IC_PMWIN
  5823.   RECTL notebookSize = rect().asRECTL();
  5824.  
  5825.   if ( isPMCompatible() )
  5826.   {
  5827.     IEventResult
  5828.        retVal = handle().sendEvent( BKM_CALCPAGERECT,
  5829.                                     ¬ebookSize,
  5830.                                     true);
  5831.     if (retVal.asUnsignedLong() == false)
  5832.     {
  5833.        ITHROWGUIERROR("BKM_CALCPAGERECT");
  5834.     }
  5835.   }
  5836. #ifdef IC_WIN
  5837.   else
  5838.   {
  5839.     adjustRect( false, ¬ebookSize );
  5840.   }
  5841. #endif //IC_WIN
  5842.  
  5843.   return( ISize( notebookSize ) );
  5844. #endif // IC_PMWIN
  5845. #ifdef IC_MOTIF
  5846.   // Call widget function to determine the page size.
  5847.   Dimension width,
  5848.             height;
  5849.   XuiclPageSize( fNotebookData->notebook,
  5850.                  &width,
  5851.                  &height );
  5852.  
  5853.   return ISize( width, height );
  5854. #endif
  5855. }
  5856.  
  5857.  
  5858. /*------------------------------------------------------------------------------
  5859. | INotebook::totalPages                                                        |
  5860. |                                                                              |
  5861. | Return the total number of pages in the notebook.                            |
  5862. ------------------------------------------------------------------------------*/
  5863. unsigned long INotebook :: totalPages ( ) const
  5864. {
  5865. #ifdef IC_PMWIN
  5866.   unsigned long ulRetVal;
  5867.  
  5868.   if ( isPMCompatible() )
  5869.   {
  5870.     ulRetVal = (unsigned long)queryPageCount( 0, MPFROMSHORT (BKA_END) );
  5871.   }
  5872. #ifdef IC_WIN
  5873.   else
  5874.   {
  5875.     ulRetVal = (unsigned long)TabCtrl_GetItemCount( handle() );
  5876.   }
  5877. #endif //IC_WIN
  5878.  
  5879.   return( ulRetVal );
  5880. #endif // IC_PMWIN
  5881. #ifdef IC_MOTIF
  5882.   int firstPage, lastPage;
  5883.   XtVaGetValues(fNotebookData->notebook,
  5884.                 XmNfirstPageNumber, &firstPage,
  5885.                 XmNlastPageNumber, &lastPage,
  5886.                 NULL);
  5887.  
  5888.   if (firstPage == 0 && lastPage == 0)
  5889.      return 0;
  5890.  
  5891.   return (lastPage - firstPage + 1);
  5892. #endif
  5893. }
  5894.  
  5895.  
  5896. /*------------------------------------------------------------------------------
  5897. | INotebook::pagesToMajorTab                                                   |
  5898. |                                                                              |
  5899. | Return the number of pages between the specified page and the next page with |
  5900. | a major tab.                                                                 |
  5901. ------------------------------------------------------------------------------*/
  5902. unsigned long INotebook :: pagesToMajorTab ( const IPageHandle& page ) const
  5903. {
  5904.   ITRACE_WIN_NOP();
  5905.  
  5906. #ifdef IC_PMWIN
  5907.   unsigned long ulRetVal = 1;
  5908.  
  5909.   if ( isPMCompatible() )
  5910.   {
  5911.     ulRetVal = (unsigned long)queryPageCount( MPFROMLONG( UPAGE ),
  5912.                      MPFROMSHORT( PageSettings::majorTab.asUnsignedLong()) );
  5913.   }
  5914.  
  5915.   return( ulRetVal );
  5916. #endif // IC_PMWIN
  5917. #ifdef IC_MOTIF
  5918.   return fNotebookData->pagesToTab( fNotebookData->pageNumber( page ),
  5919.                                     True );
  5920. #endif // IC_MOTIF
  5921. }
  5922.  
  5923.  
  5924. /*------------------------------------------------------------------------------
  5925. | INotebook::pagesToMajorTab                                                   |
  5926. |                                                                              |
  5927. | Return the number of pages between the specified page and the next page with |
  5928. | a major tab.                                                                 |
  5929. ------------------------------------------------------------------------------*/
  5930. unsigned long INotebook :: pagesToMajorTab ( const Cursor& cursor) const
  5931. {
  5932.   ITRACE_WIN_NOP();
  5933.  
  5934.   return pagesToMajorTab(cursor.current());
  5935. }
  5936.  
  5937.  
  5938. /*------------------------------------------------------------------------------
  5939. | INotebook::pagesToMinorTab                                                   |
  5940. |                                                                              |
  5941. | Return the number of pages between the specified page and the next page with |
  5942. | a minor tab.                                                                 |
  5943. ------------------------------------------------------------------------------*/
  5944. unsigned long INotebook :: pagesToMinorTab ( const IPageHandle& page ) const
  5945. {
  5946.   ITRACE_WIN_NOP();
  5947.  
  5948. #ifdef IC_PMWIN
  5949.   unsigned long ulRetVal = 0;
  5950.  
  5951.   if ( isPMCompatible() )
  5952.   {
  5953.     ulRetVal = (unsigned long)queryPageCount( MPFROMLONG( UPAGE ),
  5954.                       MPFROMSHORT( PageSettings::minorTab.asUnsignedLong()) );
  5955.   }
  5956.  
  5957.   return( ulRetVal );
  5958. #endif // IC_PMWIN
  5959. #ifdef IC_MOTIF
  5960.   return fNotebookData->pagesToTab( fNotebookData->pageNumber( page ),
  5961.                                     False );
  5962. #endif
  5963. }
  5964.  
  5965.  
  5966. /*------------------------------------------------------------------------------
  5967. | INotebook::pagesToMinorTab                                                   |
  5968. |                                                                              |
  5969. | Return the number of pages between the specified page and the next page with |
  5970. | a minor tab.                                                                 |
  5971. ------------------------------------------------------------------------------*/
  5972. unsigned long INotebook :: pagesToMinorTab ( const Cursor& cursor ) const
  5973. {
  5974.   ITRACE_WIN_NOP();
  5975.  
  5976.   return pagesToMinorTab(cursor.current());
  5977. }
  5978.  
  5979.  
  5980. /*------------------------------------------------------------------------------
  5981. | INotebook::pagesToEnd                                                        |
  5982. |                                                                              |
  5983. | Return the number of pages between the specified page and the end of the     |
  5984. | notebook.                                                                    |
  5985. ------------------------------------------------------------------------------*/
  5986. unsigned long INotebook :: pagesToEnd ( const IPageHandle& page ) const
  5987. {
  5988. #ifdef IC_PMWIN
  5989.   unsigned long ulRetVal = 0;
  5990.  
  5991.   if ( isPMCompatible() )
  5992.   {
  5993.     ulRetVal = (unsigned long)queryPageCount( MPFROMLONG (UPAGE),
  5994.                                               MPFROMSHORT (BKA_END) );
  5995.   }
  5996. #ifdef IC_WIN
  5997.   else
  5998.   {
  5999.     long lEnd = totalPages() - tabPageIndex( page );
  6000.     if ( lEnd >= 0 )
  6001.     {
  6002.       ulRetVal = lEnd;
  6003.     }
  6004.     else
  6005.     {
  6006.       ITHROWLIBRARYERROR( IC_INVALIDHANDLE,
  6007.                           IBaseErrorInfo::invalidParameter,
  6008.                           IException::recoverable);
  6009.     }
  6010.   }
  6011. #endif //IC_WIN
  6012.  
  6013.   return( ulRetVal );
  6014. #endif // IC_PMWIN
  6015. #ifdef IC_MOTIF
  6016.   int lastPage;
  6017.   XtVaGetValues(fNotebookData->notebook, XmNlastPageNumber, &lastPage, NULL);
  6018.   return (lastPage - fNotebookData->pageNumber( page ) + 1);
  6019. #endif
  6020. }
  6021.  
  6022.  
  6023. /*------------------------------------------------------------------------------
  6024. | INotebook::pagesToEnd                                                        |
  6025. |                                                                              |
  6026. | Return the number of pages between the specified page and the end of the     |
  6027. | notebook.                                                                    |
  6028. ------------------------------------------------------------------------------*/
  6029. unsigned long INotebook :: pagesToEnd ( const Cursor& cursor ) const
  6030. {
  6031.   return pagesToEnd(cursor.current());
  6032. }
  6033.  
  6034.  
  6035. /*------------------------------------------------------------------------------
  6036. | INotebook::isEmpty                                                           |
  6037. |                                                                              |
  6038. | Queries whether the notebook has any pages.                                  |
  6039. ------------------------------------------------------------------------------*/
  6040. bool INotebook :: isEmpty ( ) const
  6041. {
  6042.   if ( totalPages() )
  6043.     return false;
  6044.   else
  6045.     return true;
  6046. }
  6047.  
  6048.  
  6049. #ifdef IC_PMWIN
  6050. /*------------------------------------------------------------------------------
  6051. | INotebook::queryPageCount                                                    |
  6052. |                                                                              |
  6053. | Queries whether the notebook has any pages.                                  |
  6054. ------------------------------------------------------------------------------*/
  6055. short INotebook :: queryPageCount ( void* mp1, void* mp2 ) const
  6056. {
  6057.   short retVal = sendEvent(BKM_QUERYPAGECOUNT, mp1, mp2);
  6058.  
  6059.   if (retVal == BOOKERR_INVALID_PARAMETERS)
  6060.   {
  6061.      ITHROWGUIERROR("BKM_QUERYPAGECOUNT");
  6062.   }
  6063.   return retVal;
  6064. }
  6065. #endif // IC_PMWIN
  6066.  
  6067.  
  6068. #ifdef IC_WIN
  6069. /*------------------------------------------------------------------------------
  6070. | INotebook::setLayoutDistorted                                                |
  6071. |                                                                              |
  6072. | Propagate the font change to the page windows.                               |
  6073. ------------------------------------------------------------------------------*/
  6074. INotebook& INotebook :: setLayoutDistorted ( unsigned long layoutAttributesOn,
  6075.                                              unsigned long layoutAttributesOff )
  6076. {
  6077.   this->Inherited::setLayoutDistorted( layoutAttributesOn, layoutAttributesOff );
  6078.   return *this;
  6079. }
  6080. #endif // IC_WIN
  6081.  
  6082.  
  6083. /*------------------------------------------------------------------------------
  6084. | INotebook::calcMinimumSize                                                   |
  6085. |                                                                              |
  6086. | Calculate the minimum screen size needed by the control.  The height is      |
  6087. | based on the minimum size of the superclass control, with the notebook       |
  6088. | drawing around it.                                                           |
  6089. ------------------------------------------------------------------------------*/
  6090. ISize INotebook :: calcMinimumSize ( ) const
  6091. {
  6092.   // Get notebook rectangle.
  6093.   ISize szLargestBook;
  6094.  
  6095.   // Determine the largest notebook size which is determined by the largest
  6096.   // application page window.
  6097.   for (IPageHandle pageHandle = this->firstPage();
  6098.        pageHandle;
  6099.        pageHandle = this->nextPage( pageHandle ))
  6100.   {
  6101.      ISize szNoteBook = this->notebookSize( pageHandle );
  6102.      szLargestBook = szLargestBook.maximum( szNoteBook );
  6103.   }
  6104.  
  6105.   // If either the width or height is 0, then we must use the control's API
  6106.   // to calculate the minimum size.  This may be the case when no pages have
  6107.   // been added to the notebook.
  6108.   if ((szLargestBook.height() == 0) ||
  6109.       (szLargestBook.width()  == 0))
  6110.   {
  6111.      // Get the default minimum size from our base class.
  6112.      ISize pageSize = this->Inherited::calcMinimumSize();
  6113.  
  6114. #ifdef IC_PMWIN
  6115.      bool bRetVal = true;
  6116.      RECTL pageRect = this->rect().asRECTL();
  6117.  
  6118.      // Using the actual control rectangle, determine the page window rectangle.
  6119.      if (isPMCompatible())
  6120.      {
  6121.         bRetVal = (bool)this->sendEvent( BKM_CALCPAGERECT, &pageRect, true )
  6122.                          .asUnsignedLong();
  6123.      }
  6124. #ifdef IC_WIN
  6125.      else
  6126.      {
  6127.         adjustRect( false, &pageRect );
  6128.      }
  6129. #endif //IC_WIN
  6130.  
  6131.      if (bRetVal)
  6132.      {
  6133.         // Determine the new page rectangle from the adjusted control rectangle
  6134.         // position and the default minimum size for a page window.  Use this
  6135.         // rectangle to determine the minimum size of the notebook.
  6136. #ifdef IC_WIN
  6137.         RECTL newPageRect = IRectangle( IPoint( pageRect.left, pageRect.bottom ),
  6138.                                         pageSize ).asRECTL();
  6139. #endif // IC_WIN
  6140. #ifdef IC_PM
  6141.         RECTL newPageRect = IRectangle( IPoint( pageRect.xLeft, pageRect.yBottom ),
  6142.                                         pageSize ).asRECTL();
  6143. #endif // IC_PM
  6144.  
  6145.         bRetVal = true;
  6146.  
  6147.         if (isPMCompatible())
  6148.         {
  6149.            bRetVal = (bool)this->sendEvent( BKM_CALCPAGERECT, &newPageRect, false )
  6150.                            .asUnsignedLong();
  6151.         }
  6152. #ifdef IC_WIN
  6153.         else
  6154.         {
  6155.            adjustRect( true, &newPageRect );
  6156.         }
  6157. #endif //IC_WIN
  6158.  
  6159.         if (bRetVal)
  6160.         {
  6161.            szLargestBook = ISize( newPageRect );
  6162.         }
  6163.         else
  6164.         {
  6165.            ITHROWGUIERROR( "BKM_CALCPAGERECT" );
  6166.         }
  6167.      }
  6168.      else
  6169.      {
  6170.         ITHROWGUIERROR( "BKM_CALCPAGERECT" );
  6171.      }
  6172. #endif // IC_PMWIN
  6173.  
  6174. #ifdef IC_MOTIF
  6175.      // If the minimum size of the notebook is still (0, 0) then we don't yet have any
  6176.      // pages added to the notebook.  Go ahead and calculate the minimum size of the
  6177.      // notebook using the default page window size.
  6178.      Dimension width,
  6179.                height;
  6180.      XuiclMinSize( fNotebookData->notebook,
  6181.                    pageSize.width(),
  6182.                    pageSize.height(),
  6183.                    &width,
  6184.                    &height );
  6185.  
  6186.      szLargestBook = ISize( width, height );
  6187. #endif // IC_MOTIF
  6188.   }
  6189.  
  6190.   return( szLargestBook );
  6191. }
  6192.  
  6193. #ifdef IC_PMWIN
  6194. /*------------------------------------------------------------------------------
  6195. | INotebook::setNotebookColors                              *** private ***    |
  6196. |                                                                              |
  6197. | This function handles the setting of the notebook colors that are not        |
  6198. | identified by system defined PP_* values.  The notebook has some special     |
  6199. | color areas defined that can only be set using a specific notebook message.  |
  6200. | In addition, the presentation manager notebook does not provide a way to     |
  6201. | query these colors.                                                          |
  6202. ------------------------------------------------------------------------------*/
  6203. void INotebook::setNotebookColors ( unsigned long color,
  6204.                                     unsigned long colorArea )
  6205. {
  6206.   bool colorChanged = false;
  6207.  
  6208.   /********************************************************************/
  6209.   /* Check to see if the current color is different from the color we */
  6210.   /* are trying to set.                                               */
  6211.   /********************************************************************/
  6212.   switch (colorArea)
  6213.   {
  6214.     case BKA_BACKGROUNDPAGECOLOR:
  6215.       if (pageBackgroundColor() != UnsignedLongAsRGB(color))
  6216.       {
  6217.         colorChanged = true;
  6218.       }
  6219.     break;
  6220.  
  6221.     case BKA_BACKGROUNDMAJORCOLOR:
  6222.       if (majorTabBackgroundColor() != UnsignedLongAsRGB(color))
  6223.       {
  6224.         colorChanged = true;
  6225.       }
  6226.     break;
  6227.  
  6228.     case BKA_BACKGROUNDMINORCOLOR:
  6229.       if (minorTabBackgroundColor() != UnsignedLongAsRGB(color))
  6230.       {
  6231.         colorChanged = true;
  6232.       }
  6233.     break;
  6234.  
  6235.     case BKA_FOREGROUNDMAJORCOLOR:
  6236.       if (majorTabForegroundColor() != UnsignedLongAsRGB(color))
  6237.       {
  6238.         colorChanged = true;
  6239.       }
  6240.     break;
  6241.  
  6242.     case BKA_FOREGROUNDMINORCOLOR:
  6243.       if (minorTabForegroundColor() != UnsignedLongAsRGB(color))
  6244.       {
  6245.         colorChanged = true;
  6246.       }
  6247.     break;
  6248.   }
  6249.  
  6250.   if (colorChanged)
  6251.   {
  6252.     /* Set the color on the notebook. */
  6253.     IEventResult
  6254.        retVal = sendEvent(BKM_SETNOTEBOOKCOLORS, color, colorArea);
  6255.     if (retVal.asUnsignedLong() == false)
  6256.     {
  6257.       ITHROWGUIERROR("BKM_SETNOTEBOOKCOLORS");
  6258.     }
  6259.   }
  6260. }
  6261.  
  6262. /*------------------------------------------------------------------------------
  6263. | INotebook::storeNotebookColors                              *** private ***  |
  6264. |                                                                              |
  6265. | This function handles the storing of the notebook colors that are not        |
  6266. | identified by system defined PP_* values.  This enables the colors to be     |
  6267. | querying later since the system notebook does not provide a query mechanism  |
  6268. | of its own.                                                                  |
  6269. ------------------------------------------------------------------------------*/
  6270. void INotebook::storeNotebookColors ( unsigned long color,
  6271.                                       unsigned long colorArea )
  6272. {
  6273.   if (!pnotebookColors)
  6274.   {
  6275.     pnotebookColors = new NotebookColors;
  6276.   }
  6277.  
  6278.   /*******************************************************************/
  6279.   /* Set a flag to indicate which color we are setting and store the */
  6280.   /* color we set so it can be queried later.                        */
  6281.   /*******************************************************************/
  6282.   if (colorArea == BKA_BACKGROUNDPAGECOLOR)
  6283.   {
  6284.     pnotebookColors->pageBackgroundColor = color;
  6285.     colorFlags |= INotebook::bgnPageColor;
  6286.   }
  6287.   else if (colorArea == BKA_BACKGROUNDMAJORCOLOR)
  6288.   {
  6289.     pnotebookColors->majorTabBackgroundColor = color;
  6290.     colorFlags |= INotebook::bgnMajorColor;
  6291.   }
  6292.   else if (colorArea == BKA_BACKGROUNDMINORCOLOR)
  6293.   {
  6294.     pnotebookColors->minorTabBackgroundColor = color;
  6295.     colorFlags |= INotebook::bgnMinorColor;
  6296.   }
  6297.   else if (colorArea == BKA_FOREGROUNDMAJORCOLOR)
  6298.   {
  6299.     pnotebookColors->majorTabForegroundColor = color;
  6300.     colorFlags |= INotebook::fgnMajorColor;
  6301.   }
  6302.   else if (colorArea == BKA_FOREGROUNDMINORCOLOR)
  6303.   {
  6304.     pnotebookColors->minorTabForegroundColor = color;
  6305.     colorFlags |= INotebook::fgnMinorColor;
  6306.   }
  6307. }
  6308. #endif // IC_PMWIN
  6309.  
  6310. /*------------------------------------------------------------------------------
  6311. | INotebook::UnsignedLongAsRGB                            *** private ***      |
  6312. |                                                                              |
  6313. | This function converts an unsigned long to an RGB value and returns it as    |
  6314. | an IColor object.                                                            |
  6315. ------------------------------------------------------------------------------*/
  6316. IColor INotebook::UnsignedLongAsRGB ( unsigned long color ) const
  6317. {
  6318.   /****************************************************************************/
  6319.   /* Convert the long color to an RGB value then to an IColor object.         */
  6320.   /*                                                                          */
  6321.   /* Note: Remember that the calculations for red and blue are flipped in     */
  6322.   /*       Windows.                                                           */
  6323.   /****************************************************************************/
  6324. #ifdef IC_MOTIFPM
  6325.   unsigned char blue  = (unsigned char)(color);
  6326.   unsigned char red   = (unsigned char)(color >> 16);
  6327. #else
  6328.   unsigned char red   = (unsigned char)(color);
  6329.   unsigned char blue  = (unsigned char)(color >> 16);
  6330. #endif //IC_MOTIFPM
  6331.  
  6332.   unsigned char green = (unsigned char)(color >> 8);
  6333.   return IColor(red, green, blue);
  6334. }
  6335.  
  6336.  
  6337. #ifdef IC_WIN
  6338. /*------------------------------------------------------------------------------
  6339. | INotebook::pageClippingWindow                           *** private ***      |
  6340. |                                                                              |
  6341. | This function returns the page clipping window that is used to prevent the   |
  6342. | application page window from drawing over the tab control.                   |
  6343. | using the autoPageSize attribute.                                            |
  6344. ------------------------------------------------------------------------------*/
  6345. IWindow* INotebook::pageClippingWindow ( void ) const
  6346. {
  6347.   return( fNotebookData->pPageClipWindow );
  6348. }
  6349.  
  6350.  
  6351. /*------------------------------------------------------------------------------
  6352. | INotebook::processTabSelect                             *** private ***      |
  6353. |                                                                              |
  6354. ------------------------------------------------------------------------------*/
  6355. bool INotebook :: processTabSelect ( void* pPageSelNotify,
  6356.                                         bool bSelectPending ) const
  6357. {
  6358.   IMODTRACE_DEVELOP( "INotebook::processTabSelect" );
  6359.  
  6360.   PAGESELECTNOTIFY* pPSN = (PAGESELECTNOTIFY *)pPageSelNotify;
  6361.   long iNewPageIndex = tabPageIndex( (void*)pPSN->ulPageIdNew );
  6362.   long iCurrentPageIndex = tabPageIndex( (void*)pPSN->ulPageIdCur );
  6363.  
  6364.   if (bSelectPending)
  6365.   {
  6366.     /**************************************************************************/
  6367.     /* Simulate the CUA '91 notebook's select pending notification            */
  6368.     /**************************************************************************/
  6369.     return( (bool)parent()->handle().sendEvent(
  6370.                                   WM_COMMAND,
  6371.                                   IEventParameter1( (unsigned short)id(),
  6372.                                                     BKN_PAGESELECTEDPENDING ),
  6373.                                   IEventParameter2( pPSN ) ).asUnsignedLong() );
  6374.   }
  6375.   else
  6376.   {
  6377.     /**************************************************************************/
  6378.     /* Simulate the CUA '91 notebook's page selection notification            */
  6379.     /**************************************************************************/
  6380.     parent()->handle().sendEvent( WM_COMMAND,
  6381.                                   IEventParameter1( (unsigned short)id(),
  6382.                                                     BKN_PAGESELECTED ),
  6383.                                   IEventParameter2( pPSN ) );
  6384.   }
  6385.  
  6386.   /****************************************************************************/
  6387.   /* Initialize variables we'll use later.                                    */
  6388.   /****************************************************************************/
  6389.   IOC_ITEM tabCtrlItem;
  6390.   tabCtrlItem.itemHeader.mask = TCIF_PARAM;
  6391.   bool bChangeFocus = false;
  6392.  
  6393.   /****************************************************************************/
  6394.   /* If the current page index equals the new page index, then we are         */
  6395.   /* processing the selection notification that occurs when the first page    */
  6396.   /* is added to the notebook.  If this is the case, do not hide the          */
  6397.   /* application window for the current page.                                 */
  6398.   /****************************************************************************/
  6399.   if ( iCurrentPageIndex != iNewPageIndex )
  6400.   {
  6401.     /**************************************************************************/
  6402.     /* Get the application page window's index for the current tab page.      */
  6403.     /**************************************************************************/
  6404.     if ( !TabCtrl_GetItem( handle(), iCurrentPageIndex, &tabCtrlItem ) )
  6405.     {
  6406.       ITHROWGUIERROR("TabCtrl_GetItem");
  6407.     }
  6408.  
  6409.     /**************************************************************************/
  6410.     /* Hide the application page window for the current tab page if the       */
  6411.     /* application page window exists.  Check to see if it has the focus      */
  6412.     /* before hiding as we will use this indicator later.                     */
  6413.     /**************************************************************************/
  6414.     IWindow* pOldPageWindow = windowWithHandle( tabCtrlItem.hPageWindow );
  6415.     if ( pOldPageWindow )
  6416.     {
  6417.        // We will reset the focus window is the page window or one of its
  6418.        // descendants.
  6419.        for (IWindowHandle hwnd = IQUERYFOCUS( IWindow::desktopWindow() );
  6420.             !bChangeFocus && hwnd;
  6421.             hwnd = IPARENTOF( hwnd ))
  6422.        {
  6423.           if (hwnd == tabCtrlItem.hPageWindow)
  6424.              bChangeFocus = true;
  6425.        }
  6426.        pOldPageWindow->hide();
  6427.  
  6428.        fNotebookData->fTopPageKeyboardHandler.stopHandlingEventsFor(
  6429.                                                                pOldPageWindow );
  6430.     }
  6431.   }
  6432.  
  6433.   /****************************************************************************/
  6434.   /* Get the tab control's client area                                        */
  6435.   /****************************************************************************/
  6436.   RECTL tabCtrlRect = rect().asRECTL();
  6437.  
  6438.   /****************************************************************************/
  6439.   /* Calculate the display rectangle based upon the tab                       */
  6440.   /* control's client area, adjusted                                          */
  6441.   /****************************************************************************/
  6442.   adjustRect( false, &tabCtrlRect );
  6443.  
  6444.   /****************************************************************************/
  6445.   /* Show the new top page window.                                            */
  6446.   /****************************************************************************/
  6447.   showTopPage( iNewPageIndex, &tabCtrlRect );
  6448.  
  6449.   /****************************************************************************/
  6450.   /* If the focus was on the old application page window, set it to the new   */
  6451.   /* application page window if it exists.                                    */
  6452.   /****************************************************************************/
  6453.   if (bChangeFocus)
  6454.   {
  6455.     /**************************************************************************/
  6456.     /* Get the tab item for the newly selected tab page.                      */
  6457.     /**************************************************************************/
  6458.     tabCtrlItem.itemHeader.mask = TCIF_PARAM;
  6459.     if ( !TabCtrl_GetItem( handle(), iNewPageIndex, &tabCtrlItem ) )
  6460.     {
  6461.       ITHROWGUIERROR("TabCtrl_GetItem");
  6462.     }
  6463.  
  6464.     IWindow* pNewPageWindow = windowWithHandle( tabCtrlItem.hPageWindow );
  6465.     if ( pNewPageWindow )
  6466.     {
  6467.       pNewPageWindow->setFocus();
  6468.     }
  6469.   }
  6470.  
  6471.   return( true );
  6472. }
  6473.  
  6474.  
  6475. /*------------------------------------------------------------------------------
  6476. | INotebook::showTopPage                                  *** private ***      |
  6477. |                                                                              |
  6478. | Show the top page.                                                           |
  6479. ------------------------------------------------------------------------------*/
  6480. void INotebook::showTopPage( long iPageIndex, void* pRect,
  6481.                              bool bNotResizing ) const
  6482. {
  6483.   IMODTRACE_DEVELOP( "INotebook::showTopPage" );
  6484.  
  6485.   /****************************************************************************/
  6486.   /* Get the tab control item for the currently selected page.                */
  6487.   /****************************************************************************/
  6488.   IOC_ITEM tabCtrlItem;
  6489.   tabCtrlItem.itemHeader.mask = TCIF_PARAM;
  6490.   if ( !TabCtrl_GetItem( handle(), iPageIndex, &tabCtrlItem ) )
  6491.   {
  6492.     ITHROWGUIERROR("TabCtrl_GetItem");
  6493.   }
  6494.  
  6495.   RECT tabCtrlRect;
  6496.  
  6497.   /****************************************************************************/
  6498.   /* Position, size, and show the page clipping window.  We position and      */
  6499.   /* size it here as well as in the private resize handler to handle the      */
  6500.   /* the tab control's placement on a canvas.  If the tab control is placed   */
  6501.   /* on a canvas, then there is a possibility that a resize event is not      */
  6502.   /* generated.  Hence, we resize here so both the page clipping window and   */
  6503.   /* the application page window are shown.  Note that we must re-calculate   */
  6504.   /* and re-adjust the display rectangle because of this dilemna.             */
  6505.   /****************************************************************************/
  6506.  
  6507.   /**************************************************************************/
  6508.   /* Get the tab control's client area                                      */
  6509.   /**************************************************************************/
  6510.   RECTL tempRectl = rect().asRECTL();
  6511.  
  6512.   /**************************************************************************/
  6513.   /* Calculate the display rectangle based upon the tab                     */
  6514.   /* control's client area, adjusted                                        */
  6515.   /**************************************************************************/
  6516.   SetRect( &tabCtrlRect, 0, 0,
  6517.            (int)(tempRectl.right - tempRectl.left),
  6518.            (int)(tempRectl.bottom - tempRectl.top) );
  6519.  
  6520.   adjustRect( false, &tabCtrlRect );
  6521.  
  6522.   SetWindowPos( pageClippingWindow()->handle(),
  6523.                 NULL, (int)tabCtrlRect.left, (int)tabCtrlRect.top,
  6524.                 (int)(tabCtrlRect.right - tabCtrlRect.left),
  6525.                 (int)(tabCtrlRect.bottom - tabCtrlRect.top),
  6526.                 SWP_NOACTIVATE );
  6527.  
  6528.   if ( !pageClippingWindow()->isVisible() )
  6529.     pageClippingWindow()->show();
  6530.  
  6531.   /****************************************************************************/
  6532.   /* If the application page window exists, position and size it to fit the   */
  6533.   /* tab control's display area, as long as the autoPageSize attribute is     */
  6534.   /* specified.  Also, show it as well.                                       */
  6535.   /****************************************************************************/
  6536.   IWindow* pPageWindow = windowWithHandle( tabCtrlItem.hPageWindow );
  6537.   if ( pPageWindow )
  6538.   {
  6539.     if ( tabCtrlItem.ulPageStyle &
  6540.                      INotebook::PageSettings::autoPageSize.asUnsignedLong() )
  6541.     {
  6542.       SetWindowPos( tabCtrlItem.hPageWindow,
  6543.                     NULL, 0, 0,
  6544.                     (int)(tabCtrlRect.right - tabCtrlRect.left),
  6545.                     (int)(tabCtrlRect.bottom - tabCtrlRect.top),
  6546.                     0 );
  6547.     }
  6548.  
  6549.     if ( !pPageWindow->isVisible() )
  6550.       pPageWindow->show();
  6551.  
  6552.     if ( bNotResizing )
  6553.       fNotebookData->fTopPageKeyboardHandler.handleEventsFor( pPageWindow );
  6554.   }
  6555.   else
  6556.   {
  6557.     /**************************************************************************/
  6558.     /* Otherwise, invalidate the page clipping window so it is repainted.     */
  6559.     /**************************************************************************/
  6560.     pageClippingWindow()->refresh();
  6561.   }
  6562. }
  6563.  
  6564. /*------------------------------------------------------------------------------
  6565. | INotebook::adjustRect                                   *** private ***      |
  6566. |                                                                              |
  6567. | Adjust the display rectangle.                                                |
  6568. ------------------------------------------------------------------------------*/
  6569. void INotebook::adjustRect ( bool bTabCtrlSize, void* pRect ) const
  6570. {
  6571.   IMODTRACE_DEVELOP( "INotebook::adjustRect" );
  6572.  
  6573.   if ( IRectangle( *(LPRECTL)pRect ) != IRectangle() )
  6574.   {
  6575.     if ( isDrawTabsEnabled()  &&  !bTabCtrlSize )
  6576.     {
  6577.       /************************************************************************/
  6578.       /* if owner draw tabs, then we must calculate the display area to       */
  6579.       /* avoid problems that occur when the tab is resized.                   */
  6580.       /************************************************************************/
  6581.       long lTabHeight;
  6582.       if ( fNotebookData->lMajorTabHeight )
  6583.         lTabHeight = fNotebookData->lMajorTabHeight + 4;
  6584.       else
  6585.       {
  6586.         RECT tabRect;
  6587.         TabCtrl_GetItemRect( handle(), 0, &tabRect );
  6588.         lTabHeight = tabRect.top + tabRect.bottom;
  6589.       }
  6590.  
  6591.       ((LPRECTL)pRect)->top += lTabHeight;
  6592.       ((LPRECTL)pRect)->left += 4;
  6593.       ((LPRECTL)pRect)->right -= 4;
  6594.       ((LPRECTL)pRect)->bottom -= 4;
  6595.     }
  6596.     else
  6597.     {
  6598.       TabCtrl_AdjustRect( handle(), bTabCtrlSize, (LPRECTL)pRect );
  6599.     }
  6600.   }
  6601. }
  6602.  
  6603. /*------------------------------------------------------------------------------
  6604. | INotebook::tabControlResize                             *** private ***      |
  6605. |                                                                              |
  6606. | Resize the tab control, page clipping, and application page windows.         |
  6607. ------------------------------------------------------------------------------*/
  6608. void INotebook::tabControlResize ( const ISize& newSize ) const
  6609. {
  6610.   IMODTRACE_DEVELOP( "INotebook::tabControlResize" );
  6611.  
  6612.   /****************************************************************************/
  6613.   /* Calculate the display rectangle, assuming the tab control is the size    */
  6614.   /* of the client area                                                       */
  6615.   /****************************************************************************/
  6616.   RECT tabCtrlRect;
  6617.   SetRect( &tabCtrlRect, 0, 0,
  6618.            (int)newSize.width(),
  6619.            (int)newSize.height() );
  6620.  
  6621.   adjustRect( false, &tabCtrlRect );
  6622.  
  6623.   /****************************************************************************/
  6624.   /* Position and size the page clipping window, and show it if it is not     */
  6625.   /* visible.                                                                 */
  6626.   /****************************************************************************/
  6627.   SetWindowPos( pageClippingWindow()->handle(),
  6628.                 NULL, (int)tabCtrlRect.left, (int)tabCtrlRect.top,
  6629.                 (int)(tabCtrlRect.right - tabCtrlRect.left),
  6630.                 (int)(tabCtrlRect.bottom - tabCtrlRect.top),
  6631.                 SWP_NOACTIVATE );
  6632.  
  6633.   if ( !pageClippingWindow()->isVisible() )
  6634.     pageClippingWindow()->show();
  6635.  
  6636.   /****************************************************************************/
  6637.   /* We are finished if there are no pages in the notebook.                   */
  6638.   /****************************************************************************/
  6639.   if ( !totalPages() )
  6640.   {
  6641.     return;
  6642.   }
  6643.  
  6644.   /****************************************************************************/
  6645.   /* Get the index for the currently selected tab page.                       */
  6646.   /****************************************************************************/
  6647.   long
  6648.     iPageIndex = TabCtrl_GetCurSel( handle() );
  6649.   if ( iPageIndex == -1 )
  6650.   {
  6651.     ITHROWGUIERROR("TabCtrl_GetCurSel");
  6652.   }
  6653.  
  6654.   /****************************************************************************/
  6655.   /* Show the top page window.                                                */
  6656.   /****************************************************************************/
  6657.   showTopPage( iPageIndex, &tabCtrlRect, false );
  6658.  
  6659.   /****************************************************************************/
  6660.   /* Send the new page size notification to simulate PM behavior              */
  6661.   /****************************************************************************/
  6662.   parent()->handle().sendEvent( WM_COMMAND,
  6663.                                 IEventParameter1( (unsigned short)id(),
  6664.                                                   BKN_NEWPAGESIZE ),
  6665.                                 IEventParameter2( handle() ) );
  6666. }
  6667.  
  6668. /*------------------------------------------------------------------------------
  6669. | INotebook::tabPageHandleCollection                      *** private ***      |
  6670. |                                                                              |
  6671. | Returns a pointer to the collection of tab control page handles.             |
  6672. ------------------------------------------------------------------------------*/
  6673. INotebookPageSequence* INotebook :: tabPageHandleCollection( ) const
  6674. {
  6675.   return( this->pTabCtrlPageSeqCl );
  6676. }
  6677.  
  6678. /*------------------------------------------------------------------------------
  6679. | INotebook::tabPageIndex                                 *** private ***      |
  6680. |                                                                              |
  6681. | Returns the tab control page index (0-based) for the given handle.           |
  6682. ------------------------------------------------------------------------------*/
  6683. long INotebook :: tabPageIndex( const IPageHandle& pageHandle ) const
  6684. {
  6685.   long iPageIndex = -1;
  6686.  
  6687.   INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
  6688.   if ( tabPageHandleCollection()->locate( pageHandle, cursor ) )
  6689.   {
  6690.     /**************************************************************************/
  6691.     /* Position is 1-based, and tab page indicies are 0-based, so adjust.     */
  6692.     /**************************************************************************/
  6693.     iPageIndex = tabPageHandleCollection()->position( cursor ) - 1;
  6694.   }
  6695.   return( iPageIndex );
  6696. }
  6697.  
  6698. /*------------------------------------------------------------------------------
  6699. | INotebook::tabPageHandle                                *** private ***      |
  6700. |                                                                              |
  6701. | Returns the tab control page handle for the given index (0-based).           |
  6702. ------------------------------------------------------------------------------*/
  6703. IPageHandle INotebook :: tabPageHandle( unsigned long ulPosition ) const
  6704. {
  6705.   return( tabPageHandleCollection()->elementAtPosition( ulPosition+1 ) );
  6706. }
  6707.  
  6708. /*------------------------------------------------------------------------------
  6709. | INotebook::insertTabPage                                *** private ***      |
  6710. |                                                                              |
  6711. | Adds the tab control page handle at the given position.  Store the page      |
  6712. | handle as the element.  The page handle is unique, as we assign a unique     |
  6713. | value to each page as it is added to the notebook.  Since we add the page    |
  6714. | in the same location in both the tab control and in this equality sequence,  |
  6715. | we can locate the page handle's position in the sequence and use the         |
  6716. | position as the index of the page to the actual tab control.  However,       |
  6717. | positions in the equality sequence are 1-based and the tab control's page    |
  6718. | index is 0-based, so we must remember to adjust the position and index       |
  6719. | where appropriate.                                                           |
  6720. ------------------------------------------------------------------------------*/
  6721. IPageHandle INotebook :: insertTabPage( const PageSettings& pageInfo,
  6722.                                         const IPageHandle& referencePage,
  6723.                                         unsigned long ulPosition )
  6724. {
  6725.   unsigned long ulIndex;
  6726.  
  6727.   /****************************************************************************/
  6728.   /* Create a unique page handle for each page that is inserted.  Never       */
  6729.   /* decrement ulClPagesInserted (unless an exception is thrown).             */
  6730.   /****************************************************************************/
  6731.   ulClPagesInserted++;
  6732.   IPageHandle pageHandle( (void*)ulClPagesInserted  );
  6733.  
  6734.   switch( ulPosition )
  6735.   {
  6736.     case BKA_FIRST:
  6737.     {
  6738.       tabPageHandleCollection()->addAsFirst( pageHandle );
  6739.       ulIndex = 0;
  6740.       break;
  6741.     }
  6742.  
  6743.     case BKA_PREV:
  6744.     {
  6745.       INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
  6746.       if ( tabPageHandleCollection()->locate( referencePage, cursor ) )
  6747.       {
  6748.         tabPageHandleCollection()->addAsPrevious( pageHandle, cursor );
  6749.         ulIndex = tabPageHandleCollection()->position( cursor ) - 1;
  6750.       }
  6751.       else
  6752.       {
  6753.         ulClPagesInserted--;
  6754.  
  6755.         //Throw exception
  6756.         ITHROWLIBRARYERROR(IC_INDEX_OUT_OF_RANGE,
  6757.             IBaseErrorInfo::invalidRequest,
  6758.             IException::recoverable);
  6759.       }
  6760.  
  6761.       break;
  6762.     }
  6763.  
  6764.     case BKA_NEXT:
  6765.     {
  6766.       INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
  6767.       if ( tabPageHandleCollection()->locate( referencePage, cursor ) )
  6768.       {
  6769.         tabPageHandleCollection()->addAsNext( pageHandle, cursor );
  6770.         ulIndex = tabPageHandleCollection()->position( cursor ) - 1;
  6771.       }
  6772.       else
  6773.       {
  6774.         ulClPagesInserted--;
  6775.  
  6776.         //Throw exception
  6777.         ITHROWLIBRARYERROR(IC_INDEX_OUT_OF_RANGE,
  6778.             IBaseErrorInfo::invalidRequest,
  6779.             IException::recoverable);
  6780.       }
  6781.  
  6782.       break;
  6783.     }
  6784.  
  6785.     case BKA_LAST:
  6786.     {
  6787.       tabPageHandleCollection()->addAsLast( pageHandle );
  6788.       ulIndex = totalPages();
  6789.       break;
  6790.     }
  6791.  
  6792.     default:
  6793.       ulClPagesInserted--;
  6794.  
  6795.       //Throw exception
  6796.       ITHROWLIBRARYERROR(IC_INDEX_OUT_OF_RANGE,
  6797.           IBaseErrorInfo::invalidRequest,
  6798.           IException::recoverable);
  6799.       break;
  6800.   } // end switch
  6801.  
  6802.   /****************************************************************************/
  6803.   /* Insert the tab control page at the given index.  Please note that since  */
  6804.   /* we have extended the tab control item, we must include the TCIF_PARAM    */
  6805.   /* style to indicate that additional information is contained within it.    */
  6806.   /****************************************************************************/
  6807.   pageInfo.fPageSettingsData->tabCtrlItem.itemHeader.mask |= TCIF_PARAM;
  6808.  
  6809.   if ( TabCtrl_InsertItem( handle(), ulIndex,
  6810.                            &pageInfo.fPageSettingsData->tabCtrlItem ) == -1 )
  6811.   {
  6812.     ulClPagesInserted--;
  6813.  
  6814.     //If insert was not successful, throw an exception
  6815.     ITHROWGUIERROR("TCM_INSERTITEM");
  6816.   }
  6817.  
  6818.   ulClValidate++;
  6819.  
  6820.   return( pageHandle );
  6821. }
  6822.  
  6823. /*------------------------------------------------------------------------------
  6824. | INotebook::removeTabPage                                *** private ***      |
  6825. |                                                                              |
  6826. | Removes the tab control page handle at the given position.                   |
  6827. ------------------------------------------------------------------------------*/
  6828. bool INotebook :: removeTabPage( const IPageHandle& pageHandle )
  6829. {
  6830.   INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
  6831.   if ( tabPageHandleCollection()->locate( pageHandle, cursor ) )
  6832.   {
  6833.     tabPageHandleCollection()->removeAt( cursor );
  6834.   }
  6835.   return( true );
  6836. }
  6837.  
  6838. #endif  //IC_WIN
  6839.  
  6840. #ifdef IC_MOTIF
  6841. /*------------------------------------------------------------------------------
  6842. | INotebookData::registerCallbacks                                             |
  6843. |                                                                              |
  6844. | Add callbacks and X event handlers for events which notebooks can            |
  6845. | experience.                                                                  |
  6846. ------------------------------------------------------------------------------*/
  6847. void INotebookData::registerCallbacks()
  6848. {
  6849.    // Add the callback to handle the changed flag
  6850.    XtAddCallback( notebook,
  6851.                   XmNpageChangedCallback,
  6852.                   iwindowMotifCallback,
  6853.                   IWindow::windowWithHandle( notebook ));
  6854. }
  6855.  
  6856. /*------------------------------------------------------------------------------
  6857. | INotebookData::unregisterCallbacks                                           |
  6858. |                                                                              |
  6859. | Remove callbacks and X event handlers added in registerCallbacks().          |
  6860. ------------------------------------------------------------------------------*/
  6861. void INotebookData::unregisterCallbacks()
  6862. {
  6863.    // Remove the callback to handle the changed flag
  6864.    XtRemoveCallback( notebook,
  6865.                      XmNpageChangedCallback,
  6866.                      iwindowMotifCallback,
  6867.                      IWindow::windowWithHandle( notebook ));
  6868. }
  6869.  
  6870. #endif // IC_MOTIF
  6871.