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