home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
notebvac.zip
/
inotebk.cpp
Wrap
C/C++ Source or Header
|
2002-11-05
|
266KB
|
6,871 lines
// Revision: 18 1.39.1.4 source/ui/basectl/inotebk.cpp, notebook, ioc.v400, 001113
/*******************************************************************************
* FILE NAME: inotebk.cpp *
* *
* DESCRIPTION: *
* Implementation of the class(es): *
* IPageHandle *
* INotebook *
* *
* See inotebk0.cpp for the implementation of the platform independent *
* nested classes: *
* INotebook::Cursor *
* INotebook::PageSettings *
* *
* COPYRIGHT: *
* IBM Open Class Library *
* (C) Copyright International Business Machines Corporation 1992, 1997 *
* Licensed Material - Program-Property of IBM - All Rights Reserved. *
* US Government Users Restricted Rights - Use, duplication, or disclosure *
* restricted by GSA ADP Schedule Contract with IBM Corp. *
* *
*******************************************************************************/
#pragma priority( -2147481524 )
extern "C" {
#define INCL_DOSMODULEMGR
#define INCL_WINSYS
#define INCL_WINENTRYFIELDS
#define INCL_WINCLIPBOARD
#define INCL_WININPUT // WM_CHAR, etc.
#define INCL_WINMESSAGEMGR // for WNDPARAM struct
#define INCL_NLS // ES_ANY, ES_SBCS, ES_DBCS, ES_MIXED
#define INCL_WINSTDDRAG
#define INCL_WINWINDOWMGR // WinQueryWindowULong
#define INCL_WINSTDBOOK
#define INCL_WINDIALOGS // Needed for PDLGTEMPLATE in BOOKPAGEINFO
#define INCL_GPI
#include <iwindefs.h>
}
#ifdef IC_MOTIF
#include <notebk.h>
#include <Xm/Label.h>
#include <Xm/PushB.h>
#endif
#ifdef IC_WIN
#ifndef _ICLNOTEBOOKW_
#include <iclnbw.h>
#endif
#include <icctlsta.hpp> // Statics to load dll.
#include <ibmpctl.hpp>
#endif
#include <inotebk.hpp>
#include <inotebk0.hpp>
#include <icconst.h>
#include <icolor.hpp>
#include <iexcept.hpp>
#include <iframe.hpp>
#include <imphdr.hpp>
#include <inotifev.hpp>
#include <irect.hpp>
#include <ireslib.hpp>
#include <istring.hpp>
#include <itrace.hpp>
#ifdef IC_PMWIN
#include <inotehdr.hpp>
#include <isizehdr.hpp>
#include <iwcname.hpp>
#include <ibmpstat.hpp>
#endif // IC_PMWIN
#ifdef IC_WIN
#include <ifont.hpp>
#include <ipagehdr.hpp>
#include <ipainhdr.hpp>
#include <ipainevt.hpp>
#include <ikeyevt.hpp>
#include <igimage.hpp>
#endif //IC_WIN
#ifdef IC_MOTIF
#include <ifont.hpp>
#include <imstring.hpp>
#include <iwinpriv.hpp>
#include <ixmlabel.hpp>
#endif // IC_MOTIF
#ifdef IC_MOTIFWIN
#pragma info(none)
#include <ies2.h>
#pragma info(restore)
#endif // IC_MOTIFWIN
// Segment definitions.
#ifdef IC_PAGETUNE
#define _INOTEBK_CPP_
#include <ipagetun.h>
#endif
#ifdef IC_WIN
extern unsigned long propagationInProgress;
#endif
/*------------------------------------------------------------------------------
| Public notebook styles. |
------------------------------------------------------------------------------*/
const INotebook::Style
INotebook::backPagesBottomRight = BKS_BACKPAGESBR, // 0x00000001
INotebook::backPagesBottomLeft = BKS_BACKPAGESBL, // 0x00000002
INotebook::backPagesTopRight = BKS_BACKPAGESTR, // 0x00000004
INotebook::backPagesTopLeft = BKS_BACKPAGESTL, // 0x00000008
INotebook::majorTabsRight = BKS_MAJORTABRIGHT, // 0x00000010
INotebook::majorTabsLeft = BKS_MAJORTABLEFT, // 0x00000020
INotebook::majorTabsTop = BKS_MAJORTABTOP, // 0x00000040
INotebook::majorTabsBottom = BKS_MAJORTABBOTTOM, // 0x00000080
INotebook::squareTabs ( 0, IBKS_SQUARETABS ), // 0x00000001 *
INotebook::roundedTabs = BKS_ROUNDEDTABS, // 0x00000100
INotebook::polygonTabs = BKS_POLYGONTABS, // 0x00000200
INotebook::solidBinding ( 0, IBKS_SOLIDBIND ), // 0x00000002 *
INotebook::spiralBinding = BKS_SPIRALBIND, // 0x00000400
INotebook::statusTextLeft ( 0, IBKS_STATUSTEXTLEFT ), // 0x00000004 *
INotebook::statusTextRight = BKS_STATUSTEXTRIGHT, // 0x00001000
INotebook::statusTextCenter = BKS_STATUSTEXTCENTER, // 0x00002000
INotebook::tabTextLeft ( 0, IBKS_TABTEXTLEFT ), // 0x00000008 *
INotebook::pmCompatible ( 0, IBKS_PMCOMPATIBLE), // 0x00000010 *
INotebook::allTabsVisible ( 0, IBKS_ALLTABSVISIBLE), // 0x00000020 *
INotebook::handleDrawTabs ( 0, IBKS_HANDLEDRAWTABS), // 0x00000040 *
INotebook::tabTextRight = BKS_TABTEXTRIGHT, // 0x00004000
INotebook::tabTextCenter = BKS_TABTEXTCENTER, // 0x00008000
INotebook::classDefaultStyle ( BKS_BACKPAGESBR |
BKS_MAJORTABRIGHT |
BKS_TABTEXTCENTER |
WS_VISIBLE ,
IBKS_SQUARETABS |
IBKS_SOLIDBIND |
IBKS_STATUSTEXTLEFT );
// 0x00000001 backPagesBottomRight
// 0x00000010 majorTabsRight
// 0x00008000 tabTextCenter
// 0x80000000 visible
// 0x00000001 squareTabs
// 0x00000002 solidBinding
// 0x00000004 statusTextLeft
const INotebook::PageSettings::Attribute
INotebook::PageSettings::noAttribute = 0, // 0x00000000
INotebook::PageSettings::statusTextOn = BKA_STATUSTEXTON, // 0x00000001
INotebook::PageSettings::majorTab = BKA_MAJOR, // 0x00000040
INotebook::PageSettings::minorTab = BKA_MINOR, // 0x00000080
INotebook::PageSettings::autoPageSize = BKA_AUTOPAGESIZE; // 0x00000100
const INotebook::clrFlags
INotebook::bgnPageColor = IBKA_BACKGROUNDPAGECOLOR, // 0x00000001 *
INotebook::bgnMajorColor = IBKA_BACKGROUNDMAJORCOLOR, // 0x00000002 *
INotebook::bgnMinorColor = IBKA_BACKGROUNDMINORCOLOR, // 0x00000004 *
INotebook::fgnMajorColor = IBKA_FOREGROUNDMAJORCOLOR, // 0x00000008 *
INotebook::fgnMinorColor = IBKA_FOREGROUNDMINORCOLOR; // 0x00000010 *
/*------------------------------------------------------------------------------
| Default style for new notebook objects (initial value). |
------------------------------------------------------------------------------*/
INotebook::Style
INotebook::currentDefaultStyle ( BKS_BACKPAGESBR |
BKS_MAJORTABRIGHT |
BKS_TABTEXTCENTER |
WS_VISIBLE ,
IBKS_SQUARETABS |
IBKS_SOLIDBIND |
IBKS_STATUSTEXTLEFT );
#ifdef IC_WIN
bool INotebook::hasBeenRegistered = false;
#endif
#ifdef IC_WIN
#define UPAGE (unsigned long)(void*)page
#endif // IC_WIN
#ifdef IC_PM
#define UPAGE (unsigned long)page
#endif // IC_PM
#ifdef IC_WIN
#define WC_PAGECLIP "IOC Page Clipping Window"
#define ID_PAGECLIP 8000
#endif // IC_WIN
#ifdef IC_MOTIF
// In INotebookData we maintain two arrays that for each colorArea
// define the following info respectively:
// colorSet - whether this color has been set by the user
// curColor - what this color has been set to
// We use PrivateColorArea enum as the index to these arrays.
enum PrivateColorArea {
pcaPageBackground,
pcaMajorTabBackground,
pcaMajorTabForeground,
pcaMinorTabBackground,
pcaMinorTabForeground
};
static const int numColorAreas = pcaMinorTabForeground + 1;
#pragma enum(4)
#pragma pack(push,4)
// Note: In order to keep this struct declaration out of the public
// interface and to avoid creating a new file for just this
// struct, this declaration appears here and in ipageevt.cpp.
// Any changes made here MUST be made in that file as well.
struct PageData
{
unsigned long userData;
unsigned long pageHandle;
bool isAutoSize;
};
#pragma pack(pop)
#pragma enum(pop)
#endif // IC_MOTIF
/*------------------------------------------------------------------------------
| ITabBitmapMgr |
| |
| This class is used to manage the tab bitmaps for a notebook's pages. |
------------------------------------------------------------------------------*/
#pragma enum(4)
#pragma pack(push,4)
class ITabBitmapMgr {
public:
ITabBitmapMgr ( const IBitmapHandle& tabBitmap,
const IPageHandle& pgHandle );
void
setNext ( ITabBitmapMgr* );
ITabBitmapMgr
*next ( );
private:
IBitmapHandle
bitmapHandle;
IPageHandle
pageHandle;
ITabBitmapMgr
*nextInList;
};
#pragma pack(pop)
#pragma enum(pop)
/*------------------------------------------------------------------------------
| ITabBitmapMgr::ITabBitmapMgr |
------------------------------------------------------------------------------*/
ITabBitmapMgr :: ITabBitmapMgr ( const IBitmapHandle& tabBitmap,
const IPageHandle& pgHandle )
{
bitmapHandle = tabBitmap;
pageHandle = pgHandle;
nextInList = 0;
}
/*------------------------------------------------------------------------------
| ITabBitmapMgr::setNext |
------------------------------------------------------------------------------*/
void ITabBitmapMgr :: setNext ( ITabBitmapMgr* nextOne )
{
nextInList = nextOne;
}
/*------------------------------------------------------------------------------
| ITabBitmapMgr::next |
------------------------------------------------------------------------------*/
ITabBitmapMgr* ITabBitmapMgr :: next ( )
{
return nextInList;
}
#ifdef IC_WIN
/*------------------------------------------------------------------------------
| IPageClipPaintHandler |
| |
| Handle paint requests for the page clipping window. |
------------------------------------------------------------------------------*/
#pragma enum(4)
#pragma pack(push,4)
class IPageClipPaintHandler : public IPaintHandler
{
typedef IPaintHandler
Inherited;
public:
IPageClipPaintHandler ( );
virtual
~IPageClipPaintHandler ( );
protected:
virtual bool
paintWindow ( IPaintEvent& event );
};
#pragma pack(pop)
#pragma enum(pop)
/*------------------------------------------------------------------------------
| IPageClipPaintHandler::IPageClipPaintHandler |
| Constructor |
------------------------------------------------------------------------------*/
IPageClipPaintHandler :: IPageClipPaintHandler( )
{}
/*------------------------------------------------------------------------------
| IPageClipPaintHandler::~IPageClipPaintHandler |
| Destructor |
------------------------------------------------------------------------------*/
IPageClipPaintHandler :: ~IPageClipPaintHandler( )
{}
/*------------------------------------------------------------------------------
| IPageClipPaintHandler::paintWindow |
| |
------------------------------------------------------------------------------*/
bool IPageClipPaintHandler :: paintWindow ( IPaintEvent& event )
{
IMODTRACE_DEVELOP( "IPageClipPaintHandler::paintWindow" );
INotebook*
pNotebook = (INotebook *)event.window()->parent();
if (pNotebook)
{
IPresSpaceHandle hps = event.presSpaceHandle();
event.clearBackground( pNotebook->pageBackgroundColor() );
return( true );
}
return( false );
}
/*------------------------------------------------------------------------------
| IPageClipEraseHandler |
| |
| Handle background erase requests for the page clipping window. |
------------------------------------------------------------------------------*/
#pragma enum(4)
#pragma pack(push,4)
class IPageClipEraseHandler : public IHandler
{
typedef IHandler
Inherited;
public:
IPageClipEraseHandler ( );
virtual
~IPageClipEraseHandler ( );
protected:
virtual bool
dispatchHandlerEvent ( IEvent& event );
};
#pragma pack(pop)
#pragma enum(pop)
/*------------------------------------------------------------------------------
| IPageClipEraseHandler::IPageClipEraseHandler |
| Constructor |
------------------------------------------------------------------------------*/
IPageClipEraseHandler :: IPageClipEraseHandler( )
{}
/*------------------------------------------------------------------------------
| IPageClipEraseHandler::~IPageClipEraseHandler |
| Destructor |
------------------------------------------------------------------------------*/
IPageClipEraseHandler :: ~IPageClipEraseHandler( )
{}
/*------------------------------------------------------------------------------
| IPageClipEraseHandler::dispatchHandlerEvent |
| |
------------------------------------------------------------------------------*/
bool IPageClipEraseHandler :: dispatchHandlerEvent( IEvent& event )
{
/****************************************************************************/
/* Only processes WM_ERASEBKGND to prevent default processing */
/****************************************************************************/
switch( event.eventId() )
{
case WM_ERASEBKGND:
event.setResult( true );
return( true );
default:
break;
}
return( false );
}
/*------------------------------------------------------------------------------
| IPageClipWindow |
| |
| Page clipping window class for the Windows tab control implementation. |
| Clips the application page window to the allowable display area within the |
| tab control to prevent it from painting over areas of the control. |
------------------------------------------------------------------------------*/
#pragma enum(4)
#pragma pack(push,4)
class IPageClipWindow : public IWindow
{
public:
IPageClipWindow ( INotebook* parentNbk );
virtual
~IPageClipWindow ( );
private:
IPageClipWindow ( const IPageClipWindow& pageClipWindow );
IPageClipWindow
&operator = ( const IPageClipWindow& pageClipWindow );
IPageClipPaintHandler
fPaintHandler;
IPageClipEraseHandler
fEraseHandler;
};
#pragma pack(pop)
#pragma enum(pop)
/*------------------------------------------------------------------------------
| IPageClipWindow::IPageClipWindow |
| Constructor |
------------------------------------------------------------------------------*/
IPageClipWindow :: IPageClipWindow( INotebook* parentNbk )
: fPaintHandler(),
fEraseHandler()
{
if ( !parentNbk->hasBeenRegistered )
{
WNDCLASS wndClass;
wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
wndClass.lpfnWndProc = DefWindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = GetModuleHandle( 0 );
wndClass.hIcon = 0;
wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
wndClass.lpszMenuName = 0;
wndClass.lpszClassName = WC_PAGECLIP;
if ( RegisterClass( &wndClass ) )
{
parentNbk->hasBeenRegistered = true;
}
else
{
ITHROWGUIERROR("RegisterClass");
}
}
if ( parentNbk->hasBeenRegistered )
{
IWindowHandle
handlePage = create( ID_PAGECLIP,
0,
WS_CHILD | WS_CLIPCHILDREN,
WC_PAGECLIP,
parentNbk->handle(),
IWindowHandle(0),
IRectangle(),
0,
0 );
if ( handlePage.isValid() )
{
setAutoDestroyWindow( true );
startHandlingEventsFor( handlePage );
fPaintHandler.handleEventsFor( this );
fEraseHandler.handleEventsFor( this );
}
else
{
ITHROWGUIERROR("CreateWindow");
}
}
}
/*------------------------------------------------------------------------------
| IPageClipWindow::IPageClipWindow |
| Copy constructor |
------------------------------------------------------------------------------*/
IPageClipWindow :: IPageClipWindow( const IPageClipWindow& pageClipWindow )
{
}
/*------------------------------------------------------------------------------
| IPageClipWindow::operator = |
| Assignment |
------------------------------------------------------------------------------*/
IPageClipWindow& IPageClipWindow ::
operator = ( const IPageClipWindow& pageClipWindow )
{
return( *this );
}
/*------------------------------------------------------------------------------
| IPageClipWindow::~IPageClipWindow |
| Destructor |
------------------------------------------------------------------------------*/
IPageClipWindow :: ~IPageClipWindow( )
{
fPaintHandler.stopHandlingEventsFor( this );
fEraseHandler.stopHandlingEventsFor( this );
}
/*------------------------------------------------------------------------------
| ITopPageKeyboardHandler |
| |
| Process Alt+PageUp, Alt+PageDown, and Alt+UpArrow keys for the application |
| page window that is on top. This handler is only attached to the |
| application page window that is on top. When a new page becomes the top |
| page this handler is removed from the current page and attached to the new |
| top page. |
------------------------------------------------------------------------------*/
#pragma enum(4)
#pragma pack(push,4)
class ITopPageKeyboardHandler : public IHandler
{
typedef IHandler
Inherited;
public:
ITopPageKeyboardHandler ( );
virtual
~ITopPageKeyboardHandler ( );
protected:
bool
dispatchHandlerEvent ( IEvent& event );
};
#pragma pack(pop)
#pragma enum(pop)
/*------------------------------------------------------------------------------
| ITopPageKeyboardHandler::ITopPageKeyboardHandler |
| Constructor |
------------------------------------------------------------------------------*/
ITopPageKeyboardHandler :: ITopPageKeyboardHandler( )
{}
/*------------------------------------------------------------------------------
| ITopPageKeyboardHandler::~ITopPageKeyboardHandler |
| Destructor |
------------------------------------------------------------------------------*/
ITopPageKeyboardHandler :: ~ITopPageKeyboardHandler( )
{}
/*------------------------------------------------------------------------------
| ITopPageKeyboardHandler::dispatchHandlerEvent |
| |
------------------------------------------------------------------------------*/
bool ITopPageKeyboardHandler :: dispatchHandlerEvent( IEvent& event )
{
bool stopProcessingEvent = false;
/****************************************************************************/
/* Only processes WM_SYSKEYDOWN to simulate CUA '91 notebook behavior. */
/****************************************************************************/
switch( event.eventId() )
{
case WM_SYSKEYDOWN:
{
/**********************************************************************/
/* Get a pointer to the notebook object. The parent of the top */
/* application page window is always the page clipping window, and */
/* the parent of the page clipping window is always the notebook. */
/**********************************************************************/
IWindowHandle
hwndControl( event.window()->parent()->parent()->handle() );
if ( !hwndControl )
break;
/**********************************************************************/
/* Only process Windows tab control keyboard events of interest. */
/**********************************************************************/
if ( IWindowClassName( hwndControl ) != WC_TABCONTROL )
break;
/**********************************************************************/
/* Process key events for the Windows tab control. */
/**********************************************************************/
IKeyboardEvent keyevt( event );
if ( !keyevt.isVirtual() || !keyevt.isAltDown() ||
keyevt.isShiftDown() || keyevt.isCtrlDown() )
{
break;
}
/**********************************************************************/
/* Obtain pointer to notebook object. */
/**********************************************************************/
INotebook*
pNotebk = (INotebook*)IWindow::windowWithHandle( hwndControl );
/**********************************************************************/
/* If Alt+PageUp or Alt+PageDown was pressed, send to the notebook */
/* for processing. */
/**********************************************************************/
if ( (keyevt.virtualKey() == IKeyboardEvent::pageUp) ||
(keyevt.virtualKey() == IKeyboardEvent::pageDown) )
{
HWND hwndOldFocus = IQUERYFOCUS(HWND_DESKTOP);
pNotebk->sendEvent( event );
/********************************************************************/
/* If the focus hasn't changed after the page-turn, the application */
/* left it on the old page, so put it on the tab control */
/********************************************************************/
if ( IQUERYFOCUS(HWND_DESKTOP) == hwndOldFocus )
pNotebk->setFocus();
stopProcessingEvent = true;
}
/**********************************************************************/
/* Alt+Up: set the focus to the tab control */
/**********************************************************************/
else if ( keyevt.virtualKey() == IKeyboardEvent::up )
{
pNotebk->setFocus();
stopProcessingEvent = true;
}
} //WM_SYSKEYDOWN
break;
default:
break;
}
return( stopProcessingEvent );
}
#endif // IC_WIN
#ifdef IC_PM
/*------------------------------------------------------------------------------
| IPageResizeHandler |
| |
| This handler is used to workaround a PM problem. The problem manifests |
| itself when a page window is resized subsequent to its being set as a page |
| window in the notebook. When this occurs, the notebook doesn't correctly |
| manage the geometry for the resized page unless it is the page window for |
| the current top page. The fix for this is to add a resize handler to the |
| page windows as they are set in the notebook. The resize handler will reset |
| the page window for the corresponding page if and when the page window is |
| resized. This resetting of the page window causes the PM notebook to |
| correctly cache the new page size and manage the page window geometry before |
| it becomes the top page. |
------------------------------------------------------------------------------*/
#pragma enum(4)
#pragma pack(push,4)
class IPageResizeHandler : public IResizeHandler
{
public:
IPageResizeHandler ( ) { };
virtual
~IPageResizeHandler ( ) { };
protected:
bool
windowResize ( IResizeEvent& event );
};
#pragma pack(pop)
#pragma enum(pop)
/*------------------------------------------------------------------------------
| IPageResizeHandler :: windowResize |
------------------------------------------------------------------------------*/
bool IPageResizeHandler :: windowResize( IResizeEvent& event )
{
// Get the notebook for this page window.
IWindow *pageWindow = event.controlWindow();
INotebook *notebook = 0;
if (pageWindow)
notebook = dynamic_cast<INotebook*>(pageWindow->parent());
if (notebook)
{
// If the top page window is being resized, just return.
if (pageWindow == notebook->window( notebook->topPage()))
return false;
// Reset the page window for the first page found that has this window as
// its page window.
INotebook::Cursor cursor( *notebook );
bool pageFound = false;
for (cursor.setToFirst();
cursor.isValid() && !pageFound;
cursor.setToNext())
{
IPageHandle pageHandle = cursor.current();
if (notebook->window( pageHandle ) == pageWindow)
{
notebook->sendEvent( BKM_SETPAGEWINDOWHWND,
(unsigned long)pageHandle,
(unsigned long)pageWindow->handle() );
pageFound = true;
}
}
}
return false;
}
#endif // IC_PM
#ifdef IC_MOTIFWIN
/*------------------------------------------------------------------------------
| INotebookPageSequence |
------------------------------------------------------------------------------*/
#pragma enum(4)
#pragma pack(push,4)
class INotebookPageSequence : public IEqualitySequence< IPageHandle > {
public:
INotebookPageSequence ( );
~INotebookPageSequence ( );
};
#pragma pack(pop)
#pragma enum(pop)
/*------------------------------------------------------------------------------
| INotebookPageSequence::INotebookPageSequence |
| Constructor |
------------------------------------------------------------------------------*/
INotebookPageSequence :: INotebookPageSequence( )
: IEqualitySequence< IPageHandle >( 20 )
{
}
/*------------------------------------------------------------------------------
| INotebookPageSequence::~INotebookPageSequence |
| Destructor |
------------------------------------------------------------------------------*/
INotebookPageSequence :: ~INotebookPageSequence( )
{
}
#endif // IC_MOTIFWIN
/*------------------------------------------------------------------------------
| INotebookData class definition |
------------------------------------------------------------------------------*/
#pragma enum(4)
#pragma pack(push,4)
class INotebookData
{
public:
INotebookData ( );
~INotebookData ( );
#ifdef IC_PMWIN
INotebookHandler
fdefaultHandler;
IMousePointerHandler
fMousePointerHandler;
#endif
#ifdef IC_PM
IPageResizeHandler
fPageResizeHandler;
#endif // IC_PM
#ifdef IC_WIN
IPageClipWindow
*pPageClipWindow;
HIMAGELIST
hWndImageList; // Image list window handle
long
lMajorTabHeight;
ITopPageKeyboardHandler
fTopPageKeyboardHandler;
#endif
#ifdef IC_MOTIF
void registerCallbacks();
void unregisterCallbacks();
IColor getColor(PrivateColorArea);
void setColor(PrivateColorArea, Pixel value);
void refreshTabs();
void refreshStatus();
void adjustPages(int firstPage, int lastPage,
int adjustment);
int pagesToTab(int startPage, bool gotMajor);
void deletePages(int startPage,
int endPage,
bool removeGaps = true);
int pageNumber( IPageHandle page );
IPageHandle pageHandle( int pageNumber );
// Data members
Widget notebook; // the notebook widget itself
unsigned char statusAlignment;
unsigned char tabAlignment;
// Arrays mentioned above for tracking what ColorAreas have been set and
// what they have been set to.
bool colorSet[numColorAreas];
Pixel curColor[numColorAreas];
// Sizes of major and minor tabs
ISize majorTabSize;
ISize minorTabSize;
// Sequence of page handles and member to maintain next available page
// handle.
INotebookPageSequence
*fPageSequence;
unsigned long
fNextPageHandle;
IString
xlfdString;
#endif // IC_MOTIF
};
#pragma pack(pop)
#pragma enum(pop)
/*------------------------------------------------------------------------------
| INotebookData::INotebookData |
| |
| This class contains the private data and functions necessary for the |
| implementation of the INotebook class. |
------------------------------------------------------------------------------*/
INotebookData::INotebookData()
#ifdef IC_PMWIN
: fdefaultHandler()
, fMousePointerHandler()
#endif
#ifdef IC_PM
, fPageResizeHandler()
#endif // IC_PM
#ifdef IC_WIN
, pPageClipWindow (0)
, hWndImageList (0)
, lMajorTabHeight (0)
, fTopPageKeyboardHandler()
#endif // IC_WIN
#ifdef IC_MOTIF
: notebook(0)
, colorSet()
, curColor()
, majorTabSize()
, minorTabSize()
, statusAlignment(XmALIGNMENT_BEGINNING)
, tabAlignment(XmALIGNMENT_CENTER)
, fPageSequence( 0 )
, fNextPageHandle( 1 )
, xlfdString( "" )
#endif // IC_MOTIF
{
#ifdef IC_MOTIF
int i;
// Indicate that no colorAreas have been set yet
for(i=0;i<numColorAreas;i++)
colorSet[i] = false;
#endif
}
/*------------------------------------------------------------------------------
| INotebookData::~INotebookData |
| |
| Destructor here for page tuning. |
------------------------------------------------------------------------------*/
INotebookData::~INotebookData()
{
#ifdef IC_WIN
// Destroy the page clipping window if it exists
if ( this->pPageClipWindow )
delete this->pPageClipWindow;
// Destroy the image list if it exists
if ( this->hWndImageList )
{
if ( !ImageList_Destroy( this->hWndImageList ) )
ITHROWGUIERROR("ImageList_Destroy");
}
#endif // IC_WIN
#ifdef IC_MOTIF
// Delete the sequence of page handles.
delete fPageSequence;
#endif // IC_MOTIF
}
#ifdef IC_MOTIF
/*------------------------------------------------------------------------------
| INotebookData :: getColor() |
------------------------------------------------------------------------------*/
IColor INotebookData :: getColor(PrivateColorArea colorArea)
{
if (colorSet[colorArea])
return IColor(curColor[colorArea]);
// Color has never been set, have to retrieve pixel values from widgets
// Cruise notebook pages till we find a page with what we're looking for
int firstPage, lastPage;
XtVaGetValues(notebook,
XmNfirstPageNumber, &firstPage,
XmNlastPageNumber, &lastPage,
NULL);
XmNotebookPageStatus pageStatus;
XmNotebookPageInfo pageInfo;
bool keepLooking = true;
Pixel value;
for (int i=firstPage;(i<=lastPage && keepLooking); i++) {
pageStatus = XmNotebookGetPageInfo(notebook, i, &pageInfo);
switch (colorArea) {
case pcaPageBackground:
if (pageInfo.page_widget != 0) {
XtVaGetValues(pageInfo.page_widget,
XmNbackground, &value,
NULL);
keepLooking = false;
}
break;
case pcaMajorTabBackground:
if (pageInfo.major_tab_widget != 0) {
XtVaGetValues(pageInfo.major_tab_widget,
XmNbackground, &value,
NULL);
keepLooking = false;
}
break;
case pcaMajorTabForeground:
if (pageInfo.major_tab_widget != 0) {
XtVaGetValues(pageInfo.major_tab_widget,
XmNforeground, &value,
NULL);
keepLooking = false;
}
break;
case pcaMinorTabBackground:
if (pageInfo.minor_tab_widget != 0) {
XtVaGetValues(pageInfo.minor_tab_widget,
XmNbackground, &value,
NULL);
keepLooking = false;
}
break;
case pcaMinorTabForeground:
if (pageInfo.minor_tab_widget != 0) {
XtVaGetValues(pageInfo.minor_tab_widget,
XmNforeground, &value,
NULL);
keepLooking = false;
}
break;
default:
ITHROWLIBRARYERROR(IC_INVALIDENUMVALUE,IBaseErrorInfo::invalidParameter,
IException::recoverable);
break;
} // end switch
} // end for
if (keepLooking)
// Looked at all the pages and didn't find a widget that matches
// what this hoser wants, so return black same as IWindow functions
return IColor(0,0,0);
else
return IColor(value);
}
/*------------------------------------------------------------------------------
| INotebookData :: setColor() |
------------------------------------------------------------------------------*/
void INotebookData :: setColor(PrivateColorArea colorArea,
Pixel value)
{
// Record that this color area was set and what it was set to
// Future calls to addPageAt() will honor this setting
colorSet[colorArea] = true;
curColor[colorArea] = value;
// Now set this color area on all existing pages of the notebook
int firstPage, lastPage;
XtVaGetValues(notebook,
XmNfirstPageNumber, &firstPage,
XmNlastPageNumber, &lastPage,
NULL);
XmNotebookPageStatus pageStatus;
XmNotebookPageInfo pageInfo;
int pcaPageBackgroundSet = 0;
int pcaMajorTabBackgroundSet = 0;
int pcaMajorTabForegroundSet = 0;
int pcaMinorTabBackgroundSet = 0;
int pcaMinorTabForegroundSet = 0;
for (int i=firstPage;i<=lastPage; i++) {
pageStatus = XmNotebookGetPageInfo(notebook, i, &pageInfo);
switch (colorArea) {
case pcaPageBackground:
if (pageInfo.page_widget != 0) {
IXmColor::setBackgroundColor( pageInfo.page_widget, value );
pcaPageBackgroundSet++;
}
if (pageInfo.status_area_widget != 0) {
IXmColor::setBackgroundColor( pageInfo.status_area_widget, value );
}
break;
case pcaMajorTabBackground:
if (pageInfo.major_tab_widget != 0) {
if ( colorSet[pcaMajorTabForeground] ) // This is a bit faster.
IXmColor::setColor( pageInfo.major_tab_widget,
true, value, curColor[pcaMajorTabForeground] );
else
IXmColor::setBackgroundColor( pageInfo.major_tab_widget, value );
pcaMajorTabBackgroundSet++;
}
break;
case pcaMajorTabForeground:
if (pageInfo.major_tab_widget != 0) {
XtVaSetValues(pageInfo.major_tab_widget,
XmNforeground, value,
NULL);
pcaMajorTabForegroundSet++;
}
break;
case pcaMinorTabBackground:
if (pageInfo.minor_tab_widget != 0) {
if ( colorSet[pcaMinorTabForeground] ) // This is a bit faster.
IXmColor::setColor( pageInfo.minor_tab_widget,
true, value, curColor[pcaMinorTabForeground] );
else
IXmColor::setBackgroundColor( pageInfo.minor_tab_widget, value );
pcaMinorTabBackgroundSet++;
}
break;
case pcaMinorTabForeground:
if (pageInfo.minor_tab_widget != 0) {
XtVaSetValues(pageInfo.minor_tab_widget,
XmNforeground, value,
NULL);
pcaMinorTabForegroundSet++;
}
break;
default:
ITHROWLIBRARYERROR(IC_INVALIDENUMVALUE,IBaseErrorInfo::invalidParameter,
IException::recoverable);
break;
} // end switch
} // end for
IWindow* thisWindow = IWindow::windowWithHandle(notebook);
if (thisWindow) {
if (pcaPageBackgroundSet > 0)
thisWindow->notifyObservers(INotificationEvent(
INotebook::pageBackgroundColorId, *thisWindow));
if (pcaMajorTabBackgroundSet > 0)
thisWindow->notifyObservers(INotificationEvent(
INotebook::majorTabBackgroundColorId, *thisWindow));
if (pcaMajorTabForegroundSet > 0)
thisWindow->notifyObservers(INotificationEvent(
INotebook::majorTabForegroundColorId, *thisWindow));
if (pcaMinorTabBackgroundSet > 0)
thisWindow->notifyObservers(INotificationEvent(
INotebook::minorTabBackgroundColorId, *thisWindow));
if (pcaMinorTabForegroundSet > 0)
thisWindow->notifyObservers(INotificationEvent(
INotebook::minorTabForegroundColorId, *thisWindow));
}
}
/*------------------------------------------------------------------------------
| INotebookData :: refreshStatus |
------------------------------------------------------------------------------*/
void INotebookData :: refreshStatus()
{
// Change all existing status alignment
int firstPage, lastPage;
XtVaGetValues(notebook,
XmNfirstPageNumber, &firstPage,
XmNlastPageNumber, &lastPage,
NULL);
XmNotebookPageStatus pageStatus;
XmNotebookPageInfo pageInfo;
for (int i=firstPage;i<=lastPage; i++) {
pageStatus = XmNotebookGetPageInfo(notebook, i, &pageInfo);
if (pageInfo.status_area_widget != 0)
XtVaSetValues(pageInfo.status_area_widget,
XmNalignment, statusAlignment,
NULL);
} // end for
}
/*------------------------------------------------------------------------------
| INotebookData :: refreshTabs |
------------------------------------------------------------------------------*/
void INotebookData :: refreshTabs()
{
// Change all existing tab alignment and size
int firstPage, lastPage;
XtVaGetValues(notebook,
XmNfirstPageNumber, &firstPage,
XmNlastPageNumber, &lastPage,
NULL);
XmNotebookPageStatus pageStatus;
XmNotebookPageInfo pageInfo;
Widget tabWidget;
Arg args[10];
int n;
for (int i=firstPage;i<=lastPage; i++) {
n = 0;
pageStatus = XmNotebookGetPageInfo(notebook, i, &pageInfo);
if (pageInfo.major_tab_widget != 0) {
tabWidget = pageInfo.major_tab_widget;
if (majorTabSize != ISize()) {
XtSetArg(args[n],XmNresizable, True);
n++;
XtSetArg(args[n],XmNwidth, majorTabSize.width());
n++;
XtSetArg(args[n],XmNheight, majorTabSize.height());
n++;
}
}
else {
tabWidget = pageInfo.minor_tab_widget;
if (minorTabSize != ISize()) {
XtSetArg(args[n],XmNresizable, True);
n++;
XtSetArg(args[n],XmNwidth, minorTabSize.width());
n++;
XtSetArg(args[n],XmNheight, minorTabSize.height());
n++;
}
}
if (tabWidget != 0) {
XtSetArg(args[n], XmNalignment, tabAlignment);
n++;
XtSetValues(tabWidget, args, n);
}
} // end for
}
/*------------------------------------------------------------------------------
| INotebookData :: adjustPages |
| |
| private function for making pages contiguous after add or remove |
------------------------------------------------------------------------------*/
void INotebookData :: adjustPages(int firstPage, int lastPage,
int adjustment)
{
// The interface to this function is a little tricky, but it is private.
// If you had a notebook with pages 1 to 5 and you:
// Add a new page 3:
// firstPage = 3
// lastPage = 5
// adjustment = +1
// RESULT: pages 3-5 become pages 4-6 and the new page will be pg. 3
//
// Delete pages 2-3:
// first page = 4
// last page = 5
// adjustment = -2
// RESULT: pages 4-5 become pages 2-3
// addPageAt call this function BEFORE adding a page.
// deletePages calls this function AFTER deleting the page(s)
XmNotebookPageInfo pageInfo;
XmNotebookPageStatus pageStatus;
int startPage, finishPage, increment;
if (adjustment > 0) { // adjust after an add of one page
startPage = lastPage;
finishPage = firstPage-1;
increment = -1; // adjust working from end to start - avoid duplicates
// so last page is valid in loop below
XtVaSetValues(notebook, XmNlastPageNumber, lastPage+adjustment, NULL);
}
else { // adjust after removing one or more pages
startPage = firstPage;
finishPage = lastPage+1;
increment = 1;
}
// loop to change pageNumber for affected pages
for (int i = startPage; i != finishPage; i+=increment)
{
pageStatus = XmNotebookGetPageInfo(notebook, i, &pageInfo);
if (pageInfo.page_widget != 0)
XtVaSetValues(pageInfo.page_widget, XmNpageNumber, i+adjustment, NULL);
if (pageInfo.status_area_widget != 0)
XtVaSetValues(pageInfo.status_area_widget, XmNpageNumber, i+adjustment, NULL);
if (pageInfo.major_tab_widget != 0)
XtVaSetValues(pageInfo.major_tab_widget, XmNpageNumber, i+adjustment, NULL);
if (pageInfo.minor_tab_widget != 0)
XtVaSetValues(pageInfo.minor_tab_widget, XmNpageNumber, i+adjustment, NULL);
}
// if we filled in a gap now set new last page number
// Couldn't do this before above loop because we would have then
// tried to access an invalid page
if (adjustment < 0)
XtVaSetValues(notebook, XmNlastPageNumber, lastPage+adjustment, NULL);
}
/*------------------------------------------------------------------------------
| INotebookData :: pagesToTab |
| |
| private function called by pagesToMajorTab() and pagesToMinorTab() |
------------------------------------------------------------------------------*/
int INotebookData :: pagesToTab(int startPage, bool gotMajor)
{
bool keepGoing = true;
int origLast, pageCount = 0;
XmNotebookPageInfo pageInfo;
XmNotebookPageStatus pageStatus;
XtVaGetValues(notebook, XmNlastPageNumber, &origLast, NULL);
for(int i = startPage+1; i<=origLast && keepGoing; i++) {
pageStatus = XmNotebookGetPageInfo(notebook, i, &pageInfo);
switch (pageStatus) {
case XmPAGE_FOUND:
case XmPAGE_EMPTY: // empty page could have tab or status area
pageCount++;
if ( (gotMajor && pageInfo.major_tab_widget !=0) ||
(!gotMajor && pageInfo.minor_tab_widget != 0) )
keepGoing = false;
break;
case XmPAGE_INVALID:
ITHROWGUIERROR("Found invalid page");
break;
case XmPAGE_DUPLICATED:
ITHROWGUIERROR("Duplicate pages found in INotebook");
break;
default:
ITHROWGUIERROR("Unexpected pageStatus from XmNotebookGetPageInfo");
} // end switch
} // end for
return pageCount;
}
/*------------------------------------------------------------------------------
| INotebookData :: deletePages |
| |
| private function that removes pages |
------------------------------------------------------------------------------*/
void INotebookData :: deletePages(int startPage,
int endPage,
bool removeGaps)
{
int origFirst, origLast;
XmNotebookPageInfo pageInfo;
XmNotebookPageStatus pageStatus;
XtVaGetValues(notebook,
XmNfirstPageNumber, &origFirst,
XmNlastPageNumber, &origLast,
NULL);
for(int i = startPage; i<=endPage; i++) {
pageStatus = XmNotebookGetPageInfo(notebook, i, &pageInfo);
switch (pageStatus) {
case XmPAGE_FOUND:
case XmPAGE_EMPTY: // empty page could have tab or status area
if (pageInfo.page_widget != 0)
// setting pageNumber to -1 effectively removes the page because
// it can no longer be accessed by the user
XtVaSetValues(pageInfo.page_widget,
XmNpageNumber, -1,
NULL);
// Destroy tab and status widgets associated with the removed page.
// If the page is added back, these will be re created based on the
// PageSettings passed on the add call.
if (pageInfo.status_area_widget != 0)
{
// First delete the page data structure pointer to by the status
// widget's user data.
unsigned long userData;
XtVaGetValues( pageInfo.status_area_widget,
XmNuserData, &userData,
NULL );
delete ((PageData*)userData);
XtDestroyWidget(pageInfo.status_area_widget);
}
if (pageInfo.major_tab_widget != 0)
XtDestroyWidget(pageInfo.major_tab_widget);
if (pageInfo.minor_tab_widget != 0)
XtDestroyWidget(pageInfo.minor_tab_widget);
break;
case XmPAGE_INVALID:
ITHROWGUIERROR("Tried to delete invalid page");
break;
case XmPAGE_DUPLICATED:
ITHROWGUIERROR("Duplicate pages found in INotebook");
break;
default:
ITHROWGUIERROR("Unexpected pageStatus from XmNotebookGetPageInfo");
} // end switch
} // end for
// Get rid of empty pages created by above.
// How we do this depends on where the pages were deleted from.
// But, we don't get rid of gaps when called by setWindow() since
// it will be immediately filling in the gap with a page with the
// new IWindow* value that was passed to it.
if (removeGaps) {
// Deleted all the pages
if (startPage == origFirst && endPage == origLast)
{
XtVaSetValues( notebook,
XmNfirstPageNumber, 0,
XmNlastPageNumber, 0,
NULL );
fPageSequence->removeAll();
}
// Deleted up to the last page
else if (endPage == origLast)
{
XtVaSetValues( notebook,
XmNlastPageNumber, startPage - 1,
NULL );
int removeCnt = endPage - startPage + 1;
for (int i = 1; i <= removeCnt; i++)
{
fPageSequence->removeLast();
}
}
// Deleted somewhere in the middle
else {
int removeCnt = endPage - startPage + 1;
// have to fill in the "hole" left by deleting pages from the middle
adjustPages(endPage+1, origLast,
-removeCnt);
for (int i = 1; i <= removeCnt; i++)
{
fPageSequence->removeAtPosition( startPage );
}
}
} // if removeGaps
}
/*------------------------------------------------------------------------------
| INotebookData :: pageNumber |
| |
| Determine the page number for this page handle. |
------------------------------------------------------------------------------*/
int INotebookData :: pageNumber( IPageHandle page )
{
int pageNumber = 0;
if (!fPageSequence->isEmpty())
{
INotebookPageSequence::Cursor cursor( *fPageSequence );
if (fPageSequence->locate( page, cursor ))
{
pageNumber = fPageSequence->position( cursor );
}
}
return pageNumber;
}
/*------------------------------------------------------------------------------
| INotebookData :: pageHandle |
| |
| Determine the page handle for this page number. |
------------------------------------------------------------------------------*/
IPageHandle INotebookData :: pageHandle( int pageNumber )
{
IPageHandle page( 0 );
XmNotebookPageInfo pageInfo;
XmNotebookPageStatus
pageStatus = XmNotebookGetPageInfo( notebook, pageNumber, &pageInfo );
if ((pageStatus == XmPAGE_FOUND || pageStatus == XmPAGE_EMPTY) &&
pageInfo.status_area_widget)
{
unsigned long userData;
XtVaGetValues( pageInfo.status_area_widget,
XmNuserData, &userData,
NULL );
page = IPageHandle( ((PageData*)userData)->pageHandle );
}
return page;
}
#endif // IC_MOTIF
/*------------------------------------------------------------------------------
| IPageHandle::IPageHandle |
| |
| Class constructor |
------------------------------------------------------------------------------*/
IPageHandle :: IPageHandle ( Value pageId )
: IHandle( pageId )
{}
/*------------------------------------------------------------------------------
| INotebook::INotebook |
| |
| Construct a notebook from a window id, parent, and owner window handles, |
| and initial size rectangle, and a style. |
------------------------------------------------------------------------------*/
INotebook :: INotebook ( unsigned long windowId,
IWindow* parent,
IWindow* pOwner,
const IRectangle& initial,
const Style& style )
: fNotebookData( new INotebookData( ) )
, bmClTabBitmapMgr( 0 )
, pnotebookColors( 0 )
, colorFlags( 0 )
, ulClValidate( 0 )
#ifdef IC_WIN
, pTabCtrlPageSeqCl( 0 )
, ulClPagesInserted( 0 )
#endif
{
// assertions on input parms
IASSERTPARM(parent != 0);
// Save the extended style to make sure we have a copy of it stored
setExtendedStyle( extendedStyle() | style.asExtendedUnsignedLong() );
#ifdef IC_PMWIN
IWindowHandle owner = (pOwner == 0) ? IWindowHandle(0) : pOwner->handle();
// Default notebook window class name
char* windowClass = WC_NOTEBOOK;
#ifdef IC_WIN
if ( isPMCompatible() )
{
// Use CUA '91 notebook control.
// If needed, load the DLL containing the control code.
IControlStatics::loadControlDLL();
}
else
{
//Use native tab control
InitCommonControls();
windowClass = WC_TABCONTROL;
}
#endif
IWindowHandle whNB =
this -> create( windowId,
0,
convertToGUIStyle( style ),
windowClass,
parent->handleForChildCreation(),
owner,
initial,
0,
0,
defaultOrdering(),
convertToGUIStyle( style, true ) );
startHandlingEventsFor( whNB );
fNotebookData->fdefaultHandler.handleEventsFor( this );
fNotebookData->fMousePointerHandler.handleEventsFor( this );
/********************************************************************/
/* pmCompatible style is set for CUA '91 notebook in both PM and */
/* Windows. If this style is not set, treat the notebook as a */
/* Windows tab control. */
/********************************************************************/
if ( isPMCompatible() )
{
// Set Default Major Tab Dimensions
SHORT MajorTabWidth = 50;
SHORT MajorTabHeight = 30;
setMajorTabSize( ISize(MajorTabWidth,MajorTabHeight) );
// Set Default Minor Tab Dimensions
SHORT MinorTabWidth = 50;
SHORT MinorTabHeight = 30;
setMinorTabSize( ISize(MinorTabWidth,MinorTabHeight) );
// Set Default DogEar Dimensions
SHORT DogEarWidth = 30;
SHORT DogEarHeight = 20;
setPageButtonSize( ISize(DogEarWidth,DogEarHeight) );
}
#ifdef IC_WIN
else
{
//Create the page clipping window
fNotebookData->pPageClipWindow = new IPageClipWindow( this );
//Since we have defined our own tab control item structure, we must
//indicate the number of extra bytes in addition to the TC_ITEMHEADER
//structure. The TC_ITEMHEADER structure must be the first field in
//the new item structure.
if ( !TabCtrl_SetItemExtra( whNB,
sizeof(IOC_ITEM) - sizeof(TC_ITEMHEADER) ) )
{
ITHROWGUIERROR("TabCtrl_SetItemExtra");
}
//Create the tab page sequence collection
pTabCtrlPageSeqCl = new INotebookPageSequence( );
//The tab control automatically sizes the tabs based upon the
//tab text and/or bitmap size. We do not need to set a default
//size.
}
#endif //IC_WIN
#endif // IC_PMWIN
#ifdef IC_MOTIF
Arg args[9];
int n = 0;
IRectangle activeRect = initial;
// Signals addPageAt() that it's got an empty notebook
// Need this to prevent getting a blank first page
XtSetArg(args[n], XmNfirstPageNumber, 0); n++;
XtSetArg(args[n], XmNlastPageNumber, 0); n++;
// There are geometry problems in the Notebook widget if it has
// no size, so give it a default. It will be sized to its parent
// anyway.
if (initial == IRectangle())
activeRect.sizeTo(ISize(200,200));
IWindowHandle notebook =
Inherited::create(
windowId,
NULL,
style.asUnsignedLong(),
(IXmCreateFunction)XmCreateNotebook,
parent->handleForChildCreation(),
pOwner ? pOwner->handle() : desktopWindow()->handle(),
activeRect,
args,
n);
// Save Widget in private data and use this rather than
// always calling handle()
fNotebookData->notebook = notebook;
// Create a page sequence used to store unique page handles for the
// notebook.
fNotebookData->fPageSequence = new INotebookPageSequence();
startHandlingEventsFor( notebook );
fNotebookData->registerCallbacks();
// Set appearance programmatically
if ( style != IWindow::noStyle ) {
// Binding
if (style & spiralBinding)
setBinding(spiral);
// Orientation
if (style & backPagesBottomLeft)
if (style & majorTabsLeft)
setOrientation(backpagesBottomTabsLeft);
else
setOrientation(backpagesLeftTabsBottom);
else if (style & backPagesBottomRight)
if (style & majorTabsRight)
setOrientation(backpagesBottomTabsRight);
else
setOrientation(backpagesRightTabsBottom);
else if (style & backPagesTopLeft)
if (style & majorTabsLeft)
setOrientation(backpagesTopTabsLeft);
else
setOrientation(backpagesLeftTabsBottom);
else if (style & backPagesTopRight)
if (style & majorTabsRight)
setOrientation(backpagesTopTabsRight);
else
setOrientation(backpagesRightTabsTop);
// Tab shape
// noop for now
// Status alignment
if (style & statusTextLeft)
setStatusTextAlignment(left);
else if (style & statusTextCenter)
setStatusTextAlignment(center);
else if (style & statusTextRight)
setStatusTextAlignment(right);
// Tab alignment
if (style & tabTextLeft)
setTabTextAlignment(left);
else if (style & tabTextCenter)
setTabTextAlignment(center);
else if (style & tabTextRight)
setTabTextAlignment(right);
} // if noStyle off
// Default Tab Dimensions from the PM version
int MajorTabWidth = 50;
int MajorTabHeight = 30;
int MinorTabWidth = 50;
int MinorTabHeight = 30;
#if 0
// Default DogEar Dimensions from the PM version
int DogEarWidth = 30;
int DogEarHeight = 20;
// Set the various notebook dimensions
// Need a fix to the notebook widget itself for this to have
// any effect.
setPageButtonSize( ISize(DogEarWidth,DogEarHeight) );
setMajorTabSize( ISize(MajorTabWidth,MajorTabHeight) );
setMinorTabSize( ISize(MinorTabWidth,MinorTabHeight) );
#endif
#endif // IC_MOTIF
}
#ifdef IC_PMWIN
/*------------------------------------------------------------------------------
| INotebook::INotebook |
| |
| Construct a notebook from a window id and the window handle which serves |
| as both parent and owner. |
------------------------------------------------------------------------------*/
INotebook :: INotebook( unsigned long windowId,
IWindow* parentAndOwner )
: fNotebookData( new INotebookData( ) )
, bmClTabBitmapMgr( 0 )
, pnotebookColors( 0 )
, colorFlags( 0 )
, ulClValidate( 0 )
#ifdef IC_WIN
, pTabCtrlPageSeqCl( 0 )
, ulClPagesInserted( 0 )
#endif
{
IASSERTPARM(parentAndOwner != 0);
setAutoDestroyWindow(false);
reserveUserWindowWord( false );
startHandlingEventsFor(windowId, parentAndOwner);
#ifdef IC_PMWIN
fNotebookData->fdefaultHandler.handleEventsFor( this );
fNotebookData->fMousePointerHandler.handleEventsFor( this );
#ifdef IC_WIN
/********************************************************************/
/* Get the window class of the control window to determine if */
/* we're dealing with a tab control. */
/********************************************************************/
IWindowHandle
hwndControl = IWindow::handleWithParent( windowId,
parentAndOwner->handle() );
if ( IWindowClassName( hwndControl ) == WC_TABCONTROL )
{
//Create the page clipping window
fNotebookData->pPageClipWindow = new IPageClipWindow( this );
//Since we have defined our own tab control item structure, we must
//indicate the number of extra bytes in addition to the TC_ITEMHEADER
//structure. The TC_ITEMHEADER structure must be the first field in
//the new item structure.
if ( !TabCtrl_SetItemExtra( hwndControl,
sizeof(IOC_ITEM) - sizeof(TC_ITEMHEADER) ) )
{
ITHROWGUIERROR("TabCtrl_SetItemExtra");
}
//Create the tab page sequence collection
pTabCtrlPageSeqCl = new INotebookPageSequence( );
//The tab control automatically sizes the tabs based upon the
//tab text and/or bitmap size. We do not need to set a default
//size, so we return.
return;
}
#endif
// Set Default Major Tab Dimensions
SHORT MajorTabWidth = 50;
SHORT MajorTabHeight = 30;
setMajorTabSize( ISize(MajorTabWidth,MajorTabHeight) );
// Set Default Minor Tab Dimensions
SHORT MinorTabWidth = 50;
SHORT MinorTabHeight = 30;
setMinorTabSize( ISize(MinorTabWidth,MinorTabHeight) );
// Set Default DogEar Dimensions
SHORT DogEarWidth = 30;
SHORT DogEarHeight = 20;
setPageButtonSize( ISize(DogEarWidth,DogEarHeight) );
#endif // IC_PMWIN
#ifdef IC_MOTIF
fNotebookData->notebook = handleWithId(windowId, parentAndOwner->handle());
#endif
}
#endif
#ifdef IC_PMWIN
/*------------------------------------------------------------------------------
| INotebook::INotebook |
| |
| Constructor to instantiate from an existing notebook control. |
------------------------------------------------------------------------------*/
INotebook :: INotebook ( const IWindowHandle& handle )
: fNotebookData( new INotebookData( ) )
, bmClTabBitmapMgr( 0 )
, pnotebookColors( 0 )
, colorFlags( 0 )
, ulClValidate( 0 )
#ifdef IC_WIN
, pTabCtrlPageSeqCl( 0 )
, ulClPagesInserted( 0 )
#endif
{
setAutoDestroyWindow(false);
reserveUserWindowWord( false );
startHandlingEventsFor(handle);
fNotebookData->fdefaultHandler.handleEventsFor( this );
fNotebookData->fMousePointerHandler.handleEventsFor( this );
#ifdef IC_WIN
/********************************************************************/
/* Get the window class of the control window to determine if */
/* we're dealing with a tab control. */
/********************************************************************/
if ( IWindowClassName( handle ) == WC_TABCONTROL )
{
//Create the page clipping window
fNotebookData->pPageClipWindow = new IPageClipWindow( this );
//Since we have defined our own tab control item structure, we must
//indicate the number of extra bytes in addition to the TC_ITEMHEADER
//structure. The TC_ITEMHEADER structure must be the first field in
//the new item structure.
if ( !TabCtrl_SetItemExtra( handle,
sizeof(IOC_ITEM) - sizeof(TC_ITEMHEADER) ) )
{
ITHROWGUIERROR("TabCtrl_SetItemExtra");
}
//Create the tab page sequence collection
pTabCtrlPageSeqCl = new INotebookPageSequence( );
}
#endif
}
#endif // IC_PMWIN
/*------------------------------------------------------------------------------
| INotebook::~INotebook |
| |
------------------------------------------------------------------------------*/
INotebook :: ~INotebook ( )
{
#ifdef IC_PMWIN
fNotebookData->fdefaultHandler.stopHandlingEventsFor( this );
fNotebookData->fMousePointerHandler.stopHandlingEventsFor( this );
delete (pnotebookColors);
while (bmClTabBitmapMgr) // Remove the associated bitmap managers
{
ITabBitmapMgr *tmpTabBitmapMgr = bmClTabBitmapMgr;
bmClTabBitmapMgr = bmClTabBitmapMgr->next();
delete tmpTabBitmapMgr;
}
#ifdef IC_WIN
if ( !isPMCompatible() )
{
if (pTabCtrlPageSeqCl)
delete pTabCtrlPageSeqCl;
}
#endif
#endif // IC_PMWIN
#ifdef IC_MOTIF
while (bmClTabBitmapMgr) // Remove the associated bitmap managers
{
ITabBitmapMgr *tmpTabBitmapMgr = bmClTabBitmapMgr;
delete tmpTabBitmapMgr;
bmClTabBitmapMgr = bmClTabBitmapMgr->next();
}
if (fNotebookData && isValid())
fNotebookData->unregisterCallbacks();
#endif
delete fNotebookData;
}
/*------------------------------------------------------------------------------
| INotebook::defaultStyle |
| |
| Return the default style for new notebook objects. |
------------------------------------------------------------------------------*/
INotebook::Style INotebook :: defaultStyle ( )
{
return currentDefaultStyle;
}
#ifdef IC_WIN
/*------------------------------------------------------------------------------
| INotebook::setDefaultStyle |
| |
| Sets the default style. |
| |
| Note: This function is inlined on all platforms except Windows due to |
| variables it references not being exported. |
------------------------------------------------------------------------------*/
void INotebook::setDefaultStyle ( const INotebook::Style& style )
{
currentDefaultStyle = style;
}
#endif //IC_WIN
/*------------------------------------------------------------------------------
| INotebook::convertToGUIStyle |
| |
| Returns base style for the control by default, or extended style if |
| extended flag (bExtOnly) is set. |
------------------------------------------------------------------------------*/
unsigned long INotebook::convertToGUIStyle ( const IBitFlag& guiStyle,
bool bExtOnly ) const
{
// Obtain the style from the class (IControl) that we inherit from
unsigned long ulStyle = Inherited::convertToGUIStyle( guiStyle, bExtOnly );
if (bExtOnly)
{
// Use mask to only return extended styles in the user defined range
ulStyle |= guiStyle.asExtendedUnsignedLong() & IS_EXTMASK;
}
else
{
#ifdef IC_WIN
if ( !isPMCompatible() )
{
// Add the new styles required by the tab control
ulStyle |= TCS_TABS | TCS_SINGLELINE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
// Set the multiple row tab style if requested
ulStyle |= ( guiStyle.asExtendedUnsignedLong() &
allTabsVisible.asExtendedUnsignedLong() ) ? TCS_MULTILINE : 0;
// Set the owner draw tab style if requested
ulStyle |= ( guiStyle.asExtendedUnsignedLong() &
handleDrawTabs.asExtendedUnsignedLong() ) ? TCS_OWNERDRAWFIXED
: 0;
}
else
{
#endif // IC_WIN
// BKS_ styles use all but one of their available bits in the lower
// word of the base GUI style. Therefore, obtain that portion asis,
// masking out the upper word. Four of the styles were denoted as
// 0 (OS/2 PM), due to the lack of available bits. We are representing
// those as extended bits so we or the developer can accurately test
// for them later. Since their native values are 0, we do not have to
// do any additional processing here.
ulStyle |= guiStyle.asUnsignedLong() & IBKS_MASK;
#ifdef IC_WIN
}
ulStyle |= WS_CHILD;
#endif // IC_WIN
}
return( ulStyle );
}
#ifdef IC_MOTIF
// Bitmaps used for spiral binding in setBinding()
#define spiral_width 24
#define spiral_height 18
static char spiral_bits[] = {
0x00, 0x0c, 0x00, 0xc0, 0x0f, 0x00, 0xe0, 0x0c, 0x00, 0x38, 0x0c, 0x00,
0x8c, 0x0f, 0x00, 0xc6, 0x0d, 0x00, 0x66, 0x0c, 0x00, 0x62, 0x0c, 0x00,
0x66, 0x0c, 0x00, 0xc6, 0x0c, 0x1e, 0x8c, 0x0d, 0x3f, 0x18, 0x8e, 0x7f,
0x70, 0xf8, 0x73, 0xc0, 0x01, 0x70, 0x00, 0x0f, 0x7c, 0x00, 0xfc, 0x3f,
0x00, 0x0c, 0x1e, 0x00, 0x0c, 0x00};
#define spiral90_width 18
#define spiral90_height 24
static char spiral90_bits[] = {
0x00,0x00,0x00,0xe0,0x03,0x00,0x70,0x07,0x00,0x18,0x0c,0x00,0x08,0x18,0x00,
0xcc,0x11,0x00,0xe6,0x33,0x00,0x36,0x26,0x00,0x32,0x64,0x00,0x12,0x48,0x00,
0xff,0xcf,0x03,0xff,0xdf,0x03,0x00,0x90,0x00,0x00,0x90,0x00,0x00,0x90,0x00,
0x00,0x98,0x00,0x00,0x9c,0x00,0x00,0x9e,0x01,0x00,0xce,0x01,0x00,0xce,0x01,
0x00,0xfe,0x01,0x00,0xfc,0x00,0x00,0x78,0x00,0x00,0x00,0x00};
#define spiral180_width 24
#define spiral180_height 18
static char spiral180_bits[] = {
0x00,0x30,0x00,0x00,0xf0,0x03,0x00,0x30,0x07,0x00,0x30,0x1c,0x00,0xf0,0x31,
0x00,0xb0,0x63,0x00,0x30,0x66,0x00,0x30,0x46,0x00,0x30,0x66,0x78,0x30,0x63,
0xfc,0xb0,0x31,0xfe,0x71,0x18,0xce,0x1f,0x0e,0x0e,0x80,0x03,0x3e,0xf0,0x00,
0xfc,0x3f,0x00,0x78,0x30,0x00,0x00,0x30,0x00};
#define spiral270_width 18
#define spiral270_height 24
static char spiral270_bits[] = {
0x00,0x00,0x00,0x00,0x78,0x00,0x00,0xfc,0x00,0x00,0xfe,0x01,0x00,0xce,0x01,
0x00,0xce,0x01,0x00,0x9e,0x01,0x00,0x9c,0x00,0x00,0x98,0x00,0x00,0x90,0x00,
0x00,0x90,0x00,0x00,0x90,0x00,0xff,0xdf,0x03,0xff,0xcf,0x03,0x12,0x48,0x00,
0x32,0x64,0x00,0x36,0x26,0x00,0xe6,0x33,0x00,0xcc,0x11,0x00,0x08,0x18,0x00,
0x18,0x0c,0x00,0x70,0x07,0x00,0xe0,0x03,0x00,0x00,0x00,0x00};
#endif // IC_MOTIF
/*------------------------------------------------------------------------------
| INotebook::setBinding |
| |
| Set the binding style of the notebook. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setBinding ( Binding binding )
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
unsigned long ulStyle = style();
unsigned long ulOldStyle = ulStyle;
unsigned long ulExtStyle = extendedStyle();
if (binding == spiral)
{
ulStyle |= spiralBinding.asUnsignedLong();
ulExtStyle &= ~solidBinding.asExtendedUnsignedLong();
}
else if (binding == solid)
{
ulStyle &= ~spiralBinding.asUnsignedLong();
ulExtStyle |= solidBinding.asExtendedUnsignedLong();
}
else
{
ITHROWLIBRARYERROR(IC_INVALIDENUMVALUE,
IBaseErrorInfo::invalidParameter,
IException::recoverable);
}
if (ulStyle != ulOldStyle)
{
setStyle(ulStyle);
refresh();
// Update extended style ...
setExtendedStyle(ulExtStyle);
}
}
#endif // IC_PMWIN
#ifdef IC_MOTIF
if (binding == solid)
XtVaSetValues(fNotebookData->notebook,
XmNbindingType, XmSOLID,
NULL);
else
{
Pixel fg, bg;
Pixmap tile;
unsigned int width, height;
char* bitData;
Display* display = XtDisplay(fNotebookData->notebook);
XtVaGetValues(fNotebookData->notebook,
XmNforeground, &fg,
XmNbackground, &bg,
XmNbindingPixmap, &tile,
NULL);
if (tile != XmUNSPECIFIED_PIXMAP)
XFreePixmap(display, tile);
switch(orientation())
{
case backpagesLeftTabsBottom:
case backpagesRightTabsBottom:
bitData = spiral90_bits;
width = spiral90_width;
height = spiral90_height;
break;
case backpagesRightTabsTop:
case backpagesLeftTabsTop:
bitData = spiral270_bits;
width = spiral270_width;
height = spiral270_height;
break;
case backpagesBottomTabsRight:
case backpagesTopTabsRight:
bitData = spiral_bits;
width = spiral_width;
height = spiral_height;
break;
case backpagesBottomTabsLeft:
case backpagesTopTabsLeft:
bitData = spiral180_bits;
width = spiral180_width;
height = spiral180_height;
break;
} // end switch
tile = XCreatePixmapFromBitmapData(display,
RootWindow(display, DefaultScreen(display)),
bitData,
width, height,
fg, bg,
DefaultDepthOfScreen(XtScreen(fNotebookData->notebook)));
XtVaSetValues(fNotebookData->notebook,
XmNbindingType, XmPIXMAP,
XmNbindingPixmap, tile,
NULL);
}
#endif // IC_MOTIF
return( *this );
}
/*------------------------------------------------------------------------------
| INotebook::setOrientation |
| |
| Set the orientation style of the notebook. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setOrientation ( Orientation orientation )
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
unsigned long ulStyle = style();
unsigned long ulOldStyle = ulStyle;
unsigned long ulMask = ~(backPagesBottomRight.asUnsignedLong() |
backPagesBottomLeft.asUnsignedLong() |
backPagesTopRight.asUnsignedLong() |
backPagesTopLeft.asUnsignedLong() |
majorTabsRight.asUnsignedLong() |
majorTabsLeft.asUnsignedLong() |
majorTabsTop.asUnsignedLong() |
majorTabsBottom.asUnsignedLong());
ulStyle &= ulMask;
switch (orientation)
{
case backpagesBottomTabsRight:
ulStyle |= (backPagesBottomRight.asUnsignedLong() |
majorTabsRight.asUnsignedLong());
break;
case backpagesTopTabsRight:
ulStyle |= (backPagesTopRight.asUnsignedLong() |
majorTabsRight.asUnsignedLong());
break;
case backpagesBottomTabsLeft:
ulStyle |= (backPagesBottomLeft.asUnsignedLong() |
majorTabsLeft.asUnsignedLong());
break;
case backpagesTopTabsLeft:
ulStyle |= (backPagesTopLeft.asUnsignedLong() |
majorTabsLeft.asUnsignedLong());
break;
case backpagesRightTabsTop:
ulStyle |= (backPagesTopRight.asUnsignedLong() |
majorTabsTop.asUnsignedLong());
break;
case backpagesLeftTabsTop:
ulStyle |= (backPagesTopLeft.asUnsignedLong() |
majorTabsTop.asUnsignedLong());
break;
case backpagesRightTabsBottom:
ulStyle |= (backPagesBottomRight.asUnsignedLong() |
majorTabsBottom.asUnsignedLong());
break;
case backpagesLeftTabsBottom:
ulStyle |= (backPagesBottomLeft.asUnsignedLong() |
majorTabsBottom.asUnsignedLong());
break;
default:
ITHROWLIBRARYERROR(IC_INVALIDENUMVALUE,
IBaseErrorInfo::invalidParameter,
IException::recoverable);
break;
}
if (ulStyle != ulOldStyle)
{
setStyle(ulStyle);
refresh();
notifyObservers(INotificationEvent(INotebook::orientationId,
*this, true, (void*)orientation));
}
}
#endif // IC_PMWIN
#ifdef IC_MOTIF
unsigned char pagePlacement = XmBOTTOM_RIGHT,
nbOrientation = XmHORIZONTAL;
switch (orientation)
{
case backpagesBottomTabsRight:
pagePlacement = XmBOTTOM_RIGHT;
nbOrientation = XmHORIZONTAL;
break;
case backpagesTopTabsRight:
pagePlacement = XmTOP_RIGHT;
nbOrientation = XmHORIZONTAL;
break;
case backpagesBottomTabsLeft:
pagePlacement = XmBOTTOM_LEFT;
nbOrientation = XmHORIZONTAL;
break;
case backpagesTopTabsLeft:
pagePlacement = XmTOP_LEFT;
nbOrientation = XmHORIZONTAL;
break;
case backpagesRightTabsTop:
pagePlacement = XmTOP_RIGHT;
nbOrientation = XmVERTICAL;
break;
case backpagesLeftTabsTop:
pagePlacement = XmTOP_LEFT;
nbOrientation = XmVERTICAL;
break;
case backpagesRightTabsBottom:
pagePlacement = XmBOTTOM_RIGHT;
nbOrientation = XmVERTICAL;
break;
case backpagesLeftTabsBottom:
pagePlacement = XmBOTTOM_LEFT;
nbOrientation = XmVERTICAL;
break;
}
XtVaSetValues(fNotebookData->notebook,
XmNbackPagePlacement, pagePlacement,
XmNorientation, nbOrientation,
NULL);
// May need a new binding pixmap if using spiral binding
if (binding() == spiral)
setBinding(spiral);
this->notifyObservers(INotificationEvent(INotebook::orientationId,
*this, true, (void*)orientation));
#endif // IC_MOTIF
return( *this );
}
/*------------------------------------------------------------------------------
| INotebook::setTabShape |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setTabShape ( TabShape tabShape )
{
ITRACE_MOTIF_NOP();
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
unsigned long ulStyle = style();
unsigned long ulOldStyle = ulStyle;
unsigned long ulExtStyle = extendedStyle();
unsigned long ulMask = ~(roundedTabs.asUnsignedLong() |
polygonTabs.asUnsignedLong());
ulStyle &= ulMask;
ulExtStyle &= ~squareTabs.asExtendedUnsignedLong();
switch (tabShape)
{
case square:
ulExtStyle |= squareTabs.asExtendedUnsignedLong();
break;
case rounded:
ulStyle |= roundedTabs.asUnsignedLong();
break;
case polygon:
ulStyle |= polygonTabs.asUnsignedLong();
break;
default:
ITHROWLIBRARYERROR(IC_INVALIDENUMVALUE,
IBaseErrorInfo::invalidParameter,
IException::recoverable);
break;
}
if (ulStyle != ulOldStyle)
{
setStyle(ulStyle);
refresh();
// Update extended style ...
setExtendedStyle(ulExtStyle);
}
}
#endif
return( *this );
}
/*------------------------------------------------------------------------------
| INotebook::setStatusTextAlignment |
| |
| Set the alignment style of the text in the notebook's status line. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setStatusTextAlignment ( TextAlignment align )
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
unsigned long ulStyle = style();
unsigned long ulOldStyle = ulStyle;
unsigned long ulExtStyle = extendedStyle();
unsigned long ulMask = ~(statusTextRight.asUnsignedLong() |
statusTextCenter.asUnsignedLong());
ulStyle &= ulMask;
ulExtStyle &= ~statusTextLeft.asExtendedUnsignedLong();
switch (align)
{
case left:
ulExtStyle |= statusTextLeft.asExtendedUnsignedLong();
break;
case right:
ulStyle |= statusTextRight.asUnsignedLong();
break;
case center:
ulStyle |= statusTextCenter.asUnsignedLong();
break;
default:
ITHROWLIBRARYERROR(IC_INVALIDENUMVALUE,
IBaseErrorInfo::invalidParameter,
IException::recoverable);
break;
}
if (ulStyle != ulOldStyle)
{
setStyle(ulStyle);
refresh();
// Update extended style ...
setExtendedStyle(ulExtStyle);
}
}
#endif // IC_PMWIN
#ifdef IC_MOTIF
switch (align)
{
case left:
if (fNotebookData->statusAlignment == XmALIGNMENT_BEGINNING)
return *this;
fNotebookData->statusAlignment = XmALIGNMENT_BEGINNING;
break;
case right:
if (fNotebookData->statusAlignment == XmALIGNMENT_END)
return *this;
fNotebookData->statusAlignment = XmALIGNMENT_END;
break;
case center:
if (fNotebookData->statusAlignment == XmALIGNMENT_CENTER)
return *this;
fNotebookData->statusAlignment = XmALIGNMENT_CENTER;
break;
}
fNotebookData->refreshStatus();
#endif // IC_MOTIF
return( *this );
}
/*------------------------------------------------------------------------------
| INotebook::setTabTextAlignment |
| |
| Set the alignment of the text in the notebook's tabs. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setTabTextAlignment ( TextAlignment align )
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
unsigned long ulStyle = style();
unsigned long ulOldStyle = ulStyle;
unsigned long ulExtStyle = extendedStyle();
unsigned long ulMask = ~(tabTextRight.asUnsignedLong() |
tabTextCenter.asUnsignedLong());
ulStyle &= ulMask;
ulExtStyle &= ~statusTextLeft.asExtendedUnsignedLong();
switch (align)
{
case left:
ulExtStyle |= tabTextLeft.asExtendedUnsignedLong();
break;
case right:
ulStyle |= tabTextRight.asUnsignedLong();
break;
case center:
ulStyle |= tabTextCenter.asUnsignedLong();
break;
default:
ITHROWLIBRARYERROR(IC_INVALIDENUMVALUE,
IBaseErrorInfo::invalidParameter,
IException::recoverable);
break;
}
if (ulStyle != ulOldStyle)
{
setStyle(ulStyle);
refresh();
// Update extended style ...
setExtendedStyle(ulExtStyle);
}
}
#endif // IC_PMWIN
#ifdef IC_MOTIF
switch (align)
{
case left:
if (fNotebookData->tabAlignment == XmALIGNMENT_BEGINNING)
return *this;
fNotebookData->tabAlignment = XmALIGNMENT_BEGINNING;
break;
case right:
if (fNotebookData->tabAlignment == XmALIGNMENT_END)
return *this;
fNotebookData->tabAlignment = XmALIGNMENT_END;
break;
case center:
if (fNotebookData->tabAlignment == XmALIGNMENT_CENTER)
return *this;
fNotebookData->tabAlignment = XmALIGNMENT_CENTER;
break;
}
fNotebookData->refreshTabs();
#endif // IC_MOTIF
return( *this );
}
/*------------------------------------------------------------------------------
| INotebook::binding |
------------------------------------------------------------------------------*/
INotebook::Binding INotebook :: binding ( ) const
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
return( (style() & spiralBinding.asUnsignedLong()) ? INotebook::spiral
: INotebook::solid );
}
else
{
return( INotebook::solid ); //return default
}
#endif // IC_PMWIN
#ifdef IC_MOTIF
unsigned char bindingType;
XtVaGetValues(fNotebookData->notebook,
XmNbindingType, &bindingType,
NULL);
// For a spiral binding we set the Pixmap in setBinding()
if (bindingType == XmPIXMAP)
return INotebook::spiral;
return INotebook::solid;
#endif
}
/*------------------------------------------------------------------------------
| INotebook::orientation |
------------------------------------------------------------------------------*/
INotebook::Orientation INotebook :: orientation ( ) const
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
unsigned long ulStyle = style();
INotebook::Orientation currentOrientation(backpagesRightTabsBottom);
if (ulStyle & majorTabsRight.asUnsignedLong())
{
if (ulStyle & backPagesBottomRight.asUnsignedLong())
currentOrientation = INotebook::backpagesBottomTabsRight;
else
currentOrientation = INotebook::backpagesTopTabsRight;
}
else if (ulStyle & majorTabsLeft.asUnsignedLong())
{
if (ulStyle & backPagesBottomLeft.asUnsignedLong())
currentOrientation = INotebook::backpagesBottomTabsLeft;
else
currentOrientation = INotebook::backpagesTopTabsLeft;
}
else if (ulStyle & majorTabsTop.asUnsignedLong())
{
if (ulStyle & backPagesTopLeft.asUnsignedLong())
currentOrientation = INotebook::backpagesLeftTabsTop;
else
currentOrientation = INotebook::backpagesRightTabsTop;
}
else if (ulStyle & majorTabsBottom.asUnsignedLong())
{
if (ulStyle & backPagesBottomLeft.asUnsignedLong())
currentOrientation = INotebook::backpagesLeftTabsBottom;
else
currentOrientation = INotebook::backpagesRightTabsBottom;
}
return currentOrientation;
}
else
{
return( INotebook::backpagesRightTabsTop );
}
#endif
#ifdef IC_MOTIF
unsigned char bPP, ornt;
XtVaGetValues(fNotebookData->notebook,
XmNbackPagePlacement, &bPP,
XmNorientation, &ornt,
NULL);
INotebook::Orientation currentOrientation(backpagesRightTabsBottom);
if (bPP == XmBOTTOM_RIGHT)
{
if (ornt == XmHORIZONTAL)
currentOrientation = INotebook::backpagesBottomTabsRight;
else
currentOrientation = INotebook::backpagesRightTabsBottom;
}
else if (bPP == XmBOTTOM_LEFT)
{
if (ornt == XmHORIZONTAL)
currentOrientation = INotebook::backpagesBottomTabsLeft;
else
currentOrientation = INotebook::backpagesLeftTabsBottom;
}
else if (bPP == XmTOP_RIGHT)
{
if (ornt == XmHORIZONTAL)
currentOrientation = INotebook::backpagesTopTabsRight;
else
currentOrientation = INotebook::backpagesRightTabsTop;
}
else if (bPP == XmTOP_LEFT)
{
if (ornt == XmHORIZONTAL)
currentOrientation = INotebook::backpagesTopTabsLeft;
else
currentOrientation = INotebook::backpagesLeftTabsTop;
}
return currentOrientation;
#endif
}
/*------------------------------------------------------------------------------
| INotebook::tabShape |
------------------------------------------------------------------------------*/
INotebook::TabShape INotebook :: tabShape ( ) const
{
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
unsigned long ulStyle = style();
if (ulStyle & roundedTabs.asUnsignedLong())
return( INotebook::rounded );
else if (ulStyle & polygonTabs.asUnsignedLong())
return( INotebook::polygon );
else
return( INotebook::square );
}
else
{
return( INotebook::rounded );
}
#endif // IC_PMWIN
#ifdef IC_MOTIF
// Only square is currently supported
return INotebook::square;
#endif
}
/*------------------------------------------------------------------------------
| INotebook::statusTextAlignment |
| |
| Return the alignment of the status text of the notebook. |
------------------------------------------------------------------------------*/
INotebook::TextAlignment INotebook :: statusTextAlignment ( ) const
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
unsigned long ulStyle = style();
if (ulStyle & statusTextRight.asUnsignedLong())
return( INotebook::right );
else if (ulStyle & statusTextCenter.asUnsignedLong())
return( INotebook::center );
else
return( INotebook::left );
}
else
{
return( INotebook::left ); //return default
}
#endif // IC_PMWIN
#ifdef IC_MOTIF
if (fNotebookData->statusAlignment == XmALIGNMENT_END)
return INotebook::right;
else if (fNotebookData->statusAlignment == XmALIGNMENT_CENTER)
return INotebook::center;
else
return INotebook::left;
#endif
}
/*------------------------------------------------------------------------------
| INotebook::tabTextAlignment |
| |
| Return the alignment of the tab text of the notebook. |
------------------------------------------------------------------------------*/
INotebook::TextAlignment INotebook :: tabTextAlignment ( ) const
{
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
unsigned long ulStyle = style();
if (ulStyle & tabTextRight.asUnsignedLong())
return( INotebook::right );
else if (ulStyle & tabTextCenter.asUnsignedLong())
return( INotebook::center );
else
return( INotebook::left );
}
else
{
return( INotebook::center );
}
#endif // IC_PMWIN
#ifdef IC_MOTIF
if (fNotebookData->tabAlignment == XmALIGNMENT_END)
return INotebook::right;
else if (fNotebookData->tabAlignment == XmALIGNMENT_CENTER)
return INotebook::center;
else
return INotebook::left;
#endif // IC_MOTIF
}
/*------------------------------------------------------------------------------
| INotebook::setMajorTabSize |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setMajorTabSize ( const ISize& sizeMajorTab )
{
#ifdef IC_PMWIN
IMODTRACE_DEVELOP( "INotebook::setMajorTabSize" );
if ( isPMCompatible() )
{
IEventResult
retVal = sendEvent( BKM_SETDIMENSIONS,
MPFROM2SHORT(sizeMajorTab.width(),
sizeMajorTab.height()),
BKA_MAJORTAB );
if (retVal.asUnsignedLong() == false)
{
ITHROWGUIERROR("BKM_SETDIMENSIONS");
}
}
#ifdef IC_WIN
else
{
unsigned long ulStyle = style();
if ( !(ulStyle & TCS_FIXEDWIDTH) )
{
setStyle( ulStyle | TCS_FIXEDWIDTH );
}
if ( isDrawTabsEnabled() )
{
fNotebookData->lMajorTabHeight = sizeMajorTab.height();
tabControlResize( size() );
}
sendEvent( TCM_SETITEMSIZE,
0,
MPFROM2SHORT(sizeMajorTab.width(),
sizeMajorTab.height()) );
/**************************************************************************/
/* Simulate a resizing event to force repainting of the client area */
/**************************************************************************/
if ( !isDrawTabsEnabled() )
parent()->sizeTo( parent()->size() );
}
#endif //IC_WIN
#endif // IC_PMWIN
#ifdef IC_MOTIF
fNotebookData->majorTabSize = sizeMajorTab;
fNotebookData->refreshTabs();
#endif // IC_MOTIF
return *this;
}
/*------------------------------------------------------------------------------
| INotebook::setMinorTabSize |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setMinorTabSize ( const ISize& sizeMinorTab )
{
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
IEventResult
retVal = sendEvent( BKM_SETDIMENSIONS,
MPFROM2SHORT(sizeMinorTab.width(),
sizeMinorTab.height()),
BKA_MINORTAB );
if (retVal.asUnsignedLong() == false)
{
ITHROWGUIERROR("BKM_SETDIMENSIONS");
}
}
#endif // IC_PMWIN
#ifdef IC_MOTIF
fNotebookData->minorTabSize = sizeMinorTab;
fNotebookData->refreshTabs();
#endif
return *this;
}
/*------------------------------------------------------------------------------
| INotebook::setPageButtonSize |
| |
| Set the size of the arrow buttons used to turn the notebook's pages, in |
| pixels. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setPageButtonSize ( const ISize& sizePageButton )
{
ITRACE_MOTIF_NOP();
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
IEventResult
retVal = sendEvent( BKM_SETDIMENSIONS,
MPFROM2SHORT(sizePageButton.width(),
sizePageButton.height()),
BKA_PAGEBUTTON );
if (retVal.asUnsignedLong() == false)
{
ITHROWGUIERROR("BKM_SETDIMENSIONS");
}
}
#endif // IC_PMWIN
#ifdef IC_MOTIF
// Setting the height and width resources will be ignored by the Notebook
// widget until a fix is made. Once that fix is made and this function
// starts working, then...
// This code will break if OSF changes the name of NextPageButton or
// PrevPageButton. If this happens, this function will harmlessly return
// with no action having been taken.
// The widget names aren't really a documented interface, used editres
// to find the names.
Widget nextPageButton
= XtNameToWidget(fNotebookData->notebook, "NextPageButton");
Widget prevPageButton
= XtNameToWidget(fNotebookData->notebook, "PrevPageButton");
if (nextPageButton != 0)
XtVaSetValues(nextPageButton,
XmNresizable, True,
XmNwidth, sizePageButton.width(),
XmNheight, sizePageButton.height(),
NULL);
if (prevPageButton != 0)
XtVaSetValues(prevPageButton,
XmNresizable, True,
XmNwidth, sizePageButton.width(),
XmNheight, sizePageButton.height(),
NULL);
#endif // IC_MOTIF
return *this;
}
/*------------------------------------------------------------------------------
| INotebook::refreshTabs |
| |
| Causes all tabs in the notebook to be invalidated (and thus repainted). |
------------------------------------------------------------------------------*/
INotebook& INotebook :: refreshTabs ( )
{
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
IEventResult
retVal = sendEvent( BKM_INVALIDATETABS, 0, 0 );
if (retVal.asUnsignedLong() == false)
{
ITHROWGUIERROR("BKM_INVALIDATETABS");
}
}
#ifdef IC_WIN
else
{
RECT firstTab,
lastTab,
updateRect;
if (( TabCtrl_GetItemRect( handle(), 0, &firstTab ) ) &&
( TabCtrl_GetItemRect( handle(), (totalPages() - 1), &lastTab ) ))
{
updateRect.left = firstTab.left;
updateRect.top = firstTab.top;
updateRect.right = lastTab.right;
updateRect.bottom = lastTab.bottom;
InvalidateRect( handle(), &updateRect, false );
}
else
{
ITHROWGUIERROR("TabCtrl_GetItemRect");
}
}
#endif //IC_WIN
#endif // IC_PMWIN
#ifdef IC_MOTIF
fNotebookData->refreshTabs();
#endif
return *this;
}
/*------------------------------------------------------------------------------
| WIN32 Color Support |
| |
| Windows has no API equivalent for Presentation Parameters. The following |
| notebook color functions are NOPed for Windows. The query functions return |
| an appropriate default IColor object. |
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
| INoteBook::backgroundColor |
| |
| Returns the background color of the notebook. |
------------------------------------------------------------------------------*/
IColor INotebook::backgroundColor ( ) const
{
#ifdef IC_PM
return (IWindow::color(PP_BACKGROUNDCOLOR,
IGUIColor(IGUIColor::defaultControl)));
#endif // IC_PM
#ifdef IC_WIN
return IGUIColor( IGUIColor::defaultControl );
#endif //IC_WIN
#ifdef IC_MOTIF
return Inherited::backgroundColor();
#endif
}
/*------------------------------------------------------------------------------
| INoteBook::hiliteBackgroundColor |
| |
| Returns the hilite background color of the notebook. |
------------------------------------------------------------------------------*/
IColor INotebook::hiliteBackgroundColor ( ) const
{
#ifdef IC_PM
return (IWindow::color(PP_HILITEBACKGROUNDCOLOR,
IGUIColor(IGUIColor::defaultButton)));
#endif //IC_PM
#ifdef IC_WIN
return IGUIColor( IGUIColor::defaultButton );
#endif //IC_WIN
#ifdef IC_MOTIF
return Inherited::hiliteBackgroundColor();
#endif
}
/*------------------------------------------------------------------------------
| INoteBook::pageBackgroundColor |
| |
| Returns the background page color of the notebook. |
------------------------------------------------------------------------------*/
IColor INotebook::pageBackgroundColor ( ) const
{
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
/********************************************************************/
/* If this color was set previously, retrieve it from where we saved*/
/* it and return it. Otherwise, if a color has not been previously */
/* set, return the default. */
/********************************************************************/
if (colorFlags & INotebook::bgnPageColor)
{
if (pnotebookColors)
{
return (UnsignedLongAsRGB(pnotebookColors->pageBackgroundColor));
}
}
}
return( IGUIColor(IGUIColor::notebookPageBgnd) );
#endif // IC_PMWIN
#ifdef IC_MOTIF
return fNotebookData->getColor(pcaPageBackground);
#endif // IC_MOTIF
}
/*------------------------------------------------------------------------------
| INoteBook::majorTabBackgroundColor |
| |
| Returns the major tab background color. |
------------------------------------------------------------------------------*/
IColor INotebook::majorTabBackgroundColor ( ) const
{
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
/********************************************************************/
/* If this color was set previously, retrieve it from where we saved*/
/* it and return it. Otherwise, if a color has not been previously */
/* set, return the default. */
/********************************************************************/
if (colorFlags & INotebook::bgnMajorColor)
{
if (pnotebookColors)
{
return (UnsignedLongAsRGB(pnotebookColors->majorTabBackgroundColor));
}
}
}
return( IGUIColor(IGUIColor::notebookPageBgnd) );
#endif // IC_PMWIN
#ifdef IC_MOTIF
return fNotebookData->getColor(pcaMajorTabBackground);
#endif // IC_MOTIF
}
/*------------------------------------------------------------------------------
| INoteBook::minorTabBackgroundColor |
| |
| Returns the minor tab background color. |
------------------------------------------------------------------------------*/
IColor INotebook::minorTabBackgroundColor ( ) const
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
/********************************************************************/
/* If this color was set previously, retrieve it from where we saved*/
/* it and return it. Otherwise, if a color has not been previously */
/* set, return the default. */
/********************************************************************/
if (colorFlags & INotebook::bgnMinorColor)
{
if (pnotebookColors)
{
return (UnsignedLongAsRGB(pnotebookColors->minorTabBackgroundColor));
}
}
}
return( IGUIColor(IGUIColor::notebookPageBgnd) );
#endif // IC_PMWIN
#ifdef IC_MOTIF
return fNotebookData->getColor(pcaMinorTabBackground);
#endif // IC_MOTIF
}
/*------------------------------------------------------------------------------
| INoteBook::majorTabForegroundColor |
| |
| Returns the major tab foreground color. |
------------------------------------------------------------------------------*/
IColor INotebook::majorTabForegroundColor ( ) const
{
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
/********************************************************************/
/* If this color was set previously, retrieve it from where we saved*/
/* it and return it. Otherwise, if a color has not been previously */
/* set, return the default. */
/********************************************************************/
if (colorFlags & INotebook::fgnMajorColor)
{
if (pnotebookColors)
{
return (UnsignedLongAsRGB(pnotebookColors->majorTabForegroundColor));
}
}
}
return( IGUIColor(IGUIColor::windowText) );
#endif // IC_PMWIN
#ifdef IC_MOTIF
return fNotebookData->getColor(pcaMajorTabForeground);
#endif // IC_MOTIF
}
/*------------------------------------------------------------------------------
| INoteBook::minorTabForegroundColor |
| |
| Returns the minor tab foreground color. |
------------------------------------------------------------------------------*/
IColor INotebook::minorTabForegroundColor ( ) const
{
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
/********************************************************************/
/* If this color was set previously, retrieve it from where we saved*/
/* it and return it. Otherwise, if a color has not been previously */
/* set, return the default. */
/********************************************************************/
if (colorFlags & INotebook::fgnMinorColor)
{
if (pnotebookColors)
{
return (UnsignedLongAsRGB(pnotebookColors->minorTabForegroundColor));
}
}
}
return IGUIColor(IGUIColor::windowText);
#endif // IC_PMWIN
#ifdef IC_MOTIF
return fNotebookData->getColor(pcaMinorTabForeground);
#endif // IC_MOTIF
}
#ifdef IC_MOTIF
/*------------------------------------------------------------------------------
| INotebook::setBackgroundColor |
| |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setBackgroundColor (const IColor& color )
{
// the inherited setForegroundColor calls setColor, so the code
// to set color of binding can be moved to setColor.
Inherited::setBackgroundColor(color);
return *this;
}
/*------------------------------------------------------------------------------
| INotebook::setForegroundColor |
| |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setForegroundColor (const IColor& color )
{
// the inherited setForegroundColor calls setColor, so the code
// to set color of binding can be moved to setColor.
Inherited::setForegroundColor(color);
return *this;
}
/*------------------------------------------------------------------------------
| INotebook::setColor |
| |
| setColor is used for propagating colors down to children. Calling the |
| inherited version will assure that the colors are inherited by children.
------------------------------------------------------------------------------*/
INotebook& INotebook :: setColor (unsigned long colorArea,
const IColor& color )
{
Inherited::setColor(colorArea, color);
// update color of spiral binding pixmap
if ( (colorArea == PP_FOREGROUNDCOLOR) ||
(colorArea == PP_BACKGROUNDCOLOR) )
{
if (binding() == spiral)
setBinding(spiral);
}
return *this;
}
#endif
/*------------------------------------------------------------------------------
| INoteBook::setPageBackgroundColor |
| |
| Sets the page background color in a notebook. |
------------------------------------------------------------------------------*/
INotebook& INotebook::setPageBackgroundColor ( const IColor &color )
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
setNotebookColors (color.asRGBLong(), BKA_BACKGROUNDPAGECOLOR);
}
#endif // IC_PMWIN
#ifdef IC_MOTIF
fNotebookData->setColor(pcaPageBackground, color.index());
#endif
return *this;
}
/*------------------------------------------------------------------------------
| INoteBook::setMajorTabBackgroundColor |
| |
| Sets the major tab background color. |
------------------------------------------------------------------------------*/
INotebook& INotebook::setMajorTabBackgroundColor ( const IColor &color )
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
setNotebookColors (color.asRGBLong(), BKA_BACKGROUNDMAJORCOLOR);
}
#endif // IC_PMWIN
#ifdef IC_MOTIF
fNotebookData->setColor(pcaMajorTabBackground, color.index());
#endif // IC_MOTIF
return *this;
}
/*------------------------------------------------------------------------------
| INoteBook::setMinorTabBackgroundColor |
| |
| Sets the minor tab background color. |
------------------------------------------------------------------------------*/
INotebook& INotebook::setMinorTabBackgroundColor ( const IColor &color )
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
setNotebookColors (color.asRGBLong(), BKA_BACKGROUNDMINORCOLOR);
}
/********************************************************************/
/* Windows tab control has no concept of minor tabs. Therefore, */
/* this function is a no-op. */
/********************************************************************/
#endif // IC_PMWIN
#ifdef IC_MOTIF
fNotebookData->setColor(pcaMinorTabBackground, color.index());
#endif // IC_MOTIF
return *this;
}
/*------------------------------------------------------------------------------
| INoteBook::setMajorTabForegroundColor |
| |
| Sets the major tab foreground color. |
------------------------------------------------------------------------------*/
INotebook& INotebook::setMajorTabForegroundColor ( const IColor &color )
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
setNotebookColors (color.asRGBLong(), BKA_FOREGROUNDMAJORCOLOR);
}
#endif // IC_PMWIN
#ifdef IC_MOTIF
fNotebookData->setColor(pcaMajorTabForeground, color.index());
#endif // IC_MOTIF
return *this;
}
/*------------------------------------------------------------------------------
| INoteBook::setMinorTabForegroundColor |
| |
| Sets the minor tab foreground color. |
------------------------------------------------------------------------------*/
INotebook& INotebook::setMinorTabForegroundColor ( const IColor &color )
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
setNotebookColors (color.asRGBLong(), BKA_FOREGROUNDMINORCOLOR);
}
/********************************************************************/
/* Windows tab control has no concept of minor tabs. Therefore, */
/* this function is a no-op. */
/********************************************************************/
#endif // IC_PMWIN
#ifdef IC_MOTIF
fNotebookData->setColor(pcaMinorTabForeground, color.index());
#endif // IC_MOTIF
return *this;
}
/*------------------------------------------------------------------------------
| INoteBook::resetPageBackgroundColor |
| |
| Resets the page background color by undoing a previous set. |
------------------------------------------------------------------------------*/
INotebook& INotebook::resetPageBackgroundColor ( )
{
ITRACE_MOTIF_NOP();
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
colorFlags &= ~bgnPageColor;
#endif // IC_PMWIN
return *this;
}
/*------------------------------------------------------------------------------
| INoteBook::resetMajorTabBackgroundColor |
| |
| Resets the major tab background color by undoing a previous set. |
------------------------------------------------------------------------------*/
INotebook& INotebook::resetMajorTabBackgroundColor ( )
{
ITRACE_MOTIF_NOP();
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
colorFlags &= ~bgnMajorColor;
#endif // IC_PMWIN
return *this;
}
/*------------------------------------------------------------------------------
| INoteBook::resetMinorTabBackgroundColor |
| |
| Resets the minor tab background color by undoing a previous set. |
------------------------------------------------------------------------------*/
INotebook& INotebook::resetMinorTabBackgroundColor ( )
{
ITRACE_MOTIF_NOP();
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
colorFlags &= ~bgnMinorColor;
#endif // IC_PMWIN
return *this;
}
/*------------------------------------------------------------------------------
| INoteBook::resetMajorTabForegroundColor |
| |
| Resets the major tab foreground color by undoing a previous set. |
------------------------------------------------------------------------------*/
INotebook& INotebook::resetMajorTabForegroundColor ( )
{
ITRACE_MOTIF_NOP();
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
colorFlags &= ~fgnMajorColor;
#endif // IC_PMWIN
return *this;
}
/*------------------------------------------------------------------------------
| INoteBook::resetMinorTabForegroundColor |
| |
| Resets the minor tab foreground color by undoing a previous set. |
------------------------------------------------------------------------------*/
INotebook& INotebook::resetMinorTabForegroundColor ( )
{
ITRACE_MOTIF_NOP();
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
colorFlags &= ~fgnMinorColor;
#endif // IC_PMWIN
return *this;
}
#ifdef IC_MOTIF
/*------------------------------------------------------------------------------
| INotebook::setFont |
| |
| Sets the font for the notebook. |
------------------------------------------------------------------------------*/
INotebook& INotebook::setFont ( const IFont& fm )
{
// cache X Windows Logical Font Descriptor (XLFD) string
fNotebookData->xlfdString = fm.qualifiedName();
Inherited::setFont( fm );
return *this;
}
/*------------------------------------------------------------------------------
| INotebook::font |
| |
| Returns the font used for the notebook. |
------------------------------------------------------------------------------*/
IFont INotebook::font () const
{
if (fNotebookData->xlfdString.length() > 0)
// construct font based on cached XLFD string
return IFont(fNotebookData->xlfdString);
else
return Inherited::font();
}
#endif //IC_MOTIF
/*------------------------------------------------------------------------------
| INoteBook::areAllTabsVisible |
| |
| Returns true if multiple rows of tabs can be displayed on the tab control. |
------------------------------------------------------------------------------*/
bool INotebook::areAllTabsVisible ( ) const
{
ITRACE_MOTIF_NOP();
ITRACE_PM_NOP();
#ifdef IC_WIN
if ( !isPMCompatible() )
{
return( (style() & TCS_MULTILINE) ? true : false );
}
else
#endif
{
return( false );
}
}
/*------------------------------------------------------------------------------
| INoteBook::isDrawTabsEnabled |
| |
| Returns true if owner draw tabs style is specified. |
------------------------------------------------------------------------------*/
bool INotebook::isDrawTabsEnabled ( ) const
{
#ifdef IC_WIN
if ( !isPMCompatible() )
{
return( (style() & TCS_OWNERDRAWFIXED) ? true : false );
}
else
#endif
{
return( false );
}
}
/*------------------------------------------------------------------------------
| INoteBook::isPMCompatible |
| |
| Returns true if the notebook is displayed as the CUA '91 notebook. |
------------------------------------------------------------------------------*/
bool INotebook::isPMCompatible ( ) const
{
ITRACE_MOTIF_NOP();
#ifdef IC_MOTIFPM
return( true );
#else
return( (extendedStyle() &
pmCompatible.asExtendedUnsignedLong()) ? true : false );
#endif
}
//
// PageSettings and Cursor classes now implemented in inotebk0.cpp
//
#ifdef IC_PMWIN
/*------------------------------------------------------------------------------
| INotebook::insertPageInfo |
| |
| Set the values in the PageSettings into the notebook. |
------------------------------------------------------------------------------*/
IPageHandle INotebook :: insertPageInfo ( const PageSettings& pageInfo,
const IPageHandle& referencePage,
IWindow* window,
unsigned long fPosition )
{
IMODTRACE_DEVELOP( "INotebook::insertPageInfo" );
IPageHandle pageHandle( 0 );
#ifdef IC_WIN
if ( isPMCompatible() )
{
/**************************************************************************/
/* Insert page in the CUA '91 notebook. */
/**************************************************************************/
pageHandle =
(void*)insertPage( MPFROMLONG( ((void*)referencePage) ),
MPFROM2SHORT( (USHORT)pageInfo.pageStyle.asUnsignedLong(),
fPosition) );
}
else
{
/**************************************************************************/
/* Handle the tab control page in a separate function to increase */
/* readability/maintainability of the code. */
/**************************************************************************/
return( insertPageInfo2( pageInfo, referencePage, window, fPosition ) );
}
#else
pageHandle =
insertPage( MPFROMLONG( referencePage ),
MPFROM2SHORT( (USHORT)pageInfo.pageStyle.asUnsignedLong(),
fPosition) );
#endif
if (window && pageHandle)
{
IRectangle pageRect;
/**************************************************************************/
/* If the page window is a frame, we need to set the owner to NULL. The */
/* notebook will set the parent to the page window (id 8006) and then we */
/* can set the owner to the notebook. (We cannot set the owner to the */
/* notebook initially because this might cause the frame to have the same */
/* parent and owner and cause problems). If the owner of the frame is */
/* not the notebook, a focus loop problem will occur. */
/**************************************************************************/
#ifndef IC_WIN
if ( window->isFrameWindow() )
window->setOwner( NULL );
#endif
/**************************************************************************/
/* save the page window rect */
/**************************************************************************/
if ( pageInfo.isAutoSize() )
pageRect = window->rect();
/**************************************************************************/
/* Set (associate) the application page window with the notebook page */
/**************************************************************************/
IEventResult
retVal = sendEvent( BKM_SETPAGEWINDOWHWND,
#ifdef IC_WIN
(unsigned long)(void*)pageHandle,
(unsigned long)(void*)(window->handle()) );
#else
(unsigned long)pageHandle,
(unsigned long)window->handle() );
#endif
if (retVal.asUnsignedLong() == false)
{
ITHROWGUIERROR("BKM_SETPAGEWINDOWHWND");
}
else
{
/************************************************************************/
/* restore the page window size */
/************************************************************************/
if ( pageInfo.isAutoSize() )
window->sizeTo( ISize( pageRect.width(), pageRect.height() ));
/************************************************************************/
/* If there is no owner for the page, set it to the notebook. */
/************************************************************************/
#ifdef IC_PM
if ( window->owner() == NULL )
window->setOwner( this );
// Add the page window resize handler for PM. Only add it if this page
// window is not already a page window for another page.
Cursor cursor( *this );
bool isHandled = false;
for (cursor.setToFirst();
cursor.isValid() && !isHandled;
cursor.setToNext())
{
IPageHandle currentHandle = cursor.current();
if (currentHandle != pageHandle &&
this->window( currentHandle ) == window)
isHandled = true;
}
if (!isHandled)
fNotebookData->fPageResizeHandler.handleEventsFor( window );
#endif // IC_PM
}
}
if (pageHandle)
{
if (pageInfo.savedStatusText.size() != 0)
setStatusText(pageHandle, pageInfo.savedStatusText);
if (pageInfo.savedTabText.size() != 0)
setTabText(pageHandle, pageInfo.savedTabText);
if (pageInfo.savedTabBitmap != 0)
setTabBitmap(pageHandle, pageInfo.savedTabBitmap);
setUserData(pageHandle, pageInfo.savedUserData);
}
return pageHandle;
}
#endif // IC_PMWIN
#ifdef IC_WIN
/*------------------------------------------------------------------------------
| INotebook::insertPageInfo2 |
| |
| Set the values in the PageSettings into the notebook. |
------------------------------------------------------------------------------*/
IPageHandle INotebook :: insertPageInfo2 ( const PageSettings& pageInfo,
const IPageHandle& referencePage,
IWindow* window,
unsigned long fPosition )
{
IMODTRACE_DEVELOP( "INotebook::insertPageInfo2" );
/****************************************************************************/
/* Update the page styles so we can store them in our extended tab control */
/* item. */
/****************************************************************************/
if ( pageInfo.isAutoSize() )
{
pageInfo.fPageSettingsData->tabCtrlItem.ulPageStyle |=
PageSettings::autoPageSize.asUnsignedLong();
}
else
{
pageInfo.fPageSettingsData->tabCtrlItem.ulPageStyle &=
~PageSettings::autoPageSize.asUnsignedLong();
}
/****************************************************************************/
/* Add the application page window handle and its parent's handle to our */
/* extended tab control item, as well as any application user-defined data */
/* to our extended tab control item. */
/****************************************************************************/
if (window)
{
pageInfo.fPageSettingsData->tabCtrlItem.hPageWindow = window->handle();
pageInfo.fPageSettingsData->tabCtrlItem.hPageWindowParent =
( window->parent() ? window->parent()->handle() : IWindowHandle(0) );
}
else
{
pageInfo.fPageSettingsData->tabCtrlItem.hPageWindow = 0;
pageInfo.fPageSettingsData->tabCtrlItem.hPageWindowParent = 0;
}
pageInfo.fPageSettingsData->tabCtrlItem.ulUserData = pageInfo.userData();
/****************************************************************************/
/* Insert the tab page into the tab control, and associate the application */
/* page window to it if one is supplied. */
/****************************************************************************/
IPageHandle
pageHandle = insertTabPage( pageInfo, referencePage, fPosition );
/****************************************************************************/
/* If we have an application page window and if the tab page was inserted */
/* successfully then do the following: */
/****************************************************************************/
if (window && pageHandle)
{
IRectangle pageRect;
/**************************************************************************/
/* Make the page clipping window the parent of the application page */
/* window. */
/**************************************************************************/
window->setParent( pageClippingWindow() );
/**************************************************************************/
/* Simulate CUA notebook's processing of the addition of the first page */
/* in the notebook. */
/**************************************************************************/
if ( pageHandle.asUnsigned() == 1 )
{
PAGESELECTNOTIFY pageSelectNotify;
pageSelectNotify.hwndBook = handle();
pageSelectNotify.ulPageIdNew = 1;
pageSelectNotify.ulPageIdCur = 1;
/************************************************************************/
/* Set tab selection on the first tab in the tab control. */
/************************************************************************/
processTabSelect( &pageSelectNotify, false );
}
else
window->hide();
}
if (pageHandle)
{
if (pageInfo.savedTabBitmap != 0)
setTabBitmap(pageHandle, pageInfo.savedTabBitmap);
}
return( pageHandle );
}
#endif
#ifdef IC_MOTIF
/*------------------------------------------------------------------------------
| INotebook :: addPageAt |
| |
| private member function for actually doing the add of a page |
------------------------------------------------------------------------------*/
IPageHandle INotebook :: addPageAt( int pageNumber,
const PageSettings& settings,
IWindow* newPage,
bool replacePage )
{
IPageHandle page( 0 );
// Adjust the page numbers if needed then add the page
int firstPage, lastPage;
XtVaGetValues(fNotebookData->notebook,
XmNfirstPageNumber, &firstPage,
XmNlastPageNumber, &lastPage,
NULL);
// If called from addAsLast, the page number will be 0.
// Set it to the correct value.
if (pageNumber == 0)
pageNumber = lastPage + 1;
XmNotebookPageInfo pageInfo;
XmNotebookPageStatus pageStatus;
pageStatus = XmNotebookGetPageInfo(
fNotebookData->notebook, pageNumber, &pageInfo);
switch (pageStatus) {
case XmPAGE_FOUND:
fNotebookData->adjustPages(pageNumber, lastPage, 1);
// Create a unique page handle for this new page.
page = IPageHandle( fNotebookData->fNextPageHandle++ );
fNotebookData->fPageSequence->addAtPosition( pageNumber, page );
break;
case XmPAGE_INVALID:
if (pageNumber = lastPage + 1)
{
// Create a unique page handle for this new page.
page = IPageHandle( fNotebookData->fNextPageHandle++ );
fNotebookData->fPageSequence->addAsLast( page );
}
else
ITHROWGUIERROR(IString("Tried to add notebook page ") +
IString(pageNumber) +
IString(" with lastPage ") +
IString(lastPage) );
break;
case XmPAGE_EMPTY:
// If we are replacing a page (ie, called from setWindow) then we should
// use the existing page handle; otherwise, create a unique page handle for
// the new page.
if (replacePage)
page = fNotebookData->fPageSequence->elementAtPosition( pageNumber );
else
{
fNotebookData->adjustPages( pageNumber, lastPage, 1 );
page = IPageHandle( fNotebookData->fNextPageHandle++ );
fNotebookData->fPageSequence->addAtPosition( pageNumber, page );
}
break;
case XmPAGE_DUPLICATED:
ITHROWGUIERROR("Duplicate pages found in INotebook");
break;
default:
ITHROWGUIERROR("Unexpected pageStatus from XmNotebookGetPageInfo");
} // end switch
// Used on XtSetArg calls below
Arg args[20];
int n;
if (newPage != 0) {
if (newPage->size() != ISize() || settings.isAutoSize())
{
// Make sure the page window is managed at this point. We'll let the
// notebook widget handle it from herein.
XtManageChild( newPage->handle() );
}
n = 0;
XtSetArg(args[n], XmNpageNumber, pageNumber); n++;
XtSetArg(args[n], XmNnotebookChildType, XmPAGE); n++;
// Note that the notebook widget's handling of resizable children was
// not what we wanted for autoPageSize page windows. The resizable resource
// indicates whether size requests from the child widget should be honored.
// The notebook widget has been modified to allow a different usage of the
// resizable constraint resource for XmPAGE children. If the resizable
// resource is set to True for XmPAGE children, the page window will be
// auto sized. If this resource is set to False for XmPAGE children, the
// page window will still be allowed to resize; it won't, however, be auto
// sized by the notebook widget.
XtSetArg(args[n], XmNresizable, settings.isAutoSize() ? True : False); n++;
if(fNotebookData->colorSet[pcaPageBackground]) {
IXmColor::setBackgroundColor( newPage->handle(),
fNotebookData->curColor[pcaPageBackground]);
}
XtSetValues(newPage->handle(), args, n);
}
// Create status
// The notebook widget can't properly calculate its height
// before it is shown if there's no statusText.
// It doesn't create the pageScroller until it's shown, so
// its NewPreferredGeometry will return a height that lacks the
// height of the pageScroller.
// So to get around this we always create a status text LabelWidget
// Note: at one point we tried using a LabelGadget. This caused a
// segmentation violation when we called XtCreateManagedWidget when
// we created the same notebook a second time in the same app.
n = 0;
XtSetArg(args[n], XmNnotebookChildType, XmSTATUS_AREA); n++;
XtSetArg(args[n], XmNpageNumber, pageNumber); n++;
XtSetArg(args[n], XmNalignment, fNotebookData->statusAlignment); n++;
IString statusText;
IMString imStatusText;
if (settings.isStatusTextOn())
statusText = settings.statusText();
if ( statusText.size() != 0 ) {
imStatusText += statusText;
XtSetArg( args[n], XmNlabelString, (XmString)imStatusText ); n++;
}
// Create a page data structure to save the user data and auto size preference.
// We don't always create the page window when the page is added and this
// information must be available when the page window is set later.
// It is necessary to store this with the status text since it is the only
// widget associated with the page that is created unconditionally.
PageData *pageData = new PageData;
pageData->userData = settings.userData() ? settings.userData() : 0;
pageData->pageHandle = page;
pageData->isAutoSize = settings.isAutoSize() ? true : false;
XtSetArg( args[n], XmNuserData, pageData ); n++;
Widget theStatusArea = XtCreateManagedWidget("IC_NB_STATUS",
xmLabelWidgetClass,
fNotebookData->notebook, args,n);
//
// If we did not set the status text, check to see if the text was set
// from a resource file. If not, set to blank.
//
if ( statusText.size() == 0 ) { // We did not set the text.
IXmLabel::initializeXmLabelString( theStatusArea, IString("IC_NB_STATUS") );
}
// Create tab
Widget theTab = 0;
if ((settings.isMajorTab()) || (settings.isMinorTab())) {
n = 0;
IString label = settings.tabText();
// Strip any PM accelerator that we can't support
IXmLabel::removeMnemonic( label );
IMString labelString;
// Set up label string or pixmap
if (label.size() != 0) { // use a string
labelString += label;
XtSetArg(args[n], XmNlabelType, XmSTRING); n++;
XtSetArg(args[n], XmNlabelString, (XmString)labelString); n++;
XtSetArg(args[n], XmNalignment, fNotebookData->tabAlignment); n++;
}
else if (settings.tabBitmap() != 0) { // use a Pixmap
XtSetArg(args[n], XmNlabelType, XmPIXMAP); n++;
XtSetArg(args[n], XmNlabelPixmap, settings.tabBitmap()); n++;
}
// Set tab type and pageNumber
unsigned char tabType =
(settings.isMajorTab()) ?
(unsigned char)XmMAJOR_TAB : (unsigned char)XmMINOR_TAB;
XtSetArg(args[n], XmNnotebookChildType, tabType); n++;
XtSetArg(args[n], XmNpageNumber, pageNumber); n++;
// Set size
Dimension tabWidth = fNotebookData->minorTabSize.width();
Dimension tabHeight = fNotebookData->minorTabSize.height();
if (tabType == XmMAJOR_TAB) {
tabWidth = fNotebookData->majorTabSize.width();
tabHeight = fNotebookData->majorTabSize.height();
}
if ( tabWidth && tabHeight ) {
XtSetArg(args[n],XmNresizable, True); n++;
XtSetArg(args[n],XmNwidth, tabWidth); n++;
XtSetArg(args[n],XmNheight, tabHeight); n++;
}
//
// Set foreground color only if background is not going to be set.
//
PrivateColorArea bgColorArea = pcaMinorTabBackground;
PrivateColorArea fgColorArea = pcaMinorTabForeground;
if (tabType == XmMAJOR_TAB) {
bgColorArea = pcaMajorTabBackground;
fgColorArea = pcaMajorTabForeground;
}
if ( !fNotebookData->colorSet[bgColorArea]
&& fNotebookData->colorSet[fgColorArea] ) {
XtSetArg(args[n], XmNforeground, fNotebookData->curColor[fgColorArea]);
n++;
}
// Create the tab widget.
theTab = XtCreateManagedWidget("IC_NB_TAB",
xmPushButtonWidgetClass,
fNotebookData->notebook,
args, n);
//
// Set background and foreground colors
// Do this after it is created, so XmChangeColor can be used to
// adjust the shadow colors.
//
if (fNotebookData->colorSet[bgColorArea]) {
if (fNotebookData->colorSet[fgColorArea]) {
IXmColor::setColor( theTab,
true,
fNotebookData->curColor[bgColorArea],
fNotebookData->curColor[fgColorArea] ); // Slightly faster.
}
else {
IXmColor::setBackgroundColor( theTab,
fNotebookData->curColor[bgColorArea] );
}
}
//
// If we did not set the tab text, check to see if the text was set
// from a resource file. If so, remove mnemonic. If not, set to blank.
//
if ( label.size() == 0 ) { // We did not set the text.
IXmLabel::initializeXmLabelString( theTab, IString("IC_NB_TAB"), true );
}
}
// Set the font of the status and tab widgets if we previously stored a font
// for the widget.
if (fNotebookData->xlfdString != IString( "" ))
{
IString xFontName = fNotebookData->xlfdString;
xFontName.stripLeading( IString( "IOC:" ));
XFontStruct *xfont = XLoadQueryFont( XtDisplay( fNotebookData->notebook ),
xFontName );
if (xfont)
{
// We found the font. Create a font list resource.
XmFontListEntry
entry = XmFontListEntryCreate( XmFONTLIST_DEFAULT_TAG,
XmFONT_IS_FONT,
xfont );
XmFontList fontList = 0;
fontList = XmFontListAppendEntry(fontList, entry);
XmFontListEntryFree( &entry );
// Set the font resources.
XtVaSetValues( theStatusArea,
XmNfontList, fontList,
NULL );
if (theTab)
{
XtVaSetValues( theTab,
XmNfontList, fontList,
NULL );
}
XmFontListFree( fontList );
}
}
// Now adjust the first and last page numbers in the notebook if necessary.
// If the first and last pages numbers are adjusted before the widgets are
// created, a selection event may be generated for an invalid page. We also
// want to make sure the status widget is created before any selection event
// is generated to ensure access to the page handle contained therein.
n = 0;
if (firstPage == 0)
{
XtSetArg( args[n], XmNfirstPageNumber, 1 ); n++;
}
if (pageNumber > lastPage)
{
XtSetArg( args[n], XmNlastPageNumber, pageNumber ); n++;
}
if (n)
{
XtSetValues( fNotebookData->notebook,
args,
n );
}
return page;
}
#endif // IC_MOTIF
/*------------------------------------------------------------------------------
| INotebook::addFirstPage |
| |
| Add a given window to the notebook as the first page, using the given |
| page settings. |
------------------------------------------------------------------------------*/
IPageHandle INotebook :: addFirstPage ( const PageSettings& pageInfo,
IWindow* window )
{
#ifdef IC_PMWIN
return insertPageInfo(pageInfo, IPageHandle(0), window, BKA_FIRST);
#endif
#ifdef IC_MOTIF
return addPageAt(1, pageInfo, window);
#endif // IC_MOTIF
}
/*------------------------------------------------------------------------------
| INotebook::addLastPage |
| |
| Add a given window to the notebook as the last page, using the given |
| page settings. |
------------------------------------------------------------------------------*/
IPageHandle INotebook :: addLastPage ( const PageSettings& pageInfo,
IWindow* window )
{
#ifdef IC_PMWIN
return insertPageInfo(pageInfo, IPageHandle(0), window, BKA_LAST);
#endif // IC_PMWIN
#ifdef IC_MOTIF
return addPageAt(0, pageInfo, window);
#endif // IC_MOTIF
}
/*------------------------------------------------------------------------------
| INotebook::addPageBefore |
| |
| Add a given window to the notebook before the referenced page, using the |
| given page settings. |
------------------------------------------------------------------------------*/
IPageHandle INotebook :: addPageBefore ( const PageSettings& newPageInfo,
const IPageHandle& referencePage,
IWindow* window )
{
#ifdef IC_PMWIN
return insertPageInfo(newPageInfo, referencePage, window, BKA_PREV);
#endif // IC_PMWIN
#ifdef IC_MOTIF
return addPageAt( fNotebookData->pageNumber( referencePage ),
newPageInfo,
window );
#endif // IC_MOTIF
}
/*------------------------------------------------------------------------------
| INotebook::addPageBefore |
| |
| Add a given window to the notebook before the referenced page, using the |
| given page settings. |
------------------------------------------------------------------------------*/
IPageHandle INotebook :: addPageBefore ( const PageSettings& newPageInfo,
const Cursor& cursor,
IWindow* window )
{
#ifdef IC_PMWIN
return insertPageInfo(newPageInfo, cursor.current(), window, BKA_PREV);
#endif // IC_PMWIN
#ifdef IC_MOTIF
return addPageAt( fNotebookData->pageNumber( cursor.current() ),
newPageInfo,
window );
#endif // IC_MOTIF
}
/*------------------------------------------------------------------------------
| INotebook::addPageAfter |
| |
| Add a given window to the notebook after the referenced page, using the |
| given page settings. |
------------------------------------------------------------------------------*/
IPageHandle INotebook :: addPageAfter ( const PageSettings& newPageInfo,
const IPageHandle& referencePage,
IWindow* window )
{
#ifdef IC_PMWIN
return insertPageInfo(newPageInfo, referencePage, window, BKA_NEXT);
#endif // IC_PMWIN
#ifdef IC_MOTIF
return addPageAt( fNotebookData->pageNumber( referencePage ) + 1,
newPageInfo,
window );
#endif // IC_MOTIF
}
/*------------------------------------------------------------------------------
| INotebook::addPageAfter |
| |
| Add a given window to the notebook after the referenced page, using the |
| given page settings. |
------------------------------------------------------------------------------*/
IPageHandle INotebook :: addPageAfter ( const PageSettings& newPageInfo,
const Cursor& cursor,
IWindow* window )
{
#ifdef IC_PMWIN
return insertPageInfo(newPageInfo, cursor.current(), window, BKA_NEXT);
#endif // IC_PMWIN
#ifdef IC_MOTIF
return addPageAt( fNotebookData->pageNumber( cursor.current() ) + 1,
newPageInfo,
window );
#endif // IC_MOTIF
}
#ifdef IC_PMWIN
/*------------------------------------------------------------------------------
| INotebook::insertPage |
------------------------------------------------------------------------------*/
unsigned long INotebook :: insertPage ( void* mp1, void* mp2 )
{
unsigned long retVal = sendEvent(BKM_INSERTPAGE, mp1, mp2);
if (!retVal)
{
ITHROWGUIERROR("BKM_INSERTPAGE");
}
ulClValidate++;
return retVal;
}
#endif
/*------------------------------------------------------------------------------
| INotebook::removePage |
------------------------------------------------------------------------------*/
INotebook& INotebook :: removePage ( const IPageHandle& page )
{
#ifdef IC_WIN
deletePage( MPFROMLONG( ((void*)page)), MPFROMSHORT (BKA_SINGLE) );
#endif // IC_WIN
#ifdef IC_PM
deletePage (MPFROMLONG (page), MPFROMSHORT (BKA_SINGLE));
#endif // IC_PM
#ifdef IC_MOTIF
int pageNumber = fNotebookData->pageNumber( page );
fNotebookData->deletePages( pageNumber, pageNumber );
#endif
return( *this );
}
/*------------------------------------------------------------------------------
| INotebook::removePage |
------------------------------------------------------------------------------*/
INotebook& INotebook :: removePage ( const Cursor& cursor )
{
return removePage(cursor.current());
}
/*------------------------------------------------------------------------------
| INotebook::removeAllPages |
------------------------------------------------------------------------------*/
INotebook& INotebook :: removeAllPages ( )
{
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
deletePage (0, MPFROMSHORT (BKA_ALL));
}
#ifdef IC_WIN
else
{
/**************************************************************************/
/* We cannot use the tab control's delete all functions if we want to */
/* send a page deleted notification. Instead we have to loop thru */
/* every page to simulate the PM behavior, since the tab control does */
/* not have a TCN_ notification defined for page deletion. */
/**************************************************************************/
/**************************************************************************/
/* Hide the page clipping window if we're deleting all of the pages. */
/**************************************************************************/
pageClippingWindow()->hide();
/**************************************************************************/
/* This is the hack to simulate the PM page deleted notification that */
/* was mentioned above. */
/**************************************************************************/
unsigned long
ulTotalPages = totalPages();
for ( unsigned i = 1; i <= ulTotalPages; i++ )
{
deletePage( MPFROMLONG ((void*)tabPageHandle( 0 )),
MPFROMSHORT (BKA_ALL) );
}
/**************************************************************************/
/* Reset pages inserted count to 0, since we have just deleted all of */
/* the pages. */
/**************************************************************************/
ulClPagesInserted = 0;
/******************************************************************/
/* Also clear the equality sequence of all its entries */
/******************************************************************/
tabPageHandleCollection()->removeAll();
}
#endif //IC_WIN
#endif // IC_PMWIN
#ifdef IC_MOTIF
int firstPage, lastPage;
XtVaGetValues(fNotebookData->notebook,
XmNfirstPageNumber, &firstPage,
XmNlastPageNumber, &lastPage,
NULL);
fNotebookData->deletePages (firstPage, lastPage);
#endif
return( *this );
}
/*------------------------------------------------------------------------------
| INotebook::removeTabSection |
| |
| If the page specified is a major tab page, the specified page and all |
| subsequent pages up to the next major tab page are removed. |
| If the page specified is a minor tab page, the specified page and all |
| subsequent pages up to the next page with any tab are removed. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: removeTabSection ( const IPageHandle& page )
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
unsigned short pageStyle = sendEvent( BKM_QUERYPAGESTYLE,
MPFROMLONG( UPAGE ),
0 );
IASSERTSTATE( ( pageStyle & (BKA_MAJOR | BKA_MINOR) ) != 0 );
deletePage (MPFROMLONG( UPAGE ), MPFROMSHORT( BKA_TAB ));
}
#endif // IC_PMWIN
#ifdef IC_MOTIF
int startPage = fNotebookData->pageNumber( page );
bool keepGoing = true;
bool gotMajor;
int origLast;
XmNotebookPageInfo pageInfo;
XmNotebookPageStatus pageStatus;
XtVaGetValues(fNotebookData->notebook, XmNlastPageNumber, &origLast, NULL);
pageStatus = XmNotebookGetPageInfo(
fNotebookData->notebook, startPage, &pageInfo);
if (pageStatus == XmPAGE_FOUND || pageStatus == XmPAGE_EMPTY) {
if (pageInfo.major_tab_widget != 0)
gotMajor = true;
else if (pageInfo.minor_tab_widget != 0)
gotMajor = false;
else
ITHROWGUIERROR("Invalid Page");
}
else
ITHROWGUIERROR("Invalid Page");
for(int i = startPage+1; i<=origLast && keepGoing; i++) {
pageStatus = XmNotebookGetPageInfo(fNotebookData->notebook, i, &pageInfo);
switch (pageStatus) {
case XmPAGE_FOUND:
case XmPAGE_EMPTY: // empty page could have tab or status area
if ( (gotMajor && pageInfo.major_tab_widget !=0) ||
(!gotMajor && (pageInfo.major_tab_widget != 0 ||
pageInfo.minor_tab_widget != 0)) ) {
keepGoing = false;
i--;
}
break;
case XmPAGE_INVALID:
ITHROWGUIERROR("Found invalid page while removing tab section");
break;
case XmPAGE_DUPLICATED:
ITHROWGUIERROR("Duplicate pages found in INotebook");
break;
default:
ITHROWGUIERROR("Unexpected pageStatus from XmNotebookGetPageInfo");
} // end switch
} // end for
fNotebookData->deletePages(startPage, --i);
#endif
return( *this );
}
/*------------------------------------------------------------------------------
| INotebook::removeTabSection |
| |
| If the page cursored is a major tab page, remove the cursored page and |
| all subsequent pages up to the next major tab page. |
| If the page cursored is a minor tab page, remove the cursored page and |
| all subsequent pages up to the next page with any tab. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: removeTabSection ( const Cursor& cursor )
{
return removeTabSection(cursor.current());
}
#ifdef IC_PMWIN
/*------------------------------------------------------------------------------
| INotebook::deletePage |
------------------------------------------------------------------------------*/
bool INotebook :: deletePage ( void* mp1, void* mp2 )
{
if ( isPMCompatible() )
{
#ifdef IC_PM
// Remove the page window resize handler for PM. Only remove it if
// this page window is not the page window for another page.
IWindow *pageWindow = window( (IPageHandle)(unsigned long)mp1 );
if (pageWindow)
{
Cursor cursor( *this );
bool pageWindowFound = false;
for (cursor.setToFirst();
cursor.isValid() && !pageWindowFound;
cursor.setToNext())
{
IPageHandle currentHandle = cursor.current();
if (currentHandle != (IPageHandle)(unsigned long)mp1 &&
this->window( currentHandle ) == pageWindow)
pageWindowFound = true;
}
if (!pageWindowFound)
fNotebookData->fPageResizeHandler.stopHandlingEventsFor( pageWindow );
}
#endif // IC_PM
IEventResult
retVal = sendEvent(BKM_DELETEPAGE, mp1, mp2);
if (retVal.asUnsignedLong() == false)
{
ITHROWGUIERROR("BKM_DELETEPAGE");
}
}
#ifdef IC_WIN
else
{
/**************************************************************************/
/* Windows tab control processing */
/* ---------------------------------------------------------------------- */
/* Query the tab item's information */
/**************************************************************************/
IOC_ITEM tabCtrlItem;
tabCtrlItem.itemHeader.mask = TCIF_PARAM | TCIF_IMAGE;
long
iPageIndex = tabPageIndex( mp1 );
if ( !TabCtrl_GetItem( handle(), iPageIndex, &tabCtrlItem ) )
{
if ( (unsigned long)mp2 == BKA_SINGLE )
ITHROWGUIERROR("TabCtrl_GetItem");
else
return( false );
}
/**************************************************************************/
/* If we have created an image list, then check to see if an image exists */
/* for the specified page. If an image exists, then remove it from the */
/* image list. */
/**************************************************************************/
IMAGEINFO imageInfo;
if ( fNotebookData->hWndImageList )
{
if ( tabCtrlItem.itemHeader.iImage != -1 )
{
/**********************************************************************/
/* Get the bitmap's handle before we delete it from the image list, */
/* so we can pass it as part of the page deleted notification. */
/**********************************************************************/
ImageList_GetImageInfo( fNotebookData->hWndImageList,
tabCtrlItem.itemHeader.iImage,
&imageInfo );
TabCtrl_RemoveImage( handle(), tabCtrlItem.itemHeader.iImage );
}
}
/**************************************************************************/
/* If the delete request is for the current top page, we must select a */
/* new top page, unless the notebook is empty. */
/**************************************************************************/
if ( ((unsigned long)mp2 == BKA_SINGLE) &&
(IPageHandle( mp1 ) == topPage()) )
{
/************************************************************************/
/* Reset the top page to the next page if it exists, or the previous */
/* page if it exists. */
/************************************************************************/
long
iNewPageIndex = iPageIndex + 1;
long
retVal = TabCtrl_SetCurSel( handle(), iNewPageIndex );
if ( retVal == -1 )
{
if ( iPageIndex )
{
iNewPageIndex = iPageIndex - 1;
retVal = TabCtrl_SetCurSel( handle(), iNewPageIndex );
}
}
if ( retVal != -1 )
{
/**********************************************************************/
/* Notify the parent (i.e. owner) that a new page is now the top */
/* page. because the current top page is being deleted. */
/**********************************************************************/
PAGESELECTNOTIFY pageSelectNotify;
pageSelectNotify.hwndBook = handle();
pageSelectNotify.ulPageIdNew =
tabPageHandle( iNewPageIndex ).asUnsigned();
pageSelectNotify.ulPageIdCur = (long)mp1;
processTabSelect( &pageSelectNotify, false );
}
}
/**************************************************************************/
/* Delete the specified page. */
/**************************************************************************/
if ( !TabCtrl_DeleteItem( handle(), iPageIndex ) )
{
ITHROWGUIERROR("TabCtrl_DeleteItem");
}
/**************************************************************************/
/* Send the page deleted notification to simulate PM behavior */
/**************************************************************************/
DELETENOTIFY deleteNotify;
deleteNotify.hwndBook = handle();
deleteNotify.hwndPage = tabCtrlItem.hPageWindow;
deleteNotify.ulAppPageData = tabCtrlItem.ulUserData;
if ( fNotebookData->hWndImageList )
deleteNotify.hbmTab = imageInfo.hbmImage;
else
deleteNotify.hbmTab = NULL;
parent()->handle().sendEvent( WM_COMMAND,
IEventParameter1( (unsigned short)id(),
BKN_PAGEDELETED ),
IEventParameter2( &deleteNotify ) );
/**************************************************************************/
/* Reset the parent of the application page window for the tab page we */
/* just deleted. We only want to do this if this if the application page */
/* isn't associated with any other tab page. */
/**************************************************************************/
bool bResetParent = true;
if ( (unsigned long)mp2 == BKA_SINGLE )
{
IOC_ITEM tempTabCtrlItem;
unsigned long
ulTotalPages = totalPages();
for ( unsigned i = 0; i < ulTotalPages; i++ )
{
tempTabCtrlItem.itemHeader.mask = TCIF_PARAM;
if ( TabCtrl_GetItem( handle(), i, &tempTabCtrlItem ) )
{
if ( tempTabCtrlItem.hPageWindow == tabCtrlItem.hPageWindow )
{
bResetParent = false;
break;
}
}
}
}
/**************************************************************************/
/* If we didn't find a page (other than the one being freed) that has the */
/* same application page window as the one being freed, reset the */
/* application page window's parent to its original parent. */
/**************************************************************************/
if ( bResetParent )
{
IWindow* pPageWindow = windowWithHandle( tabCtrlItem.hPageWindow );
if ( pPageWindow )
{
SetParent( tabCtrlItem.hPageWindow, tabCtrlItem.hPageWindowParent );
pPageWindow->hide();
}
}
/**************************************************************************/
/* Remove the tab control page handle from our tab page sequence */
/* collection. */
/**************************************************************************/
if ( (unsigned long)mp2 == BKA_SINGLE )
removeTabPage( mp1 );
} //tab control
#endif //IC_WIN
ulClValidate--;
return( true );
}
#endif //IC_PMWIN
/*------------------------------------------------------------------------------
| INotebook::turnToPage |
------------------------------------------------------------------------------*/
INotebook& INotebook :: turnToPage ( const IPageHandle& page )
{
#ifdef IC_PMWIN
IMODTRACE_DEVELOP( "INotebook::turnToPage" );
if ( isPMCompatible() )
{
IEventResult
retVal = sendEvent(BKM_TURNTOPAGE, UPAGE, 0);
if (retVal.asUnsignedLong() == false)
{
ITHROWGUIERROR("BKM_TURNTOPAGE");
}
}
#ifdef IC_WIN
else
{
/**************************************************************************/
/* Verify that pages exist in the Windows tab control. */
/**************************************************************************/
if ( !totalPages() )
{
return( *this );
}
else
{
/************************************************************************/
/* Fill in the PAGESELECTNOTIFY structure that we use in Windows */
/************************************************************************/
PAGESELECTNOTIFY pageSelectNotify;
pageSelectNotify.hwndBook = handle();
pageSelectNotify.ulPageIdNew = page.asUnsigned();
pageSelectNotify.ulPageIdCur = (DWORD)topPage().asUnsigned();
/************************************************************************/
/* The tab selection is now in progress (pending). Do our required */
/* processing and issue the selection pending notification. If the */
/* new page selection is rejected, cancel the page turn request. */
/************************************************************************/
if ( processTabSelect( &pageSelectNotify, true ) )
return( *this );
/************************************************************************/
/* Set the index of the tab page we're turning to. */
/************************************************************************/
long
iPageIndex = tabPageIndex( page );
long
retVal = TabCtrl_SetCurSel( handle(), iPageIndex );
if ( retVal == -1 )
{
ITHROWGUIERROR("TabCtrl_SetCurSel");
}
/************************************************************************/
/* The tab selection has already occurred and the new tab is now the */
/* top page in the tab control. Do our required processing and issue */
/* the selection notification. */
/************************************************************************/
processTabSelect( &pageSelectNotify, false );
}
}
#endif //IC_WIN
#endif // IC_PMWIN
#ifdef IC_MOTIF
XtVaSetValues( fNotebookData->notebook,
XmNcurrentPageNumber, fNotebookData->pageNumber( page ),
NULL );
#endif
return( *this );
}
/*------------------------------------------------------------------------------
| INotebook::turnToPage |
------------------------------------------------------------------------------*/
INotebook& INotebook :: turnToPage ( const Cursor& cursor )
{
return turnToPage(cursor.current());
}
/*------------------------------------------------------------------------------
| INotebook::topPage |
| |
| Returns an IPageHandle object that references the current top page of the |
| notebook. |
------------------------------------------------------------------------------*/
IPageHandle INotebook :: topPage ( ) const
{
#ifdef IC_PMWIN
IPageHandle topPageHandle (0);
if ( isPMCompatible() )
{
/**************************************************************************/
/* CUA '91 notebook */
/**************************************************************************/
unsigned long
retVal = queryPage (0, MPFROM2SHORT (BKA_TOP, 0));
if (retVal)
#ifdef IC_WIN
topPageHandle = (void*)retVal;
#else
topPageHandle = retVal;
#endif
}
#ifdef IC_WIN
else
{
/**************************************************************************/
/* Windows tab control */
/**************************************************************************/
long
iPageIndex = TabCtrl_GetCurSel( handle() );
if ( iPageIndex == -1 )
{
ITHROWGUIERROR("TabCtrl_GetCurSel");
}
/**************************************************************************/
/* We must increment the index since the tab control uses a 0-based index */
/* and sequence collection positions are 1-based. */
/**************************************************************************/
topPageHandle = tabPageHandle( iPageIndex );
}
#endif //IC_WIN
return( topPageHandle );
#endif // IC_PMWIN
#ifdef IC_MOTIF
int curPage;
XtVaGetValues(fNotebookData->notebook, XmNcurrentPageNumber, &curPage, NULL);
return fNotebookData->pageHandle( curPage );
#endif // IC_MOTIF
}
/*------------------------------------------------------------------------------
| INotebook::firstPage |
| |
| Returns an IPageHandle object that references the first page of the notebook.|
------------------------------------------------------------------------------*/
IPageHandle INotebook :: firstPage ( ) const
{
#ifdef IC_PMWIN
unsigned long retVal;
IPageHandle firstPageHandle (0);
if ( isPMCompatible() )
{
retVal = queryPage (0, MPFROM2SHORT (BKA_FIRST, 0));
if (retVal)
#ifdef IC_WIN
firstPageHandle = (void*)retVal;
#else
firstPageHandle = retVal;
#endif
}
#ifdef IC_WIN
else
{
/**************************************************************************/
/* Value of the first page is always the first element in the tab page */
/* sequence collection. */
/**************************************************************************/
if ( totalPages() )
firstPageHandle = tabPageHandle( 0 );
}
#endif //IC_WIN
return( firstPageHandle );
#endif // IC_PMWIN
#ifdef IC_MOTIF
int firstPage;
XtVaGetValues(fNotebookData->notebook, XmNfirstPageNumber, &firstPage, NULL);
return fNotebookData->pageHandle( firstPage );
#endif
}
/*------------------------------------------------------------------------------
| INotebook::lastPage |
| |
| Returns an IPageHandle object that references the last page of the notebook. |
------------------------------------------------------------------------------*/
IPageHandle INotebook :: lastPage ( ) const
{
#ifdef IC_PMWIN
unsigned long retVal;
IPageHandle lastPageHandle (0);
if ( isPMCompatible() )
{
retVal = queryPage (0, MPFROM2SHORT (BKA_LAST, 0));
if (retVal)
#ifdef IC_WIN
lastPageHandle = (void*)retVal;
#else
lastPageHandle = retVal;
#endif
}
#ifdef IC_WIN
else
{
/**************************************************************************/
/* Value of the last page is always the last element in the tab page */
/* sequence collection. */
/**************************************************************************/
lastPageHandle = tabPageHandle( totalPages()-1 );
}
#endif //IC_WIN
return( lastPageHandle );
#endif // IC_PMWIN
#ifdef IC_MOTIF
int lastPage;
XtVaGetValues(fNotebookData->notebook, XmNlastPageNumber, &lastPage, NULL);
return fNotebookData->pageHandle( lastPage );
#endif // iC_MOTIF
}
/*------------------------------------------------------------------------------
| INotebook::nextPage |
| |
| Returns an IPageHandle object that references the next page of the notebook. |
------------------------------------------------------------------------------*/
IPageHandle INotebook :: nextPage ( const IPageHandle& page ) const
{
#ifdef IC_PMWIN
IPageHandle nextPageHandle (0);
if (page)
{
if ( isPMCompatible() )
{
unsigned long retVal = queryPage( MPFROMLONG( UPAGE ),
MPFROM2SHORT( BKA_NEXT, 0 ));
if (retVal)
#ifdef IC_WIN
nextPageHandle = (void*)retVal;
#else
nextPageHandle = retVal;
#endif
}
#ifdef IC_WIN
else
{
/************************************************************************/
/* Verify the reference page. If it does not exist, throw an exception.*/
/************************************************************************/
INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
if ( tabPageHandleCollection()->locate( page, cursor ) )
{
/**********************************************************************/
/* Value of the next page is always the position of the reference */
/* page's element + 1 (in the tab page sequence collection). */
/**********************************************************************/
unsigned long
ulPosition = tabPageHandleCollection()->position( cursor ) + 1;
if ( ulPosition <= tabPageHandleCollection()->numberOfElements() )
{
// Note: tabPageHandle takes a 0-based index.
nextPageHandle = tabPageHandle( ulPosition-1 );
}
}
else
{
ITHROWLIBRARYERROR( IC_INVALIDHANDLE,
IBaseErrorInfo::invalidParameter,
IException::recoverable);
}
}
#endif //IC_WIN
}
return( nextPageHandle );
#endif // IC_PMWIN
#ifdef IC_MOTIF
IPageHandle nextPageHandle (0);
int pageNumber = fNotebookData->pageNumber( page ),
lastPage;
XtVaGetValues(fNotebookData->notebook, XmNlastPageNumber, &lastPage, NULL);
if (++pageNumber <= lastPage)
nextPageHandle = fNotebookData->pageHandle( pageNumber );
return nextPageHandle;
#endif
}
/*------------------------------------------------------------------------------
| INotebook::previousPage |
| |
| Returns an IPageHandle object that references the page preceding the |
| referenced page. |
------------------------------------------------------------------------------*/
IPageHandle INotebook :: previousPage ( const IPageHandle& page ) const
{
#ifdef IC_PMWIN
IPageHandle prevPageHandle (0);
if (page)
{
if ( isPMCompatible() )
{
unsigned long retVal = queryPage( MPFROMLONG( UPAGE ),
MPFROM2SHORT( BKA_PREV, 0 ));
if (retVal)
#ifdef IC_WIN
prevPageHandle = (void*)retVal;
#else
prevPageHandle = retVal;
#endif
}
#ifdef IC_WIN
else
{
/************************************************************************/
/* Verify the reference page. If it does not exist, throw an exception.*/
/************************************************************************/
INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
if ( tabPageHandleCollection()->locate( page, cursor ) )
{
/**********************************************************************/
/* Value of the previous page is always the position of the reference */
/* page's element - 1 (in the tab page sequence collection). */
/**********************************************************************/
unsigned long
ulPosition = tabPageHandleCollection()->position( cursor ) - 1;
if ( ulPosition >= 1 )
{
// Note: tabPageHandle takes a 0-based index.
prevPageHandle = tabPageHandle( ulPosition-1 );
}
}
else
{
ITHROWLIBRARYERROR( IC_INVALIDHANDLE,
IBaseErrorInfo::invalidParameter,
IException::recoverable);
}
}
#endif //IC_WIN
}
return( prevPageHandle );
#endif // IC_PMWIN
#ifdef IC_MOTIF
IPageHandle prevPageHandle (0);
int pageNumber = fNotebookData->pageNumber( page ),
firstPage;
XtVaGetValues(fNotebookData->notebook, XmNfirstPageNumber, &firstPage, NULL);
if (--pageNumber >= firstPage)
prevPageHandle = fNotebookData->pageHandle( pageNumber );
return prevPageHandle;
#endif
}
#ifdef IC_PMWIN
/*------------------------------------------------------------------------------
| INotebook::queryPage |
------------------------------------------------------------------------------*/
unsigned long INotebook :: queryPage ( void* mp1, void* mp2 ) const
{
long retVal = (long)sendEvent(BKM_QUERYPAGEID, mp1, mp2);
if (retVal == BOOKERR_INVALID_PARAMETERS)
{
ITHROWGUIERROR("BKM_QUERYPAGEID:INVALID_PARAMETERS");
}
return (unsigned long)retVal;
}
#endif // IC_PMWIN
/*------------------------------------------------------------------------------
| INotebook::window |
| |
| Returns the window used by the notebook page. |
------------------------------------------------------------------------------*/
IWindow* INotebook :: window ( const INotebook::Cursor& cursor ) const
{
return window(cursor.current()); // Return window for current page
}
/*------------------------------------------------------------------------------
| INotebook::window |
| |
| Returns the window used by the notebook page. |
------------------------------------------------------------------------------*/
IWindow* INotebook :: window ( const IPageHandle& page ) const
{
#ifdef IC_PMWIN
IWindow* pwinReturn = 0; // Assume no window
if ( isPMCompatible() )
{
IWindowHandle wh = (IWindowHandle::Value)
this->sendEvent( BKM_QUERYPAGEWINDOWHWND, UPAGE, 0 );
if ( (long)(IWindowHandle::Value) wh == BOOKERR_INVALID_PARAMETERS )
{
ITHROWGUIERROR("BKM_QUERYPAGEWINDOWHWND");
}
else if (wh != 0)
{
pwinReturn = windowWithHandle(wh);
}
}
#ifdef IC_WIN
else
{
/**************************************************************************/
/* Locate the notebook page. If it does not exist, throw an exception. */
/**************************************************************************/
INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
if ( tabPageHandleCollection()->locate( page, cursor ) )
{
/************************************************************************/
/* Get the pointer to the application page window from the extended tab */
/* control item. */
/************************************************************************/
IOC_ITEM tabCtrlItem;
tabCtrlItem.itemHeader.mask = TCIF_PARAM;
if ( TabCtrl_GetItem( handle(), tabPageIndex( page ), &tabCtrlItem ) )
{
pwinReturn = windowWithHandle( tabCtrlItem.hPageWindow );
}
else
{
ITHROWGUIERROR("TabCtrl_GetItem");
}
}
else
{
ITHROWLIBRARYERROR( IC_INVALIDHANDLE,
IBaseErrorInfo::invalidParameter,
IException::recoverable);
}
}
#endif //IC_WIN
return( pwinReturn );
#endif // IC_PMWIN
#ifdef IC_MOTIF
IWindow* pwinReturn = 0; // Assume no window
XmNotebookPageStatus pageStatus;
XmNotebookPageInfo pageInfo;
pageStatus = XmNotebookGetPageInfo( fNotebookData->notebook,
fNotebookData->pageNumber( page ),
&pageInfo );
IWindowHandle wh = pageInfo.page_widget;
if (wh != 0)
{
pwinReturn = windowWithHandle(wh);
}
return pwinReturn;
#endif
}
/*------------------------------------------------------------------------------
| INotebook::pageSettings |
| |
| Create and return a PageSettings object representing the page. |
------------------------------------------------------------------------------*/
INotebook::PageSettings INotebook :: pageSettings
( const INotebook::Cursor& cursor ) const
{
return pageSettings(cursor.current());
}
/*------------------------------------------------------------------------------
| INotebook::pageSettings |
| |
| Create and return a PageSettings object representing the page. |
------------------------------------------------------------------------------*/
INotebook::PageSettings INotebook :: pageSettings
( const IPageHandle& page ) const
{
#ifdef IC_PMWIN
INotebook::PageSettings newPageSettings (0);
char bookBuffer [100];
if ( isPMCompatible() )
{
/**************************************************************************/
/* CUA '91 notebook processing */
/**************************************************************************/
BOOKTEXT bookText;
unsigned long ulStyle =
(unsigned long)sendEvent(BKM_QUERYPAGESTYLE, UPAGE, 0);
if (ulStyle & PageSettings::autoPageSize.asUnsignedLong())
newPageSettings.pageStyle |= (PageSettings::autoPageSize);
if (ulStyle & PageSettings::statusTextOn.asUnsignedLong())
newPageSettings.pageStyle |= (PageSettings::statusTextOn);
if (ulStyle & PageSettings::majorTab.asUnsignedLong())
newPageSettings.pageStyle |= (PageSettings::majorTab);
if (ulStyle & PageSettings::minorTab.asUnsignedLong())
newPageSettings.pageStyle |= (PageSettings::minorTab);
newPageSettings.savedUserData =
sendEvent(BKM_QUERYPAGEDATA, UPAGE, 0);
bookText.textLen = sizeof (bookBuffer);
bookText.pString = bookBuffer;
short usRetVal = sendEvent( BKM_QUERYSTATUSLINETEXT,
UPAGE,
&bookText );
if (usRetVal && (usRetVal != (short)BOOKERR_INVALID_PARAMETERS))
newPageSettings.savedStatusText = IString (bookBuffer);
usRetVal = sendEvent(BKM_QUERYTABTEXT, UPAGE, &bookText);
if (usRetVal && (usRetVal != (short)BOOKERR_INVALID_PARAMETERS))
newPageSettings.savedTabText = IString (bookBuffer);
HBITMAP hTabBitmap =
sendEvent(BKM_QUERYTABBITMAP, UPAGE, 0);
#ifdef IC_WIN
if (hTabBitmap && (hTabBitmap != (void*)BOOKERR_INVALID_PARAMETERS))
#else
if (hTabBitmap && ((long)hTabBitmap != BOOKERR_INVALID_PARAMETERS))
#endif
{
newPageSettings.savedTabBitmap = IBitmapHandle (hTabBitmap);
}
}
#ifdef IC_WIN
else
{
/**************************************************************************/
/* Windows tab control processing */
/* ---------------------------------------------------------------------- */
/* Locate the notebook page. If it does not exist, throw an exception. */
/**************************************************************************/
INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
if ( !tabPageHandleCollection()->locate( page, cursor ) )
{
ITHROWLIBRARYERROR( IC_INVALIDHANDLE,
IBaseErrorInfo::invalidParameter,
IException::recoverable);
}
/**************************************************************************/
/* Get tab text for the tab page and any user-defined data. Get page */
/* settings attributes from the extended tab control item. */
/**************************************************************************/
IOC_ITEM tabCtrlItem;
tabCtrlItem.itemHeader.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM;
tabCtrlItem.itemHeader.pszText = bookBuffer;
tabCtrlItem.itemHeader.cchTextMax = sizeof(bookBuffer);
if ( !TabCtrl_GetItem( handle(), tabPageIndex( page ), &tabCtrlItem ) )
{
ITHROWGUIERROR("TabCtrl_GetItem");
}
if ( tabCtrlItem.ulPageStyle & PageSettings::autoPageSize.asUnsignedLong() )
newPageSettings.pageStyle |= (PageSettings::autoPageSize);
if ( tabCtrlItem.ulPageStyle & PageSettings::statusTextOn.asUnsignedLong())
newPageSettings.pageStyle |= (PageSettings::statusTextOn);
if ( tabCtrlItem.ulPageStyle & PageSettings::majorTab.asUnsignedLong())
newPageSettings.pageStyle |= (PageSettings::majorTab);
if ( tabCtrlItem.ulPageStyle & PageSettings::minorTab.asUnsignedLong())
newPageSettings.pageStyle |= (PageSettings::minorTab);
newPageSettings.savedUserData = tabCtrlItem.ulUserData;
if ( tabCtrlItem.itemHeader.cchTextMax )
newPageSettings.savedTabText = IString( tabCtrlItem.itemHeader.pszText );
/**************************************************************************/
/* Get tab bitmap for the tab page. */
/**************************************************************************/
if ( fNotebookData->hWndImageList )
{
IMAGEINFO imageInfo;
if ( ImageList_GetImageInfo( fNotebookData->hWndImageList,
tabCtrlItem.itemHeader.iImage,
&imageInfo ) )
{
newPageSettings.savedTabBitmap = IBitmapHandle( imageInfo.hbmImage );
}
else
{
ITHROWGUIERROR("ImageList_GetImageInfo");
}
}
} //isPMCompatible()
#endif //IC_WIN
return newPageSettings;
#endif // IC_PMWIN
#ifdef IC_MOTIF
XmNotebookPageStatus pageStatus;
XmNotebookPageInfo pageInfo;
INotebook::PageSettings newPageSettings (0);
pageStatus = XmNotebookGetPageInfo( fNotebookData->notebook,
fNotebookData->pageNumber( page ),
&pageInfo );
if (pageStatus == XmPAGE_INVALID)
ITHROWGUIERROR("Tried to construct pageSettings for invalid page");
if (pageStatus == XmPAGE_DUPLICATED)
ITHROWGUIERROR("Tried to construct pageSettings for duplicated page");
unsigned long userData = 0;
if (pageInfo.status_area_widget != 0)
{
// The status area widget should always be present. Get the auto size
// and user data information for the page from the page data structure.
XtVaGetValues( pageInfo.status_area_widget,
XmNuserData, &userData,
NULL );
PageData *pageData = (PageData*)userData;
if (pageData->isAutoSize)
newPageSettings.pageStyle |= PageSettings::autoPageSize;
newPageSettings.savedUserData = pageData->userData;
// Get the status text.
newPageSettings.savedStatusText =
IMString( pageInfo.status_area_widget, XmNlabelString ).asString();
newPageSettings.pageStyle |= PageSettings::statusTextOn;
}
if (pageInfo.major_tab_widget != 0)
newPageSettings.pageStyle |= (PageSettings::majorTab);
if (pageInfo.minor_tab_widget != 0)
newPageSettings.pageStyle |= (PageSettings::minorTab);
// Get tab text or bitmap
Widget tabWidget = (pageInfo.major_tab_widget != 0) ?
pageInfo.major_tab_widget :
pageInfo.minor_tab_widget;
if (tabWidget != 0) {
unsigned char labelType;
Pixmap pixmap;
XtVaGetValues(tabWidget,
XmNlabelType, &labelType,
XmNlabelPixmap, &pixmap,
NULL);
if (labelType == XmSTRING) {
newPageSettings.savedTabText =
IMString( tabWidget, XmNlabelString).asString();
//
// When the XmNlabelString text was set, the first mnemonic was removed.
// Any other mnemonics are left to be displayed.
// So if we find a mnemonic in the text now, it should not be removed
// the next time the settings are used to set the XmNlabelString text.
// In that case, insert a tilde at the beginning of the string.
// It will be removed when the XmNlabelString text is set again,
// leaving the existing mnemonic unchanged.
//
IString temp(newPageSettings.savedTabText);
if ( IXmLabel::removeMnemonic( temp ) ) {
newPageSettings.savedTabText.insert( IString('~') );
}
}
else if (labelType == XmPIXMAP) {
newPageSettings.savedTabBitmap = IBitmapHandle (pixmap);
}
}
return newPageSettings;
#endif
}
/*------------------------------------------------------------------------------
| INotebook::setStatusText |
| |
| Change the status text of the specified page in the notebook. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setStatusText ( const IPageHandle& page,
const char* text )
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
PageSettings settings = this->pageSettings( page );
if ( ! settings.isStatusTextOn() )
{ // Ensure the page has a status text area.
ITHROWLIBRARYERROR( IC_NOSTATUSTEXTLINE,
IBaseErrorInfo::invalidRequest,
IException::recoverable );
}
else if ( settings.statusText() != text )
{
if ( isPMCompatible() )
{
IString strText( text ); //Avoid compiler warning!
IEventResult retVal =
this->sendEvent( BKM_SETSTATUSLINETEXT, UPAGE, (char*)strText );
if (retVal.asUnsignedLong() == false)
{
ITHROWGUIERROR( "BKM_SETSTATUSLINETEXT" );
}
}
}
#endif // IC_PMWIN
#ifdef IC_MOTIF
XmNotebookPageStatus pageStatus;
XmNotebookPageInfo pageInfo;
pageStatus = XmNotebookGetPageInfo( fNotebookData->notebook,
fNotebookData->pageNumber( page ),
&pageInfo );
if (pageStatus == XmPAGE_FOUND || pageStatus == XmPAGE_EMPTY) {
if (pageInfo.status_area_widget != 0) {
IMString statusText = IMString( text );
XtVaSetValues(pageInfo.status_area_widget,
XmNlabelString, (XmString)statusText,
NULL);
}
else
ITHROWGUIERROR("Page not added with statusTextOn");
}
else
ITHROWGUIERROR("Invalid page");
#endif
return *this;
}
/*------------------------------------------------------------------------------
| INotebook::setStatusText |
| |
| Change the status text of the specified page in the notebook. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setStatusText ( const IPageHandle& page,
const IResourceId& resId )
{
ITRACE_WIN_NOP();
return setStatusText(page,
resId.resourceLibrary().loadString(resId.id()));
}
/*------------------------------------------------------------------------------
| INotebook::setTabText |
| |
| Change the tab text of the specified notebook page. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setTabText ( const IPageHandle& page,
const char* text )
{
#ifdef IC_PMWIN
IString strText( text ); //Avoid compiler warning!
if ( isPMCompatible() )
{
IEventResult
retVal = sendEvent( BKM_SETTABTEXT, UPAGE, (char *)strText );
if (retVal.asUnsignedLong() == false)
{
ITHROWGUIERROR("BKM_SETTABTEXT");
}
}
#ifdef IC_WIN
else
{
/**************************************************************************/
/* Windows tab control processing */
/* ---------------------------------------------------------------------- */
/* Locate the notebook page. If it does not exist, throw an exception. */
/**************************************************************************/
INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
if ( !tabPageHandleCollection()->locate( page, cursor ) )
{
ITHROWLIBRARYERROR( IC_INVALIDHANDLE,
IBaseErrorInfo::invalidParameter,
IException::recoverable);
}
/**************************************************************************/
/* Set tab text for the tab page. */
/**************************************************************************/
IOC_ITEM tabCtrlItem;
tabCtrlItem.itemHeader.mask = TCIF_TEXT;
tabCtrlItem.itemHeader.pszText = strText;
if ( !TabCtrl_SetItem( handle(), tabPageIndex( page ), &tabCtrlItem ) )
{
ITHROWGUIERROR("TabCtrl_SetItem");
}
}
#endif //IC_WIN
#endif // IC_PMWIN
#ifdef IC_MOTIF
XmNotebookPageStatus pageStatus;
XmNotebookPageInfo pageInfo;
Widget tabWidget;
pageStatus = XmNotebookGetPageInfo( fNotebookData->notebook,
fNotebookData->pageNumber( page ),
&pageInfo );
if (pageStatus == XmPAGE_FOUND || pageStatus == XmPAGE_EMPTY) {
if ((tabWidget = pageInfo.major_tab_widget) == 0)
tabWidget = pageInfo.minor_tab_widget;
if (tabWidget == 0)
ITHROWGUIERROR("Page not added with a tab");
IString itext(text);
IXmLabel::removeMnemonic( itext );
IMString statusText( itext );
XtVaSetValues(tabWidget,
XmNlabelString, (XmString)statusText,
NULL);
}
else
ITHROWGUIERROR("Invalid page");
#endif // IC_MOTIF
return( *this );
}
/*------------------------------------------------------------------------------
| INotebook::setTabText |
| |
| Change the tab text of the specified notebook page. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setTabText ( const IPageHandle& page,
const IResourceId& resId )
{
return setTabText(page,
resId.resourceLibrary().loadString(resId.id()));
}
/*------------------------------------------------------------------------------
| INotebook::setTabBitmap |
| |
| Change the tab bitmap for the specified notebook page. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setTabBitmap ( const IPageHandle& page,
const IBitmapHandle& bitmap )
{
#ifdef IC_PMWIN
IEventResult retVal;
#ifdef IC_PM
IBitmapHandle desktopBitmap = IBitmapStaticPtr::desktopCompatibleBitmap(bitmap);
#endif //IC_PM
if ( isPMCompatible() )
{
retVal = sendEvent( BKM_SETTABBITMAP, UPAGE,
#if defined(IC_WIN)
(unsigned long)(void*)bitmap );
#elif defined(IC_PM)
(unsigned long)desktopBitmap );
#elif defined(IC_MOTIF)
(unsigned long)bitmap );
#endif
if (retVal.asUnsignedLong() == false)
{
ITHROWGUIERROR("BKM_SETTABBITMAP");
}
}
#ifdef IC_WIN
else
{
/**************************************************************************/
/* Windows tab control processing */
/* ---------------------------------------------------------------------- */
/* Locate the notebook page. If it does not exist, throw an exception. */
/**************************************************************************/
INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
if ( !tabPageHandleCollection()->locate( page, cursor ) )
{
ITHROWLIBRARYERROR( IC_INVALIDHANDLE,
IBaseErrorInfo::invalidParameter,
IException::recoverable);
}
/**************************************************************************/
/* Get icon/bitmap dimensions. */
/**************************************************************************/
//SHAJI
long lCXIcon = GetSystemMetrics( SM_CXICON );
long lCYIcon = GetSystemMetrics( SM_CYICON );
IGImage bmpImage( bitmap );
IGRect2D cur_rect = IGImage::imageBounds(bmpImage);
long lCXIcon_actual = cur_rect.width();
long lCYIcon_actual = cur_rect.height();
if ( (lCXIcon_actual <= lCXIcon) || (lCYIcon_actual <= lCYIcon) )
{
lCXIcon = lCXIcon_actual;
lCYIcon = lCYIcon_actual;
}
//SHAJI
/**************************************************************************/
/* We must use an image list per the tab control's requirements. Create */
/* it if it does not exist. */
/**************************************************************************/
if ( !fNotebookData->hWndImageList )
{
/************************************************************************/
/* Create the image list to initially contain 10 bitmaps and grow it */
/* by an increment of 10 whenever the current increment list size is */
/* exceeded. Also, set the bitmap to the system icon size. */
/************************************************************************/
fNotebookData->hWndImageList =
ImageList_Create( (int)lCXIcon, (int)lCYIcon, ILC_COLOR24, 10, 10 );
if ( !fNotebookData->hWndImageList )
ITHROWGUIERROR("ImageList_Create");
/************************************************************************/
/* Set the tab control's image list. */
/************************************************************************/
TabCtrl_SetImageList( handle(), fNotebookData->hWndImageList );
}
/**************************************************************************/
/* Set the image index in the tab control item that identifies the */
/* bitmap's index in the image list. Query the tab control item for */
/* the specified page. */
/**************************************************************************/
long iPageIndex = tabPageIndex( page );
IOC_ITEM tabCtrlItem;
tabCtrlItem.itemHeader.mask = TCIF_PARAM | TCIF_IMAGE;
if ( !TabCtrl_GetItem( handle(), iPageIndex, &tabCtrlItem ) )
{
ITHROWGUIERROR("TabCtrl_GetItem");
}
/**************************************************************************/
/* Use an IGBitmap object to size the bitmap to the system icon size. */
/**************************************************************************/
//IGImage bmpImage( bitmap );
//SHAJI 30397.
bmpImage.sizeTo(IGPoint2D((GCoordinate)lCXIcon, (GCoordinate)lCYIcon));
/**************************************************************************/
/* If the image for the specified page does not exist, add the bitmap */
/* to the image list. */
/**************************************************************************/
if ( tabCtrlItem.itemHeader.iImage == -1 )
{
long
retVal = ImageList_Add( fNotebookData->hWndImageList,
bmpImage.handle(),
NULL );
//If add was not successful, throw an exception
if ( retVal == -1 )
{
ITHROWGUIERROR("ImageList_Add");
}
/************************************************************************/
/* Use the index returned from the add to update the tab control item. */
/************************************************************************/
tabCtrlItem.itemHeader.iImage = (int)retVal;
}
else
{
/************************************************************************/
/* If the image for the specified page exists, replace it with the */
/* specified bitmap. */
/************************************************************************/
if ( !ImageList_Replace( fNotebookData->hWndImageList,
tabCtrlItem.itemHeader.iImage,
bmpImage.handle(),
NULL ) )
{
ITHROWGUIERROR("ImageList_Replace");
}
}
/**************************************************************************/
/* Set the image index in the tab control item that identifies the */
/* bitmap's index in the image list. */
/**************************************************************************/
if ( !TabCtrl_SetItem( handle(), iPageIndex, &tabCtrlItem ) )
{
ITHROWGUIERROR("TabCtrl_SetItem");
}
}
#endif //IC_WIN
ITabBitmapMgr *tmpBitmapMgr = new ITabBitmapMgr(bitmap, page);
tmpBitmapMgr->setNext(bmClTabBitmapMgr);
bmClTabBitmapMgr = tmpBitmapMgr;
#endif // IC_PMWIN
#ifdef IC_MOTIF
XmNotebookPageStatus pageStatus;
XmNotebookPageInfo pageInfo;
Widget tabWidget;
pageStatus = XmNotebookGetPageInfo( fNotebookData->notebook,
fNotebookData->pageNumber( page ),
&pageInfo );
if (pageStatus == XmPAGE_FOUND || pageStatus == XmPAGE_EMPTY) {
if ((tabWidget = pageInfo.major_tab_widget) == 0)
tabWidget = pageInfo.minor_tab_widget;
if (tabWidget == 0)
ITHROWGUIERROR("Page not added with a tab");
XtVaSetValues(tabWidget,
XmNlabelType, XmPIXMAP,
XmNlabelPixmap, bitmap,
NULL);
}
else
ITHROWGUIERROR("Invalid page");
ITabBitmapMgr *tmpBitmapMgr = new ITabBitmapMgr(bitmap, page);
tmpBitmapMgr->setNext(bmClTabBitmapMgr);
bmClTabBitmapMgr = tmpBitmapMgr;
#endif // IC_MOTIF
return *this;
}
/*------------------------------------------------------------------------------
| INotebook::setTabBitmap |
| |
| Change the tab bitmap for the specified notebook page. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setTabBitmap ( const IPageHandle& page,
const IResourceId& resId )
{
return setTabBitmap(page,
resId.resourceLibrary().loadBitmap(resId.id()));
}
/*------------------------------------------------------------------------------
| INotebook::setUserData |
| |
| Change the user data in the specified notebook page. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setUserData ( const IPageHandle& page,
unsigned long ulData )
{
#ifdef IC_PMWIN
if ( isPMCompatible() )
{
IEventResult
retVal = sendEvent( BKM_SETPAGEDATA, UPAGE, ulData );
if (retVal.asUnsignedLong() == false)
{
ITHROWGUIERROR("BKM_SETPAGEDATA");
}
}
#ifdef IC_WIN
else
{
/**************************************************************************/
/* Windows tab control processing */
/* ---------------------------------------------------------------------- */
/* Locate the notebook page. If it does not exist, throw an exception. */
/**************************************************************************/
INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
if ( !tabPageHandleCollection()->locate( page, cursor ) )
{
ITHROWLIBRARYERROR( IC_INVALIDHANDLE,
IBaseErrorInfo::invalidParameter,
IException::recoverable);
}
/**************************************************************************/
/* Get the extended tab item data for the tab page. */
/**************************************************************************/
long iPageIndex = tabPageIndex( page );
IOC_ITEM tabCtrlItem;
tabCtrlItem.itemHeader.mask = TCIF_PARAM;
if ( !TabCtrl_GetItem( handle(), iPageIndex, &tabCtrlItem ) )
{
ITHROWGUIERROR("TabCtrl_GetItem");
}
/**************************************************************************/
/* Set the user data for the tab page. */
/**************************************************************************/
tabCtrlItem.ulUserData = ulData;
if ( !TabCtrl_SetItem( handle(), iPageIndex, &tabCtrlItem ) )
{
ITHROWGUIERROR("TabCtrl_SetItem");
}
}
#endif //IC_WIN
#endif // IC_PMWIN
#ifdef IC_MOTIF
// Store the user data with the status widget since it is always created
// when the page is inserted.
XmNotebookPageStatus pageStatus;
XmNotebookPageInfo pageInfo;
pageStatus = XmNotebookGetPageInfo( fNotebookData->notebook,
fNotebookData->pageNumber( page ),
&pageInfo );
if (pageStatus == XmPAGE_FOUND && pageInfo.status_area_widget != 0)
{
unsigned long userData;
XtVaGetValues( pageInfo.status_area_widget,
XmNuserData, &userData,
NULL );
PageData *pageData = (PageData*)userData;
pageData->userData = ulData;
}
#endif // IC_MOTIF
return( *this );
}
/*------------------------------------------------------------------------------
| INotebook::setWindow |
| |
| Associates the specified page with the window. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setWindow ( const IPageHandle& page,
IWindow* window )
{
#ifdef IC_PMWIN
IMODTRACE_DEVELOP( "INotebook::setWindow" );
/****************************************************************************/
/* Throw assertion if window is 0 */
/****************************************************************************/
IASSERTPARM(window != 0);
INotebook::PageSettings pageInfo = this->pageSettings( page );
if ( isPMCompatible() )
{
/**************************************************************************/
/* CUA '91 notebook processing */
/**************************************************************************/
#ifdef IC_PM
// Remove the page window resize handler for the previous page window if
// one exists. Only remove it if the page window is not also the page
// window for another page.
IWindow *pageWindow = 0;
IWindowHandle hwndPageWindow = sendEvent( BKM_QUERYPAGEWINDOWHWND,
UPAGE,
0).asUnsignedLong();
if (hwndPageWindow)
pageWindow = windowWithHandle( hwndPageWindow );
if (pageWindow)
{
Cursor cursor( *this );
bool pageWindowFound = false;
for (cursor.setToFirst();
cursor.isValid() && !pageWindowFound;
cursor.setToNext())
{
IPageHandle currentHandle = cursor.current();
if (currentHandle != page &&
this->window( currentHandle ) == pageWindow)
pageWindowFound = true;
}
if (!pageWindowFound)
fNotebookData->fPageResizeHandler.stopHandlingEventsFor( pageWindow );
}
#endif // IC_PM
#ifndef IC_WIN
/****************************************************************************/
/* If the page window is a frame, we need to set the owner to NULL. The */
/* notebook will set the parent to the page window (id 8006) and then we */
/* can set the owner to the notebook. (We cannot set the owner to the */
/* notebook initially because this might cause the frame to have the same */
/* parent and owner and cause problems). If the owner of the frame is */
/* not the notebook, a focus loop problem will occur. */
/**************************************************************************/
if ( window->isFrameWindow() )
window->setOwner( NULL );
#endif
#ifdef IC_WIN
unsigned long temphwnd = 0;
if (window)
temphwnd = (unsigned long)(void*)window->handle();
#else
unsigned long temphwnd = (window ? (unsigned long)window->handle() : 0);
#endif
IEventResult
retVal = sendEvent(BKM_SETPAGEWINDOWHWND, UPAGE, temphwnd );
if (retVal.asUnsignedLong() == false)
{
ITHROWGUIERROR("BKM_SETPAGEWINDOWHWND");
}
#ifdef IC_PM
else
{
/***********************************************************************/
/* If there is no owner for the page, set it to the notebook. */
/***********************************************************************/
if ( window->owner() == NULL )
window->setOwner( this );
}
// Add the page window resize handler for PM. Only add it if this page
// window is not already a page window for another page.
Cursor cursor( *this );
bool isHandled = false;
hwndPageWindow = window->handle();
for (cursor.setToFirst();
cursor.isValid() && !isHandled;
cursor.setToNext())
{
IPageHandle currentHandle = cursor.current();
if (currentHandle != page &&
this->window( currentHandle ) == window)
isHandled = true;
}
if (!isHandled)
fNotebookData->fPageResizeHandler.handleEventsFor( window );
#endif // IC_PM
}
#ifdef IC_WIN
else
{
/**************************************************************************/
/* Windows tab control processing */
/**************************************************************************/
if ( pageInfo.isAutoSize() )
{
pageInfo.fPageSettingsData->tabCtrlItem.ulPageStyle |=
PageSettings::autoPageSize.asUnsignedLong();
}
else
{
pageInfo.fPageSettingsData->tabCtrlItem.ulPageStyle &=
~PageSettings::autoPageSize.asUnsignedLong();
}
/**************************************************************************/
/* Add the application page window handle and its parent's handle to our */
/* extended tab control item in addition to any user-defined data. */
/**************************************************************************/
pageInfo.fPageSettingsData->tabCtrlItem.hPageWindow = window->handle();
pageInfo.fPageSettingsData->tabCtrlItem.hPageWindowParent =
( window->parent() ? window->parent()->handle() : IWindowHandle(0) );
pageInfo.fPageSettingsData->tabCtrlItem.ulUserData = pageInfo.userData();
pageInfo.fPageSettingsData->tabCtrlItem.itemHeader.mask = TCIF_PARAM;
if ( !TabCtrl_SetItem( handle(),
tabPageIndex( page ),
&pageInfo.fPageSettingsData->tabCtrlItem ) )
{
ITHROWGUIERROR("TabCtrl_SetItem");
}
/**************************************************************************/
/* Make the page clipping window the parent of the application page */
/* window. */
/**************************************************************************/
window->setParent( pageClippingWindow() );
/**************************************************************************/
/* Size and show the application page window if it is on the top page. */
/**************************************************************************/
if ( page == topPage() )
{
/************************************************************************/
/* Get the tab control's client area */
/************************************************************************/
RECTL tabCtrlRect = rect().asRECTL();
/************************************************************************/
/* Calculate the display rectangle based upon the tab */
/* control's client area, adjusted */
/************************************************************************/
adjustRect( false, &tabCtrlRect );
/************************************************************************/
/* Show the top page window. */
/************************************************************************/
showTopPage( tabPageIndex( page ), &tabCtrlRect );
}
else
{
/************************************************************************/
/* Hide the application window since it is not on the top page. */
/************************************************************************/
window->hide();
}
}
#endif //IC_WIN
#endif // IC_PMWIN
#ifdef IC_MOTIF
// The Motif Notebook widget isn't really designed to support
// setWindow(). Tried to implement this efficiently by setting the
// pageNumber resource of the current page_widget to -1 and then
// setting window->handle's pageNumber to this page.
// That gives us a duplicate page and a null page_widget.
// So for now, just:
// Save the pageSettings for page whose window will be set
INotebook::PageSettings pageSettings = this->pageSettings( page );
// Delete the page, but use false flag to leave a "hole" for the page
int pageNumber = fNotebookData->pageNumber( page );
fNotebookData->deletePages( pageNumber, pageNumber, false);
// Add the page using saved settings and new window, put it in the
// "hole" left when we deleted original page.
addPageAt( pageNumber, pageSettings, window, true );
#endif
return( *this );
}
/*------------------------------------------------------------------------------
| INotebook::setWindow |
| |
| Associates the specified page with the window. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setWindow ( const Cursor& cursor,
IWindow* window )
{
return setWindow(cursor.current(), window);
}
/*------------------------------------------------------------------------------
| INotebook::notebookSize |
| |
| Return the size of the notebook needed to display a page. |
------------------------------------------------------------------------------*/
ISize INotebook :: notebookSize ( const IPageHandle& page ) const
{
ISize pageSize;
IWindow *pageWindow = window( page );
// If there is no page window set, use the default minimum window size.
if (pageWindow == 0)
{
pageSize = Inherited::calcMinimumSize();
}
else
{
#ifdef IC_PMWIN
// Try a dynamic cast to determine whether the page window is a frame
// window.
if (dynamic_cast<IFrameWindow*>(pageWindow))
{
// For dialog page windows, use their actual size.
pageSize = pageWindow->size();
}
else
#endif // IC_PMWIN
{
PageSettings settings = pageSettings( page );
if (!settings.isAutoSize())
{
// If the page window is not auto sized, then use its actual
// size.
pageSize = pageWindow->size();
}
if (pageSize == ISize())
{
// if the page window has not been sized yet or it is to be
// auto sized, then use its minimum size.
pageSize = pageWindow->minimumSize();
}
}
}
#ifdef IC_PMWIN
IRectangle pageRect;
RECTL rectlSize;
pageRect.sizeTo( pageSize );
rectlSize = pageRect.asRECTL();
if (isPMCompatible())
{
IEventResult retVal = handle().sendEvent( BKM_CALCPAGERECT,
&rectlSize,
false );
if (retVal.asUnsignedLong() == false)
{
ITHROWGUIERROR( "BKM_CALCPAGERECT" );
}
}
#ifdef IC_WIN
else
{
adjustRect( true, &rectlSize );
}
#endif //IC_WIN
return ISize( rectlSize );
#endif // IC_PMWIN
#ifdef IC_MOTIF
// Call widget function to determine the notebook size.
Dimension width,
height;
XuiclMinSize( fNotebookData->notebook,
pageSize.width(),
pageSize.height(),
&width,
&height );
return ISize( width, height );
#endif // IC_MOTIF
}
/*------------------------------------------------------------------------------
| INotebook::pageSize |
| |
| Return the size of the "viewport" in which the notebook draws the pages |
| it contains. |
------------------------------------------------------------------------------*/
ISize INotebook :: pageSize ( ) const
{
#ifdef IC_PMWIN
RECTL notebookSize = rect().asRECTL();
if ( isPMCompatible() )
{
IEventResult
retVal = handle().sendEvent( BKM_CALCPAGERECT,
¬ebookSize,
true);
if (retVal.asUnsignedLong() == false)
{
ITHROWGUIERROR("BKM_CALCPAGERECT");
}
}
#ifdef IC_WIN
else
{
adjustRect( false, ¬ebookSize );
}
#endif //IC_WIN
return( ISize( notebookSize ) );
#endif // IC_PMWIN
#ifdef IC_MOTIF
// Call widget function to determine the page size.
Dimension width,
height;
XuiclPageSize( fNotebookData->notebook,
&width,
&height );
return ISize( width, height );
#endif
}
/*------------------------------------------------------------------------------
| INotebook::totalPages |
| |
| Return the total number of pages in the notebook. |
------------------------------------------------------------------------------*/
unsigned long INotebook :: totalPages ( ) const
{
#ifdef IC_PMWIN
unsigned long ulRetVal;
if ( isPMCompatible() )
{
ulRetVal = (unsigned long)queryPageCount( 0, MPFROMSHORT (BKA_END) );
}
#ifdef IC_WIN
else
{
ulRetVal = (unsigned long)TabCtrl_GetItemCount( handle() );
}
#endif //IC_WIN
return( ulRetVal );
#endif // IC_PMWIN
#ifdef IC_MOTIF
int firstPage, lastPage;
XtVaGetValues(fNotebookData->notebook,
XmNfirstPageNumber, &firstPage,
XmNlastPageNumber, &lastPage,
NULL);
if (firstPage == 0 && lastPage == 0)
return 0;
return (lastPage - firstPage + 1);
#endif
}
/*------------------------------------------------------------------------------
| INotebook::pagesToMajorTab |
| |
| Return the number of pages between the specified page and the next page with |
| a major tab. |
------------------------------------------------------------------------------*/
unsigned long INotebook :: pagesToMajorTab ( const IPageHandle& page ) const
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
unsigned long ulRetVal = 1;
if ( isPMCompatible() )
{
ulRetVal = (unsigned long)queryPageCount( MPFROMLONG( UPAGE ),
MPFROMSHORT( PageSettings::majorTab.asUnsignedLong()) );
}
return( ulRetVal );
#endif // IC_PMWIN
#ifdef IC_MOTIF
return fNotebookData->pagesToTab( fNotebookData->pageNumber( page ),
True );
#endif // IC_MOTIF
}
/*------------------------------------------------------------------------------
| INotebook::pagesToMajorTab |
| |
| Return the number of pages between the specified page and the next page with |
| a major tab. |
------------------------------------------------------------------------------*/
unsigned long INotebook :: pagesToMajorTab ( const Cursor& cursor) const
{
ITRACE_WIN_NOP();
return pagesToMajorTab(cursor.current());
}
/*------------------------------------------------------------------------------
| INotebook::pagesToMinorTab |
| |
| Return the number of pages between the specified page and the next page with |
| a minor tab. |
------------------------------------------------------------------------------*/
unsigned long INotebook :: pagesToMinorTab ( const IPageHandle& page ) const
{
ITRACE_WIN_NOP();
#ifdef IC_PMWIN
unsigned long ulRetVal = 0;
if ( isPMCompatible() )
{
ulRetVal = (unsigned long)queryPageCount( MPFROMLONG( UPAGE ),
MPFROMSHORT( PageSettings::minorTab.asUnsignedLong()) );
}
return( ulRetVal );
#endif // IC_PMWIN
#ifdef IC_MOTIF
return fNotebookData->pagesToTab( fNotebookData->pageNumber( page ),
False );
#endif
}
/*------------------------------------------------------------------------------
| INotebook::pagesToMinorTab |
| |
| Return the number of pages between the specified page and the next page with |
| a minor tab. |
------------------------------------------------------------------------------*/
unsigned long INotebook :: pagesToMinorTab ( const Cursor& cursor ) const
{
ITRACE_WIN_NOP();
return pagesToMinorTab(cursor.current());
}
/*------------------------------------------------------------------------------
| INotebook::pagesToEnd |
| |
| Return the number of pages between the specified page and the end of the |
| notebook. |
------------------------------------------------------------------------------*/
unsigned long INotebook :: pagesToEnd ( const IPageHandle& page ) const
{
#ifdef IC_PMWIN
unsigned long ulRetVal = 0;
if ( isPMCompatible() )
{
ulRetVal = (unsigned long)queryPageCount( MPFROMLONG (UPAGE),
MPFROMSHORT (BKA_END) );
}
#ifdef IC_WIN
else
{
long lEnd = totalPages() - tabPageIndex( page );
if ( lEnd >= 0 )
{
ulRetVal = lEnd;
}
else
{
ITHROWLIBRARYERROR( IC_INVALIDHANDLE,
IBaseErrorInfo::invalidParameter,
IException::recoverable);
}
}
#endif //IC_WIN
return( ulRetVal );
#endif // IC_PMWIN
#ifdef IC_MOTIF
int lastPage;
XtVaGetValues(fNotebookData->notebook, XmNlastPageNumber, &lastPage, NULL);
return (lastPage - fNotebookData->pageNumber( page ) + 1);
#endif
}
/*------------------------------------------------------------------------------
| INotebook::pagesToEnd |
| |
| Return the number of pages between the specified page and the end of the |
| notebook. |
------------------------------------------------------------------------------*/
unsigned long INotebook :: pagesToEnd ( const Cursor& cursor ) const
{
return pagesToEnd(cursor.current());
}
/*------------------------------------------------------------------------------
| INotebook::isEmpty |
| |
| Queries whether the notebook has any pages. |
------------------------------------------------------------------------------*/
bool INotebook :: isEmpty ( ) const
{
if ( totalPages() )
return false;
else
return true;
}
#ifdef IC_PMWIN
/*------------------------------------------------------------------------------
| INotebook::queryPageCount |
| |
| Queries whether the notebook has any pages. |
------------------------------------------------------------------------------*/
short INotebook :: queryPageCount ( void* mp1, void* mp2 ) const
{
short retVal = sendEvent(BKM_QUERYPAGECOUNT, mp1, mp2);
if (retVal == BOOKERR_INVALID_PARAMETERS)
{
ITHROWGUIERROR("BKM_QUERYPAGECOUNT");
}
return retVal;
}
#endif // IC_PMWIN
#ifdef IC_WIN
/*------------------------------------------------------------------------------
| INotebook::setLayoutDistorted |
| |
| Propagate the font change to the page windows. |
------------------------------------------------------------------------------*/
INotebook& INotebook :: setLayoutDistorted ( unsigned long layoutAttributesOn,
unsigned long layoutAttributesOff )
{
this->Inherited::setLayoutDistorted( layoutAttributesOn, layoutAttributesOff );
return *this;
}
#endif // IC_WIN
/*------------------------------------------------------------------------------
| INotebook::calcMinimumSize |
| |
| Calculate the minimum screen size needed by the control. The height is |
| based on the minimum size of the superclass control, with the notebook |
| drawing around it. |
------------------------------------------------------------------------------*/
ISize INotebook :: calcMinimumSize ( ) const
{
// Get notebook rectangle.
ISize szLargestBook;
// Determine the largest notebook size which is determined by the largest
// application page window.
for (IPageHandle pageHandle = this->firstPage();
pageHandle;
pageHandle = this->nextPage( pageHandle ))
{
ISize szNoteBook = this->notebookSize( pageHandle );
szLargestBook = szLargestBook.maximum( szNoteBook );
}
// If either the width or height is 0, then we must use the control's API
// to calculate the minimum size. This may be the case when no pages have
// been added to the notebook.
if ((szLargestBook.height() == 0) ||
(szLargestBook.width() == 0))
{
// Get the default minimum size from our base class.
ISize pageSize = this->Inherited::calcMinimumSize();
#ifdef IC_PMWIN
bool bRetVal = true;
RECTL pageRect = this->rect().asRECTL();
// Using the actual control rectangle, determine the page window rectangle.
if (isPMCompatible())
{
bRetVal = (bool)this->sendEvent( BKM_CALCPAGERECT, &pageRect, true )
.asUnsignedLong();
}
#ifdef IC_WIN
else
{
adjustRect( false, &pageRect );
}
#endif //IC_WIN
if (bRetVal)
{
// Determine the new page rectangle from the adjusted control rectangle
// position and the default minimum size for a page window. Use this
// rectangle to determine the minimum size of the notebook.
#ifdef IC_WIN
RECTL newPageRect = IRectangle( IPoint( pageRect.left, pageRect.bottom ),
pageSize ).asRECTL();
#endif // IC_WIN
#ifdef IC_PM
RECTL newPageRect = IRectangle( IPoint( pageRect.xLeft, pageRect.yBottom ),
pageSize ).asRECTL();
#endif // IC_PM
bRetVal = true;
if (isPMCompatible())
{
bRetVal = (bool)this->sendEvent( BKM_CALCPAGERECT, &newPageRect, false )
.asUnsignedLong();
}
#ifdef IC_WIN
else
{
adjustRect( true, &newPageRect );
}
#endif //IC_WIN
if (bRetVal)
{
szLargestBook = ISize( newPageRect );
}
else
{
ITHROWGUIERROR( "BKM_CALCPAGERECT" );
}
}
else
{
ITHROWGUIERROR( "BKM_CALCPAGERECT" );
}
#endif // IC_PMWIN
#ifdef IC_MOTIF
// If the minimum size of the notebook is still (0, 0) then we don't yet have any
// pages added to the notebook. Go ahead and calculate the minimum size of the
// notebook using the default page window size.
Dimension width,
height;
XuiclMinSize( fNotebookData->notebook,
pageSize.width(),
pageSize.height(),
&width,
&height );
szLargestBook = ISize( width, height );
#endif // IC_MOTIF
}
return( szLargestBook );
}
#ifdef IC_PMWIN
/*------------------------------------------------------------------------------
| INotebook::setNotebookColors *** private *** |
| |
| This function handles the setting of the notebook colors that are not |
| identified by system defined PP_* values. The notebook has some special |
| color areas defined that can only be set using a specific notebook message. |
| In addition, the presentation manager notebook does not provide a way to |
| query these colors. |
------------------------------------------------------------------------------*/
void INotebook::setNotebookColors ( unsigned long color,
unsigned long colorArea )
{
bool colorChanged = false;
/********************************************************************/
/* Check to see if the current color is different from the color we */
/* are trying to set. */
/********************************************************************/
switch (colorArea)
{
case BKA_BACKGROUNDPAGECOLOR:
if (pageBackgroundColor() != UnsignedLongAsRGB(color))
{
colorChanged = true;
}
break;
case BKA_BACKGROUNDMAJORCOLOR:
if (majorTabBackgroundColor() != UnsignedLongAsRGB(color))
{
colorChanged = true;
}
break;
case BKA_BACKGROUNDMINORCOLOR:
if (minorTabBackgroundColor() != UnsignedLongAsRGB(color))
{
colorChanged = true;
}
break;
case BKA_FOREGROUNDMAJORCOLOR:
if (majorTabForegroundColor() != UnsignedLongAsRGB(color))
{
colorChanged = true;
}
break;
case BKA_FOREGROUNDMINORCOLOR:
if (minorTabForegroundColor() != UnsignedLongAsRGB(color))
{
colorChanged = true;
}
break;
}
if (colorChanged)
{
/* Set the color on the notebook. */
IEventResult
retVal = sendEvent(BKM_SETNOTEBOOKCOLORS, color, colorArea);
if (retVal.asUnsignedLong() == false)
{
ITHROWGUIERROR("BKM_SETNOTEBOOKCOLORS");
}
}
}
/*------------------------------------------------------------------------------
| INotebook::storeNotebookColors *** private *** |
| |
| This function handles the storing of the notebook colors that are not |
| identified by system defined PP_* values. This enables the colors to be |
| querying later since the system notebook does not provide a query mechanism |
| of its own. |
------------------------------------------------------------------------------*/
void INotebook::storeNotebookColors ( unsigned long color,
unsigned long colorArea )
{
if (!pnotebookColors)
{
pnotebookColors = new NotebookColors;
}
/*******************************************************************/
/* Set a flag to indicate which color we are setting and store the */
/* color we set so it can be queried later. */
/*******************************************************************/
if (colorArea == BKA_BACKGROUNDPAGECOLOR)
{
pnotebookColors->pageBackgroundColor = color;
colorFlags |= INotebook::bgnPageColor;
}
else if (colorArea == BKA_BACKGROUNDMAJORCOLOR)
{
pnotebookColors->majorTabBackgroundColor = color;
colorFlags |= INotebook::bgnMajorColor;
}
else if (colorArea == BKA_BACKGROUNDMINORCOLOR)
{
pnotebookColors->minorTabBackgroundColor = color;
colorFlags |= INotebook::bgnMinorColor;
}
else if (colorArea == BKA_FOREGROUNDMAJORCOLOR)
{
pnotebookColors->majorTabForegroundColor = color;
colorFlags |= INotebook::fgnMajorColor;
}
else if (colorArea == BKA_FOREGROUNDMINORCOLOR)
{
pnotebookColors->minorTabForegroundColor = color;
colorFlags |= INotebook::fgnMinorColor;
}
}
#endif // IC_PMWIN
/*------------------------------------------------------------------------------
| INotebook::UnsignedLongAsRGB *** private *** |
| |
| This function converts an unsigned long to an RGB value and returns it as |
| an IColor object. |
------------------------------------------------------------------------------*/
IColor INotebook::UnsignedLongAsRGB ( unsigned long color ) const
{
/****************************************************************************/
/* Convert the long color to an RGB value then to an IColor object. */
/* */
/* Note: Remember that the calculations for red and blue are flipped in */
/* Windows. */
/****************************************************************************/
#ifdef IC_MOTIFPM
unsigned char blue = (unsigned char)(color);
unsigned char red = (unsigned char)(color >> 16);
#else
unsigned char red = (unsigned char)(color);
unsigned char blue = (unsigned char)(color >> 16);
#endif //IC_MOTIFPM
unsigned char green = (unsigned char)(color >> 8);
return IColor(red, green, blue);
}
#ifdef IC_WIN
/*------------------------------------------------------------------------------
| INotebook::pageClippingWindow *** private *** |
| |
| This function returns the page clipping window that is used to prevent the |
| application page window from drawing over the tab control. |
| using the autoPageSize attribute. |
------------------------------------------------------------------------------*/
IWindow* INotebook::pageClippingWindow ( void ) const
{
return( fNotebookData->pPageClipWindow );
}
/*------------------------------------------------------------------------------
| INotebook::processTabSelect *** private *** |
| |
------------------------------------------------------------------------------*/
bool INotebook :: processTabSelect ( void* pPageSelNotify,
bool bSelectPending ) const
{
IMODTRACE_DEVELOP( "INotebook::processTabSelect" );
PAGESELECTNOTIFY* pPSN = (PAGESELECTNOTIFY *)pPageSelNotify;
long iNewPageIndex = tabPageIndex( (void*)pPSN->ulPageIdNew );
long iCurrentPageIndex = tabPageIndex( (void*)pPSN->ulPageIdCur );
if (bSelectPending)
{
/**************************************************************************/
/* Simulate the CUA '91 notebook's select pending notification */
/**************************************************************************/
return( (bool)parent()->handle().sendEvent(
WM_COMMAND,
IEventParameter1( (unsigned short)id(),
BKN_PAGESELECTEDPENDING ),
IEventParameter2( pPSN ) ).asUnsignedLong() );
}
else
{
/**************************************************************************/
/* Simulate the CUA '91 notebook's page selection notification */
/**************************************************************************/
parent()->handle().sendEvent( WM_COMMAND,
IEventParameter1( (unsigned short)id(),
BKN_PAGESELECTED ),
IEventParameter2( pPSN ) );
}
/****************************************************************************/
/* Initialize variables we'll use later. */
/****************************************************************************/
IOC_ITEM tabCtrlItem;
tabCtrlItem.itemHeader.mask = TCIF_PARAM;
bool bChangeFocus = false;
/****************************************************************************/
/* If the current page index equals the new page index, then we are */
/* processing the selection notification that occurs when the first page */
/* is added to the notebook. If this is the case, do not hide the */
/* application window for the current page. */
/****************************************************************************/
if ( iCurrentPageIndex != iNewPageIndex )
{
/**************************************************************************/
/* Get the application page window's index for the current tab page. */
/**************************************************************************/
if ( !TabCtrl_GetItem( handle(), iCurrentPageIndex, &tabCtrlItem ) )
{
ITHROWGUIERROR("TabCtrl_GetItem");
}
/**************************************************************************/
/* Hide the application page window for the current tab page if the */
/* application page window exists. Check to see if it has the focus */
/* before hiding as we will use this indicator later. */
/**************************************************************************/
IWindow* pOldPageWindow = windowWithHandle( tabCtrlItem.hPageWindow );
if ( pOldPageWindow )
{
// We will reset the focus window is the page window or one of its
// descendants.
for (IWindowHandle hwnd = IQUERYFOCUS( IWindow::desktopWindow() );
!bChangeFocus && hwnd;
hwnd = IPARENTOF( hwnd ))
{
if (hwnd == tabCtrlItem.hPageWindow)
bChangeFocus = true;
}
pOldPageWindow->hide();
fNotebookData->fTopPageKeyboardHandler.stopHandlingEventsFor(
pOldPageWindow );
}
}
/****************************************************************************/
/* Get the tab control's client area */
/****************************************************************************/
RECTL tabCtrlRect = rect().asRECTL();
/****************************************************************************/
/* Calculate the display rectangle based upon the tab */
/* control's client area, adjusted */
/****************************************************************************/
adjustRect( false, &tabCtrlRect );
/****************************************************************************/
/* Show the new top page window. */
/****************************************************************************/
showTopPage( iNewPageIndex, &tabCtrlRect );
/****************************************************************************/
/* If the focus was on the old application page window, set it to the new */
/* application page window if it exists. */
/****************************************************************************/
if (bChangeFocus)
{
/**************************************************************************/
/* Get the tab item for the newly selected tab page. */
/**************************************************************************/
tabCtrlItem.itemHeader.mask = TCIF_PARAM;
if ( !TabCtrl_GetItem( handle(), iNewPageIndex, &tabCtrlItem ) )
{
ITHROWGUIERROR("TabCtrl_GetItem");
}
IWindow* pNewPageWindow = windowWithHandle( tabCtrlItem.hPageWindow );
if ( pNewPageWindow )
{
pNewPageWindow->setFocus();
}
}
return( true );
}
/*------------------------------------------------------------------------------
| INotebook::showTopPage *** private *** |
| |
| Show the top page. |
------------------------------------------------------------------------------*/
void INotebook::showTopPage( long iPageIndex, void* pRect,
bool bNotResizing ) const
{
IMODTRACE_DEVELOP( "INotebook::showTopPage" );
/****************************************************************************/
/* Get the tab control item for the currently selected page. */
/****************************************************************************/
IOC_ITEM tabCtrlItem;
tabCtrlItem.itemHeader.mask = TCIF_PARAM;
if ( !TabCtrl_GetItem( handle(), iPageIndex, &tabCtrlItem ) )
{
ITHROWGUIERROR("TabCtrl_GetItem");
}
RECT tabCtrlRect;
/****************************************************************************/
/* Position, size, and show the page clipping window. We position and */
/* size it here as well as in the private resize handler to handle the */
/* the tab control's placement on a canvas. If the tab control is placed */
/* on a canvas, then there is a possibility that a resize event is not */
/* generated. Hence, we resize here so both the page clipping window and */
/* the application page window are shown. Note that we must re-calculate */
/* and re-adjust the display rectangle because of this dilemna. */
/****************************************************************************/
/**************************************************************************/
/* Get the tab control's client area */
/**************************************************************************/
RECTL tempRectl = rect().asRECTL();
/**************************************************************************/
/* Calculate the display rectangle based upon the tab */
/* control's client area, adjusted */
/**************************************************************************/
SetRect( &tabCtrlRect, 0, 0,
(int)(tempRectl.right - tempRectl.left),
(int)(tempRectl.bottom - tempRectl.top) );
adjustRect( false, &tabCtrlRect );
SetWindowPos( pageClippingWindow()->handle(),
NULL, (int)tabCtrlRect.left, (int)tabCtrlRect.top,
(int)(tabCtrlRect.right - tabCtrlRect.left),
(int)(tabCtrlRect.bottom - tabCtrlRect.top),
SWP_NOACTIVATE );
if ( !pageClippingWindow()->isVisible() )
pageClippingWindow()->show();
/****************************************************************************/
/* If the application page window exists, position and size it to fit the */
/* tab control's display area, as long as the autoPageSize attribute is */
/* specified. Also, show it as well. */
/****************************************************************************/
IWindow* pPageWindow = windowWithHandle( tabCtrlItem.hPageWindow );
if ( pPageWindow )
{
if ( tabCtrlItem.ulPageStyle &
INotebook::PageSettings::autoPageSize.asUnsignedLong() )
{
SetWindowPos( tabCtrlItem.hPageWindow,
NULL, 0, 0,
(int)(tabCtrlRect.right - tabCtrlRect.left),
(int)(tabCtrlRect.bottom - tabCtrlRect.top),
0 );
}
if ( !pPageWindow->isVisible() )
pPageWindow->show();
if ( bNotResizing )
fNotebookData->fTopPageKeyboardHandler.handleEventsFor( pPageWindow );
}
else
{
/**************************************************************************/
/* Otherwise, invalidate the page clipping window so it is repainted. */
/**************************************************************************/
pageClippingWindow()->refresh();
}
}
/*------------------------------------------------------------------------------
| INotebook::adjustRect *** private *** |
| |
| Adjust the display rectangle. |
------------------------------------------------------------------------------*/
void INotebook::adjustRect ( bool bTabCtrlSize, void* pRect ) const
{
IMODTRACE_DEVELOP( "INotebook::adjustRect" );
if ( IRectangle( *(LPRECTL)pRect ) != IRectangle() )
{
if ( isDrawTabsEnabled() && !bTabCtrlSize )
{
/************************************************************************/
/* if owner draw tabs, then we must calculate the display area to */
/* avoid problems that occur when the tab is resized. */
/************************************************************************/
long lTabHeight;
if ( fNotebookData->lMajorTabHeight )
lTabHeight = fNotebookData->lMajorTabHeight + 4;
else
{
RECT tabRect;
TabCtrl_GetItemRect( handle(), 0, &tabRect );
lTabHeight = tabRect.top + tabRect.bottom;
}
((LPRECTL)pRect)->top += lTabHeight;
((LPRECTL)pRect)->left += 4;
((LPRECTL)pRect)->right -= 4;
((LPRECTL)pRect)->bottom -= 4;
}
else
{
TabCtrl_AdjustRect( handle(), bTabCtrlSize, (LPRECTL)pRect );
}
}
}
/*------------------------------------------------------------------------------
| INotebook::tabControlResize *** private *** |
| |
| Resize the tab control, page clipping, and application page windows. |
------------------------------------------------------------------------------*/
void INotebook::tabControlResize ( const ISize& newSize ) const
{
IMODTRACE_DEVELOP( "INotebook::tabControlResize" );
/****************************************************************************/
/* Calculate the display rectangle, assuming the tab control is the size */
/* of the client area */
/****************************************************************************/
RECT tabCtrlRect;
SetRect( &tabCtrlRect, 0, 0,
(int)newSize.width(),
(int)newSize.height() );
adjustRect( false, &tabCtrlRect );
/****************************************************************************/
/* Position and size the page clipping window, and show it if it is not */
/* visible. */
/****************************************************************************/
SetWindowPos( pageClippingWindow()->handle(),
NULL, (int)tabCtrlRect.left, (int)tabCtrlRect.top,
(int)(tabCtrlRect.right - tabCtrlRect.left),
(int)(tabCtrlRect.bottom - tabCtrlRect.top),
SWP_NOACTIVATE );
if ( !pageClippingWindow()->isVisible() )
pageClippingWindow()->show();
/****************************************************************************/
/* We are finished if there are no pages in the notebook. */
/****************************************************************************/
if ( !totalPages() )
{
return;
}
/****************************************************************************/
/* Get the index for the currently selected tab page. */
/****************************************************************************/
long
iPageIndex = TabCtrl_GetCurSel( handle() );
if ( iPageIndex == -1 )
{
ITHROWGUIERROR("TabCtrl_GetCurSel");
}
/****************************************************************************/
/* Show the top page window. */
/****************************************************************************/
showTopPage( iPageIndex, &tabCtrlRect, false );
/****************************************************************************/
/* Send the new page size notification to simulate PM behavior */
/****************************************************************************/
parent()->handle().sendEvent( WM_COMMAND,
IEventParameter1( (unsigned short)id(),
BKN_NEWPAGESIZE ),
IEventParameter2( handle() ) );
}
/*------------------------------------------------------------------------------
| INotebook::tabPageHandleCollection *** private *** |
| |
| Returns a pointer to the collection of tab control page handles. |
------------------------------------------------------------------------------*/
INotebookPageSequence* INotebook :: tabPageHandleCollection( ) const
{
return( this->pTabCtrlPageSeqCl );
}
/*------------------------------------------------------------------------------
| INotebook::tabPageIndex *** private *** |
| |
| Returns the tab control page index (0-based) for the given handle. |
------------------------------------------------------------------------------*/
long INotebook :: tabPageIndex( const IPageHandle& pageHandle ) const
{
long iPageIndex = -1;
INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
if ( tabPageHandleCollection()->locate( pageHandle, cursor ) )
{
/**************************************************************************/
/* Position is 1-based, and tab page indicies are 0-based, so adjust. */
/**************************************************************************/
iPageIndex = tabPageHandleCollection()->position( cursor ) - 1;
}
return( iPageIndex );
}
/*------------------------------------------------------------------------------
| INotebook::tabPageHandle *** private *** |
| |
| Returns the tab control page handle for the given index (0-based). |
------------------------------------------------------------------------------*/
IPageHandle INotebook :: tabPageHandle( unsigned long ulPosition ) const
{
return( tabPageHandleCollection()->elementAtPosition( ulPosition+1 ) );
}
/*------------------------------------------------------------------------------
| INotebook::insertTabPage *** private *** |
| |
| Adds the tab control page handle at the given position. Store the page |
| handle as the element. The page handle is unique, as we assign a unique |
| value to each page as it is added to the notebook. Since we add the page |
| in the same location in both the tab control and in this equality sequence, |
| we can locate the page handle's position in the sequence and use the |
| position as the index of the page to the actual tab control. However, |
| positions in the equality sequence are 1-based and the tab control's page |
| index is 0-based, so we must remember to adjust the position and index |
| where appropriate. |
------------------------------------------------------------------------------*/
IPageHandle INotebook :: insertTabPage( const PageSettings& pageInfo,
const IPageHandle& referencePage,
unsigned long ulPosition )
{
unsigned long ulIndex;
/****************************************************************************/
/* Create a unique page handle for each page that is inserted. Never */
/* decrement ulClPagesInserted (unless an exception is thrown). */
/****************************************************************************/
ulClPagesInserted++;
IPageHandle pageHandle( (void*)ulClPagesInserted );
switch( ulPosition )
{
case BKA_FIRST:
{
tabPageHandleCollection()->addAsFirst( pageHandle );
ulIndex = 0;
break;
}
case BKA_PREV:
{
INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
if ( tabPageHandleCollection()->locate( referencePage, cursor ) )
{
tabPageHandleCollection()->addAsPrevious( pageHandle, cursor );
ulIndex = tabPageHandleCollection()->position( cursor ) - 1;
}
else
{
ulClPagesInserted--;
//Throw exception
ITHROWLIBRARYERROR(IC_INDEX_OUT_OF_RANGE,
IBaseErrorInfo::invalidRequest,
IException::recoverable);
}
break;
}
case BKA_NEXT:
{
INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
if ( tabPageHandleCollection()->locate( referencePage, cursor ) )
{
tabPageHandleCollection()->addAsNext( pageHandle, cursor );
ulIndex = tabPageHandleCollection()->position( cursor ) - 1;
}
else
{
ulClPagesInserted--;
//Throw exception
ITHROWLIBRARYERROR(IC_INDEX_OUT_OF_RANGE,
IBaseErrorInfo::invalidRequest,
IException::recoverable);
}
break;
}
case BKA_LAST:
{
tabPageHandleCollection()->addAsLast( pageHandle );
ulIndex = totalPages();
break;
}
default:
ulClPagesInserted--;
//Throw exception
ITHROWLIBRARYERROR(IC_INDEX_OUT_OF_RANGE,
IBaseErrorInfo::invalidRequest,
IException::recoverable);
break;
} // end switch
/****************************************************************************/
/* Insert the tab control page at the given index. Please note that since */
/* we have extended the tab control item, we must include the TCIF_PARAM */
/* style to indicate that additional information is contained within it. */
/****************************************************************************/
pageInfo.fPageSettingsData->tabCtrlItem.itemHeader.mask |= TCIF_PARAM;
if ( TabCtrl_InsertItem( handle(), ulIndex,
&pageInfo.fPageSettingsData->tabCtrlItem ) == -1 )
{
ulClPagesInserted--;
//If insert was not successful, throw an exception
ITHROWGUIERROR("TCM_INSERTITEM");
}
ulClValidate++;
return( pageHandle );
}
/*------------------------------------------------------------------------------
| INotebook::removeTabPage *** private *** |
| |
| Removes the tab control page handle at the given position. |
------------------------------------------------------------------------------*/
bool INotebook :: removeTabPage( const IPageHandle& pageHandle )
{
INotebookPageSequence::Cursor cursor(*tabPageHandleCollection());
if ( tabPageHandleCollection()->locate( pageHandle, cursor ) )
{
tabPageHandleCollection()->removeAt( cursor );
}
return( true );
}
#endif //IC_WIN
#ifdef IC_MOTIF
/*------------------------------------------------------------------------------
| INotebookData::registerCallbacks |
| |
| Add callbacks and X event handlers for events which notebooks can |
| experience. |
------------------------------------------------------------------------------*/
void INotebookData::registerCallbacks()
{
// Add the callback to handle the changed flag
XtAddCallback( notebook,
XmNpageChangedCallback,
iwindowMotifCallback,
IWindow::windowWithHandle( notebook ));
}
/*------------------------------------------------------------------------------
| INotebookData::unregisterCallbacks |
| |
| Remove callbacks and X event handlers added in registerCallbacks(). |
------------------------------------------------------------------------------*/
void INotebookData::unregisterCallbacks()
{
// Remove the callback to handle the changed flag
XtRemoveCallback( notebook,
XmNpageChangedCallback,
iwindowMotifCallback,
IWindow::windowWithHandle( notebook ));
}
#endif // IC_MOTIF