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