1*cdf0e10cSrcweir/************************************************************************ 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir// MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir#include "precompiled_vcl.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir#include "tools/resary.hxx" 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir#include "vcl/print.hxx" 34*cdf0e10cSrcweir#include "vcl/image.hxx" 35*cdf0e10cSrcweir#include "vcl/virdev.hxx" 36*cdf0e10cSrcweir#include "vcl/svapp.hxx" 37*cdf0e10cSrcweir#include "vcl/unohelp.hxx" 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir#include "aqua/aquaprintview.h" 40*cdf0e10cSrcweir#include "aqua/salinst.h" 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir#include "svdata.hxx" 43*cdf0e10cSrcweir#include "svids.hrc" 44*cdf0e10cSrcweir 45*cdf0e10cSrcweir#include "com/sun/star/i18n/XBreakIterator.hpp" 46*cdf0e10cSrcweir#include "com/sun/star/i18n/WordType.hpp" 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir#include <map> 49*cdf0e10cSrcweir 50*cdf0e10cSrcweirusing namespace vcl; 51*cdf0e10cSrcweirusing namespace com::sun::star; 52*cdf0e10cSrcweirusing namespace com::sun::star::beans; 53*cdf0e10cSrcweirusing namespace com::sun::star::uno; 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir/* Note: the accesory view as implemented here is already deprecated in Leopard. Unfortunately 56*cdf0e10cSrcweir as long as our baseline is Tiger we cannot gain the advantages over multiple accessory views 57*cdf0e10cSrcweir as well havs having accessory views AND a preview (as long as you are linked vs. 10.4 libraries 58*cdf0e10cSrcweir the preview insists on not being present. This is unfortunate. 59*cdf0e10cSrcweir*/ 60*cdf0e10cSrcweir 61*cdf0e10cSrcweirclass ControllerProperties; 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir@interface ControlTarget : NSObject 64*cdf0e10cSrcweir{ 65*cdf0e10cSrcweir ControllerProperties* mpController; 66*cdf0e10cSrcweir} 67*cdf0e10cSrcweir-(id)initWithControllerMap: (ControllerProperties*)pController; 68*cdf0e10cSrcweir-(void)triggered:(id)pSender; 69*cdf0e10cSrcweir-(void)triggeredNumeric:(id)pSender; 70*cdf0e10cSrcweir-(void)triggeredPreview:(id)pSender; 71*cdf0e10cSrcweir-(void)dealloc; 72*cdf0e10cSrcweir@end 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir 75*cdf0e10cSrcweirclass ControllerProperties 76*cdf0e10cSrcweir{ 77*cdf0e10cSrcweir vcl::PrinterController* mpController; 78*cdf0e10cSrcweir std::map< int, rtl::OUString > maTagToPropertyName; 79*cdf0e10cSrcweir std::map< int, sal_Int32 > maTagToValueInt; 80*cdf0e10cSrcweir std::map< NSView*, NSView* > maViewPairMap; 81*cdf0e10cSrcweir std::vector< NSObject* > maViews; 82*cdf0e10cSrcweir int mnNextTag; 83*cdf0e10cSrcweir sal_Int32 mnLastPageCount; 84*cdf0e10cSrcweir PrintAccessoryViewState* mpState; 85*cdf0e10cSrcweir NSPrintOperation* mpOp; 86*cdf0e10cSrcweir NSView* mpAccessoryView; 87*cdf0e10cSrcweir NSTabView* mpTabView; 88*cdf0e10cSrcweir NSBox* mpPreviewBox; 89*cdf0e10cSrcweir NSImageView* mpPreview; 90*cdf0e10cSrcweir NSTextField* mpPageEdit; 91*cdf0e10cSrcweir NSStepper* mpStepper; 92*cdf0e10cSrcweir NSTextView* mpPagesLabel; 93*cdf0e10cSrcweir ResStringArray maLocalizedStrings; 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir public: 96*cdf0e10cSrcweir ControllerProperties( vcl::PrinterController* i_pController, 97*cdf0e10cSrcweir NSPrintOperation* i_pOp, 98*cdf0e10cSrcweir NSView* i_pAccessoryView, 99*cdf0e10cSrcweir NSTabView* i_pTabView, 100*cdf0e10cSrcweir PrintAccessoryViewState* i_pState ) 101*cdf0e10cSrcweir : mpController( i_pController ), 102*cdf0e10cSrcweir mnNextTag( 0 ), 103*cdf0e10cSrcweir mnLastPageCount( i_pController->getFilteredPageCount() ), 104*cdf0e10cSrcweir mpState( i_pState ), 105*cdf0e10cSrcweir mpOp( i_pOp ), 106*cdf0e10cSrcweir mpAccessoryView( i_pAccessoryView ), 107*cdf0e10cSrcweir mpTabView( i_pTabView ), 108*cdf0e10cSrcweir mpPreviewBox( nil ), 109*cdf0e10cSrcweir mpPreview( nil ), 110*cdf0e10cSrcweir mpPageEdit( nil ), 111*cdf0e10cSrcweir mpStepper( nil ), 112*cdf0e10cSrcweir mpPagesLabel( nil ), 113*cdf0e10cSrcweir maLocalizedStrings( VclResId( SV_PRINT_NATIVE_STRINGS ) ) 114*cdf0e10cSrcweir { 115*cdf0e10cSrcweir mpState->bNeedRestart = false; 116*cdf0e10cSrcweir DBG_ASSERT( maLocalizedStrings.Count() >= 5, "resources not found !" ); 117*cdf0e10cSrcweir } 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir rtl::OUString getMoreString() 120*cdf0e10cSrcweir { 121*cdf0e10cSrcweir return maLocalizedStrings.Count() >= 4 122*cdf0e10cSrcweir ? rtl::OUString( maLocalizedStrings.GetString( 3 ) ) 123*cdf0e10cSrcweir : rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "More" ) ); 124*cdf0e10cSrcweir } 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir rtl::OUString getPrintSelectionString() 127*cdf0e10cSrcweir { 128*cdf0e10cSrcweir return maLocalizedStrings.Count() >= 5 129*cdf0e10cSrcweir ? rtl::OUString( maLocalizedStrings.GetString( 4 ) ) 130*cdf0e10cSrcweir : rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Print selection only" ) ); 131*cdf0e10cSrcweir } 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir void updatePrintJob() 134*cdf0e10cSrcweir { 135*cdf0e10cSrcweir // TODO: refresh page count etc from mpController 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir // page range may have changed depending on options 138*cdf0e10cSrcweir sal_Int32 nPages = mpController->getFilteredPageCount(); 139*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 140*cdf0e10cSrcweir if( nPages != mnLastPageCount ) 141*cdf0e10cSrcweir fprintf( stderr, "trouble: number of pages changed from %ld to %ld !\n", mnLastPageCount, nPages ); 142*cdf0e10cSrcweir #endif 143*cdf0e10cSrcweir mpState->bNeedRestart = (nPages != mnLastPageCount); 144*cdf0e10cSrcweir NSTabViewItem* pItem = [mpTabView selectedTabViewItem]; 145*cdf0e10cSrcweir if( pItem ) 146*cdf0e10cSrcweir mpState->nLastPage = [mpTabView indexOfTabViewItem: pItem]; 147*cdf0e10cSrcweir else 148*cdf0e10cSrcweir mpState->nLastPage = 0; 149*cdf0e10cSrcweir mnLastPageCount = nPages; 150*cdf0e10cSrcweir if( mpState->bNeedRestart ) 151*cdf0e10cSrcweir { 152*cdf0e10cSrcweir #if 0 153*cdf0e10cSrcweir // Warning: bad hack ahead 154*cdf0e10cSrcweir // Apple does not give us a chance of changing the page count, 155*cdf0e10cSrcweir // and they don't let us cancel the dialog either 156*cdf0e10cSrcweir // hack: send a cancel message to the window displaying our views. 157*cdf0e10cSrcweir // this is ugly. 158*cdf0e10cSrcweir for( std::vector< NSObject* >::iterator it = maViews.begin(); it != maViews.end(); ++it ) 159*cdf0e10cSrcweir { 160*cdf0e10cSrcweir if( [*it isKindOfClass: [NSView class]] ) 161*cdf0e10cSrcweir { 162*cdf0e10cSrcweir NSView* pView = (NSView*)*it; 163*cdf0e10cSrcweir NSWindow* pWindow = [pView window]; 164*cdf0e10cSrcweir if( pWindow ) 165*cdf0e10cSrcweir { 166*cdf0e10cSrcweir [pWindow cancelOperation: nil]; 167*cdf0e10cSrcweir break; 168*cdf0e10cSrcweir } 169*cdf0e10cSrcweir } 170*cdf0e10cSrcweir } 171*cdf0e10cSrcweir #else 172*cdf0e10cSrcweir NSWindow* pWindow = [NSApp modalWindow]; 173*cdf0e10cSrcweir if( pWindow ) 174*cdf0e10cSrcweir [pWindow cancelOperation: nil]; 175*cdf0e10cSrcweir #endif 176*cdf0e10cSrcweir [[mpOp printInfo] setJobDisposition: NSPrintCancelJob]; 177*cdf0e10cSrcweir } 178*cdf0e10cSrcweir else 179*cdf0e10cSrcweir { 180*cdf0e10cSrcweir sal_Int32 nPage = [mpStepper intValue]; 181*cdf0e10cSrcweir updatePreviewImage( nPage-1 ); 182*cdf0e10cSrcweir } 183*cdf0e10cSrcweir } 184*cdf0e10cSrcweir 185*cdf0e10cSrcweir int addNameTag( const rtl::OUString& i_rPropertyName ) 186*cdf0e10cSrcweir { 187*cdf0e10cSrcweir int nNewTag = mnNextTag++; 188*cdf0e10cSrcweir maTagToPropertyName[ nNewTag ] = i_rPropertyName; 189*cdf0e10cSrcweir return nNewTag; 190*cdf0e10cSrcweir } 191*cdf0e10cSrcweir 192*cdf0e10cSrcweir int addNameAndValueTag( const rtl::OUString& i_rPropertyName, sal_Int32 i_nValue ) 193*cdf0e10cSrcweir { 194*cdf0e10cSrcweir int nNewTag = mnNextTag++; 195*cdf0e10cSrcweir maTagToPropertyName[ nNewTag ] = i_rPropertyName; 196*cdf0e10cSrcweir maTagToValueInt[ nNewTag ] = i_nValue; 197*cdf0e10cSrcweir return nNewTag; 198*cdf0e10cSrcweir } 199*cdf0e10cSrcweir 200*cdf0e10cSrcweir void addObservedControl( NSObject* i_pView ) 201*cdf0e10cSrcweir { 202*cdf0e10cSrcweir maViews.push_back( i_pView ); 203*cdf0e10cSrcweir } 204*cdf0e10cSrcweir 205*cdf0e10cSrcweir void addViewPair( NSView* i_pLeft, NSView* i_pRight ) 206*cdf0e10cSrcweir { 207*cdf0e10cSrcweir maViewPairMap[ i_pLeft ] = i_pRight; 208*cdf0e10cSrcweir maViewPairMap[ i_pRight ] = i_pLeft; 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir 211*cdf0e10cSrcweir NSView* getPair( NSView* i_pLeft ) const 212*cdf0e10cSrcweir { 213*cdf0e10cSrcweir NSView* pRight = nil; 214*cdf0e10cSrcweir std::map< NSView*, NSView* >::const_iterator it = maViewPairMap.find( i_pLeft ); 215*cdf0e10cSrcweir if( it != maViewPairMap.end() ) 216*cdf0e10cSrcweir pRight = it->second; 217*cdf0e10cSrcweir return pRight; 218*cdf0e10cSrcweir } 219*cdf0e10cSrcweir 220*cdf0e10cSrcweir void changePropertyWithIntValue( int i_nTag ) 221*cdf0e10cSrcweir { 222*cdf0e10cSrcweir std::map< int, rtl::OUString >::const_iterator name_it = maTagToPropertyName.find( i_nTag ); 223*cdf0e10cSrcweir std::map< int, sal_Int32 >::const_iterator value_it = maTagToValueInt.find( i_nTag ); 224*cdf0e10cSrcweir if( name_it != maTagToPropertyName.end() && value_it != maTagToValueInt.end() ) 225*cdf0e10cSrcweir { 226*cdf0e10cSrcweir PropertyValue* pVal = mpController->getValue( name_it->second ); 227*cdf0e10cSrcweir if( pVal ) 228*cdf0e10cSrcweir { 229*cdf0e10cSrcweir pVal->Value <<= value_it->second; 230*cdf0e10cSrcweir updatePrintJob(); 231*cdf0e10cSrcweir } 232*cdf0e10cSrcweir } 233*cdf0e10cSrcweir } 234*cdf0e10cSrcweir 235*cdf0e10cSrcweir void changePropertyWithIntValue( int i_nTag, sal_Int64 i_nValue ) 236*cdf0e10cSrcweir { 237*cdf0e10cSrcweir std::map< int, rtl::OUString >::const_iterator name_it = maTagToPropertyName.find( i_nTag ); 238*cdf0e10cSrcweir if( name_it != maTagToPropertyName.end() ) 239*cdf0e10cSrcweir { 240*cdf0e10cSrcweir PropertyValue* pVal = mpController->getValue( name_it->second ); 241*cdf0e10cSrcweir if( pVal ) 242*cdf0e10cSrcweir { 243*cdf0e10cSrcweir pVal->Value <<= i_nValue; 244*cdf0e10cSrcweir updatePrintJob(); 245*cdf0e10cSrcweir } 246*cdf0e10cSrcweir } 247*cdf0e10cSrcweir } 248*cdf0e10cSrcweir 249*cdf0e10cSrcweir void changePropertyWithBoolValue( int i_nTag, sal_Bool i_bValue ) 250*cdf0e10cSrcweir { 251*cdf0e10cSrcweir std::map< int, rtl::OUString >::const_iterator name_it = maTagToPropertyName.find( i_nTag ); 252*cdf0e10cSrcweir if( name_it != maTagToPropertyName.end() ) 253*cdf0e10cSrcweir { 254*cdf0e10cSrcweir PropertyValue* pVal = mpController->getValue( name_it->second ); 255*cdf0e10cSrcweir if( pVal ) 256*cdf0e10cSrcweir { 257*cdf0e10cSrcweir // ugly 258*cdf0e10cSrcweir if( name_it->second.equalsAscii( "PrintContent" ) ) 259*cdf0e10cSrcweir pVal->Value <<= i_bValue ? sal_Int32(2) : sal_Int32(0); 260*cdf0e10cSrcweir else 261*cdf0e10cSrcweir pVal->Value <<= i_bValue; 262*cdf0e10cSrcweir updatePrintJob(); 263*cdf0e10cSrcweir } 264*cdf0e10cSrcweir } 265*cdf0e10cSrcweir } 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir void changePropertyWithStringValue( int i_nTag, const rtl::OUString& i_rValue ) 268*cdf0e10cSrcweir { 269*cdf0e10cSrcweir std::map< int, rtl::OUString >::const_iterator name_it = maTagToPropertyName.find( i_nTag ); 270*cdf0e10cSrcweir if( name_it != maTagToPropertyName.end() ) 271*cdf0e10cSrcweir { 272*cdf0e10cSrcweir PropertyValue* pVal = mpController->getValue( name_it->second ); 273*cdf0e10cSrcweir if( pVal ) 274*cdf0e10cSrcweir { 275*cdf0e10cSrcweir pVal->Value <<= i_rValue; 276*cdf0e10cSrcweir updatePrintJob(); 277*cdf0e10cSrcweir } 278*cdf0e10cSrcweir } 279*cdf0e10cSrcweir } 280*cdf0e10cSrcweir 281*cdf0e10cSrcweir void updateEnableState() 282*cdf0e10cSrcweir { 283*cdf0e10cSrcweir for( std::vector< NSObject* >::iterator it = maViews.begin(); it != maViews.end(); ++it ) 284*cdf0e10cSrcweir { 285*cdf0e10cSrcweir NSObject* pObj = *it; 286*cdf0e10cSrcweir NSControl* pCtrl = nil; 287*cdf0e10cSrcweir NSCell* pCell = nil; 288*cdf0e10cSrcweir if( [pObj isKindOfClass: [NSControl class]] ) 289*cdf0e10cSrcweir pCtrl = (NSControl*)pObj; 290*cdf0e10cSrcweir else if( [pObj isKindOfClass: [NSCell class]] ) 291*cdf0e10cSrcweir pCell = (NSCell*)pObj; 292*cdf0e10cSrcweir 293*cdf0e10cSrcweir int nTag = pCtrl ? [pCtrl tag] : 294*cdf0e10cSrcweir pCell ? [pCell tag] : 295*cdf0e10cSrcweir -1; 296*cdf0e10cSrcweir 297*cdf0e10cSrcweir std::map< int, rtl::OUString >::const_iterator name_it = maTagToPropertyName.find( nTag ); 298*cdf0e10cSrcweir if( name_it != maTagToPropertyName.end() && ! name_it->second.equalsAscii( "PrintContent" ) ) 299*cdf0e10cSrcweir { 300*cdf0e10cSrcweir BOOL bEnabled = mpController->isUIOptionEnabled( name_it->second ) ? YES : NO; 301*cdf0e10cSrcweir if( pCtrl ) 302*cdf0e10cSrcweir { 303*cdf0e10cSrcweir [pCtrl setEnabled: bEnabled]; 304*cdf0e10cSrcweir NSView* pOther = getPair( pCtrl ); 305*cdf0e10cSrcweir if( pOther && [pOther isKindOfClass: [NSControl class]] ) 306*cdf0e10cSrcweir [(NSControl*)pOther setEnabled: bEnabled]; 307*cdf0e10cSrcweir } 308*cdf0e10cSrcweir else if( pCell ) 309*cdf0e10cSrcweir [pCell setEnabled: bEnabled]; 310*cdf0e10cSrcweir 311*cdf0e10cSrcweir } 312*cdf0e10cSrcweir } 313*cdf0e10cSrcweir } 314*cdf0e10cSrcweir 315*cdf0e10cSrcweir void updatePreviewImage( sal_Int32 i_nPage ) 316*cdf0e10cSrcweir { 317*cdf0e10cSrcweir sal_Int32 nPages = mpController->getFilteredPageCount(); 318*cdf0e10cSrcweir NSRect aViewFrame = [mpPreview frame]; 319*cdf0e10cSrcweir Size aPixelSize( static_cast<long>(aViewFrame.size.width), 320*cdf0e10cSrcweir static_cast<long>(aViewFrame.size.height) ); 321*cdf0e10cSrcweir if( i_nPage >= 0 && nPages > i_nPage ) 322*cdf0e10cSrcweir { 323*cdf0e10cSrcweir GDIMetaFile aMtf; 324*cdf0e10cSrcweir PrinterController::PageSize aPageSize( mpController->getFilteredPageFile( i_nPage, aMtf, false ) ); 325*cdf0e10cSrcweir VirtualDevice aDev; 326*cdf0e10cSrcweir if( mpController->getPrinter()->GetPrinterOptions().IsConvertToGreyscales() ) 327*cdf0e10cSrcweir aDev.SetDrawMode( aDev.GetDrawMode() | ( DRAWMODE_GRAYLINE | DRAWMODE_GRAYFILL | DRAWMODE_GRAYTEXT | 328*cdf0e10cSrcweir DRAWMODE_GRAYBITMAP | DRAWMODE_GRAYGRADIENT ) ); 329*cdf0e10cSrcweir // see salprn.cxx, currently we pretend to be a 720dpi device on printers 330*cdf0e10cSrcweir aDev.SetReferenceDevice( 720, 720 ); 331*cdf0e10cSrcweir aDev.EnableOutput( TRUE ); 332*cdf0e10cSrcweir Size aLogicSize( aDev.PixelToLogic( aPixelSize, MapMode( MAP_100TH_MM ) ) ); 333*cdf0e10cSrcweir double fScaleX = double(aLogicSize.Width())/double(aPageSize.aSize.Width()); 334*cdf0e10cSrcweir double fScaleY = double(aLogicSize.Height())/double(aPageSize.aSize.Height()); 335*cdf0e10cSrcweir double fScale = (fScaleX < fScaleY) ? fScaleX : fScaleY; 336*cdf0e10cSrcweir // #i104784# if we render the page too small then rounding issues result in 337*cdf0e10cSrcweir // layout artifacts looking really bad. So scale the page unto a device that is not 338*cdf0e10cSrcweir // full page size but not too small either. This also results in much better visual 339*cdf0e10cSrcweir // quality of the preview, e.g. when its height approaches the number of text lines 340*cdf0e10cSrcweir if( fScale < 0.1 ) 341*cdf0e10cSrcweir fScale = 0.1; 342*cdf0e10cSrcweir aMtf.WindStart(); 343*cdf0e10cSrcweir aMtf.Scale( fScale, fScale ); 344*cdf0e10cSrcweir aMtf.WindStart(); 345*cdf0e10cSrcweir aLogicSize.Width() = long(double(aPageSize.aSize.Width()) * fScale); 346*cdf0e10cSrcweir aLogicSize.Height() = long(double(aPageSize.aSize.Height()) * fScale); 347*cdf0e10cSrcweir aPixelSize = aDev.LogicToPixel( aLogicSize, MapMode( MAP_100TH_MM ) ); 348*cdf0e10cSrcweir aDev.SetOutputSizePixel( aPixelSize ); 349*cdf0e10cSrcweir aMtf.WindStart(); 350*cdf0e10cSrcweir aDev.SetMapMode( MapMode( MAP_100TH_MM ) ); 351*cdf0e10cSrcweir aMtf.Play( &aDev, Point( 0, 0 ), aLogicSize ); 352*cdf0e10cSrcweir aDev.EnableMapMode( FALSE ); 353*cdf0e10cSrcweir Image aImage( aDev.GetBitmap( Point( 0, 0 ), aPixelSize ) ); 354*cdf0e10cSrcweir NSImage* pImage = CreateNSImage( aImage ); 355*cdf0e10cSrcweir [mpPreview setImage: [pImage autorelease]]; 356*cdf0e10cSrcweir } 357*cdf0e10cSrcweir else 358*cdf0e10cSrcweir [mpPreview setImage: nil]; 359*cdf0e10cSrcweir } 360*cdf0e10cSrcweir 361*cdf0e10cSrcweir void setupPreview( ControlTarget* i_pCtrlTarget ) 362*cdf0e10cSrcweir { 363*cdf0e10cSrcweir if( maLocalizedStrings.Count() < 3 ) 364*cdf0e10cSrcweir return; 365*cdf0e10cSrcweir 366*cdf0e10cSrcweir // get the preview control 367*cdf0e10cSrcweir NSRect aPreviewFrame = [mpAccessoryView frame]; 368*cdf0e10cSrcweir aPreviewFrame.origin.x = 0; 369*cdf0e10cSrcweir aPreviewFrame.origin.y = 5; 370*cdf0e10cSrcweir aPreviewFrame.size.width = 190; 371*cdf0e10cSrcweir aPreviewFrame.size.height -= 7; 372*cdf0e10cSrcweir 373*cdf0e10cSrcweir // create a box to put the preview controls in 374*cdf0e10cSrcweir mpPreviewBox = [[NSBox alloc] initWithFrame: aPreviewFrame]; 375*cdf0e10cSrcweir [mpPreviewBox setTitle: [CreateNSString( maLocalizedStrings.GetString( 0 ) ) autorelease]]; 376*cdf0e10cSrcweir [mpAccessoryView addSubview: [mpPreviewBox autorelease]]; 377*cdf0e10cSrcweir 378*cdf0e10cSrcweir // now create the image view of the preview 379*cdf0e10cSrcweir NSSize aMargins = [mpPreviewBox contentViewMargins]; 380*cdf0e10cSrcweir aPreviewFrame.origin.x = 0; 381*cdf0e10cSrcweir aPreviewFrame.origin.y = 34; 382*cdf0e10cSrcweir aPreviewFrame.size.width -= 2*(aMargins.width+1); 383*cdf0e10cSrcweir aPreviewFrame.size.height -= 61; 384*cdf0e10cSrcweir mpPreview = [[NSImageView alloc] initWithFrame: aPreviewFrame]; 385*cdf0e10cSrcweir [mpPreview setImageScaling: NSScaleProportionally]; 386*cdf0e10cSrcweir [mpPreview setImageAlignment: NSImageAlignCenter]; 387*cdf0e10cSrcweir [mpPreview setImageFrameStyle: NSImageFrameNone]; 388*cdf0e10cSrcweir [mpPreviewBox addSubview: [mpPreview autorelease]]; 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir // add a label 391*cdf0e10cSrcweir sal_Int32 nPages = mpController->getFilteredPageCount(); 392*cdf0e10cSrcweir rtl::OUStringBuffer aBuf( 16 ); 393*cdf0e10cSrcweir aBuf.appendAscii( "/ " ); 394*cdf0e10cSrcweir aBuf.append( rtl::OUString::valueOf( nPages ) ); 395*cdf0e10cSrcweir 396*cdf0e10cSrcweir NSString* pText = CreateNSString( aBuf.makeStringAndClear() ); 397*cdf0e10cSrcweir NSRect aTextRect = { { 100, 5 }, { 100, 22 } }; 398*cdf0e10cSrcweir mpPagesLabel = [[NSTextView alloc] initWithFrame: aTextRect]; 399*cdf0e10cSrcweir [mpPagesLabel setFont: [NSFont controlContentFontOfSize: 0]]; 400*cdf0e10cSrcweir [mpPagesLabel setEditable: NO]; 401*cdf0e10cSrcweir [mpPagesLabel setSelectable: NO]; 402*cdf0e10cSrcweir [mpPagesLabel setDrawsBackground: NO]; 403*cdf0e10cSrcweir [mpPagesLabel setString: [pText autorelease]]; 404*cdf0e10cSrcweir [mpPagesLabel setToolTip: [CreateNSString( maLocalizedStrings.GetString( 2 ) ) autorelease]]; 405*cdf0e10cSrcweir [mpPreviewBox addSubview: [mpPagesLabel autorelease]]; 406*cdf0e10cSrcweir 407*cdf0e10cSrcweir NSRect aFieldRect = { { 45, 5 }, { 35, 25 } }; 408*cdf0e10cSrcweir mpPageEdit = [[NSTextField alloc] initWithFrame: aFieldRect]; 409*cdf0e10cSrcweir [mpPageEdit setEditable: YES]; 410*cdf0e10cSrcweir [mpPageEdit setSelectable: YES]; 411*cdf0e10cSrcweir [mpPageEdit setDrawsBackground: YES]; 412*cdf0e10cSrcweir [mpPageEdit setToolTip: [CreateNSString( maLocalizedStrings.GetString( 1 ) ) autorelease]]; 413*cdf0e10cSrcweir [mpPreviewBox addSubview: [mpPageEdit autorelease]]; 414*cdf0e10cSrcweir 415*cdf0e10cSrcweir // add a stepper control 416*cdf0e10cSrcweir NSRect aStepFrame = { { 85, 5 }, { 15, 25 } }; 417*cdf0e10cSrcweir mpStepper = [[NSStepper alloc] initWithFrame: aStepFrame]; 418*cdf0e10cSrcweir [mpStepper setIncrement: 1]; 419*cdf0e10cSrcweir [mpStepper setValueWraps: NO]; 420*cdf0e10cSrcweir [mpPreviewBox addSubview: [mpStepper autorelease]]; 421*cdf0e10cSrcweir 422*cdf0e10cSrcweir // constrain the text field to decimal numbers 423*cdf0e10cSrcweir NSNumberFormatter* pFormatter = [[NSNumberFormatter alloc] init]; 424*cdf0e10cSrcweir [pFormatter setFormatterBehavior: NSNumberFormatterBehavior10_4]; 425*cdf0e10cSrcweir [pFormatter setMinimum: [[NSNumber numberWithInt: 1] autorelease]]; 426*cdf0e10cSrcweir [pFormatter setMaximum: [[NSNumber numberWithInt: nPages] autorelease]]; 427*cdf0e10cSrcweir [pFormatter setNumberStyle: NSNumberFormatterDecimalStyle]; 428*cdf0e10cSrcweir [pFormatter setAllowsFloats: NO]; 429*cdf0e10cSrcweir [pFormatter setMaximumFractionDigits: 0]; 430*cdf0e10cSrcweir [mpPageEdit setFormatter: pFormatter]; 431*cdf0e10cSrcweir [mpStepper setMinValue: 1]; 432*cdf0e10cSrcweir [mpStepper setMaxValue: nPages]; 433*cdf0e10cSrcweir 434*cdf0e10cSrcweir [mpPageEdit setIntValue: 1]; 435*cdf0e10cSrcweir [mpStepper setIntValue: 1]; 436*cdf0e10cSrcweir 437*cdf0e10cSrcweir // connect target and action 438*cdf0e10cSrcweir [mpStepper setTarget: i_pCtrlTarget]; 439*cdf0e10cSrcweir [mpStepper setAction: @selector(triggeredPreview:)]; 440*cdf0e10cSrcweir [mpPageEdit setTarget: i_pCtrlTarget]; 441*cdf0e10cSrcweir [mpPageEdit setAction: @selector(triggeredPreview:)]; 442*cdf0e10cSrcweir 443*cdf0e10cSrcweir // set first preview image 444*cdf0e10cSrcweir updatePreviewImage( 0 ); 445*cdf0e10cSrcweir } 446*cdf0e10cSrcweir 447*cdf0e10cSrcweir void changePreview( NSObject* i_pSender ) 448*cdf0e10cSrcweir { 449*cdf0e10cSrcweir if( [i_pSender isMemberOfClass: [NSTextField class]] ) 450*cdf0e10cSrcweir { 451*cdf0e10cSrcweir NSTextField* pField = (NSTextField*)i_pSender; 452*cdf0e10cSrcweir if( pField == mpPageEdit ) // sanity check 453*cdf0e10cSrcweir { 454*cdf0e10cSrcweir sal_Int32 nPage = [pField intValue]; 455*cdf0e10cSrcweir [mpStepper setIntValue: nPage]; 456*cdf0e10cSrcweir updatePreviewImage( nPage-1 ); 457*cdf0e10cSrcweir } 458*cdf0e10cSrcweir } 459*cdf0e10cSrcweir else if( [i_pSender isMemberOfClass: [NSStepper class]] ) 460*cdf0e10cSrcweir { 461*cdf0e10cSrcweir NSStepper* pStepper = (NSStepper*)i_pSender; 462*cdf0e10cSrcweir if( pStepper == mpStepper ) // sanity check 463*cdf0e10cSrcweir { 464*cdf0e10cSrcweir sal_Int32 nPage = [pStepper intValue]; 465*cdf0e10cSrcweir [mpPageEdit setIntValue: nPage]; 466*cdf0e10cSrcweir updatePreviewImage( nPage-1 ); 467*cdf0e10cSrcweir } 468*cdf0e10cSrcweir } 469*cdf0e10cSrcweir } 470*cdf0e10cSrcweir}; 471*cdf0e10cSrcweir 472*cdf0e10cSrcweirstatic void filterAccelerator( rtl::OUString& io_rText ) 473*cdf0e10cSrcweir{ 474*cdf0e10cSrcweir rtl::OUStringBuffer aBuf( io_rText.getLength() ); 475*cdf0e10cSrcweir for( sal_Int32 nIndex = 0; nIndex != -1; ) 476*cdf0e10cSrcweir aBuf.append( io_rText.getToken( 0, '~', nIndex ) ); 477*cdf0e10cSrcweir io_rText = aBuf.makeStringAndClear(); 478*cdf0e10cSrcweir} 479*cdf0e10cSrcweir 480*cdf0e10cSrcweir@implementation ControlTarget 481*cdf0e10cSrcweir-(id)initWithControllerMap: (ControllerProperties*)pController 482*cdf0e10cSrcweir{ 483*cdf0e10cSrcweir if( (self = [super init]) ) 484*cdf0e10cSrcweir { 485*cdf0e10cSrcweir mpController = pController; 486*cdf0e10cSrcweir } 487*cdf0e10cSrcweir return self; 488*cdf0e10cSrcweir} 489*cdf0e10cSrcweir-(void)triggered:(id)pSender; 490*cdf0e10cSrcweir{ 491*cdf0e10cSrcweir if( [pSender isMemberOfClass: [NSPopUpButton class]] ) 492*cdf0e10cSrcweir { 493*cdf0e10cSrcweir NSPopUpButton* pBtn = (NSPopUpButton*)pSender; 494*cdf0e10cSrcweir NSMenuItem* pSelected = [pBtn selectedItem]; 495*cdf0e10cSrcweir if( pSelected ) 496*cdf0e10cSrcweir { 497*cdf0e10cSrcweir int nTag = [pSelected tag]; 498*cdf0e10cSrcweir mpController->changePropertyWithIntValue( nTag ); 499*cdf0e10cSrcweir } 500*cdf0e10cSrcweir } 501*cdf0e10cSrcweir else if( [pSender isMemberOfClass: [NSButton class]] ) 502*cdf0e10cSrcweir { 503*cdf0e10cSrcweir NSButton* pBtn = (NSButton*)pSender; 504*cdf0e10cSrcweir int nTag = [pBtn tag]; 505*cdf0e10cSrcweir mpController->changePropertyWithBoolValue( nTag, [pBtn state] == NSOnState ); 506*cdf0e10cSrcweir } 507*cdf0e10cSrcweir else if( [pSender isMemberOfClass: [NSMatrix class]] ) 508*cdf0e10cSrcweir { 509*cdf0e10cSrcweir NSObject* pObj = [(NSMatrix*)pSender selectedCell]; 510*cdf0e10cSrcweir if( [pObj isMemberOfClass: [NSButtonCell class]] ) 511*cdf0e10cSrcweir { 512*cdf0e10cSrcweir NSButtonCell* pCell = (NSButtonCell*)pObj; 513*cdf0e10cSrcweir int nTag = [pCell tag]; 514*cdf0e10cSrcweir mpController->changePropertyWithIntValue( nTag ); 515*cdf0e10cSrcweir } 516*cdf0e10cSrcweir } 517*cdf0e10cSrcweir else if( [pSender isMemberOfClass: [NSTextField class]] ) 518*cdf0e10cSrcweir { 519*cdf0e10cSrcweir NSTextField* pField = (NSTextField*)pSender; 520*cdf0e10cSrcweir int nTag = [pField tag]; 521*cdf0e10cSrcweir rtl::OUString aValue = GetOUString( [pSender stringValue] ); 522*cdf0e10cSrcweir mpController->changePropertyWithStringValue( nTag, aValue ); 523*cdf0e10cSrcweir } 524*cdf0e10cSrcweir else 525*cdf0e10cSrcweir { 526*cdf0e10cSrcweir DBG_ERROR( "unsupported class" ); 527*cdf0e10cSrcweir } 528*cdf0e10cSrcweir mpController->updateEnableState(); 529*cdf0e10cSrcweir} 530*cdf0e10cSrcweir-(void)triggeredNumeric:(id)pSender; 531*cdf0e10cSrcweir{ 532*cdf0e10cSrcweir if( [pSender isMemberOfClass: [NSTextField class]] ) 533*cdf0e10cSrcweir { 534*cdf0e10cSrcweir NSTextField* pField = (NSTextField*)pSender; 535*cdf0e10cSrcweir int nTag = [pField tag]; 536*cdf0e10cSrcweir sal_Int64 nValue = [pField intValue]; 537*cdf0e10cSrcweir 538*cdf0e10cSrcweir NSView* pOther = mpController->getPair( pField ); 539*cdf0e10cSrcweir if( pOther ) 540*cdf0e10cSrcweir [(NSControl*)pOther setIntValue: nValue]; 541*cdf0e10cSrcweir 542*cdf0e10cSrcweir mpController->changePropertyWithIntValue( nTag, nValue ); 543*cdf0e10cSrcweir } 544*cdf0e10cSrcweir else if( [pSender isMemberOfClass: [NSStepper class]] ) 545*cdf0e10cSrcweir { 546*cdf0e10cSrcweir NSStepper* pStep = (NSStepper*)pSender; 547*cdf0e10cSrcweir int nTag = [pStep tag]; 548*cdf0e10cSrcweir sal_Int64 nValue = [pStep intValue]; 549*cdf0e10cSrcweir 550*cdf0e10cSrcweir NSView* pOther = mpController->getPair( pStep ); 551*cdf0e10cSrcweir if( pOther ) 552*cdf0e10cSrcweir [(NSControl*)pOther setIntValue: nValue]; 553*cdf0e10cSrcweir 554*cdf0e10cSrcweir mpController->changePropertyWithIntValue( nTag, nValue ); 555*cdf0e10cSrcweir } 556*cdf0e10cSrcweir else 557*cdf0e10cSrcweir { 558*cdf0e10cSrcweir DBG_ERROR( "unsupported class" ); 559*cdf0e10cSrcweir } 560*cdf0e10cSrcweir mpController->updateEnableState(); 561*cdf0e10cSrcweir} 562*cdf0e10cSrcweir-(void)triggeredPreview:(id)pSender 563*cdf0e10cSrcweir{ 564*cdf0e10cSrcweir mpController->changePreview( pSender ); 565*cdf0e10cSrcweir} 566*cdf0e10cSrcweir-(void)dealloc 567*cdf0e10cSrcweir{ 568*cdf0e10cSrcweir delete mpController; 569*cdf0e10cSrcweir [super dealloc]; 570*cdf0e10cSrcweir} 571*cdf0e10cSrcweir@end 572*cdf0e10cSrcweir 573*cdf0e10cSrcweirstruct ColumnItem 574*cdf0e10cSrcweir{ 575*cdf0e10cSrcweir NSControl* pControl; 576*cdf0e10cSrcweir long nOffset; 577*cdf0e10cSrcweir NSControl* pSubControl; 578*cdf0e10cSrcweir 579*cdf0e10cSrcweir ColumnItem( NSControl* i_pControl = nil, long i_nOffset = 0, NSControl* i_pSub = nil ) 580*cdf0e10cSrcweir : pControl( i_pControl ) 581*cdf0e10cSrcweir , nOffset( i_nOffset ) 582*cdf0e10cSrcweir , pSubControl( i_pSub ) 583*cdf0e10cSrcweir {} 584*cdf0e10cSrcweir 585*cdf0e10cSrcweir long getWidth() const 586*cdf0e10cSrcweir { 587*cdf0e10cSrcweir long nWidth = 0; 588*cdf0e10cSrcweir if( pControl ) 589*cdf0e10cSrcweir { 590*cdf0e10cSrcweir NSRect aCtrlRect = [pControl frame]; 591*cdf0e10cSrcweir nWidth = aCtrlRect.size.width; 592*cdf0e10cSrcweir nWidth += nOffset; 593*cdf0e10cSrcweir if( pSubControl ) 594*cdf0e10cSrcweir { 595*cdf0e10cSrcweir NSRect aSubRect = [pSubControl frame]; 596*cdf0e10cSrcweir nWidth += aSubRect.size.width; 597*cdf0e10cSrcweir nWidth += aSubRect.origin.x - (aCtrlRect.origin.x + aCtrlRect.size.width); 598*cdf0e10cSrcweir } 599*cdf0e10cSrcweir } 600*cdf0e10cSrcweir return nWidth; 601*cdf0e10cSrcweir } 602*cdf0e10cSrcweir}; 603*cdf0e10cSrcweir 604*cdf0e10cSrcweirstatic void adjustViewAndChildren( NSView* pView, NSSize& rMaxSize, 605*cdf0e10cSrcweir std::vector< ColumnItem >& rLeftColumn, 606*cdf0e10cSrcweir std::vector< ColumnItem >& rRightColumn 607*cdf0e10cSrcweir ) 608*cdf0e10cSrcweir{ 609*cdf0e10cSrcweir // balance columns 610*cdf0e10cSrcweir 611*cdf0e10cSrcweir // first get overall column widths 612*cdf0e10cSrcweir long nLeftWidth = 0; 613*cdf0e10cSrcweir long nRightWidth = 0; 614*cdf0e10cSrcweir for( size_t i = 0; i < rLeftColumn.size(); i++ ) 615*cdf0e10cSrcweir { 616*cdf0e10cSrcweir long nW = rLeftColumn[i].getWidth(); 617*cdf0e10cSrcweir if( nW > nLeftWidth ) 618*cdf0e10cSrcweir nLeftWidth = nW; 619*cdf0e10cSrcweir } 620*cdf0e10cSrcweir for( size_t i = 0; i < rRightColumn.size(); i++ ) 621*cdf0e10cSrcweir { 622*cdf0e10cSrcweir long nW = rRightColumn[i].getWidth(); 623*cdf0e10cSrcweir if( nW > nRightWidth ) 624*cdf0e10cSrcweir nRightWidth = nW; 625*cdf0e10cSrcweir } 626*cdf0e10cSrcweir 627*cdf0e10cSrcweir // right align left column 628*cdf0e10cSrcweir for( size_t i = 0; i < rLeftColumn.size(); i++ ) 629*cdf0e10cSrcweir { 630*cdf0e10cSrcweir if( rLeftColumn[i].pControl ) 631*cdf0e10cSrcweir { 632*cdf0e10cSrcweir NSRect aCtrlRect = [rLeftColumn[i].pControl frame]; 633*cdf0e10cSrcweir long nX = nLeftWidth - aCtrlRect.size.width; 634*cdf0e10cSrcweir if( rLeftColumn[i].pSubControl ) 635*cdf0e10cSrcweir { 636*cdf0e10cSrcweir NSRect aSubRect = [rLeftColumn[i].pSubControl frame]; 637*cdf0e10cSrcweir nX -= aSubRect.size.width + (aSubRect.origin.x - (aCtrlRect.origin.x + aCtrlRect.size.width)); 638*cdf0e10cSrcweir aSubRect.origin.x = nLeftWidth - aSubRect.size.width; 639*cdf0e10cSrcweir [rLeftColumn[i].pSubControl setFrame: aSubRect]; 640*cdf0e10cSrcweir } 641*cdf0e10cSrcweir aCtrlRect.origin.x = nX; 642*cdf0e10cSrcweir [rLeftColumn[i].pControl setFrame: aCtrlRect]; 643*cdf0e10cSrcweir } 644*cdf0e10cSrcweir } 645*cdf0e10cSrcweir 646*cdf0e10cSrcweir // left align right column 647*cdf0e10cSrcweir for( size_t i = 0; i < rRightColumn.size(); i++ ) 648*cdf0e10cSrcweir { 649*cdf0e10cSrcweir if( rRightColumn[i].pControl ) 650*cdf0e10cSrcweir { 651*cdf0e10cSrcweir NSRect aCtrlRect = [rRightColumn[i].pControl frame]; 652*cdf0e10cSrcweir long nX = nLeftWidth + 3; 653*cdf0e10cSrcweir if( rRightColumn[i].pSubControl ) 654*cdf0e10cSrcweir { 655*cdf0e10cSrcweir NSRect aSubRect = [rRightColumn[i].pSubControl frame]; 656*cdf0e10cSrcweir aSubRect.origin.x = nX + aSubRect.origin.x - aCtrlRect.origin.x; 657*cdf0e10cSrcweir [rRightColumn[i].pSubControl setFrame: aSubRect]; 658*cdf0e10cSrcweir } 659*cdf0e10cSrcweir aCtrlRect.origin.x = nX; 660*cdf0e10cSrcweir [rRightColumn[i].pControl setFrame: aCtrlRect]; 661*cdf0e10cSrcweir } 662*cdf0e10cSrcweir } 663*cdf0e10cSrcweir 664*cdf0e10cSrcweir NSArray* pSubViews = [pView subviews]; 665*cdf0e10cSrcweir unsigned int nViews = [pSubViews count]; 666*cdf0e10cSrcweir NSRect aUnion = { { 0, 0 }, { 0, 0 } }; 667*cdf0e10cSrcweir 668*cdf0e10cSrcweir // get the combined frame of all subviews 669*cdf0e10cSrcweir for( unsigned int n = 0; n < nViews; n++ ) 670*cdf0e10cSrcweir { 671*cdf0e10cSrcweir aUnion = NSUnionRect( aUnion, [[pSubViews objectAtIndex: n] frame] ); 672*cdf0e10cSrcweir } 673*cdf0e10cSrcweir 674*cdf0e10cSrcweir // move everything so it will fit 675*cdf0e10cSrcweir for( unsigned int n = 0; n < nViews; n++ ) 676*cdf0e10cSrcweir { 677*cdf0e10cSrcweir NSView* pCurSubView = [pSubViews objectAtIndex: n]; 678*cdf0e10cSrcweir NSRect aFrame = [pCurSubView frame]; 679*cdf0e10cSrcweir aFrame.origin.x -= aUnion.origin.x - 5; 680*cdf0e10cSrcweir aFrame.origin.y -= aUnion.origin.y - 5; 681*cdf0e10cSrcweir [pCurSubView setFrame: aFrame]; 682*cdf0e10cSrcweir } 683*cdf0e10cSrcweir 684*cdf0e10cSrcweir // resize the view itself 685*cdf0e10cSrcweir aUnion.size.height += 10; 686*cdf0e10cSrcweir aUnion.size.width += 20; 687*cdf0e10cSrcweir [pView setFrameSize: aUnion.size]; 688*cdf0e10cSrcweir 689*cdf0e10cSrcweir if( aUnion.size.width > rMaxSize.width ) 690*cdf0e10cSrcweir rMaxSize.width = aUnion.size.width; 691*cdf0e10cSrcweir if( aUnion.size.height > rMaxSize.height ) 692*cdf0e10cSrcweir rMaxSize.height = aUnion.size.height; 693*cdf0e10cSrcweir} 694*cdf0e10cSrcweir 695*cdf0e10cSrcweirstatic void adjustTabViews( NSTabView* pTabView, NSSize aTabSize ) 696*cdf0e10cSrcweir{ 697*cdf0e10cSrcweir // loop over all contained tab pages 698*cdf0e10cSrcweir NSArray* pTabbedViews = [pTabView tabViewItems]; 699*cdf0e10cSrcweir int nViews = [pTabbedViews count]; 700*cdf0e10cSrcweir for( int i = 0; i < nViews; i++ ) 701*cdf0e10cSrcweir { 702*cdf0e10cSrcweir NSTabViewItem* pItem = (NSTabViewItem*)[pTabbedViews objectAtIndex: i]; 703*cdf0e10cSrcweir NSView* pView = [pItem view]; 704*cdf0e10cSrcweir if( pView ) 705*cdf0e10cSrcweir { 706*cdf0e10cSrcweir NSRect aRect = [pView frame]; 707*cdf0e10cSrcweir double nDiff = aTabSize.height - aRect.size.height; 708*cdf0e10cSrcweir aRect.size = aTabSize; 709*cdf0e10cSrcweir [pView setFrame: aRect]; 710*cdf0e10cSrcweir 711*cdf0e10cSrcweir NSArray* pSubViews = [pView subviews]; 712*cdf0e10cSrcweir unsigned int nSubViews = [pSubViews count]; 713*cdf0e10cSrcweir 714*cdf0e10cSrcweir // move everything up 715*cdf0e10cSrcweir for( unsigned int n = 0; n < nSubViews; n++ ) 716*cdf0e10cSrcweir { 717*cdf0e10cSrcweir NSView* pCurSubView = [pSubViews objectAtIndex: n]; 718*cdf0e10cSrcweir NSRect aFrame = [pCurSubView frame]; 719*cdf0e10cSrcweir aFrame.origin.y += nDiff; 720*cdf0e10cSrcweir // give separators the correct width 721*cdf0e10cSrcweir // separators are currently the only NSBoxes we use 722*cdf0e10cSrcweir if( [pCurSubView isMemberOfClass: [NSBox class]] ) 723*cdf0e10cSrcweir { 724*cdf0e10cSrcweir aFrame.size.width = aTabSize.width - aFrame.origin.x - 10; 725*cdf0e10cSrcweir } 726*cdf0e10cSrcweir [pCurSubView setFrame: aFrame]; 727*cdf0e10cSrcweir } 728*cdf0e10cSrcweir } 729*cdf0e10cSrcweir } 730*cdf0e10cSrcweir} 731*cdf0e10cSrcweir 732*cdf0e10cSrcweirstatic NSControl* createLabel( const rtl::OUString& i_rText ) 733*cdf0e10cSrcweir{ 734*cdf0e10cSrcweir NSString* pText = CreateNSString( i_rText ); 735*cdf0e10cSrcweir NSRect aTextRect = { { 0, 0 }, {20, 15} }; 736*cdf0e10cSrcweir NSTextField* pTextView = [[NSTextField alloc] initWithFrame: aTextRect]; 737*cdf0e10cSrcweir [pTextView setFont: [NSFont controlContentFontOfSize: 0]]; 738*cdf0e10cSrcweir [pTextView setEditable: NO]; 739*cdf0e10cSrcweir [pTextView setSelectable: NO]; 740*cdf0e10cSrcweir [pTextView setDrawsBackground: NO]; 741*cdf0e10cSrcweir [pTextView setBordered: NO]; 742*cdf0e10cSrcweir [pTextView setStringValue: pText]; 743*cdf0e10cSrcweir [pTextView sizeToFit]; 744*cdf0e10cSrcweir [pText release]; 745*cdf0e10cSrcweir return pTextView; 746*cdf0e10cSrcweir} 747*cdf0e10cSrcweir 748*cdf0e10cSrcweirstatic sal_Int32 findBreak( const rtl::OUString& i_rText, sal_Int32 i_nPos ) 749*cdf0e10cSrcweir{ 750*cdf0e10cSrcweir sal_Int32 nRet = i_rText.getLength(); 751*cdf0e10cSrcweir Reference< i18n::XBreakIterator > xBI( vcl::unohelper::CreateBreakIterator() ); 752*cdf0e10cSrcweir if( xBI.is() ) 753*cdf0e10cSrcweir { 754*cdf0e10cSrcweir i18n::Boundary aBoundary = xBI->getWordBoundary( i_rText, i_nPos, 755*cdf0e10cSrcweir Application::GetSettings().GetLocale(), 756*cdf0e10cSrcweir i18n::WordType::ANYWORD_IGNOREWHITESPACES, 757*cdf0e10cSrcweir sal_True ); 758*cdf0e10cSrcweir nRet = aBoundary.endPos; 759*cdf0e10cSrcweir } 760*cdf0e10cSrcweir return nRet; 761*cdf0e10cSrcweir} 762*cdf0e10cSrcweir 763*cdf0e10cSrcweirstatic void linebreakCell( NSCell* pBtn, const rtl::OUString& i_rText ) 764*cdf0e10cSrcweir{ 765*cdf0e10cSrcweir NSString* pText = CreateNSString( i_rText ); 766*cdf0e10cSrcweir [pBtn setTitle: pText]; 767*cdf0e10cSrcweir [pText release]; 768*cdf0e10cSrcweir NSSize aSize = [pBtn cellSize]; 769*cdf0e10cSrcweir if( aSize.width > 280 ) 770*cdf0e10cSrcweir { 771*cdf0e10cSrcweir // need two lines 772*cdf0e10cSrcweir sal_Int32 nLen = i_rText.getLength(); 773*cdf0e10cSrcweir sal_Int32 nIndex = nLen / 2; 774*cdf0e10cSrcweir nIndex = findBreak( i_rText, nIndex ); 775*cdf0e10cSrcweir if( nIndex < nLen ) 776*cdf0e10cSrcweir { 777*cdf0e10cSrcweir rtl::OUStringBuffer aBuf( i_rText ); 778*cdf0e10cSrcweir aBuf.setCharAt( nIndex, '\n' ); 779*cdf0e10cSrcweir pText = CreateNSString( aBuf.makeStringAndClear() ); 780*cdf0e10cSrcweir [pBtn setTitle: pText]; 781*cdf0e10cSrcweir [pText release]; 782*cdf0e10cSrcweir } 783*cdf0e10cSrcweir } 784*cdf0e10cSrcweir} 785*cdf0e10cSrcweir 786*cdf0e10cSrcweirstatic void addSubgroup( NSView* pCurParent, long& rCurY, const rtl::OUString& rText ) 787*cdf0e10cSrcweir{ 788*cdf0e10cSrcweir NSControl* pTextView = createLabel( rText ); 789*cdf0e10cSrcweir [pCurParent addSubview: [pTextView autorelease]]; 790*cdf0e10cSrcweir NSRect aTextRect = [pTextView frame]; 791*cdf0e10cSrcweir // move to nCurY 792*cdf0e10cSrcweir aTextRect.origin.y = rCurY - aTextRect.size.height; 793*cdf0e10cSrcweir [pTextView setFrame: aTextRect]; 794*cdf0e10cSrcweir 795*cdf0e10cSrcweir NSRect aSepRect = { { aTextRect.size.width + 1, aTextRect.origin.y }, { 100, 6 } }; 796*cdf0e10cSrcweir NSBox* pBox = [[NSBox alloc] initWithFrame: aSepRect]; 797*cdf0e10cSrcweir [pBox setBoxType: NSBoxSeparator]; 798*cdf0e10cSrcweir [pCurParent addSubview: [pBox autorelease]]; 799*cdf0e10cSrcweir 800*cdf0e10cSrcweir // update nCurY 801*cdf0e10cSrcweir rCurY = aTextRect.origin.y - 5; 802*cdf0e10cSrcweir} 803*cdf0e10cSrcweir 804*cdf0e10cSrcweirstatic void addBool( NSView* pCurParent, long& rCurX, long& rCurY, long nAttachOffset, 805*cdf0e10cSrcweir const rtl::OUString& rText, sal_Bool bEnabled, 806*cdf0e10cSrcweir const rtl::OUString& rProperty, sal_Bool bValue, 807*cdf0e10cSrcweir std::vector<ColumnItem >& rRightColumn, 808*cdf0e10cSrcweir ControllerProperties* pControllerProperties, 809*cdf0e10cSrcweir ControlTarget* pCtrlTarget 810*cdf0e10cSrcweir ) 811*cdf0e10cSrcweir{ 812*cdf0e10cSrcweir NSRect aCheckRect = { { rCurX + nAttachOffset, 0 }, { 0, 15 } }; 813*cdf0e10cSrcweir NSButton* pBtn = [[NSButton alloc] initWithFrame: aCheckRect]; 814*cdf0e10cSrcweir [pBtn setButtonType: NSSwitchButton]; 815*cdf0e10cSrcweir [pBtn setState: bValue ? NSOnState : NSOffState]; 816*cdf0e10cSrcweir if( ! bEnabled ) 817*cdf0e10cSrcweir [pBtn setEnabled: NO]; 818*cdf0e10cSrcweir linebreakCell( [pBtn cell], rText ); 819*cdf0e10cSrcweir [pBtn sizeToFit]; 820*cdf0e10cSrcweir 821*cdf0e10cSrcweir rRightColumn.push_back( ColumnItem( pBtn ) ); 822*cdf0e10cSrcweir 823*cdf0e10cSrcweir // connect target 824*cdf0e10cSrcweir [pBtn setTarget: pCtrlTarget]; 825*cdf0e10cSrcweir [pBtn setAction: @selector(triggered:)]; 826*cdf0e10cSrcweir int nTag = pControllerProperties->addNameTag( rProperty ); 827*cdf0e10cSrcweir pControllerProperties->addObservedControl( pBtn ); 828*cdf0e10cSrcweir [pBtn setTag: nTag]; 829*cdf0e10cSrcweir 830*cdf0e10cSrcweir aCheckRect = [pBtn frame]; 831*cdf0e10cSrcweir // #i115837# add a murphy factor; it can apparently occasionally happen 832*cdf0e10cSrcweir // that sizeToFit does not a perfect job and that the button linebreaks again 833*cdf0e10cSrcweir // if - and only if - there is already a '\n' contained in the text and the width 834*cdf0e10cSrcweir // is minimally of 835*cdf0e10cSrcweir aCheckRect.size.width += 1; 836*cdf0e10cSrcweir 837*cdf0e10cSrcweir // move to rCurY 838*cdf0e10cSrcweir aCheckRect.origin.y = rCurY - aCheckRect.size.height; 839*cdf0e10cSrcweir [pBtn setFrame: aCheckRect]; 840*cdf0e10cSrcweir 841*cdf0e10cSrcweir [pCurParent addSubview: [pBtn autorelease]]; 842*cdf0e10cSrcweir 843*cdf0e10cSrcweir // update rCurY 844*cdf0e10cSrcweir rCurY = aCheckRect.origin.y - 5; 845*cdf0e10cSrcweir} 846*cdf0e10cSrcweir 847*cdf0e10cSrcweirstatic void addRadio( NSView* pCurParent, long& rCurX, long& rCurY, long nAttachOffset, 848*cdf0e10cSrcweir const rtl::OUString& rText, 849*cdf0e10cSrcweir const rtl::OUString& rProperty, Sequence< rtl::OUString > rChoices, sal_Int32 nSelectValue, 850*cdf0e10cSrcweir std::vector<ColumnItem >& rLeftColumn, 851*cdf0e10cSrcweir std::vector<ColumnItem >& rRightColumn, 852*cdf0e10cSrcweir ControllerProperties* pControllerProperties, 853*cdf0e10cSrcweir ControlTarget* pCtrlTarget 854*cdf0e10cSrcweir ) 855*cdf0e10cSrcweir{ 856*cdf0e10cSrcweir sal_Int32 nOff = 0; 857*cdf0e10cSrcweir if( rText.getLength() ) 858*cdf0e10cSrcweir { 859*cdf0e10cSrcweir // add a label 860*cdf0e10cSrcweir NSControl* pTextView = createLabel( rText ); 861*cdf0e10cSrcweir NSRect aTextRect = [pTextView frame]; 862*cdf0e10cSrcweir aTextRect.origin.x = rCurX + nAttachOffset; 863*cdf0e10cSrcweir [pCurParent addSubview: [pTextView autorelease]]; 864*cdf0e10cSrcweir 865*cdf0e10cSrcweir rLeftColumn.push_back( ColumnItem( pTextView ) ); 866*cdf0e10cSrcweir 867*cdf0e10cSrcweir // move to nCurY 868*cdf0e10cSrcweir aTextRect.origin.y = rCurY - aTextRect.size.height; 869*cdf0e10cSrcweir [pTextView setFrame: aTextRect]; 870*cdf0e10cSrcweir 871*cdf0e10cSrcweir // update nCurY 872*cdf0e10cSrcweir rCurY = aTextRect.origin.y - 5; 873*cdf0e10cSrcweir 874*cdf0e10cSrcweir // indent the radio group relative to the text 875*cdf0e10cSrcweir // nOff = 20; 876*cdf0e10cSrcweir } 877*cdf0e10cSrcweir 878*cdf0e10cSrcweir // setup radio matrix 879*cdf0e10cSrcweir NSButtonCell* pProto = [[NSButtonCell alloc] init]; 880*cdf0e10cSrcweir 881*cdf0e10cSrcweir NSRect aRadioRect = { { rCurX + nOff, 0 }, { 280 - rCurX, 5*rChoices.getLength() } }; 882*cdf0e10cSrcweir [pProto setTitle: @"RadioButtonGroup"]; 883*cdf0e10cSrcweir [pProto setButtonType: NSRadioButton]; 884*cdf0e10cSrcweir NSMatrix* pMatrix = [[NSMatrix alloc] initWithFrame: aRadioRect 885*cdf0e10cSrcweir mode: NSRadioModeMatrix 886*cdf0e10cSrcweir prototype: (NSCell*)pProto 887*cdf0e10cSrcweir numberOfRows: rChoices.getLength() 888*cdf0e10cSrcweir numberOfColumns: 1]; 889*cdf0e10cSrcweir // set individual titles 890*cdf0e10cSrcweir NSArray* pCells = [pMatrix cells]; 891*cdf0e10cSrcweir for( sal_Int32 m = 0; m < rChoices.getLength(); m++ ) 892*cdf0e10cSrcweir { 893*cdf0e10cSrcweir NSCell* pCell = [pCells objectAtIndex: m]; 894*cdf0e10cSrcweir filterAccelerator( rChoices[m] ); 895*cdf0e10cSrcweir linebreakCell( pCell, rChoices[m] ); 896*cdf0e10cSrcweir // connect target and action 897*cdf0e10cSrcweir [pCell setTarget: pCtrlTarget]; 898*cdf0e10cSrcweir [pCell setAction: @selector(triggered:)]; 899*cdf0e10cSrcweir int nTag = pControllerProperties->addNameAndValueTag( rProperty, m ); 900*cdf0e10cSrcweir pControllerProperties->addObservedControl( pCell ); 901*cdf0e10cSrcweir [pCell setTag: nTag]; 902*cdf0e10cSrcweir // set current selection 903*cdf0e10cSrcweir if( nSelectValue == m ) 904*cdf0e10cSrcweir [pMatrix selectCellAtRow: m column: 0]; 905*cdf0e10cSrcweir } 906*cdf0e10cSrcweir [pMatrix sizeToFit]; 907*cdf0e10cSrcweir aRadioRect = [pMatrix frame]; 908*cdf0e10cSrcweir 909*cdf0e10cSrcweir // move it down, so it comes to the correct position 910*cdf0e10cSrcweir aRadioRect.origin.y = rCurY - aRadioRect.size.height; 911*cdf0e10cSrcweir [pMatrix setFrame: aRadioRect]; 912*cdf0e10cSrcweir [pCurParent addSubview: [pMatrix autorelease]]; 913*cdf0e10cSrcweir 914*cdf0e10cSrcweir rRightColumn.push_back( ColumnItem( pMatrix ) ); 915*cdf0e10cSrcweir 916*cdf0e10cSrcweir // update nCurY 917*cdf0e10cSrcweir rCurY = aRadioRect.origin.y - 5; 918*cdf0e10cSrcweir 919*cdf0e10cSrcweir [pProto release]; 920*cdf0e10cSrcweir} 921*cdf0e10cSrcweir 922*cdf0e10cSrcweirstatic void addList( NSView* pCurParent, long& rCurX, long& rCurY, long /*nAttachOffset*/, 923*cdf0e10cSrcweir const rtl::OUString& rText, 924*cdf0e10cSrcweir const rtl::OUString& rProperty, const Sequence< rtl::OUString > rChoices, sal_Int32 nSelectValue, 925*cdf0e10cSrcweir std::vector<ColumnItem >& rLeftColumn, 926*cdf0e10cSrcweir std::vector<ColumnItem >& rRightColumn, 927*cdf0e10cSrcweir ControllerProperties* pControllerProperties, 928*cdf0e10cSrcweir ControlTarget* pCtrlTarget 929*cdf0e10cSrcweir ) 930*cdf0e10cSrcweir{ 931*cdf0e10cSrcweir // don't indent attached lists, looks bad in the existing cases 932*cdf0e10cSrcweir NSControl* pTextView = createLabel( rText ); 933*cdf0e10cSrcweir [pCurParent addSubview: [pTextView autorelease]]; 934*cdf0e10cSrcweir rLeftColumn.push_back( ColumnItem( pTextView ) ); 935*cdf0e10cSrcweir NSRect aTextRect = [pTextView frame]; 936*cdf0e10cSrcweir aTextRect.origin.x = rCurX /* + nAttachOffset*/; 937*cdf0e10cSrcweir 938*cdf0e10cSrcweir // don't indent attached lists, looks bad in the existing cases 939*cdf0e10cSrcweir NSRect aBtnRect = { { rCurX /*+ nAttachOffset*/ + aTextRect.size.width, 0 }, { 0, 15 } }; 940*cdf0e10cSrcweir NSPopUpButton* pBtn = [[NSPopUpButton alloc] initWithFrame: aBtnRect pullsDown: NO]; 941*cdf0e10cSrcweir 942*cdf0e10cSrcweir // iterate options 943*cdf0e10cSrcweir for( sal_Int32 m = 0; m < rChoices.getLength(); m++ ) 944*cdf0e10cSrcweir { 945*cdf0e10cSrcweir NSString* pItemText = CreateNSString( rChoices[m] ); 946*cdf0e10cSrcweir [pBtn addItemWithTitle: pItemText]; 947*cdf0e10cSrcweir NSMenuItem* pItem = [pBtn itemWithTitle: pItemText]; 948*cdf0e10cSrcweir int nTag = pControllerProperties->addNameAndValueTag( rProperty, m ); 949*cdf0e10cSrcweir [pItem setTag: nTag]; 950*cdf0e10cSrcweir [pItemText release]; 951*cdf0e10cSrcweir } 952*cdf0e10cSrcweir 953*cdf0e10cSrcweir [pBtn selectItemAtIndex: nSelectValue]; 954*cdf0e10cSrcweir 955*cdf0e10cSrcweir // add the button to observed controls for enabled state changes 956*cdf0e10cSrcweir // also add a tag just for this purpose 957*cdf0e10cSrcweir pControllerProperties->addObservedControl( pBtn ); 958*cdf0e10cSrcweir [pBtn setTag: pControllerProperties->addNameTag( rProperty )]; 959*cdf0e10cSrcweir 960*cdf0e10cSrcweir [pBtn sizeToFit]; 961*cdf0e10cSrcweir [pCurParent addSubview: [pBtn autorelease]]; 962*cdf0e10cSrcweir 963*cdf0e10cSrcweir rRightColumn.push_back( ColumnItem( pBtn ) ); 964*cdf0e10cSrcweir 965*cdf0e10cSrcweir // connect target and action 966*cdf0e10cSrcweir [pBtn setTarget: pCtrlTarget]; 967*cdf0e10cSrcweir [pBtn setAction: @selector(triggered:)]; 968*cdf0e10cSrcweir 969*cdf0e10cSrcweir // move to nCurY 970*cdf0e10cSrcweir aBtnRect = [pBtn frame]; 971*cdf0e10cSrcweir aBtnRect.origin.y = rCurY - aBtnRect.size.height; 972*cdf0e10cSrcweir [pBtn setFrame: aBtnRect]; 973*cdf0e10cSrcweir 974*cdf0e10cSrcweir // align label 975*cdf0e10cSrcweir aTextRect.origin.y = aBtnRect.origin.y + (aBtnRect.size.height - aTextRect.size.height)/2; 976*cdf0e10cSrcweir [pTextView setFrame: aTextRect]; 977*cdf0e10cSrcweir 978*cdf0e10cSrcweir // update rCurY 979*cdf0e10cSrcweir rCurY = aBtnRect.origin.y - 5; 980*cdf0e10cSrcweir} 981*cdf0e10cSrcweir 982*cdf0e10cSrcweirstatic void addEdit( NSView* pCurParent, long& rCurX, long& rCurY, long nAttachOffset, 983*cdf0e10cSrcweir const rtl::OUString rCtrlType, 984*cdf0e10cSrcweir const rtl::OUString& rText, 985*cdf0e10cSrcweir const rtl::OUString& rProperty, const PropertyValue* pValue, 986*cdf0e10cSrcweir sal_Int64 nMinValue, sal_Int64 nMaxValue, 987*cdf0e10cSrcweir std::vector<ColumnItem >& rLeftColumn, 988*cdf0e10cSrcweir std::vector<ColumnItem >& rRightColumn, 989*cdf0e10cSrcweir ControllerProperties* pControllerProperties, 990*cdf0e10cSrcweir ControlTarget* pCtrlTarget 991*cdf0e10cSrcweir ) 992*cdf0e10cSrcweir{ 993*cdf0e10cSrcweir sal_Int32 nOff = 0; 994*cdf0e10cSrcweir if( rText.getLength() ) 995*cdf0e10cSrcweir { 996*cdf0e10cSrcweir // add a label 997*cdf0e10cSrcweir NSControl* pTextView = createLabel( rText ); 998*cdf0e10cSrcweir [pCurParent addSubview: [pTextView autorelease]]; 999*cdf0e10cSrcweir 1000*cdf0e10cSrcweir rLeftColumn.push_back( ColumnItem( pTextView ) ); 1001*cdf0e10cSrcweir 1002*cdf0e10cSrcweir // move to nCurY 1003*cdf0e10cSrcweir NSRect aTextRect = [pTextView frame]; 1004*cdf0e10cSrcweir aTextRect.origin.x = rCurX + nAttachOffset; 1005*cdf0e10cSrcweir aTextRect.origin.y = rCurY - aTextRect.size.height; 1006*cdf0e10cSrcweir [pTextView setFrame: aTextRect]; 1007*cdf0e10cSrcweir 1008*cdf0e10cSrcweir // update nCurY 1009*cdf0e10cSrcweir rCurY = aTextRect.origin.y - 5; 1010*cdf0e10cSrcweir 1011*cdf0e10cSrcweir // and set the offset for the real edit field 1012*cdf0e10cSrcweir nOff = aTextRect.size.width + 5; 1013*cdf0e10cSrcweir } 1014*cdf0e10cSrcweir 1015*cdf0e10cSrcweir NSRect aFieldRect = { { rCurX + nOff + nAttachOffset, 0 }, { 100, 25 } }; 1016*cdf0e10cSrcweir NSTextField* pFieldView = [[NSTextField alloc] initWithFrame: aFieldRect]; 1017*cdf0e10cSrcweir [pFieldView setEditable: YES]; 1018*cdf0e10cSrcweir [pFieldView setSelectable: YES]; 1019*cdf0e10cSrcweir [pFieldView setDrawsBackground: YES]; 1020*cdf0e10cSrcweir [pFieldView sizeToFit]; // FIXME: this does nothing 1021*cdf0e10cSrcweir [pCurParent addSubview: [pFieldView autorelease]]; 1022*cdf0e10cSrcweir 1023*cdf0e10cSrcweir rRightColumn.push_back( ColumnItem( pFieldView ) ); 1024*cdf0e10cSrcweir 1025*cdf0e10cSrcweir // add the field to observed controls for enabled state changes 1026*cdf0e10cSrcweir // also add a tag just for this purpose 1027*cdf0e10cSrcweir pControllerProperties->addObservedControl( pFieldView ); 1028*cdf0e10cSrcweir int nTag = pControllerProperties->addNameTag( rProperty ); 1029*cdf0e10cSrcweir [pFieldView setTag: nTag]; 1030*cdf0e10cSrcweir // pControllerProperties->addNamedView( pFieldView, aPropertyName ); 1031*cdf0e10cSrcweir 1032*cdf0e10cSrcweir // move to nCurY 1033*cdf0e10cSrcweir aFieldRect.origin.y = rCurY - aFieldRect.size.height; 1034*cdf0e10cSrcweir [pFieldView setFrame: aFieldRect]; 1035*cdf0e10cSrcweir 1036*cdf0e10cSrcweir if( rCtrlType.equalsAscii( "Range" ) ) 1037*cdf0e10cSrcweir { 1038*cdf0e10cSrcweir // add a stepper control 1039*cdf0e10cSrcweir NSRect aStepFrame = { { aFieldRect.origin.x + aFieldRect.size.width + 5, 1040*cdf0e10cSrcweir aFieldRect.origin.y }, 1041*cdf0e10cSrcweir { 15, aFieldRect.size.height } }; 1042*cdf0e10cSrcweir NSStepper* pStep = [[NSStepper alloc] initWithFrame: aStepFrame]; 1043*cdf0e10cSrcweir [pStep setIncrement: 1]; 1044*cdf0e10cSrcweir [pStep setValueWraps: NO]; 1045*cdf0e10cSrcweir [pStep setTag: nTag]; 1046*cdf0e10cSrcweir [pCurParent addSubview: [pStep autorelease]]; 1047*cdf0e10cSrcweir 1048*cdf0e10cSrcweir rRightColumn.back().pSubControl = pStep; 1049*cdf0e10cSrcweir 1050*cdf0e10cSrcweir pControllerProperties->addObservedControl( pStep ); 1051*cdf0e10cSrcweir [pStep setTarget: pCtrlTarget]; 1052*cdf0e10cSrcweir [pStep setAction: @selector(triggered:)]; 1053*cdf0e10cSrcweir 1054*cdf0e10cSrcweir // constrain the text field to decimal numbers 1055*cdf0e10cSrcweir NSNumberFormatter* pFormatter = [[NSNumberFormatter alloc] init]; 1056*cdf0e10cSrcweir [pFormatter setFormatterBehavior: NSNumberFormatterBehavior10_4]; 1057*cdf0e10cSrcweir [pFormatter setNumberStyle: NSNumberFormatterDecimalStyle]; 1058*cdf0e10cSrcweir [pFormatter setAllowsFloats: NO]; 1059*cdf0e10cSrcweir [pFormatter setMaximumFractionDigits: 0]; 1060*cdf0e10cSrcweir if( nMinValue != nMaxValue ) 1061*cdf0e10cSrcweir { 1062*cdf0e10cSrcweir [pFormatter setMinimum: [[NSNumber numberWithInt: nMinValue] autorelease]]; 1063*cdf0e10cSrcweir [pStep setMinValue: nMinValue]; 1064*cdf0e10cSrcweir [pFormatter setMaximum: [[NSNumber numberWithInt: nMaxValue] autorelease]]; 1065*cdf0e10cSrcweir [pStep setMaxValue: nMaxValue]; 1066*cdf0e10cSrcweir } 1067*cdf0e10cSrcweir [pFieldView setFormatter: pFormatter]; 1068*cdf0e10cSrcweir 1069*cdf0e10cSrcweir sal_Int64 nSelectVal = 0; 1070*cdf0e10cSrcweir if( pValue && pValue->Value.hasValue() ) 1071*cdf0e10cSrcweir pValue->Value >>= nSelectVal; 1072*cdf0e10cSrcweir 1073*cdf0e10cSrcweir [pFieldView setIntValue: nSelectVal]; 1074*cdf0e10cSrcweir [pStep setIntValue: nSelectVal]; 1075*cdf0e10cSrcweir 1076*cdf0e10cSrcweir pControllerProperties->addViewPair( pFieldView, pStep ); 1077*cdf0e10cSrcweir // connect target and action 1078*cdf0e10cSrcweir [pFieldView setTarget: pCtrlTarget]; 1079*cdf0e10cSrcweir [pFieldView setAction: @selector(triggeredNumeric:)]; 1080*cdf0e10cSrcweir [pStep setTarget: pCtrlTarget]; 1081*cdf0e10cSrcweir [pStep setAction: @selector(triggeredNumeric:)]; 1082*cdf0e10cSrcweir } 1083*cdf0e10cSrcweir else 1084*cdf0e10cSrcweir { 1085*cdf0e10cSrcweir // connect target and action 1086*cdf0e10cSrcweir [pFieldView setTarget: pCtrlTarget]; 1087*cdf0e10cSrcweir [pFieldView setAction: @selector(triggered:)]; 1088*cdf0e10cSrcweir 1089*cdf0e10cSrcweir if( pValue && pValue->Value.hasValue() ) 1090*cdf0e10cSrcweir { 1091*cdf0e10cSrcweir rtl::OUString aValue; 1092*cdf0e10cSrcweir pValue->Value >>= aValue; 1093*cdf0e10cSrcweir if( aValue.getLength() ) 1094*cdf0e10cSrcweir { 1095*cdf0e10cSrcweir NSString* pText = CreateNSString( aValue ); 1096*cdf0e10cSrcweir [pFieldView setStringValue: pText]; 1097*cdf0e10cSrcweir [pText release]; 1098*cdf0e10cSrcweir } 1099*cdf0e10cSrcweir } 1100*cdf0e10cSrcweir } 1101*cdf0e10cSrcweir 1102*cdf0e10cSrcweir // update nCurY 1103*cdf0e10cSrcweir rCurY = aFieldRect.origin.y - 5; 1104*cdf0e10cSrcweir} 1105*cdf0e10cSrcweir 1106*cdf0e10cSrcweir@implementation AquaPrintAccessoryView 1107*cdf0e10cSrcweir+(NSObject*)setupPrinterPanel: (NSPrintOperation*)pOp withController: (vcl::PrinterController*)pController withState: (PrintAccessoryViewState*)pState; 1108*cdf0e10cSrcweir{ 1109*cdf0e10cSrcweir const Sequence< PropertyValue >& rOptions( pController->getUIOptions() ); 1110*cdf0e10cSrcweir if( rOptions.getLength() == 0 ) 1111*cdf0e10cSrcweir return nil; 1112*cdf0e10cSrcweir 1113*cdf0e10cSrcweir NSView* pCurParent = 0; 1114*cdf0e10cSrcweir long nCurY = 0; 1115*cdf0e10cSrcweir long nCurX = 0; 1116*cdf0e10cSrcweir NSRect aViewFrame = { { 0, 0 }, {600, 400 } }; 1117*cdf0e10cSrcweir NSRect aTabViewFrame = { { 190, 0 }, {410, 400 } }; 1118*cdf0e10cSrcweir NSSize aMaxTabSize = { 0, 0 }; 1119*cdf0e10cSrcweir NSView* pAccessoryView = [[NSView alloc] initWithFrame: aViewFrame]; 1120*cdf0e10cSrcweir NSTabView* pTabView = [[NSTabView alloc] initWithFrame: aTabViewFrame]; 1121*cdf0e10cSrcweir [pAccessoryView addSubview: [pTabView autorelease]]; 1122*cdf0e10cSrcweir 1123*cdf0e10cSrcweir sal_Bool bIgnoreSubgroup = sal_False; 1124*cdf0e10cSrcweir 1125*cdf0e10cSrcweir ControllerProperties* pControllerProperties = new ControllerProperties( pController, pOp, pAccessoryView, pTabView, pState ); 1126*cdf0e10cSrcweir ControlTarget* pCtrlTarget = [[ControlTarget alloc] initWithControllerMap: pControllerProperties]; 1127*cdf0e10cSrcweir 1128*cdf0e10cSrcweir std::vector< ColumnItem > aLeftColumn, aRightColumn; 1129*cdf0e10cSrcweir 1130*cdf0e10cSrcweir // ugly: 1131*cdf0e10cSrcweir // prepend a "selection" checkbox if the properties have such a selection in PrintContent 1132*cdf0e10cSrcweir bool bAddSelectionCheckBox = false, bSelectionBoxEnabled = false, bSelectionBoxChecked = false; 1133*cdf0e10cSrcweir for( int i = 0; i < rOptions.getLength(); i++ ) 1134*cdf0e10cSrcweir { 1135*cdf0e10cSrcweir Sequence< beans::PropertyValue > aOptProp; 1136*cdf0e10cSrcweir rOptions[i].Value >>= aOptProp; 1137*cdf0e10cSrcweir 1138*cdf0e10cSrcweir rtl::OUString aCtrlType; 1139*cdf0e10cSrcweir rtl::OUString aPropertyName; 1140*cdf0e10cSrcweir Sequence< rtl::OUString > aChoices; 1141*cdf0e10cSrcweir Sequence< sal_Bool > aChoicesDisabled; 1142*cdf0e10cSrcweir sal_Int32 aSelectionChecked = 0; 1143*cdf0e10cSrcweir for( int n = 0; n < aOptProp.getLength(); n++ ) 1144*cdf0e10cSrcweir { 1145*cdf0e10cSrcweir const beans::PropertyValue& rEntry( aOptProp[ n ] ); 1146*cdf0e10cSrcweir if( rEntry.Name.equalsAscii( "ControlType" ) ) 1147*cdf0e10cSrcweir { 1148*cdf0e10cSrcweir rEntry.Value >>= aCtrlType; 1149*cdf0e10cSrcweir } 1150*cdf0e10cSrcweir else if( rEntry.Name.equalsAscii( "Choices" ) ) 1151*cdf0e10cSrcweir { 1152*cdf0e10cSrcweir rEntry.Value >>= aChoices; 1153*cdf0e10cSrcweir } 1154*cdf0e10cSrcweir else if( rEntry.Name.equalsAscii( "ChoicesDisabled" ) ) 1155*cdf0e10cSrcweir { 1156*cdf0e10cSrcweir rEntry.Value >>= aChoicesDisabled; 1157*cdf0e10cSrcweir } 1158*cdf0e10cSrcweir else if( rEntry.Name.equalsAscii( "Property" ) ) 1159*cdf0e10cSrcweir { 1160*cdf0e10cSrcweir PropertyValue aVal; 1161*cdf0e10cSrcweir rEntry.Value >>= aVal; 1162*cdf0e10cSrcweir aPropertyName = aVal.Name; 1163*cdf0e10cSrcweir if( aPropertyName.equalsAscii( "PrintContent" ) ) 1164*cdf0e10cSrcweir aVal.Value >>= aSelectionChecked; 1165*cdf0e10cSrcweir } 1166*cdf0e10cSrcweir } 1167*cdf0e10cSrcweir if( aCtrlType.equalsAscii( "Radio" ) && 1168*cdf0e10cSrcweir aPropertyName.equalsAscii( "PrintContent" ) && 1169*cdf0e10cSrcweir aChoices.getLength() > 2 ) 1170*cdf0e10cSrcweir { 1171*cdf0e10cSrcweir bAddSelectionCheckBox = true; 1172*cdf0e10cSrcweir bSelectionBoxEnabled = aChoicesDisabled.getLength() < 2 || ! aChoicesDisabled[2]; 1173*cdf0e10cSrcweir bSelectionBoxChecked = (aSelectionChecked==2); 1174*cdf0e10cSrcweir break; 1175*cdf0e10cSrcweir } 1176*cdf0e10cSrcweir } 1177*cdf0e10cSrcweir 1178*cdf0e10cSrcweir for( int i = 0; i < rOptions.getLength(); i++ ) 1179*cdf0e10cSrcweir { 1180*cdf0e10cSrcweir Sequence< beans::PropertyValue > aOptProp; 1181*cdf0e10cSrcweir rOptions[i].Value >>= aOptProp; 1182*cdf0e10cSrcweir 1183*cdf0e10cSrcweir // extract ui element 1184*cdf0e10cSrcweir bool bEnabled = true; 1185*cdf0e10cSrcweir rtl::OUString aCtrlType; 1186*cdf0e10cSrcweir rtl::OUString aText; 1187*cdf0e10cSrcweir rtl::OUString aPropertyName; 1188*cdf0e10cSrcweir rtl::OUString aGroupHint; 1189*cdf0e10cSrcweir Sequence< rtl::OUString > aChoices; 1190*cdf0e10cSrcweir sal_Int64 nMinValue = 0, nMaxValue = 0; 1191*cdf0e10cSrcweir long nAttachOffset = 0; 1192*cdf0e10cSrcweir sal_Bool bIgnore = sal_False; 1193*cdf0e10cSrcweir 1194*cdf0e10cSrcweir for( int n = 0; n < aOptProp.getLength(); n++ ) 1195*cdf0e10cSrcweir { 1196*cdf0e10cSrcweir const beans::PropertyValue& rEntry( aOptProp[ n ] ); 1197*cdf0e10cSrcweir if( rEntry.Name.equalsAscii( "Text" ) ) 1198*cdf0e10cSrcweir { 1199*cdf0e10cSrcweir rEntry.Value >>= aText; 1200*cdf0e10cSrcweir filterAccelerator( aText ); 1201*cdf0e10cSrcweir } 1202*cdf0e10cSrcweir else if( rEntry.Name.equalsAscii( "ControlType" ) ) 1203*cdf0e10cSrcweir { 1204*cdf0e10cSrcweir rEntry.Value >>= aCtrlType; 1205*cdf0e10cSrcweir } 1206*cdf0e10cSrcweir else if( rEntry.Name.equalsAscii( "Choices" ) ) 1207*cdf0e10cSrcweir { 1208*cdf0e10cSrcweir rEntry.Value >>= aChoices; 1209*cdf0e10cSrcweir } 1210*cdf0e10cSrcweir else if( rEntry.Name.equalsAscii( "Property" ) ) 1211*cdf0e10cSrcweir { 1212*cdf0e10cSrcweir PropertyValue aVal; 1213*cdf0e10cSrcweir rEntry.Value >>= aVal; 1214*cdf0e10cSrcweir aPropertyName = aVal.Name; 1215*cdf0e10cSrcweir } 1216*cdf0e10cSrcweir else if( rEntry.Name.equalsAscii( "Enabled" ) ) 1217*cdf0e10cSrcweir { 1218*cdf0e10cSrcweir sal_Bool bValue = sal_True; 1219*cdf0e10cSrcweir rEntry.Value >>= bValue; 1220*cdf0e10cSrcweir bEnabled = bValue; 1221*cdf0e10cSrcweir } 1222*cdf0e10cSrcweir else if( rEntry.Name.equalsAscii( "MinValue" ) ) 1223*cdf0e10cSrcweir { 1224*cdf0e10cSrcweir rEntry.Value >>= nMinValue; 1225*cdf0e10cSrcweir } 1226*cdf0e10cSrcweir else if( rEntry.Name.equalsAscii( "MaxValue" ) ) 1227*cdf0e10cSrcweir { 1228*cdf0e10cSrcweir rEntry.Value >>= nMaxValue; 1229*cdf0e10cSrcweir } 1230*cdf0e10cSrcweir else if( rEntry.Name.equalsAscii( "AttachToDependency" ) ) 1231*cdf0e10cSrcweir { 1232*cdf0e10cSrcweir nAttachOffset = 20; 1233*cdf0e10cSrcweir } 1234*cdf0e10cSrcweir else if( rEntry.Name.equalsAscii( "InternalUIOnly" ) ) 1235*cdf0e10cSrcweir { 1236*cdf0e10cSrcweir rEntry.Value >>= bIgnore; 1237*cdf0e10cSrcweir } 1238*cdf0e10cSrcweir else if( rEntry.Name.equalsAscii( "GroupingHint" ) ) 1239*cdf0e10cSrcweir { 1240*cdf0e10cSrcweir rEntry.Value >>= aGroupHint; 1241*cdf0e10cSrcweir } 1242*cdf0e10cSrcweir } 1243*cdf0e10cSrcweir 1244*cdf0e10cSrcweir if( aCtrlType.equalsAscii( "Group" ) || 1245*cdf0e10cSrcweir aCtrlType.equalsAscii( "Subgroup" ) || 1246*cdf0e10cSrcweir aCtrlType.equalsAscii( "Radio" ) || 1247*cdf0e10cSrcweir aCtrlType.equalsAscii( "List" ) || 1248*cdf0e10cSrcweir aCtrlType.equalsAscii( "Edit" ) || 1249*cdf0e10cSrcweir aCtrlType.equalsAscii( "Range" ) || 1250*cdf0e10cSrcweir aCtrlType.equalsAscii( "Bool" ) ) 1251*cdf0e10cSrcweir { 1252*cdf0e10cSrcweir // since our build target is MacOSX 10.4 we can have only one accessory view 1253*cdf0e10cSrcweir // so we have a single accessory view that is tabbed for grouping 1254*cdf0e10cSrcweir if( aCtrlType.equalsAscii( "Group" ) 1255*cdf0e10cSrcweir || ! pCurParent 1256*cdf0e10cSrcweir || ( aCtrlType.equalsAscii( "Subgroup" ) && nCurY < -250 && ! bIgnore ) 1257*cdf0e10cSrcweir ) 1258*cdf0e10cSrcweir { 1259*cdf0e10cSrcweir rtl::OUString aGroupTitle( aText ); 1260*cdf0e10cSrcweir if( aCtrlType.equalsAscii( "Subgroup" ) ) 1261*cdf0e10cSrcweir aGroupTitle = pControllerProperties->getMoreString(); 1262*cdf0e10cSrcweir // set size of current parent 1263*cdf0e10cSrcweir if( pCurParent ) 1264*cdf0e10cSrcweir adjustViewAndChildren( pCurParent, aMaxTabSize, aLeftColumn, aRightColumn ); 1265*cdf0e10cSrcweir 1266*cdf0e10cSrcweir // new tab item 1267*cdf0e10cSrcweir if( ! aText.getLength() ) 1268*cdf0e10cSrcweir aText = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OOo" ) ); 1269*cdf0e10cSrcweir NSString* pLabel = CreateNSString( aGroupTitle ); 1270*cdf0e10cSrcweir NSTabViewItem* pItem = [[NSTabViewItem alloc] initWithIdentifier: pLabel ]; 1271*cdf0e10cSrcweir [pItem setLabel: pLabel]; 1272*cdf0e10cSrcweir [pTabView addTabViewItem: pItem]; 1273*cdf0e10cSrcweir pCurParent = [[NSView alloc] initWithFrame: aTabViewFrame]; 1274*cdf0e10cSrcweir [pItem setView: pCurParent]; 1275*cdf0e10cSrcweir [pLabel release]; 1276*cdf0e10cSrcweir 1277*cdf0e10cSrcweir // reset indent 1278*cdf0e10cSrcweir nCurX = 20; 1279*cdf0e10cSrcweir // reset Y 1280*cdf0e10cSrcweir nCurY = 0; 1281*cdf0e10cSrcweir // clear columns 1282*cdf0e10cSrcweir aLeftColumn.clear(); 1283*cdf0e10cSrcweir aRightColumn.clear(); 1284*cdf0e10cSrcweir 1285*cdf0e10cSrcweir if( bAddSelectionCheckBox ) 1286*cdf0e10cSrcweir { 1287*cdf0e10cSrcweir addBool( pCurParent, nCurX, nCurY, 0, 1288*cdf0e10cSrcweir pControllerProperties->getPrintSelectionString(), bSelectionBoxEnabled, 1289*cdf0e10cSrcweir rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintContent" ) ), bSelectionBoxChecked, 1290*cdf0e10cSrcweir aRightColumn, pControllerProperties, pCtrlTarget ); 1291*cdf0e10cSrcweir bAddSelectionCheckBox = false; 1292*cdf0e10cSrcweir } 1293*cdf0e10cSrcweir } 1294*cdf0e10cSrcweir 1295*cdf0e10cSrcweir if( aCtrlType.equalsAscii( "Subgroup" ) && pCurParent ) 1296*cdf0e10cSrcweir { 1297*cdf0e10cSrcweir bIgnoreSubgroup = bIgnore; 1298*cdf0e10cSrcweir if( bIgnore ) 1299*cdf0e10cSrcweir continue; 1300*cdf0e10cSrcweir 1301*cdf0e10cSrcweir addSubgroup( pCurParent, nCurY, aText ); 1302*cdf0e10cSrcweir } 1303*cdf0e10cSrcweir else if( bIgnoreSubgroup || bIgnore ) 1304*cdf0e10cSrcweir { 1305*cdf0e10cSrcweir continue; 1306*cdf0e10cSrcweir } 1307*cdf0e10cSrcweir else if( aCtrlType.equalsAscii( "Bool" ) && pCurParent ) 1308*cdf0e10cSrcweir { 1309*cdf0e10cSrcweir sal_Bool bVal = sal_False; 1310*cdf0e10cSrcweir PropertyValue* pVal = pController->getValue( aPropertyName ); 1311*cdf0e10cSrcweir if( pVal ) 1312*cdf0e10cSrcweir pVal->Value >>= bVal; 1313*cdf0e10cSrcweir addBool( pCurParent, nCurX, nCurY, nAttachOffset, 1314*cdf0e10cSrcweir aText, true, aPropertyName, bVal, 1315*cdf0e10cSrcweir aRightColumn, pControllerProperties, pCtrlTarget ); 1316*cdf0e10cSrcweir } 1317*cdf0e10cSrcweir else if( aCtrlType.equalsAscii( "Radio" ) && pCurParent ) 1318*cdf0e10cSrcweir { 1319*cdf0e10cSrcweir // get currently selected value 1320*cdf0e10cSrcweir sal_Int32 nSelectVal = 0; 1321*cdf0e10cSrcweir PropertyValue* pVal = pController->getValue( aPropertyName ); 1322*cdf0e10cSrcweir if( pVal && pVal->Value.hasValue() ) 1323*cdf0e10cSrcweir pVal->Value >>= nSelectVal; 1324*cdf0e10cSrcweir 1325*cdf0e10cSrcweir addRadio( pCurParent, nCurX, nCurY, nAttachOffset, 1326*cdf0e10cSrcweir aText, aPropertyName, aChoices, nSelectVal, 1327*cdf0e10cSrcweir aLeftColumn, aRightColumn, 1328*cdf0e10cSrcweir pControllerProperties, pCtrlTarget ); 1329*cdf0e10cSrcweir } 1330*cdf0e10cSrcweir else if( aCtrlType.equalsAscii( "List" ) && pCurParent ) 1331*cdf0e10cSrcweir { 1332*cdf0e10cSrcweir PropertyValue* pVal = pController->getValue( aPropertyName ); 1333*cdf0e10cSrcweir sal_Int32 aSelectVal = 0; 1334*cdf0e10cSrcweir if( pVal && pVal->Value.hasValue() ) 1335*cdf0e10cSrcweir pVal->Value >>= aSelectVal; 1336*cdf0e10cSrcweir 1337*cdf0e10cSrcweir addList( pCurParent, nCurX, nCurY, nAttachOffset, 1338*cdf0e10cSrcweir aText, aPropertyName, aChoices, aSelectVal, 1339*cdf0e10cSrcweir aLeftColumn, aRightColumn, 1340*cdf0e10cSrcweir pControllerProperties, pCtrlTarget ); 1341*cdf0e10cSrcweir } 1342*cdf0e10cSrcweir else if( (aCtrlType.equalsAscii( "Edit" ) || aCtrlType.equalsAscii( "Range" )) && pCurParent ) 1343*cdf0e10cSrcweir { 1344*cdf0e10cSrcweir // current value 1345*cdf0e10cSrcweir PropertyValue* pVal = pController->getValue( aPropertyName ); 1346*cdf0e10cSrcweir addEdit( pCurParent, nCurX, nCurY, nAttachOffset, 1347*cdf0e10cSrcweir aCtrlType, aText, aPropertyName, pVal, 1348*cdf0e10cSrcweir nMinValue, nMaxValue, 1349*cdf0e10cSrcweir aLeftColumn, aRightColumn, 1350*cdf0e10cSrcweir pControllerProperties, pCtrlTarget ); 1351*cdf0e10cSrcweir } 1352*cdf0e10cSrcweir } 1353*cdf0e10cSrcweir else 1354*cdf0e10cSrcweir { 1355*cdf0e10cSrcweir DBG_ERROR( "Unsupported UI option" ); 1356*cdf0e10cSrcweir } 1357*cdf0e10cSrcweir } 1358*cdf0e10cSrcweir 1359*cdf0e10cSrcweir pControllerProperties->updateEnableState(); 1360*cdf0e10cSrcweir adjustViewAndChildren( pCurParent, aMaxTabSize, aLeftColumn, aRightColumn ); 1361*cdf0e10cSrcweir 1362*cdf0e10cSrcweir // leave some space for the preview 1363*cdf0e10cSrcweir if( aMaxTabSize.height < 200 ) 1364*cdf0e10cSrcweir aMaxTabSize.height = 200; 1365*cdf0e10cSrcweir 1366*cdf0e10cSrcweir // now reposition everything again so it is upper bound 1367*cdf0e10cSrcweir adjustTabViews( pTabView, aMaxTabSize ); 1368*cdf0e10cSrcweir 1369*cdf0e10cSrcweir // find the minimum needed tab size 1370*cdf0e10cSrcweir NSSize aTabCtrlSize = [pTabView minimumSize]; 1371*cdf0e10cSrcweir aTabCtrlSize.height += aMaxTabSize.height + 10; 1372*cdf0e10cSrcweir if( aTabCtrlSize.width < aMaxTabSize.width + 10 ) 1373*cdf0e10cSrcweir aTabCtrlSize.width = aMaxTabSize.width + 10; 1374*cdf0e10cSrcweir [pTabView setFrameSize: aTabCtrlSize]; 1375*cdf0e10cSrcweir aViewFrame.size.width = aTabCtrlSize.width + aTabViewFrame.origin.x; 1376*cdf0e10cSrcweir aViewFrame.size.height = aTabCtrlSize.height + aTabViewFrame.origin.y; 1377*cdf0e10cSrcweir [pAccessoryView setFrameSize: aViewFrame.size]; 1378*cdf0e10cSrcweir 1379*cdf0e10cSrcweir pControllerProperties->setupPreview( pCtrlTarget ); 1380*cdf0e10cSrcweir 1381*cdf0e10cSrcweir // set the accessory view 1382*cdf0e10cSrcweir [pOp setAccessoryView: [pAccessoryView autorelease]]; 1383*cdf0e10cSrcweir 1384*cdf0e10cSrcweir // set the current selecte tab item 1385*cdf0e10cSrcweir if( pState->nLastPage >= 0 && pState->nLastPage < [pTabView numberOfTabViewItems] ) 1386*cdf0e10cSrcweir [pTabView selectTabViewItemAtIndex: pState->nLastPage]; 1387*cdf0e10cSrcweir 1388*cdf0e10cSrcweir return pCtrlTarget; 1389*cdf0e10cSrcweir} 1390*cdf0e10cSrcweir 1391*cdf0e10cSrcweir@end 1392