xref: /AOO41X/main/fpicker/source/aqua/ControlHelper.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
29*cdf0e10cSrcweir #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
30*cdf0e10cSrcweir #include <com/sun/star/ui/dialogs/ControlActions.hpp>
31*cdf0e10cSrcweir #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
32*cdf0e10cSrcweir #include <vos/mutex.hxx>
33*cdf0e10cSrcweir #include <vcl/svapp.hxx>
34*cdf0e10cSrcweir #include "CFStringUtilities.hxx"
35*cdf0e10cSrcweir #include "resourceprovider.hxx"
36*cdf0e10cSrcweir #include "NSString_OOoAdditions.hxx"
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir #include "ControlHelper.hxx"
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir #pragma mark DEFINES
41*cdf0e10cSrcweir #define CLASS_NAME "ControlHelper"
42*cdf0e10cSrcweir #define POPUP_WIDTH_MIN 200
43*cdf0e10cSrcweir #define POPUP_WIDTH_MAX 350
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir using namespace ::com::sun::star::ui::dialogs;
46*cdf0e10cSrcweir using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
47*cdf0e10cSrcweir using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds;
48*cdf0e10cSrcweir using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds;
49*cdf0e10cSrcweir using namespace ::rtl;
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir #pragma mark Constructor / Destructor
52*cdf0e10cSrcweir //------------------------------------------------------------------------------------
53*cdf0e10cSrcweir // Constructor / Destructor
54*cdf0e10cSrcweir //------------------------------------------------------------------------------------
55*cdf0e10cSrcweir ControlHelper::ControlHelper()
56*cdf0e10cSrcweir : m_pUserPane(NULL)
57*cdf0e10cSrcweir , m_pFilterControl(nil)
58*cdf0e10cSrcweir , m_bUserPaneNeeded( false )
59*cdf0e10cSrcweir , m_bIsUserPaneLaidOut(false)
60*cdf0e10cSrcweir , m_bIsFilterControlNeeded(false)
61*cdf0e10cSrcweir , m_pFilterHelper(NULL)
62*cdf0e10cSrcweir {
63*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir     int i;
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir     for( i = 0; i < TOGGLE_LAST; i++ ) {
68*cdf0e10cSrcweir         m_bToggleVisibility[i] = false;
69*cdf0e10cSrcweir     }
70*cdf0e10cSrcweir 
71*cdf0e10cSrcweir     for( i = 0; i < LIST_LAST; i++ ) {
72*cdf0e10cSrcweir         m_bListVisibility[i] = false;
73*cdf0e10cSrcweir     }
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
76*cdf0e10cSrcweir }
77*cdf0e10cSrcweir 
78*cdf0e10cSrcweir ControlHelper::~ControlHelper()
79*cdf0e10cSrcweir {
80*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir     NSAutoreleasePool *pool = [NSAutoreleasePool new];
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir     if (NULL != m_pUserPane) {
85*cdf0e10cSrcweir         [m_pUserPane release];
86*cdf0e10cSrcweir     }
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir     for(std::list<NSControl *>::iterator control = m_aActiveControls.begin(); control != m_aActiveControls.end(); control++) {
89*cdf0e10cSrcweir         NSControl* pControl = (*control);
90*cdf0e10cSrcweir         NSString* sLabelName = m_aMapListLabels[pControl];
91*cdf0e10cSrcweir         if (sLabelName != nil) {
92*cdf0e10cSrcweir             [sLabelName release];
93*cdf0e10cSrcweir         }
94*cdf0e10cSrcweir         if ([pControl class] == [NSPopUpButton class]) {
95*cdf0e10cSrcweir             NSTextField* pField = m_aMapListLabelFields[(NSPopUpButton*)pControl];
96*cdf0e10cSrcweir             if (pField != nil) {
97*cdf0e10cSrcweir                 [pField release];
98*cdf0e10cSrcweir             }
99*cdf0e10cSrcweir         }
100*cdf0e10cSrcweir         [pControl release];
101*cdf0e10cSrcweir     }
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir     if (m_pFilterControl != NULL) {
104*cdf0e10cSrcweir         [m_pFilterControl setTarget:nil];
105*cdf0e10cSrcweir     }
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir     [pool release];
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
110*cdf0e10cSrcweir }
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir #pragma mark XInitialization delegate
113*cdf0e10cSrcweir //------------------------------------------------
114*cdf0e10cSrcweir // XInitialization delegate
115*cdf0e10cSrcweir //------------------------------------------------
116*cdf0e10cSrcweir void ControlHelper::initialize( sal_Int16 nTemplateId )
117*cdf0e10cSrcweir {
118*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "templateId", nTemplateId);
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir     switch( nTemplateId )
121*cdf0e10cSrcweir     {
122*cdf0e10cSrcweir         case FILESAVE_AUTOEXTENSION_PASSWORD:
123*cdf0e10cSrcweir             m_bToggleVisibility[AUTOEXTENSION] = true;
124*cdf0e10cSrcweir             m_bToggleVisibility[PASSWORD] = true;
125*cdf0e10cSrcweir             break;
126*cdf0e10cSrcweir         case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
127*cdf0e10cSrcweir             m_bToggleVisibility[AUTOEXTENSION] = true;
128*cdf0e10cSrcweir             m_bToggleVisibility[PASSWORD] = true;
129*cdf0e10cSrcweir             m_bToggleVisibility[FILTEROPTIONS] = true;
130*cdf0e10cSrcweir             break;
131*cdf0e10cSrcweir         case FILESAVE_AUTOEXTENSION_SELECTION:
132*cdf0e10cSrcweir             m_bToggleVisibility[AUTOEXTENSION] = true;
133*cdf0e10cSrcweir             m_bToggleVisibility[SELECTION] = true;
134*cdf0e10cSrcweir             break;
135*cdf0e10cSrcweir         case FILESAVE_AUTOEXTENSION_TEMPLATE:
136*cdf0e10cSrcweir             m_bToggleVisibility[AUTOEXTENSION] = true;
137*cdf0e10cSrcweir             m_bListVisibility[TEMPLATE] = true;
138*cdf0e10cSrcweir             break;
139*cdf0e10cSrcweir         case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
140*cdf0e10cSrcweir             m_bToggleVisibility[LINK] = true;
141*cdf0e10cSrcweir             m_bToggleVisibility[PREVIEW] = true;
142*cdf0e10cSrcweir             m_bListVisibility[IMAGE_TEMPLATE] = true;
143*cdf0e10cSrcweir             break;
144*cdf0e10cSrcweir         case FILEOPEN_READONLY_VERSION:
145*cdf0e10cSrcweir             m_bToggleVisibility[READONLY] = true;
146*cdf0e10cSrcweir             m_bListVisibility[VERSION] = true;
147*cdf0e10cSrcweir             break;
148*cdf0e10cSrcweir         case FILEOPEN_LINK_PREVIEW:
149*cdf0e10cSrcweir             m_bToggleVisibility[LINK] = true;
150*cdf0e10cSrcweir             m_bToggleVisibility[PREVIEW] = true;
151*cdf0e10cSrcweir             break;
152*cdf0e10cSrcweir         case FILESAVE_AUTOEXTENSION:
153*cdf0e10cSrcweir             m_bToggleVisibility[AUTOEXTENSION] = true;
154*cdf0e10cSrcweir             break;
155*cdf0e10cSrcweir     }
156*cdf0e10cSrcweir 
157*cdf0e10cSrcweir     createControls();
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
160*cdf0e10cSrcweir }
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir #pragma mark XFilePickerControlAccess delegates
163*cdf0e10cSrcweir //------------------------------------------------------------------------------------
164*cdf0e10cSrcweir // XFilePickerControlAccess functions
165*cdf0e10cSrcweir //------------------------------------------------------------------------------------
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir void ControlHelper::enableControl( const sal_Int16 nControlId, const sal_Bool bEnable ) const
168*cdf0e10cSrcweir {
169*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "controlId", nControlId, "enable", bEnable);
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir     if (nControlId == ExtendedFilePickerElementIds::CHECKBOX_PREVIEW) {
174*cdf0e10cSrcweir         OSL_TRACE(" preview checkbox cannot be changed");
175*cdf0e10cSrcweir         DBG_PRINT_EXIT(CLASS_NAME, __func__);
176*cdf0e10cSrcweir         return;
177*cdf0e10cSrcweir     }
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir     NSControl* pControl = getControl(nControlId);
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir     if( pControl != nil ) {
182*cdf0e10cSrcweir         if( bEnable ) {
183*cdf0e10cSrcweir             OSL_TRACE( "enable" );
184*cdf0e10cSrcweir         } else {
185*cdf0e10cSrcweir             OSL_TRACE( "disable" );
186*cdf0e10cSrcweir         }
187*cdf0e10cSrcweir         [pControl setEnabled:bEnable];
188*cdf0e10cSrcweir     } else {
189*cdf0e10cSrcweir         OSL_TRACE("enable unknown control %d", nControlId );
190*cdf0e10cSrcweir     }
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
193*cdf0e10cSrcweir }
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir OUString ControlHelper::getLabel( sal_Int16 nControlId )
196*cdf0e10cSrcweir {
197*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "controlId", nControlId);
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
200*cdf0e10cSrcweir 
201*cdf0e10cSrcweir     NSControl* pControl = getControl( nControlId );
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir     if( pControl == nil ) {
204*cdf0e10cSrcweir         OSL_TRACE("Get label for unknown control %d", nControlId);
205*cdf0e10cSrcweir         return OUString();
206*cdf0e10cSrcweir     }
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir     rtl::OUString retVal;
209*cdf0e10cSrcweir     if ([pControl class] == [NSPopUpButton class]) {
210*cdf0e10cSrcweir         NSString *temp = m_aMapListLabels[pControl];
211*cdf0e10cSrcweir         if (temp != nil)
212*cdf0e10cSrcweir             retVal = [temp OUString];
213*cdf0e10cSrcweir     }
214*cdf0e10cSrcweir     else {
215*cdf0e10cSrcweir         NSString* sLabel = [[pControl cell] title];
216*cdf0e10cSrcweir         retVal = [sLabel OUString];
217*cdf0e10cSrcweir     }
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir     return retVal;
222*cdf0e10cSrcweir }
223*cdf0e10cSrcweir 
224*cdf0e10cSrcweir void ControlHelper::setLabel( sal_Int16 nControlId, const NSString* aLabel )
225*cdf0e10cSrcweir {
226*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "controlId", nControlId, "label", aLabel);
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
229*cdf0e10cSrcweir 
230*cdf0e10cSrcweir     NSAutoreleasePool *pool = [NSAutoreleasePool new];
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir     NSControl* pControl = getControl(nControlId);
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir     if (nil != pControl) {
235*cdf0e10cSrcweir         if ([pControl class] == [NSPopUpButton class]) {
236*cdf0e10cSrcweir             NSString *sOldName = m_aMapListLabels[pControl];
237*cdf0e10cSrcweir             if (sOldName != NULL && sOldName != aLabel) {
238*cdf0e10cSrcweir                 [sOldName release];
239*cdf0e10cSrcweir             }
240*cdf0e10cSrcweir 
241*cdf0e10cSrcweir             m_aMapListLabels[pControl] = [aLabel retain];
242*cdf0e10cSrcweir         } else if ([pControl class] == [NSButton class]) {
243*cdf0e10cSrcweir             [[pControl cell] setTitle:aLabel];
244*cdf0e10cSrcweir         }
245*cdf0e10cSrcweir     } else {
246*cdf0e10cSrcweir         OSL_TRACE("Control not found to set label for");
247*cdf0e10cSrcweir     }
248*cdf0e10cSrcweir 
249*cdf0e10cSrcweir     layoutControls();
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir     [pool release];
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
254*cdf0e10cSrcweir }
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir void ControlHelper::setValue( sal_Int16 nControlId, sal_Int16 nControlAction, const uno::Any& rValue )
257*cdf0e10cSrcweir {
258*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "controlId", nControlId, "controlAction", nControlAction);
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir     if (nControlId == ExtendedFilePickerElementIds::CHECKBOX_PREVIEW) {
263*cdf0e10cSrcweir         OSL_TRACE(" value for preview is unchangeable");
264*cdf0e10cSrcweir     }
265*cdf0e10cSrcweir     else {
266*cdf0e10cSrcweir         NSControl* pControl = getControl( nControlId );
267*cdf0e10cSrcweir 
268*cdf0e10cSrcweir         if( pControl == nil ) {
269*cdf0e10cSrcweir             OSL_TRACE("enable unknown control %d", nControlId);
270*cdf0e10cSrcweir         } else {
271*cdf0e10cSrcweir             if( [pControl class] == [NSPopUpButton class] ) {
272*cdf0e10cSrcweir                 HandleSetListValue(pControl, nControlAction, rValue);
273*cdf0e10cSrcweir             } else if( [pControl class] == [NSButton class] ) {
274*cdf0e10cSrcweir                 sal_Bool bChecked = false;
275*cdf0e10cSrcweir                 rValue >>= bChecked;
276*cdf0e10cSrcweir                 OSL_TRACE(" value is a bool: %d", bChecked);
277*cdf0e10cSrcweir                 [(NSButton*)pControl setState:(bChecked ? NSOnState : NSOffState)];
278*cdf0e10cSrcweir             } else
279*cdf0e10cSrcweir             {
280*cdf0e10cSrcweir                 OSL_TRACE("Can't set value on button / list %d %d",
281*cdf0e10cSrcweir                           nControlId, nControlAction);
282*cdf0e10cSrcweir             }
283*cdf0e10cSrcweir         }
284*cdf0e10cSrcweir     }
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
287*cdf0e10cSrcweir }
288*cdf0e10cSrcweir 
289*cdf0e10cSrcweir uno::Any ControlHelper::getValue( sal_Int16 nControlId, sal_Int16 nControlAction ) const
290*cdf0e10cSrcweir {
291*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "controlId", nControlId, "controlAction", nControlAction);
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
294*cdf0e10cSrcweir     uno::Any aRetval;
295*cdf0e10cSrcweir 
296*cdf0e10cSrcweir     NSControl* pControl = getControl( nControlId );
297*cdf0e10cSrcweir 
298*cdf0e10cSrcweir     if( pControl == nil ) {
299*cdf0e10cSrcweir         OSL_TRACE("get value for unknown control %d", nControlId);
300*cdf0e10cSrcweir         aRetval <<= sal_True;
301*cdf0e10cSrcweir     } else {
302*cdf0e10cSrcweir         if( [pControl class] == [NSPopUpButton class] ) {
303*cdf0e10cSrcweir             aRetval = HandleGetListValue(pControl, nControlAction);
304*cdf0e10cSrcweir         } else if( [pControl class] == [NSButton class] ) {
305*cdf0e10cSrcweir             //NSLog(@"control: %@", [[pControl cell] title]);
306*cdf0e10cSrcweir             sal_Bool bValue = [(NSButton*)pControl state] == NSOnState ? sal_True : sal_False;
307*cdf0e10cSrcweir             aRetval <<= bValue;
308*cdf0e10cSrcweir             OSL_TRACE("value is a bool (checkbox): %d", bValue);
309*cdf0e10cSrcweir         }
310*cdf0e10cSrcweir     }
311*cdf0e10cSrcweir 
312*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
313*cdf0e10cSrcweir 
314*cdf0e10cSrcweir     return aRetval;
315*cdf0e10cSrcweir }
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir void ControlHelper::createUserPane()
318*cdf0e10cSrcweir {
319*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
320*cdf0e10cSrcweir 
321*cdf0e10cSrcweir     if (m_bUserPaneNeeded == false) {
322*cdf0e10cSrcweir         OSL_TRACE("no user pane needed");
323*cdf0e10cSrcweir         DBG_PRINT_EXIT(CLASS_NAME, __func__);
324*cdf0e10cSrcweir         return;
325*cdf0e10cSrcweir     }
326*cdf0e10cSrcweir 
327*cdf0e10cSrcweir     if (nil != m_pUserPane) {
328*cdf0e10cSrcweir         OSL_TRACE("user pane already exists");
329*cdf0e10cSrcweir         DBG_PRINT_EXIT(CLASS_NAME, __func__);
330*cdf0e10cSrcweir         return;
331*cdf0e10cSrcweir     }
332*cdf0e10cSrcweir 
333*cdf0e10cSrcweir     if (m_bIsFilterControlNeeded == true && m_pFilterControl == nil) {
334*cdf0e10cSrcweir         createFilterControl();
335*cdf0e10cSrcweir     }
336*cdf0e10cSrcweir 
337*cdf0e10cSrcweir     NSRect minRect = NSMakeRect(0,0,300,33);
338*cdf0e10cSrcweir     m_pUserPane = [[NSView alloc] initWithFrame:minRect];
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir     int currentHeight = kAquaSpaceBoxFrameViewDiffTop + kAquaSpaceBoxFrameViewDiffBottom;
341*cdf0e10cSrcweir     int currentWidth = 300;
342*cdf0e10cSrcweir 
343*cdf0e10cSrcweir     sal_Bool bPopupControlPresent = NO;
344*cdf0e10cSrcweir     sal_Bool bButtonControlPresent = NO;
345*cdf0e10cSrcweir 
346*cdf0e10cSrcweir     int nCheckboxMaxWidth = 0;
347*cdf0e10cSrcweir     int nPopupMaxWidth = 0;
348*cdf0e10cSrcweir     int nPopupLabelMaxWidth = 0;
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir     for (::std::list<NSControl*>::iterator child = m_aActiveControls.begin(); child != m_aActiveControls.end(); child++) {
351*cdf0e10cSrcweir         OSL_TRACE("currentHeight: %d", currentHeight);
352*cdf0e10cSrcweir 
353*cdf0e10cSrcweir         NSControl* pControl = *child;
354*cdf0e10cSrcweir 
355*cdf0e10cSrcweir         //let the control calculate its size
356*cdf0e10cSrcweir         [pControl sizeToFit];
357*cdf0e10cSrcweir 
358*cdf0e10cSrcweir         NSRect frame = [pControl frame];
359*cdf0e10cSrcweir         OSL_TRACE("frame for control %s is {%f, %f, %f, %f}", [[pControl description] UTF8String], frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
360*cdf0e10cSrcweir 
361*cdf0e10cSrcweir         int nControlHeight = frame.size.height;
362*cdf0e10cSrcweir         int nControlWidth = frame.size.width;
363*cdf0e10cSrcweir 
364*cdf0e10cSrcweir         // Note: controls are grouped by kind, first all popup menus, then checkboxes
365*cdf0e10cSrcweir         if ([pControl class] == [NSPopUpButton class]) {
366*cdf0e10cSrcweir             if (bPopupControlPresent == YES) {
367*cdf0e10cSrcweir                 //this is not the first popup
368*cdf0e10cSrcweir                 currentHeight += kAquaSpaceBetweenPopupMenus;
369*cdf0e10cSrcweir             }
370*cdf0e10cSrcweir             else if (child != m_aActiveControls.begin()){
371*cdf0e10cSrcweir                 currentHeight += kAquaSpaceBetweenControls;
372*cdf0e10cSrcweir             }
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir             bPopupControlPresent = YES;
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir             // we have to add the label text width
377*cdf0e10cSrcweir             NSString *label = m_aMapListLabels[pControl];
378*cdf0e10cSrcweir 
379*cdf0e10cSrcweir             NSTextField *textField = createLabelWithString(label);
380*cdf0e10cSrcweir             [textField sizeToFit];
381*cdf0e10cSrcweir             m_aMapListLabelFields[(NSPopUpButton*)pControl] = textField;
382*cdf0e10cSrcweir             [m_pUserPane addSubview:textField];
383*cdf0e10cSrcweir 
384*cdf0e10cSrcweir             NSRect tfRect = [textField frame];
385*cdf0e10cSrcweir             OSL_TRACE("frame for textfield %s is {%f, %f, %f, %f}", [[textField description] UTF8String], tfRect.origin.x, tfRect.origin.y, tfRect.size.width, tfRect.size.height);
386*cdf0e10cSrcweir 
387*cdf0e10cSrcweir             int tfWidth = tfRect.size.width;
388*cdf0e10cSrcweir 
389*cdf0e10cSrcweir             if (nPopupLabelMaxWidth < tfWidth) {
390*cdf0e10cSrcweir                 nPopupLabelMaxWidth = tfWidth;
391*cdf0e10cSrcweir             }
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir             frame.origin.x += (kAquaSpaceBetweenControls - kAquaSpaceLabelFrameBoundsDiffH - kAquaSpacePopupMenuFrameBoundsDiffLeft) + tfWidth;
394*cdf0e10cSrcweir 
395*cdf0e10cSrcweir             if (nControlWidth < POPUP_WIDTH_MIN) {
396*cdf0e10cSrcweir                 nControlWidth = POPUP_WIDTH_MIN;
397*cdf0e10cSrcweir                 frame.size.width = nControlWidth;
398*cdf0e10cSrcweir                 [pControl setFrame:frame];
399*cdf0e10cSrcweir             }
400*cdf0e10cSrcweir 
401*cdf0e10cSrcweir             if (nControlWidth > POPUP_WIDTH_MAX) {
402*cdf0e10cSrcweir                 nControlWidth = POPUP_WIDTH_MAX;
403*cdf0e10cSrcweir                 frame.size.width = nControlWidth;
404*cdf0e10cSrcweir                 [pControl setFrame:frame];
405*cdf0e10cSrcweir             }
406*cdf0e10cSrcweir 
407*cdf0e10cSrcweir             //set the max size
408*cdf0e10cSrcweir             if (nPopupMaxWidth < nControlWidth) {
409*cdf0e10cSrcweir                 nPopupMaxWidth = nControlWidth;
410*cdf0e10cSrcweir             }
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir             nControlWidth += tfWidth + kAquaSpaceBetweenControls - kAquaSpaceLabelFrameBoundsDiffH - kAquaSpacePopupMenuFrameBoundsDiffLeft;
413*cdf0e10cSrcweir             if (nControlHeight < kAquaPopupButtonDefaultHeight) {
414*cdf0e10cSrcweir                 //maybe the popup has no menu item yet, so set a default height
415*cdf0e10cSrcweir                 nControlHeight = kAquaPopupButtonDefaultHeight;
416*cdf0e10cSrcweir             }
417*cdf0e10cSrcweir 
418*cdf0e10cSrcweir             nControlHeight -= kAquaSpacePopupMenuFrameBoundsDiffV;
419*cdf0e10cSrcweir         }
420*cdf0e10cSrcweir         else if ([pControl class] == [NSButton class]) {
421*cdf0e10cSrcweir             if (child != m_aActiveControls.begin()){
422*cdf0e10cSrcweir                 currentHeight += kAquaSpaceBetweenControls;
423*cdf0e10cSrcweir             }
424*cdf0e10cSrcweir 
425*cdf0e10cSrcweir             if (nCheckboxMaxWidth < nControlWidth) {
426*cdf0e10cSrcweir                 nCheckboxMaxWidth = nControlWidth;
427*cdf0e10cSrcweir             }
428*cdf0e10cSrcweir 
429*cdf0e10cSrcweir             bButtonControlPresent = YES;
430*cdf0e10cSrcweir             nControlWidth -= 2 * kAquaSpaceSwitchButtonFrameBoundsDiff;
431*cdf0e10cSrcweir             nControlHeight -= 2 * kAquaSpaceSwitchButtonFrameBoundsDiff;
432*cdf0e10cSrcweir         }
433*cdf0e10cSrcweir 
434*cdf0e10cSrcweir         // if ((nControlWidth + 2 * kAquaSpaceInsideGroupH) > currentWidth) {
435*cdf0e10cSrcweir         //     currentWidth = nControlWidth + 2 * kAquaSpaceInsideGroupH;
436*cdf0e10cSrcweir         // }
437*cdf0e10cSrcweir 
438*cdf0e10cSrcweir         currentHeight += nControlHeight;
439*cdf0e10cSrcweir 
440*cdf0e10cSrcweir         [m_pUserPane addSubview:pControl];
441*cdf0e10cSrcweir     }
442*cdf0e10cSrcweir 
443*cdf0e10cSrcweir     OSL_TRACE("height after adding all controls: %d", currentHeight);
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir     if (bPopupControlPresent && bButtonControlPresent)
446*cdf0e10cSrcweir     {
447*cdf0e10cSrcweir         //after a popup button (array) and before a different kind of control we need some extra space instead of the standard
448*cdf0e10cSrcweir         currentHeight -= kAquaSpaceBetweenControls;
449*cdf0e10cSrcweir         currentHeight += kAquaSpaceAfterPopupButtonsV;
450*cdf0e10cSrcweir         OSL_TRACE("popup extra space added, currentHeight: %d", currentHeight);
451*cdf0e10cSrcweir     }
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir     int nLongestPopupWidth = nPopupMaxWidth + nPopupLabelMaxWidth + kAquaSpaceBetweenControls - kAquaSpacePopupMenuFrameBoundsDiffLeft - kAquaSpaceLabelFrameBoundsDiffH;
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir     currentWidth = nLongestPopupWidth > nCheckboxMaxWidth ? nLongestPopupWidth : nCheckboxMaxWidth;
456*cdf0e10cSrcweir     OSL_TRACE("longest control width: %d", currentWidth);
457*cdf0e10cSrcweir 
458*cdf0e10cSrcweir     currentWidth += 2* kAquaSpaceInsideGroupH;
459*cdf0e10cSrcweir 
460*cdf0e10cSrcweir     if (currentWidth < minRect.size.width)
461*cdf0e10cSrcweir         currentWidth = minRect.size.width;
462*cdf0e10cSrcweir 
463*cdf0e10cSrcweir     if (currentHeight < minRect.size.height)
464*cdf0e10cSrcweir         currentHeight = minRect.size.height;
465*cdf0e10cSrcweir 
466*cdf0e10cSrcweir     NSRect upRect = NSMakeRect(0, 0, currentWidth, currentHeight );
467*cdf0e10cSrcweir     OSL_TRACE("setting user pane rect to {%f, %f, %f, %f}",upRect.origin.x, upRect.origin.y, upRect.size.width, upRect.size.height);
468*cdf0e10cSrcweir 
469*cdf0e10cSrcweir     [m_pUserPane setFrame:upRect];
470*cdf0e10cSrcweir 
471*cdf0e10cSrcweir     layoutControls();
472*cdf0e10cSrcweir 
473*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
474*cdf0e10cSrcweir }
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir #pragma mark Private / Misc
477*cdf0e10cSrcweir //------------------------------------------------------------------------------------
478*cdf0e10cSrcweir // Private / Misc
479*cdf0e10cSrcweir //------------------------------------------------------------------------------------
480*cdf0e10cSrcweir void ControlHelper::createControls()
481*cdf0e10cSrcweir {
482*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
483*cdf0e10cSrcweir 
484*cdf0e10cSrcweir     CResourceProvider aResProvider;
485*cdf0e10cSrcweir     for (int i = 0; i < LIST_LAST; i++) {
486*cdf0e10cSrcweir         if (true == m_bListVisibility[i]) {
487*cdf0e10cSrcweir             m_bUserPaneNeeded = true;
488*cdf0e10cSrcweir 
489*cdf0e10cSrcweir             int elementName = getControlElementName([NSPopUpButton class], i);
490*cdf0e10cSrcweir             NSString* sLabel = aResProvider.getResString(elementName);
491*cdf0e10cSrcweir 
492*cdf0e10cSrcweir             m_pListControls[i] = [NSPopUpButton new];
493*cdf0e10cSrcweir 
494*cdf0e10cSrcweir #define MAP_LIST_( elem ) \
495*cdf0e10cSrcweir  case elem: \
496*cdf0e10cSrcweir      setLabel(ExtendedFilePickerElementIds::LISTBOX_##elem, sLabel); \
497*cdf0e10cSrcweir      break
498*cdf0e10cSrcweir 
499*cdf0e10cSrcweir             switch(i) {
500*cdf0e10cSrcweir                 MAP_LIST_(VERSION);
501*cdf0e10cSrcweir                 MAP_LIST_(TEMPLATE);
502*cdf0e10cSrcweir                 MAP_LIST_(IMAGE_TEMPLATE);
503*cdf0e10cSrcweir             }
504*cdf0e10cSrcweir 
505*cdf0e10cSrcweir             m_aActiveControls.push_back(m_pListControls[i]);
506*cdf0e10cSrcweir         } else {
507*cdf0e10cSrcweir             m_pListControls[i] = nil;
508*cdf0e10cSrcweir         }
509*cdf0e10cSrcweir     }
510*cdf0e10cSrcweir 
511*cdf0e10cSrcweir     for (int i = 0/*#i102102*/; i < TOGGLE_LAST; i++) {
512*cdf0e10cSrcweir         if (true == m_bToggleVisibility[i]) {
513*cdf0e10cSrcweir             m_bUserPaneNeeded = true;
514*cdf0e10cSrcweir 
515*cdf0e10cSrcweir             int elementName = getControlElementName([NSButton class], i);
516*cdf0e10cSrcweir             NSString* sLabel = aResProvider.getResString(elementName);
517*cdf0e10cSrcweir 
518*cdf0e10cSrcweir             NSButton *button = [NSButton new];
519*cdf0e10cSrcweir             [button setTitle:sLabel];
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir             [button setButtonType:NSSwitchButton];
522*cdf0e10cSrcweir 
523*cdf0e10cSrcweir             [button setState:NSOffState];
524*cdf0e10cSrcweir 
525*cdf0e10cSrcweir             if (i == AUTOEXTENSION) {
526*cdf0e10cSrcweir                 [button setTarget:m_pDelegate];
527*cdf0e10cSrcweir                 [button setAction:@selector(autoextensionChanged:)];
528*cdf0e10cSrcweir             }
529*cdf0e10cSrcweir 
530*cdf0e10cSrcweir             m_pToggles[i] = button;
531*cdf0e10cSrcweir 
532*cdf0e10cSrcweir             m_aActiveControls.push_back(m_pToggles[i]);
533*cdf0e10cSrcweir         } else {
534*cdf0e10cSrcweir             m_pToggles[i] = nil;
535*cdf0e10cSrcweir         }
536*cdf0e10cSrcweir     }
537*cdf0e10cSrcweir 
538*cdf0e10cSrcweir     //preview is always on with Mac OS X
539*cdf0e10cSrcweir     NSControl *pPreviewBox = m_pToggles[PREVIEW];
540*cdf0e10cSrcweir     if (pPreviewBox != nil) {
541*cdf0e10cSrcweir         [pPreviewBox setEnabled:NO];
542*cdf0e10cSrcweir         [(NSButton*)pPreviewBox setState:NSOnState];
543*cdf0e10cSrcweir     }
544*cdf0e10cSrcweir 
545*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
546*cdf0e10cSrcweir }
547*cdf0e10cSrcweir 
548*cdf0e10cSrcweir #define TOGGLE_ELEMENT( elem ) \
549*cdf0e10cSrcweir case elem: \
550*cdf0e10cSrcweir     nReturn = CHECKBOX_##elem; \
551*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__, nReturn); \
552*cdf0e10cSrcweir     return nReturn
553*cdf0e10cSrcweir #define LIST_ELEMENT( elem ) \
554*cdf0e10cSrcweir case elem: \
555*cdf0e10cSrcweir     nReturn = LISTBOX_##elem##_LABEL; \
556*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__, nReturn); \
557*cdf0e10cSrcweir     return nReturn
558*cdf0e10cSrcweir 
559*cdf0e10cSrcweir int ControlHelper::getControlElementName(const Class aClazz, const int nControlId) const
560*cdf0e10cSrcweir {
561*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "aClazz", [[aClazz description] UTF8String], "controlId", nControlId);
562*cdf0e10cSrcweir 
563*cdf0e10cSrcweir     int nReturn = -1;
564*cdf0e10cSrcweir     if (aClazz == [NSButton class])
565*cdf0e10cSrcweir     {
566*cdf0e10cSrcweir         switch (nControlId) {
567*cdf0e10cSrcweir             TOGGLE_ELEMENT( AUTOEXTENSION );
568*cdf0e10cSrcweir             TOGGLE_ELEMENT( PASSWORD );
569*cdf0e10cSrcweir             TOGGLE_ELEMENT( FILTEROPTIONS );
570*cdf0e10cSrcweir             TOGGLE_ELEMENT( READONLY );
571*cdf0e10cSrcweir             TOGGLE_ELEMENT( LINK );
572*cdf0e10cSrcweir             TOGGLE_ELEMENT( PREVIEW );
573*cdf0e10cSrcweir             TOGGLE_ELEMENT( SELECTION );
574*cdf0e10cSrcweir         }
575*cdf0e10cSrcweir     }
576*cdf0e10cSrcweir     else if (aClazz == [NSPopUpButton class])
577*cdf0e10cSrcweir     {
578*cdf0e10cSrcweir         switch (nControlId) {
579*cdf0e10cSrcweir             LIST_ELEMENT( VERSION );
580*cdf0e10cSrcweir             LIST_ELEMENT( TEMPLATE );
581*cdf0e10cSrcweir             LIST_ELEMENT( IMAGE_TEMPLATE );
582*cdf0e10cSrcweir         }
583*cdf0e10cSrcweir     }
584*cdf0e10cSrcweir 
585*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__, nReturn);
586*cdf0e10cSrcweir 
587*cdf0e10cSrcweir     return nReturn;
588*cdf0e10cSrcweir }
589*cdf0e10cSrcweir 
590*cdf0e10cSrcweir void ControlHelper::HandleSetListValue(const NSControl* pControl, const sal_Int16 nControlAction, const uno::Any& rValue)
591*cdf0e10cSrcweir {
592*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "controlAction", nControlAction);
593*cdf0e10cSrcweir 
594*cdf0e10cSrcweir     if ([pControl class] != [NSPopUpButton class]) {
595*cdf0e10cSrcweir         OSL_TRACE("not a popup menu");
596*cdf0e10cSrcweir         DBG_PRINT_EXIT(CLASS_NAME, __func__);
597*cdf0e10cSrcweir         return;
598*cdf0e10cSrcweir     }
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir     NSPopUpButton *pButton = (NSPopUpButton*)pControl;
601*cdf0e10cSrcweir     NSMenu *rMenu = [pButton menu];
602*cdf0e10cSrcweir     if (nil == rMenu) {
603*cdf0e10cSrcweir         OSL_TRACE("button has no menu");
604*cdf0e10cSrcweir         DBG_PRINT_EXIT(CLASS_NAME, __func__);
605*cdf0e10cSrcweir         return;
606*cdf0e10cSrcweir     }
607*cdf0e10cSrcweir 
608*cdf0e10cSrcweir     switch (nControlAction)
609*cdf0e10cSrcweir     {
610*cdf0e10cSrcweir         case ControlActions::ADD_ITEM:
611*cdf0e10cSrcweir         {
612*cdf0e10cSrcweir             OSL_TRACE("ADD_ITEMS");
613*cdf0e10cSrcweir             OUString sItem;
614*cdf0e10cSrcweir             rValue >>= sItem;
615*cdf0e10cSrcweir 
616*cdf0e10cSrcweir             NSString* sCFItem = [NSString stringWithOUString:sItem];
617*cdf0e10cSrcweir             OSL_TRACE("Adding menu item: %s", OUStringToOString(sItem, RTL_TEXTENCODING_UTF8).getStr());
618*cdf0e10cSrcweir             [pButton addItemWithTitle:sCFItem];
619*cdf0e10cSrcweir         }
620*cdf0e10cSrcweir             break;
621*cdf0e10cSrcweir         case ControlActions::ADD_ITEMS:
622*cdf0e10cSrcweir         {
623*cdf0e10cSrcweir             OSL_TRACE("ADD_ITEMS");
624*cdf0e10cSrcweir             uno::Sequence< OUString > aStringList;
625*cdf0e10cSrcweir             rValue >>= aStringList;
626*cdf0e10cSrcweir             sal_Int32 nItemCount = aStringList.getLength();
627*cdf0e10cSrcweir             for (sal_Int32 i = 0; i < nItemCount; ++i)
628*cdf0e10cSrcweir             {
629*cdf0e10cSrcweir                 NSString* sCFItem = [NSString stringWithOUString:aStringList[i]];
630*cdf0e10cSrcweir                 OSL_TRACE("Adding menu item: %s", OUStringToOString(aStringList[i], RTL_TEXTENCODING_UTF8).getStr());
631*cdf0e10cSrcweir                 [pButton addItemWithTitle:sCFItem];
632*cdf0e10cSrcweir             }
633*cdf0e10cSrcweir         }
634*cdf0e10cSrcweir             break;
635*cdf0e10cSrcweir         case ControlActions::DELETE_ITEM:
636*cdf0e10cSrcweir         {
637*cdf0e10cSrcweir             OSL_TRACE("DELETE_ITEM");
638*cdf0e10cSrcweir             sal_Int32 nPos = -1;
639*cdf0e10cSrcweir             rValue >>= nPos;
640*cdf0e10cSrcweir             OSL_TRACE("Deleting item at position %d", (nPos));
641*cdf0e10cSrcweir             [rMenu removeItemAtIndex:nPos];
642*cdf0e10cSrcweir         }
643*cdf0e10cSrcweir             break;
644*cdf0e10cSrcweir         case ControlActions::DELETE_ITEMS:
645*cdf0e10cSrcweir         {
646*cdf0e10cSrcweir             OSL_TRACE("DELETE_ITEMS");
647*cdf0e10cSrcweir             int nItems = [rMenu numberOfItems];
648*cdf0e10cSrcweir             if (nItems == 0) {
649*cdf0e10cSrcweir                 OSL_TRACE("no menu items to delete");
650*cdf0e10cSrcweir                 DBG_PRINT_EXIT(CLASS_NAME, __func__);
651*cdf0e10cSrcweir                 return;
652*cdf0e10cSrcweir             }
653*cdf0e10cSrcweir             for(sal_Int32 i = 0; i < nItems; i++) {
654*cdf0e10cSrcweir                 [rMenu removeItemAtIndex:i];
655*cdf0e10cSrcweir             }
656*cdf0e10cSrcweir         }
657*cdf0e10cSrcweir             break;
658*cdf0e10cSrcweir         case ControlActions::SET_SELECT_ITEM:
659*cdf0e10cSrcweir         {
660*cdf0e10cSrcweir             sal_Int32 nPos = -1;
661*cdf0e10cSrcweir             rValue >>= nPos;
662*cdf0e10cSrcweir             OSL_TRACE("Selecting item at position %d", nPos);
663*cdf0e10cSrcweir             [pButton selectItemAtIndex:nPos];
664*cdf0e10cSrcweir         }
665*cdf0e10cSrcweir             break;
666*cdf0e10cSrcweir         default:
667*cdf0e10cSrcweir             OSL_TRACE("undocumented/unimplemented ControlAction for a list");
668*cdf0e10cSrcweir             break;
669*cdf0e10cSrcweir     }
670*cdf0e10cSrcweir 
671*cdf0e10cSrcweir     layoutControls();
672*cdf0e10cSrcweir 
673*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
674*cdf0e10cSrcweir }
675*cdf0e10cSrcweir 
676*cdf0e10cSrcweir 
677*cdf0e10cSrcweir uno::Any ControlHelper::HandleGetListValue(const NSControl* pControl, const sal_Int16 nControlAction) const
678*cdf0e10cSrcweir {
679*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "controlAction", nControlAction);
680*cdf0e10cSrcweir 
681*cdf0e10cSrcweir     uno::Any aAny;
682*cdf0e10cSrcweir 
683*cdf0e10cSrcweir     if ([pControl class] != [NSPopUpButton class]) {
684*cdf0e10cSrcweir         OSL_TRACE("not a popup button");
685*cdf0e10cSrcweir         DBG_PRINT_EXIT(CLASS_NAME, __func__);
686*cdf0e10cSrcweir         return aAny;
687*cdf0e10cSrcweir     }
688*cdf0e10cSrcweir 
689*cdf0e10cSrcweir     NSPopUpButton *pButton = (NSPopUpButton*)pControl;
690*cdf0e10cSrcweir     NSMenu *rMenu = [pButton menu];
691*cdf0e10cSrcweir     if (nil == rMenu) {
692*cdf0e10cSrcweir         OSL_TRACE("button has no menu");
693*cdf0e10cSrcweir         DBG_PRINT_EXIT(CLASS_NAME, __func__);
694*cdf0e10cSrcweir         return aAny;
695*cdf0e10cSrcweir     }
696*cdf0e10cSrcweir 
697*cdf0e10cSrcweir     switch (nControlAction)
698*cdf0e10cSrcweir     {
699*cdf0e10cSrcweir         case ControlActions::GET_ITEMS:
700*cdf0e10cSrcweir         {
701*cdf0e10cSrcweir             OSL_TRACE("GET_ITEMS");
702*cdf0e10cSrcweir             uno::Sequence< OUString > aItemList;
703*cdf0e10cSrcweir 
704*cdf0e10cSrcweir             int nItems = [rMenu numberOfItems];
705*cdf0e10cSrcweir             if (nItems > 0) {
706*cdf0e10cSrcweir                 aItemList.realloc(nItems);
707*cdf0e10cSrcweir             }
708*cdf0e10cSrcweir             for (int i = 0; i < nItems; i++) {
709*cdf0e10cSrcweir                 NSString* sCFItem = [pButton itemTitleAtIndex:i];
710*cdf0e10cSrcweir                 if (nil != sCFItem) {
711*cdf0e10cSrcweir                     aItemList[i] = [sCFItem OUString];
712*cdf0e10cSrcweir                     OSL_TRACE("Return value[%d]: %s", (i - 1), OUStringToOString(aItemList[i - 1], RTL_TEXTENCODING_UTF8).getStr());
713*cdf0e10cSrcweir                 }
714*cdf0e10cSrcweir             }
715*cdf0e10cSrcweir 
716*cdf0e10cSrcweir             aAny <<= aItemList;
717*cdf0e10cSrcweir         }
718*cdf0e10cSrcweir             break;
719*cdf0e10cSrcweir         case ControlActions::GET_SELECTED_ITEM:
720*cdf0e10cSrcweir         {
721*cdf0e10cSrcweir             OSL_TRACE("GET_SELECTED_ITEM");
722*cdf0e10cSrcweir             NSString* sCFItem = [pButton titleOfSelectedItem];
723*cdf0e10cSrcweir             if (nil != sCFItem) {
724*cdf0e10cSrcweir                 OUString sString = [sCFItem OUString];
725*cdf0e10cSrcweir                 OSL_TRACE("Return value: %s", OUStringToOString(sString, RTL_TEXTENCODING_UTF8).getStr());
726*cdf0e10cSrcweir                 aAny <<= sString;
727*cdf0e10cSrcweir             }
728*cdf0e10cSrcweir         }
729*cdf0e10cSrcweir             break;
730*cdf0e10cSrcweir         case ControlActions::GET_SELECTED_ITEM_INDEX:
731*cdf0e10cSrcweir         {
732*cdf0e10cSrcweir             OSL_TRACE("GET_SELECTED_ITEM_INDEX");
733*cdf0e10cSrcweir             sal_Int32 nActive = [pButton indexOfSelectedItem];
734*cdf0e10cSrcweir             OSL_TRACE("Return value: %d", nActive);
735*cdf0e10cSrcweir             aAny <<= nActive;
736*cdf0e10cSrcweir         }
737*cdf0e10cSrcweir             break;
738*cdf0e10cSrcweir         default:
739*cdf0e10cSrcweir             OSL_TRACE("undocumented/unimplemented ControlAction for a list");
740*cdf0e10cSrcweir             break;
741*cdf0e10cSrcweir     }
742*cdf0e10cSrcweir 
743*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
744*cdf0e10cSrcweir 
745*cdf0e10cSrcweir     return aAny;
746*cdf0e10cSrcweir }
747*cdf0e10cSrcweir 
748*cdf0e10cSrcweir 
749*cdf0e10cSrcweir // cf. offapi/com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.idl
750*cdf0e10cSrcweir NSControl* ControlHelper::getControl( const sal_Int16 nControlId ) const
751*cdf0e10cSrcweir {
752*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "controlId", nControlId);
753*cdf0e10cSrcweir 
754*cdf0e10cSrcweir     NSControl* pWidget = nil;
755*cdf0e10cSrcweir 
756*cdf0e10cSrcweir #define MAP_TOGGLE( elem ) \
757*cdf0e10cSrcweir case ExtendedFilePickerElementIds::CHECKBOX_##elem: \
758*cdf0e10cSrcweir     pWidget = m_pToggles[elem]; \
759*cdf0e10cSrcweir     break
760*cdf0e10cSrcweir 
761*cdf0e10cSrcweir #define MAP_BUTTON( elem ) \
762*cdf0e10cSrcweir case ExtendedFilePickerElementIds::PUSHBUTTON_##elem: \
763*cdf0e10cSrcweir     pWidget = m_pButtons[elem]; \
764*cdf0e10cSrcweir     break
765*cdf0e10cSrcweir 
766*cdf0e10cSrcweir #define MAP_LIST( elem ) \
767*cdf0e10cSrcweir case ExtendedFilePickerElementIds::LISTBOX_##elem: \
768*cdf0e10cSrcweir     pWidget = m_pListControls[elem]; \
769*cdf0e10cSrcweir     break
770*cdf0e10cSrcweir 
771*cdf0e10cSrcweir #define MAP_LIST_LABEL( elem ) \
772*cdf0e10cSrcweir case ExtendedFilePickerElementIds::LISTBOX_##elem##_LABEL: \
773*cdf0e10cSrcweir     pWidget = m_pListControls[elem]; \
774*cdf0e10cSrcweir     break
775*cdf0e10cSrcweir 
776*cdf0e10cSrcweir     switch( nControlId )
777*cdf0e10cSrcweir     {
778*cdf0e10cSrcweir             MAP_TOGGLE( AUTOEXTENSION );
779*cdf0e10cSrcweir             MAP_TOGGLE( PASSWORD );
780*cdf0e10cSrcweir             MAP_TOGGLE( FILTEROPTIONS );
781*cdf0e10cSrcweir             MAP_TOGGLE( READONLY );
782*cdf0e10cSrcweir             MAP_TOGGLE( LINK );
783*cdf0e10cSrcweir             MAP_TOGGLE( PREVIEW );
784*cdf0e10cSrcweir             MAP_TOGGLE( SELECTION );
785*cdf0e10cSrcweir             //MAP_BUTTON( PLAY );
786*cdf0e10cSrcweir             MAP_LIST( VERSION );
787*cdf0e10cSrcweir             MAP_LIST( TEMPLATE );
788*cdf0e10cSrcweir             MAP_LIST( IMAGE_TEMPLATE );
789*cdf0e10cSrcweir             MAP_LIST_LABEL( VERSION );
790*cdf0e10cSrcweir             MAP_LIST_LABEL( TEMPLATE );
791*cdf0e10cSrcweir             MAP_LIST_LABEL( IMAGE_TEMPLATE );
792*cdf0e10cSrcweir         default:
793*cdf0e10cSrcweir             OSL_TRACE("Handle unknown control %d", nControlId);
794*cdf0e10cSrcweir             break;
795*cdf0e10cSrcweir     }
796*cdf0e10cSrcweir #undef MAP
797*cdf0e10cSrcweir 
798*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
799*cdf0e10cSrcweir 
800*cdf0e10cSrcweir     return pWidget;
801*cdf0e10cSrcweir }
802*cdf0e10cSrcweir 
803*cdf0e10cSrcweir void ControlHelper::layoutControls()
804*cdf0e10cSrcweir {
805*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
806*cdf0e10cSrcweir 
807*cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
808*cdf0e10cSrcweir 
809*cdf0e10cSrcweir     if (nil == m_pUserPane) {
810*cdf0e10cSrcweir         OSL_TRACE("no user pane to layout");
811*cdf0e10cSrcweir         DBG_PRINT_EXIT(CLASS_NAME, __func__);
812*cdf0e10cSrcweir         return;
813*cdf0e10cSrcweir     }
814*cdf0e10cSrcweir 
815*cdf0e10cSrcweir     if (m_bIsUserPaneLaidOut == true) {
816*cdf0e10cSrcweir         OSL_TRACE("user pane already laid out");
817*cdf0e10cSrcweir         DBG_PRINT_EXIT(CLASS_NAME, __func__);
818*cdf0e10cSrcweir         return;
819*cdf0e10cSrcweir     }
820*cdf0e10cSrcweir 
821*cdf0e10cSrcweir     NSRect userPaneRect = [m_pUserPane frame];
822*cdf0e10cSrcweir     OSL_TRACE("userPane frame: {%f, %f, %f, %f}",userPaneRect.origin.x, userPaneRect.origin.y, userPaneRect.size.width, userPaneRect.size.height);
823*cdf0e10cSrcweir 
824*cdf0e10cSrcweir     int nUsableWidth = userPaneRect.size.width;
825*cdf0e10cSrcweir 
826*cdf0e10cSrcweir     //NOTE: NSView's coordinate system starts in the lower left hand corner but we start adding controls from the top,
827*cdf0e10cSrcweir     // so we subtract from the vertical position as we make our way down the pane.
828*cdf0e10cSrcweir     int currenttop = userPaneRect.size.height;
829*cdf0e10cSrcweir     int nCheckboxMaxWidth = 0;
830*cdf0e10cSrcweir     int nPopupMaxWidth = 0;
831*cdf0e10cSrcweir     int nPopupLabelMaxWidth = 0;
832*cdf0e10cSrcweir 
833*cdf0e10cSrcweir     //first loop to determine max sizes
834*cdf0e10cSrcweir     for (::std::list<NSControl*>::iterator child = m_aActiveControls.begin(); child != m_aActiveControls.end(); child++) {
835*cdf0e10cSrcweir         NSControl* pControl = *child;
836*cdf0e10cSrcweir 
837*cdf0e10cSrcweir         NSRect controlRect = [pControl frame];
838*cdf0e10cSrcweir         int nControlWidth = controlRect.size.width;
839*cdf0e10cSrcweir 
840*cdf0e10cSrcweir         Class aSubType = [pControl class];
841*cdf0e10cSrcweir         if (aSubType == [NSPopUpButton class]) {
842*cdf0e10cSrcweir             if (nPopupMaxWidth < nControlWidth) {
843*cdf0e10cSrcweir                 nPopupMaxWidth = nControlWidth;
844*cdf0e10cSrcweir             }
845*cdf0e10cSrcweir             NSTextField *label = m_aMapListLabelFields[(NSPopUpButton*)pControl];
846*cdf0e10cSrcweir             NSRect labelFrame = [label frame];
847*cdf0e10cSrcweir             int nLabelWidth = labelFrame.size.width;
848*cdf0e10cSrcweir             if (nPopupLabelMaxWidth < nLabelWidth) {
849*cdf0e10cSrcweir                 nPopupLabelMaxWidth = nLabelWidth;
850*cdf0e10cSrcweir             }
851*cdf0e10cSrcweir         } else {
852*cdf0e10cSrcweir             if (nCheckboxMaxWidth < nControlWidth) {
853*cdf0e10cSrcweir                 nCheckboxMaxWidth = nControlWidth;
854*cdf0e10cSrcweir             }
855*cdf0e10cSrcweir         }
856*cdf0e10cSrcweir     }
857*cdf0e10cSrcweir 
858*cdf0e10cSrcweir     int nLongestPopupWidth = nPopupMaxWidth + nPopupLabelMaxWidth + kAquaSpaceBetweenControls - kAquaSpacePopupMenuFrameBoundsDiffLeft - kAquaSpaceLabelFrameBoundsDiffH;
859*cdf0e10cSrcweir     OSL_TRACE("longest popup width: %d", nLongestPopupWidth);
860*cdf0e10cSrcweir 
861*cdf0e10cSrcweir     NSControl* previousControl = nil;
862*cdf0e10cSrcweir 
863*cdf0e10cSrcweir     int nDistBetweenControls = 0;
864*cdf0e10cSrcweir 
865*cdf0e10cSrcweir     for (::std::list<NSControl*>::iterator child = m_aActiveControls.begin(); child != m_aActiveControls.end(); child++) {
866*cdf0e10cSrcweir         NSControl* pControl = *child;
867*cdf0e10cSrcweir 
868*cdf0e10cSrcweir         //get the control's bounds
869*cdf0e10cSrcweir         NSRect controlRect = [pControl frame];
870*cdf0e10cSrcweir         int nControlHeight = controlRect.size.height;
871*cdf0e10cSrcweir         int nControlWidth = controlRect.size.width;
872*cdf0e10cSrcweir 
873*cdf0e10cSrcweir         //subtract the height from the current vertical position, because the control's bounds origin rect will be its lower left hand corner
874*cdf0e10cSrcweir         currenttop -= nControlHeight;
875*cdf0e10cSrcweir 
876*cdf0e10cSrcweir         Class aSubType = [pControl class];
877*cdf0e10cSrcweir 
878*cdf0e10cSrcweir         //add space between the previous control and this control according to Apple's HIG
879*cdf0e10cSrcweir         nDistBetweenControls = getVerticalDistance(previousControl, pControl);
880*cdf0e10cSrcweir         OSL_TRACE("vertical distance: %d", nDistBetweenControls);
881*cdf0e10cSrcweir         currenttop -= nDistBetweenControls;
882*cdf0e10cSrcweir 
883*cdf0e10cSrcweir         previousControl = pControl;
884*cdf0e10cSrcweir 
885*cdf0e10cSrcweir         if (aSubType == [NSPopUpButton class]) {
886*cdf0e10cSrcweir             //move vertically up some pixels to space the controls between their real (visual) bounds
887*cdf0e10cSrcweir             currenttop += kAquaSpacePopupMenuFrameBoundsDiffTop;//from top
888*cdf0e10cSrcweir 
889*cdf0e10cSrcweir             //get the corresponding popup label
890*cdf0e10cSrcweir             NSTextField *label = m_aMapListLabelFields[(NSPopUpButton*)pControl];
891*cdf0e10cSrcweir             NSRect labelFrame = [label frame];
892*cdf0e10cSrcweir             int totalWidth = nPopupMaxWidth + labelFrame.size.width + kAquaSpaceBetweenControls - kAquaSpacePopupMenuFrameBoundsDiffLeft - kAquaSpaceLabelFrameBoundsDiffH;
893*cdf0e10cSrcweir             OSL_TRACE("totalWidth: %d", totalWidth);
894*cdf0e10cSrcweir             //let's center popups
895*cdf0e10cSrcweir             int left = (nUsableWidth + nLongestPopupWidth) / 2 - totalWidth;
896*cdf0e10cSrcweir             OSL_TRACE("left: %d", left);
897*cdf0e10cSrcweir             labelFrame.origin.x = left;
898*cdf0e10cSrcweir             labelFrame.origin.y = currenttop + kAquaSpaceLabelPopupDiffV;
899*cdf0e10cSrcweir             OSL_TRACE("setting label at: {%f, %f, %f, %f}",labelFrame.origin.x, labelFrame.origin.y, labelFrame.size.width, labelFrame.size.height);
900*cdf0e10cSrcweir             [label setFrame:labelFrame];
901*cdf0e10cSrcweir 
902*cdf0e10cSrcweir             controlRect.origin.x = left + labelFrame.size.width + kAquaSpaceBetweenControls - kAquaSpaceLabelFrameBoundsDiffH - kAquaSpacePopupMenuFrameBoundsDiffLeft;
903*cdf0e10cSrcweir             controlRect.origin.y = currenttop;
904*cdf0e10cSrcweir             controlRect.size.width = nPopupMaxWidth;
905*cdf0e10cSrcweir             OSL_TRACE("setting popup at: {%f, %f, %f, %f}",controlRect.origin.x, controlRect.origin.y, controlRect.size.width, controlRect.size.height);
906*cdf0e10cSrcweir             [pControl setFrame:controlRect];
907*cdf0e10cSrcweir 
908*cdf0e10cSrcweir             //add some space to place the vertical position right below the popup's visual bounds
909*cdf0e10cSrcweir             currenttop += kAquaSpacePopupMenuFrameBoundsDiffBottom;
910*cdf0e10cSrcweir         } else {
911*cdf0e10cSrcweir             currenttop += kAquaSpaceSwitchButtonFrameBoundsDiff;//from top
912*cdf0e10cSrcweir 
913*cdf0e10cSrcweir             nControlWidth = nCheckboxMaxWidth;
914*cdf0e10cSrcweir             int left = (nUsableWidth - nCheckboxMaxWidth) / 2;
915*cdf0e10cSrcweir             controlRect.origin.x = left;
916*cdf0e10cSrcweir             controlRect.origin.y = currenttop;
917*cdf0e10cSrcweir             controlRect.size.width = nPopupMaxWidth;
918*cdf0e10cSrcweir             [pControl setFrame:controlRect];
919*cdf0e10cSrcweir             OSL_TRACE("setting checkbox at: {%f, %f, %f, %f}",controlRect.origin.x, controlRect.origin.y, controlRect.size.width, controlRect.size.height);
920*cdf0e10cSrcweir 
921*cdf0e10cSrcweir             currenttop += kAquaSpaceSwitchButtonFrameBoundsDiff;
922*cdf0e10cSrcweir         }
923*cdf0e10cSrcweir     }
924*cdf0e10cSrcweir 
925*cdf0e10cSrcweir     m_bIsUserPaneLaidOut = true;
926*cdf0e10cSrcweir 
927*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
928*cdf0e10cSrcweir }
929*cdf0e10cSrcweir 
930*cdf0e10cSrcweir void ControlHelper::createFilterControl() {
931*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
932*cdf0e10cSrcweir 
933*cdf0e10cSrcweir     CResourceProvider aResProvider;
934*cdf0e10cSrcweir     NSString* sLabel = aResProvider.getResString(CommonFilePickerElementIds::LISTBOX_FILTER_LABEL);
935*cdf0e10cSrcweir 
936*cdf0e10cSrcweir     m_pFilterControl = [NSPopUpButton new];
937*cdf0e10cSrcweir 
938*cdf0e10cSrcweir     [m_pFilterControl setAction:@selector(filterSelectedAtIndex:)];
939*cdf0e10cSrcweir     [m_pFilterControl setTarget:m_pDelegate];
940*cdf0e10cSrcweir 
941*cdf0e10cSrcweir     NSMenu *menu = [m_pFilterControl menu];
942*cdf0e10cSrcweir 
943*cdf0e10cSrcweir     for (NSStringList::iterator iter = m_pFilterHelper->getFilterNames()->begin(); iter != m_pFilterHelper->getFilterNames()->end(); iter++) {
944*cdf0e10cSrcweir         NSString *filterName = *iter;
945*cdf0e10cSrcweir         OSL_TRACE("adding filter name: %s", [filterName UTF8String]);
946*cdf0e10cSrcweir         if ([filterName isEqualToString:@"-"]) {
947*cdf0e10cSrcweir             [menu addItem:[NSMenuItem separatorItem]];
948*cdf0e10cSrcweir         }
949*cdf0e10cSrcweir         else {
950*cdf0e10cSrcweir             [m_pFilterControl addItemWithTitle:filterName];
951*cdf0e10cSrcweir         }
952*cdf0e10cSrcweir     }
953*cdf0e10cSrcweir 
954*cdf0e10cSrcweir     // always add the filter as first item
955*cdf0e10cSrcweir     m_aActiveControls.push_front(m_pFilterControl);
956*cdf0e10cSrcweir     m_aMapListLabels[m_pFilterControl] = [sLabel retain];
957*cdf0e10cSrcweir 
958*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
959*cdf0e10cSrcweir }
960*cdf0e10cSrcweir 
961*cdf0e10cSrcweir NSTextField* ControlHelper::createLabelWithString(const NSString* labelString) {
962*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "label", labelString);
963*cdf0e10cSrcweir 
964*cdf0e10cSrcweir     NSTextField *textField = [NSTextField new];
965*cdf0e10cSrcweir     [textField setEditable:NO];
966*cdf0e10cSrcweir     [textField setSelectable:NO];
967*cdf0e10cSrcweir     [textField setDrawsBackground:NO];
968*cdf0e10cSrcweir     [textField setBordered:NO];
969*cdf0e10cSrcweir     [[textField cell] setTitle:labelString];
970*cdf0e10cSrcweir 
971*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
972*cdf0e10cSrcweir     return textField;
973*cdf0e10cSrcweir }
974*cdf0e10cSrcweir 
975*cdf0e10cSrcweir int ControlHelper::getVerticalDistance(const NSControl* first, const NSControl* second)
976*cdf0e10cSrcweir {
977*cdf0e10cSrcweir     if (first == nil) {
978*cdf0e10cSrcweir         return kAquaSpaceBoxFrameViewDiffTop;
979*cdf0e10cSrcweir     }
980*cdf0e10cSrcweir     else if (second == nil) {
981*cdf0e10cSrcweir         return kAquaSpaceBoxFrameViewDiffBottom;
982*cdf0e10cSrcweir     }
983*cdf0e10cSrcweir     else {
984*cdf0e10cSrcweir         Class firstClass = [first class];
985*cdf0e10cSrcweir         Class secondClass = [second class];
986*cdf0e10cSrcweir 
987*cdf0e10cSrcweir         if (firstClass == [NSPopUpButton class]) {
988*cdf0e10cSrcweir             if (secondClass == [NSPopUpButton class]) {
989*cdf0e10cSrcweir                 return kAquaSpaceBetweenPopupMenus;
990*cdf0e10cSrcweir             }
991*cdf0e10cSrcweir             else {
992*cdf0e10cSrcweir                 return kAquaSpaceAfterPopupButtonsV;
993*cdf0e10cSrcweir             }
994*cdf0e10cSrcweir         }
995*cdf0e10cSrcweir 
996*cdf0e10cSrcweir         return kAquaSpaceBetweenControls;
997*cdf0e10cSrcweir     }
998*cdf0e10cSrcweir }
999*cdf0e10cSrcweir 
1000*cdf0e10cSrcweir void ControlHelper::updateFilterUI()
1001*cdf0e10cSrcweir {
1002*cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
1003*cdf0e10cSrcweir 
1004*cdf0e10cSrcweir     if (m_bIsFilterControlNeeded == false || m_pFilterHelper == NULL) {
1005*cdf0e10cSrcweir         OSL_TRACE("no filter control needed or no filter helper present");
1006*cdf0e10cSrcweir         DBG_PRINT_EXIT(CLASS_NAME, __func__);
1007*cdf0e10cSrcweir         return;
1008*cdf0e10cSrcweir     }
1009*cdf0e10cSrcweir 
1010*cdf0e10cSrcweir     int index = m_pFilterHelper->getCurrentFilterIndex();
1011*cdf0e10cSrcweir 
1012*cdf0e10cSrcweir     if (m_pFilterControl == nil) {
1013*cdf0e10cSrcweir         createFilterControl();
1014*cdf0e10cSrcweir     }
1015*cdf0e10cSrcweir 
1016*cdf0e10cSrcweir     [m_pFilterControl selectItemAtIndex:index];
1017*cdf0e10cSrcweir 
1018*cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
1019*cdf0e10cSrcweir }
1020