1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: propctrl.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
35 #ifndef _USR_INTROSP_HXX
36 #include <usr/inspect.hxx>
38 #ifndef _USR_SERINFO_HXX
39 #include <usr/serinfo.hxx>
41 #ifndef _USR_INTROSP_HXX
42 #include <usr/introsp.hxx>
45 #include <propctrl.hxx>
46 #include <property.hxx>
49 // Controller-Implementation
50 class PropertyEditorControler_Impl
: public SvPropertyDataControl
52 XIntrospectionAccessRef mxUnoAccess
;
53 PropertySequence mPropSeq
;
54 XPropertyEditorRef mxEditor
;
55 SvPropertyBox
* mpPropBox
;
59 // Provisorisch direkt Window mitgeben
60 PropertyEditorControler_Impl( SvPropertyBox
* pPropBox_
);
61 //SimplePropertyEditor_Impl( void );
63 // Objekt zum Editieren setzen, dies loest das Eintragen
64 // der Properties in die PropertyBox aus
65 void setObject( XPropertyEditorRef xEditor_
, const UsrAny
& aToEditObj
,
66 /* HACK fuer History-Interface*/String aPath
, BOOL bBack
=FALSE
, BOOL bForward
=FALSE
);
69 SMART_UNO_DECLARATION(ImplIntrospection,UsrObject);
71 // Methoden von XInterface
72 XInterface * queryInterface( Uik aUik );
73 XIdlClassRef getIdlClass();
76 // Methoden von SvPropertyDataControl
77 virtual void Modified( const String
& aName
,
81 virtual void Clicked( const String
& aName
,
85 virtual void Commit( const String
& aName
,
89 virtual void Select( const String
& aName
,
92 virtual void LinkClicked(const String
& aName
,
95 // TODO: Das muss raus, sehr unglueckliche Schnittstelle
96 // PropertyBox erzwingt Zustand des Controllers
97 virtual String
GetTheCorrectProperty() const;
100 // Methoden von XPropertyEditor
101 PropertyEditorControler_Impl::PropertyEditorControler_Impl( SvPropertyBox
* pPropBox_
)
103 mpPropBox
= pPropBox_
;
106 void PropertyEditorControler_Impl::setObject( XPropertyEditorRef xEditor_
, const UsrAny
& aToEditObj
,
107 /* HACK fuer History-Interface*/ String aPath
, BOOL bBack
, BOOL bForward
)
109 static XIntrospectionRef xIntrospection
;
111 // Ohne Fenster laeuft gar nix
115 // Fenster aufraeumen
116 mpPropBox
->ClearAll();
118 // Editor und Objekt übernehmen
120 maUnoObj
= aToEditObj
;
122 if( !xIntrospection
.is() )
124 // Introspection-Service holen
125 XServiceManagerRef xServiceManager
= getGlobalServiceManager();
126 XServiceProviderRef xProv
= xServiceManager
->getServiceProvider
127 ( "com.sun.star.beans.Introspection", UikSequence(), UikSequence() );
128 xIntrospection
= (XIntrospection
*)xProv
->newInstance()
129 ->queryInterface( XIntrospection::getSmartUik() );
131 if( !xIntrospection
.is() )
135 mxUnoAccess
= xIntrospection
->inspect( maUnoObj
);
136 if( !mxUnoAccess
.Is() )
139 // Uns als Controler anmelden
140 mpPropBox
->SetController( this );
142 // Properties anlegen
143 mPropSeq
= mxUnoAccess
->getProperties();
144 UINT32 nPropCount
= mPropSeq
.getLen();
145 const Property
* pProps
= mPropSeq
.getConstArray();
148 USHORT nPropPageId
= mpPropBox
->AppendPage("Properties");
150 // Beim Eintragen solls nicht flimmern
151 mpPropBox
->DisableUpdate();
153 // Dummy-Properties fuer Path und Navigation
154 SvPropertyData aProperty
;
157 // Interface und Structs werden Hyperlinks
158 aProperty
.bIsHyperLink
= FALSE
;
159 aProperty
.bIsLocked
= TRUE
;
160 aProperty
.bHasVisibleXButton
= FALSE
;
161 aProperty
.eKind
= KOC_EDIT
;
162 aProperty
.pControl
= NULL
;
163 aProperty
.pDataPtr
= NULL
;
164 aProperty
.aName
= "Path";
165 aProperty
.aValue
= aPath
;
166 mpPropBox
->InsertEntry( aProperty
);
168 if( bBack
|| bForward
)
170 // Interface und Structs werden Hyperlinks
171 aProperty
.bIsHyperLink
= TRUE
;
172 aProperty
.bIsLocked
= TRUE
;
173 // HACK, solange Hyperlink nicht funktioniert
174 aProperty
.bHasVisibleXButton
= aProperty
.bIsHyperLink
;
175 aProperty
.eKind
= KOC_EDIT
;
177 aProperty
.pControl
= NULL
;
181 aProperty
.pDataPtr
= (void*)iHandle
;
182 aProperty
.aName
= "<-";
183 aProperty
.aValue
= "Back";
184 mpPropBox
->InsertEntry( aProperty
);
189 aProperty
.pDataPtr
= (void*)iHandle
;
190 aProperty
.aName
= "->";
191 aProperty
.aValue
= "Forward";
192 mpPropBox
->InsertEntry( aProperty
);
196 // Properties eintragen
197 // TODO: Wo kommen die Strings her
199 for( i
= 0 ; i
< nPropCount
; i
++ )
201 const Property
& rProp
= pProps
[ i
];
203 // TypeClass des Property ermitteln
204 XIdlClassRef xPropClass
= rProp
.Type
;
205 if( !xPropClass
.is() )
207 DBG_ERROR( "PropertyEditorControler_Impl::Commit(), Property without type" )
210 TypeClass eType
= xPropClass
->getTypeClass();
212 // Interface und Structs werden Hyperlinks
213 aProperty
.bIsHyperLink
= ( eType
== TYPECLASS_INTERFACE
|| eType
== TYPECLASS_STRUCT
);
214 aProperty
.bIsLocked
= ((rProp
.Attributes
& PROPERTY_READONLY
) != 0 );
216 // HACK, solange Hyperlink nicht funktioniert
217 aProperty
.bHasVisibleXButton
= aProperty
.bIsHyperLink
;
219 // Wert holen und in String wandeln
220 UsrAny aVal
= mxUnoAccess
->getPropertyValueByIndex( maUnoObj
, i
);
221 String aStrVal
= AnyToString( aVal
);
223 // Properties reinbraten
224 aProperty
.eKind
= KOC_EDIT
;
225 aProperty
.aName
= rProp
.Name
;
226 aProperty
.aValue
= aStrVal
;
227 aProperty
.pDataPtr
= (void*)i
;
228 aProperty
.pControl
= NULL
;
229 //aProperty.theValues.Insert(new String("1"),aProperty.theValues.Count());
230 //aProperty.theValues.Insert(new String("2"),aProperty.theValues.Count());
231 //aProperty.theValues.Insert(new String("3"),aProperty.theValues.Count());
232 //aProperty.theValues.Insert(new String("4"),aProperty.theValues.Count());
233 mpPropBox
->InsertEntry( aProperty
);
236 // 2. Seite fuer Listener
237 // TODO: Wo kommen die Eintraege her
238 USHORT nListenerPageId
= mpPropBox
->AppendPage("Listener");
240 XIdlClassSequence aSupportedListenerSeq
= mxUnoAccess
->getSupportedListeners();
241 const XIdlClassRef
* pListenerArray
= aSupportedListenerSeq
.getConstArray();
242 UINT32 nIfaceCount
= aSupportedListenerSeq
.getLen();
244 // Property-Data vorfuellen
245 aProperty
.eKind
= KOC_EDIT
;
246 //aProperty.eKind = KOC_UNDEFINED;
247 aProperty
.aValue
= "Listener-Value";
248 aProperty
.bHasVisibleXButton
= TRUE
;
250 //aProperty.bIsHyperLink = TRUE;
251 aProperty
.bIsHyperLink
= FALSE
;
252 aProperty
.bIsLocked
= TRUE
;
253 //aProperty.bIsLocked = FALSE;
254 aProperty
.pDataPtr
= NULL
;
255 aProperty
.pControl
= NULL
;
257 for( UINT32 j
= 0 ; j
< nIfaceCount
; j
++ )
259 const XIdlClassRef
& rxIfaceClass
= pListenerArray
[j
];
260 aProperty
.aName
= rxIfaceClass
->getName();
261 mpPropBox
->InsertEntry( aProperty
);
263 mpPropBox
->EnableUpdate();
264 mpPropBox
->SetPage( nPropPageId
);
267 void PropertyEditorControler_Impl::Modified
268 ( const String
& aName
, const String
& aVal
, void* pData
)
272 void PropertyEditorControler_Impl::Clicked
273 ( const String
& aName
, const String
& aVal
, void* pData
)
275 // HACK, solange LinkClicked nicht funktioniert
276 UINT32 iPos
= (UINT32
)pData
;
277 UINT32 nPropCount
= mPropSeq
.getLen();
278 if( iPos
>= nPropCount
)
280 // Spezial-IDs fuer forward/back?
281 BOOL bForward
= (iPos
== 1000000);
282 BOOL bBack
= (iPos
== 1000001);
283 if( bForward
|| bBack
)
285 // Unterstuetzt der PropertyEditor das?
286 XPropertyEditorNavigationRef xPropEdNav
= (XPropertyEditorNavigation
*)
287 mxEditor
->queryInterface( XPropertyEditorNavigation::getSmartUik() );
288 if( xPropEdNav
.is() )
291 xPropEdNav
->forward();
299 const Property
* pProps
= mPropSeq
.getConstArray();
300 const Property
& rProp
= pProps
[ iPos
];
301 XIdlClassRef xPropClass
= rProp
.Type
;
302 if( !xPropClass
.is() )
304 DBG_ERROR( "PropertyEditorControler_Impl::Commit(), Property without type" )
307 TypeClass eType
= xPropClass
->getTypeClass();
308 if( eType
== TYPECLASS_INTERFACE
|| eType
== TYPECLASS_STRUCT
)
309 LinkClicked( aName
, pData
);
312 void PropertyEditorControler_Impl::Commit
313 ( const String
& aName
, const String
& aVal
, void* pData
)
315 UINT32 iPos
= (UINT32
)pData
;
316 UINT32 nPropCount
= mPropSeq
.getLen();
317 if( iPos
>= nPropCount
)
320 // String in Property-Typ wandeln
321 const Property
* pProps
= mPropSeq
.getConstArray();
322 const Property
& rProp
= pProps
[ iPos
];
323 XIdlClassRef xPropClass
= rProp
.Type
;
324 if( !xPropClass
.is() )
326 DBG_ERROR( "PropertyEditorControler_Impl::Commit(), Property without type" )
329 TypeClass eType
= xPropClass
->getTypeClass();
330 UsrAny aValue
= StringToAny( aVal
, eType
);
333 mxUnoAccess
->setPropertyValueByIndex( maUnoObj
, iPos
, aValue
);
335 // Wert neu holen und ggf. neu setzen
336 UsrAny aNewVal
= mxUnoAccess
->getPropertyValueByIndex( maUnoObj
, iPos
);
337 String aNewStrVal
= AnyToString( aNewVal
);
338 if( aNewStrVal
!= aVal
)
339 mpPropBox
->SetPropertyValue( aName
, aNewStrVal
);
342 void PropertyEditorControler_Impl::Select
343 ( const String
& aName
, void* pData
)
347 void PropertyEditorControler_Impl::LinkClicked(const String
& aName
, void* pData
)
349 UINT32 iPos
= (UINT32
)pData
;
350 UINT32 nPropCount
= mPropSeq
.getLen();
351 if( iPos
>= nPropCount
)
354 // Wert holen und an Master-Controller zurueckgeben
355 UsrAny aNewObj
= mxUnoAccess
->getPropertyValueByIndex( maUnoObj
, iPos
);
356 mxEditor
->setObject( aNewObj
, aName
);
360 // TODO: Das muss raus, sehr unglueckliche Schnittstelle
361 // PropertyBox erzwingt Zustand des Controllers
362 String
PropertyEditorControler_Impl::GetTheCorrectProperty() const
368 SMART_UNO_IMPLEMENTATION(SimplePropertyEditor_Impl
,UsrObject
);
370 // Methoden von XInterface
371 XInterface
* SimplePropertyEditor_Impl::queryInterface( Uik aUik
)
373 if( aUik
== XPropertyEditor::getSmartUik() )
374 return (XPropertyEditor
*)this;
375 if( aUik
== XPropertyEditorNavigation::getSmartUik() )
376 return (XPropertyEditorNavigation
*)this;
377 return UsrObject::queryInterface( aUik
);
380 XIdlClassRef
SimplePropertyEditor_Impl::getIdlClass()
382 // TODO: Unterstuetzen
387 // Methoden von SimplePropertyEditor_Impl
388 SimplePropertyEditor_Impl::SimplePropertyEditor_Impl( Window
*pParent
)
389 : maHistorySeq( 10 ), maHistoryNames( 10 ), bSimpleHistory( FALSE
)
391 //XVCLComponent xC = pParent->getVCLComponent
392 //xC->addVCLComponentListener( MyListener )
394 pActiveControler
= NULL
;
395 mpPropBox
= new SvPropertyBox( pParent
);
398 long cxOut
= pParent
->GetOutputSizePixel().Width();
399 long cyOut
= pParent
->GetOutputSizePixel().Height();
400 Size
aSize( cxOut
, cyOut
);
401 mpPropBox
->SetPosSizePixel( Point( 0, 0 ), aSize
);
404 mnActualHistoryLevel
= -1;
407 SimplePropertyEditor_Impl::~SimplePropertyEditor_Impl()
410 if( pActiveControler
)
411 delete pActiveControler
;
414 // Private Methode zum Anlegen/Aktivieren der Controller
415 void SimplePropertyEditor_Impl::showObject( const UsrAny
& aToShowObj
)
417 if( pActiveControler
)
418 delete pActiveControler
;
420 // Neuen Controller auf der Wiese anlegen (TODO: Controller cachen?)
421 pActiveControler
= new PropertyEditorControler_Impl( mpPropBox
);
423 XPropertyEditorRef xThis
= (XPropertyEditor
*)this;
424 pActiveControler
->setObject( xThis
, aToShowObj
,
425 /*aPath*/bSimpleHistory
? getPath() : String(),
426 /*bBack*/bSimpleHistory
&& mnActualHistoryLevel
> 0,
427 /*bForward*/bSimpleHistory
&& (INT32
)mnHistoryCount
> mnActualHistoryLevel
);
430 String
SimplePropertyEditor_Impl::getPath( void )
433 const String
* pStr
= maHistoryNames
.getConstArray();
434 for( INT32 i
= 0 ; i
<= mnActualHistoryLevel
; i
++ )
436 String aName
= pStr
[i
];
438 // Root speziell behandeln
446 long l
= (long)aName
;
448 if( aNumStr
== aName
)
464 // Methoden von XPropertyEditor
465 void SimplePropertyEditor_Impl::setObject( const UsrAny
& aToEditObj
, const XubString
& aObjName
)
468 mnActualHistoryLevel
++;
469 mnHistoryCount
= (UINT32
)mnActualHistoryLevel
;
470 UINT32 iHistorySize
= maHistorySeq
.getLen();
471 if( mnHistoryCount
> iHistorySize
)
473 maHistorySeq
.realloc( iHistorySize
+ 10 );
474 maHistoryNames
.realloc( iHistorySize
+ 10 );
477 // Neues Object eintragen
478 maHistorySeq
.getArray()[ mnHistoryCount
] = aToEditObj
;
479 maHistoryNames
.getArray()[ mnHistoryCount
] = aObjName
;
482 showObject( aToEditObj
);
485 // Methoden von PropertyEditorNavigation
486 void SimplePropertyEditor_Impl::forward(void)
488 if( (INT32
)mnHistoryCount
> mnActualHistoryLevel
)
490 // Naechstes Object darstellen
491 mnActualHistoryLevel
++;
492 showObject( maHistorySeq
.getConstArray()[mnActualHistoryLevel
] );
496 void SimplePropertyEditor_Impl::back(void)
498 if( mnActualHistoryLevel
> 0 )
500 // Voriges Object darstellen
501 mnActualHistoryLevel
--;
502 showObject( maHistorySeq
.getConstArray()[mnActualHistoryLevel
] );