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