xref: /aoo41x/main/toolkit/workben/layout/editor.cxx (revision cdf0e10c)
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 "editor.hxx"
29*cdf0e10cSrcweir 
30*cdf0e10cSrcweir #undef NDEBUG
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir /*
33*cdf0e10cSrcweir #include <stdio.h>
34*cdf0e10cSrcweir #include <string.h>
35*cdf0e10cSrcweir */
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir #include <cassert>
38*cdf0e10cSrcweir #include <cstdio>
39*cdf0e10cSrcweir #include <cstring>
40*cdf0e10cSrcweir #include <list>
41*cdf0e10cSrcweir #include <vector>
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir #include <com/sun/star/awt/WindowAttribute.hpp>
44*cdf0e10cSrcweir #include <com/sun/star/awt/XLayoutConstrains.hpp>
45*cdf0e10cSrcweir #include <com/sun/star/awt/XLayoutContainer.hpp>
46*cdf0e10cSrcweir #include <com/sun/star/awt/XToolkit.hpp>
47*cdf0e10cSrcweir #include <com/sun/star/awt/XVclWindowPeer.hpp>
48*cdf0e10cSrcweir #include <com/sun/star/awt/XWindow.hpp>
49*cdf0e10cSrcweir #include <com/sun/star/awt/XWindowPeer.hpp>
50*cdf0e10cSrcweir #include <rtl/strbuf.hxx>
51*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
52*cdf0e10cSrcweir #include <toolkit/helper/property.hxx>
53*cdf0e10cSrcweir #include <vcl/lstbox.h>
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir using namespace layout::css;
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir using rtl::OUString;
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir // FIXME:
60*cdf0e10cSrcweir //#define FILEDLG
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir #include <layout/core/helper.hxx>
63*cdf0e10cSrcweir #include <layout/core/root.hxx>
64*cdf0e10cSrcweir #include <layout/core/helper.hxx>
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir // TODO: automatically generated
67*cdf0e10cSrcweir struct WidgetSpec {
68*cdf0e10cSrcweir     const char *pLabel, *pName, *pIconName;
69*cdf0e10cSrcweir     bool bIsContainer; };
70*cdf0e10cSrcweir static const WidgetSpec WIDGETS_SPECS[] = {
71*cdf0e10cSrcweir     { "Label",         "fixedtext"   , "sc_label.png",        false },
72*cdf0e10cSrcweir     { "Button",        "pushbutton"  , "sc_pushbutton.png",   false },
73*cdf0e10cSrcweir     { "Radio Button",  "radiobutton" , "sc_radiobutton.png",  false },
74*cdf0e10cSrcweir     { "Check Box",     "checkbox"    , "sc_checkbox.png",     false },
75*cdf0e10cSrcweir     { "Line Edit",     "edit"        , "sc_edit.png",         false },
76*cdf0e10cSrcweir     { "Numeric Field", "numericfield", "sc_numericfield.png", false },
77*cdf0e10cSrcweir     { "List Box                  ", "listbox"     , NULL,                  false },
78*cdf0e10cSrcweir     // containers
79*cdf0e10cSrcweir     { "Hor Box",       "hbox"        , NULL,                  true  },
80*cdf0e10cSrcweir     { "Ver Box",       "vbox"        , NULL,                  true  },
81*cdf0e10cSrcweir     { "Table",         "table"       , NULL,                  true  },
82*cdf0e10cSrcweir     { "Alignment",     "align"       , NULL,                  true  },
83*cdf0e10cSrcweir     { "Tab Control",   "tabcontrol"  , NULL,                  true  },
84*cdf0e10cSrcweir     { "Hor Splitter",  "hsplitter"   , NULL,                  true  },
85*cdf0e10cSrcweir     { "Ver Splitter",  "vsplitter"   , NULL,                  true  },
86*cdf0e10cSrcweir     { "Scroller",      "scroller"    , NULL,                  true  },
87*cdf0e10cSrcweir };
88*cdf0e10cSrcweir const int WIDGETS_SPECS_LEN = sizeof (WIDGETS_SPECS) / sizeof (WidgetSpec);
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir using namespace layout;
91*cdf0e10cSrcweir using namespace layoutimpl;
92*cdf0e10cSrcweir namespace css = ::com::sun::star;
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir static rtl::OUString anyToString (uno::Any value)
95*cdf0e10cSrcweir {
96*cdf0e10cSrcweir     try
97*cdf0e10cSrcweir     {
98*cdf0e10cSrcweir         switch (value.getValueTypeClass()) {
99*cdf0e10cSrcweir             case uno::TypeClass_STRING:
100*cdf0e10cSrcweir                 return value.get<rtl::OUString>();
101*cdf0e10cSrcweir             case uno::TypeClass_CONSTANT:
102*cdf0e10cSrcweir                 return rtl::OUString::valueOf (value.get<sal_Int32>());
103*cdf0e10cSrcweir             case uno::TypeClass_LONG:
104*cdf0e10cSrcweir                 return rtl::OUString::valueOf (value.get<sal_Int64>());
105*cdf0e10cSrcweir             case uno::TypeClass_SHORT:
106*cdf0e10cSrcweir                 // FIXME: seems broken
107*cdf0e10cSrcweir                 return rtl::OUString::valueOf ((sal_Int32) value.get<short>());
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir             case uno::TypeClass_FLOAT:
110*cdf0e10cSrcweir                 return rtl::OUString::valueOf (value.get<float>());
111*cdf0e10cSrcweir             case uno::TypeClass_DOUBLE:
112*cdf0e10cSrcweir                 return rtl::OUString::valueOf (value.get<double>());
113*cdf0e10cSrcweir 
114*cdf0e10cSrcweir             case uno::TypeClass_BOOLEAN:
115*cdf0e10cSrcweir             {
116*cdf0e10cSrcweir                 bool val = value.get<sal_Bool>();
117*cdf0e10cSrcweir                 return rtl::OUString( val ? "1" : "0", 1, RTL_TEXTENCODING_ASCII_US );
118*cdf0e10cSrcweir /*                if ( val )
119*cdf0e10cSrcweir                   return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) );
120*cdf0e10cSrcweir                   else
121*cdf0e10cSrcweir                   return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) );*/
122*cdf0e10cSrcweir             }
123*cdf0e10cSrcweir             default:
124*cdf0e10cSrcweir                 break;
125*cdf0e10cSrcweir         }
126*cdf0e10cSrcweir     }
127*cdf0e10cSrcweir     catch(...) {}
128*cdf0e10cSrcweir     return rtl::OUString();
129*cdf0e10cSrcweir }
130*cdf0e10cSrcweir 
131*cdf0e10cSrcweir static inline long anyToNatural (uno::Any value)
132*cdf0e10cSrcweir { return sal::static_int_cast<long>(anyToString( value ).toInt64()); }
133*cdf0e10cSrcweir static inline double anyToDecimal (uno::Any value)
134*cdf0e10cSrcweir { return anyToString( value ).toDouble(); }
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir /* XLayoutContainer/XLayoutConstrains are a bit of a hasle to work with.
137*cdf0e10cSrcweir    Let's wrap them. */
138*cdf0e10cSrcweir class Widget : public layoutimpl::LayoutWidget
139*cdf0e10cSrcweir {
140*cdf0e10cSrcweir     friend class EditorRoot;
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir     Widget *mpParent;
143*cdf0e10cSrcweir     std::vector< Widget *> maChildren;
144*cdf0e10cSrcweir     bool mbForeign;
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir     rtl::OUString mrId;
147*cdf0e10cSrcweir     rtl::OUString mrLabel, mrUnoName;
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir // TODO: store original properties. And some property handling methods.
150*cdf0e10cSrcweir     long mnOriAttrbs;
151*cdf0e10cSrcweir     layoutimpl::PropList maOriProps, maOriChildProps;
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir public:
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir     // to be used to wrap the root
156*cdf0e10cSrcweir     Widget( uno::Reference< awt::XLayoutConstrains > xImport, const char *label )
157*cdf0e10cSrcweir         : mpParent( 0 ), mbForeign( true )
158*cdf0e10cSrcweir     {
159*cdf0e10cSrcweir         mxWidget = xImport;
160*cdf0e10cSrcweir         mxContainer = uno::Reference< awt::XLayoutContainer >( mxWidget, uno::UNO_QUERY );
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir         mrLabel = rtl::OUString( label, strlen( label ), RTL_TEXTENCODING_UTF8  );
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir #if 0  /* obsolete */
165*cdf0e10cSrcweir         // FIXME: this code is meant to import a XML file. Just use the importer,
166*cdf0e10cSrcweir         // then pass the root widget. But information like the ID string is lost.
167*cdf0e10cSrcweir         // So, this needs to be more closely tight to the importer.
168*cdf0e10cSrcweir         uno::Sequence< uno::Reference< awt::XLayoutConstrains > > aChildren;
169*cdf0e10cSrcweir         for ( int i = 0; i < aChildren.getLength(); i++ )
170*cdf0e10cSrcweir         {
171*cdf0e10cSrcweir             Widget *pChild = new Widget( aChildren[ i ], "---" );
172*cdf0e10cSrcweir             maChildren.push_back( pChild );
173*cdf0e10cSrcweir             pChild->mpParent = this;
174*cdf0e10cSrcweir         }
175*cdf0e10cSrcweir #endif
176*cdf0e10cSrcweir     }
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir     Widget( rtl::OUString id, uno::Reference< awt::XToolkit > xToolkit,
179*cdf0e10cSrcweir             uno::Reference< awt::XLayoutContainer > xParent,
180*cdf0e10cSrcweir             rtl::OUString unoName, long nAttrbs )
181*cdf0e10cSrcweir         : mpParent( 0 ), mbForeign( false ), mrId( id ),
182*cdf0e10cSrcweir           mnOriAttrbs( nAttrbs )
183*cdf0e10cSrcweir     {
184*cdf0e10cSrcweir         while ( xParent.is() && !uno::Reference< awt::XWindow >( xParent, uno::UNO_QUERY ).is() )
185*cdf0e10cSrcweir         {
186*cdf0e10cSrcweir             uno::Reference< awt::XLayoutContainer > xContainer( xParent, uno::UNO_QUERY );
187*cdf0e10cSrcweir             OSL_ASSERT( xContainer.is() );
188*cdf0e10cSrcweir             xParent = uno::Reference< awt::XLayoutContainer >( xContainer->getParent(), uno::UNO_QUERY );
189*cdf0e10cSrcweir         }
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir         mxWidget = WidgetFactory::createWidget( xToolkit, xParent, unoName, nAttrbs );
192*cdf0e10cSrcweir         OSL_ASSERT( mxWidget.is() );
193*cdf0e10cSrcweir         mxContainer = uno::Reference< awt::XLayoutContainer >( mxWidget, uno::UNO_QUERY );
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir         mrLabel = mrUnoName = unoName;
196*cdf0e10cSrcweir         // try to get a nicer label for the widget
197*cdf0e10cSrcweir         for ( int i = 0; i < WIDGETS_SPECS_LEN; i++ )
198*cdf0e10cSrcweir             if ( unoName.equalsAscii( WIDGETS_SPECS[ i ].pName ) )
199*cdf0e10cSrcweir             {
200*cdf0e10cSrcweir                 const char *label = WIDGETS_SPECS[ i ].pLabel;
201*cdf0e10cSrcweir                 mrLabel = rtl::OUString( label, strlen( label ), RTL_TEXTENCODING_UTF8  );
202*cdf0e10cSrcweir                 break;
203*cdf0e10cSrcweir             }
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir         // set default Text property
206*cdf0e10cSrcweir         // TODO: disable editing of text fields, check boxes selected, etc...
207*cdf0e10cSrcweir #if 0
208*cdf0e10cSrcweir         uno::Reference< awt::XVclWindowPeer> xVclPeer( mxWidget, uno::UNO_QUERY )
209*cdf0e10cSrcweir             if ( xVclPeer.is() ) // XVclWindowPeer ignores missing / incorrect properties
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir //FIXME: it looks odd on widgets like NumericField seeing text which is deleted
212*cdf0e10cSrcweir // when you interact with it... We can avoid it for those widgets, by doing a getProp
213*cdf0e10cSrcweir // of "Text" and check if it is empty or not.
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir                 xVclPeer->setProperty( rtl::OUString::createFromAscii( "Text" ),
216*cdf0e10cSrcweir                                        uno::makeAny( rtl::OUString::createFromAscii( "new widget" ) ) );
217*cdf0e10cSrcweir #endif
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir         // store original properties
220*cdf0e10cSrcweir         {
221*cdf0e10cSrcweir             PropertyIterator it( this, WINDOW_PROPERTY );
222*cdf0e10cSrcweir             while ( it.hasNext() )
223*cdf0e10cSrcweir             {
224*cdf0e10cSrcweir                 beans::Property prop = it.next();
225*cdf0e10cSrcweir                 rtl::OUString name( prop.Name );
226*cdf0e10cSrcweir                 rtl::OUString value( getProperty( name, WINDOW_PROPERTY ) );
227*cdf0e10cSrcweir #if DEBUG_PRINT
228*cdf0e10cSrcweir                 fprintf(stderr, "original property: %s = %s\n", OUSTRING_CSTR(name), OUSTRING_CSTR(value));
229*cdf0e10cSrcweir #endif
230*cdf0e10cSrcweir                 std::pair< rtl::OUString, rtl::OUString > pair( name, value );
231*cdf0e10cSrcweir                 maOriProps.push_back( pair );
232*cdf0e10cSrcweir             }
233*cdf0e10cSrcweir         }
234*cdf0e10cSrcweir 
235*cdf0e10cSrcweir     }
236*cdf0e10cSrcweir 
237*cdf0e10cSrcweir     ~Widget()
238*cdf0e10cSrcweir     {
239*cdf0e10cSrcweir         for ( std::vector< Widget *>::const_iterator it = maChildren.begin();
240*cdf0e10cSrcweir              it != maChildren.end(); it++ )
241*cdf0e10cSrcweir             delete *it;
242*cdf0e10cSrcweir         if ( !mbForeign )
243*cdf0e10cSrcweir         {
244*cdf0e10cSrcweir             uno::Reference< lang::XComponent > xComp( mxWidget, uno::UNO_QUERY );
245*cdf0e10cSrcweir             if ( xComp.is() )
246*cdf0e10cSrcweir                 // some widgets, like our containers, don't implement this interface...
247*cdf0e10cSrcweir                 xComp->dispose();
248*cdf0e10cSrcweir         }
249*cdf0e10cSrcweir     }
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir     uno::Reference< awt::XLayoutConstrains > impl()
252*cdf0e10cSrcweir     {
253*cdf0e10cSrcweir         return mxWidget;
254*cdf0e10cSrcweir     }
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir     // LayoutWidget
257*cdf0e10cSrcweir     virtual bool addChild( LayoutWidget *pChild )
258*cdf0e10cSrcweir     {
259*cdf0e10cSrcweir         return addChild( static_cast< Widget * >( pChild ) );
260*cdf0e10cSrcweir     }
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir     virtual void setProperties( const PropList &rProps )
263*cdf0e10cSrcweir     {
264*cdf0e10cSrcweir //        maOriProps = rProps;
265*cdf0e10cSrcweir         LayoutWidget::setProperties( rProps );
266*cdf0e10cSrcweir     }
267*cdf0e10cSrcweir 
268*cdf0e10cSrcweir     virtual void setChildProperties( LayoutWidget *pChild, const PropList &rProps )
269*cdf0e10cSrcweir     {
270*cdf0e10cSrcweir         maOriChildProps = rProps;
271*cdf0e10cSrcweir         LayoutWidget::setChildProperties( pChild, rProps );
272*cdf0e10cSrcweir     }
273*cdf0e10cSrcweir 
274*cdf0e10cSrcweir     // tree travel
275*cdf0e10cSrcweir     Widget *up()
276*cdf0e10cSrcweir     {
277*cdf0e10cSrcweir         return mpParent;
278*cdf0e10cSrcweir     }
279*cdf0e10cSrcweir 
280*cdf0e10cSrcweir     Widget *down()
281*cdf0e10cSrcweir     {
282*cdf0e10cSrcweir         if ( maChildren.empty() )
283*cdf0e10cSrcweir             return NULL;
284*cdf0e10cSrcweir         return maChildren.front();
285*cdf0e10cSrcweir     }
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir     Widget *next()
288*cdf0e10cSrcweir     {
289*cdf0e10cSrcweir         if ( mpParent )
290*cdf0e10cSrcweir         {
291*cdf0e10cSrcweir             int pos = mpParent->getChildPos( this );
292*cdf0e10cSrcweir             return mpParent->getChild( pos+1 );
293*cdf0e10cSrcweir         }
294*cdf0e10cSrcweir         return NULL;
295*cdf0e10cSrcweir     }
296*cdf0e10cSrcweir 
297*cdf0e10cSrcweir     Widget *prev()
298*cdf0e10cSrcweir     {
299*cdf0e10cSrcweir         if ( mpParent )
300*cdf0e10cSrcweir         {
301*cdf0e10cSrcweir             int pos = mpParent->getChildPos( this );
302*cdf0e10cSrcweir             return mpParent->getChild( pos-1 );
303*cdf0e10cSrcweir         }
304*cdf0e10cSrcweir         return NULL;
305*cdf0e10cSrcweir     }
306*cdf0e10cSrcweir 
307*cdf0e10cSrcweir     // handle
308*cdf0e10cSrcweir     bool addChild( Widget *pChild, int pos = 0xffff )
309*cdf0e10cSrcweir     {
310*cdf0e10cSrcweir         if ( !mxContainer.is() )
311*cdf0e10cSrcweir             return false;
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir         uno::Sequence< uno::Reference < awt::XLayoutConstrains > > aChildren;
314*cdf0e10cSrcweir         aChildren = mxContainer->getChildren();
315*cdf0e10cSrcweir         int nChildrenLen = aChildren.getLength();
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir         // ugly, but let's check if the container is next to full...
318*cdf0e10cSrcweir         try {
319*cdf0e10cSrcweir             mxContainer->addChild( pChild->mxWidget );
320*cdf0e10cSrcweir         }
321*cdf0e10cSrcweir         catch( awt::MaxChildrenException ex ) {
322*cdf0e10cSrcweir             return false;
323*cdf0e10cSrcweir         }
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir         if ( pos < nChildrenLen )
326*cdf0e10cSrcweir         {  // if its on the middle, we need to make space for it
327*cdf0e10cSrcweir             mxContainer->removeChild( pChild->mxWidget );
328*cdf0e10cSrcweir             for ( int i = pos; i < nChildrenLen; i++ )
329*cdf0e10cSrcweir                 mxContainer->removeChild( aChildren[ i ] );
330*cdf0e10cSrcweir             mxContainer->addChild( pChild->mxWidget );
331*cdf0e10cSrcweir             for ( int i = pos; i < nChildrenLen; i++ )
332*cdf0e10cSrcweir                 mxContainer->addChild( aChildren[ i ] );
333*cdf0e10cSrcweir             maChildren.insert( maChildren.begin()+pos, pChild );
334*cdf0e10cSrcweir         }
335*cdf0e10cSrcweir         else
336*cdf0e10cSrcweir             maChildren.push_back( pChild );
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir         OSL_ASSERT( pChild->mpParent == NULL );
339*cdf0e10cSrcweir         pChild->mpParent = this;
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir         // store container props
342*cdf0e10cSrcweir         {
343*cdf0e10cSrcweir             pChild->maOriChildProps.clear();
344*cdf0e10cSrcweir             PropertyIterator it( pChild, CONTAINER_PROPERTY );
345*cdf0e10cSrcweir             while ( it.hasNext() )
346*cdf0e10cSrcweir             {
347*cdf0e10cSrcweir                 beans::Property prop = it.next();
348*cdf0e10cSrcweir                 rtl::OUString name( prop.Name );
349*cdf0e10cSrcweir 		try {
350*cdf0e10cSrcweir 			rtl::OUString value( pChild->getProperty( name, CONTAINER_PROPERTY ) );
351*cdf0e10cSrcweir 			std::pair< rtl::OUString, rtl::OUString > pair( name, value );
352*cdf0e10cSrcweir 			pChild->maOriChildProps.push_back( pair );
353*cdf0e10cSrcweir 		} catch ( beans::UnknownPropertyException &rEx ) {
354*cdf0e10cSrcweir 			fprintf (stderr, "ERROR: widget reports that it has a property it cannot return: '%s' this normally means that someone screwed up their PROPERTY_SET_INFO macro usage.\n",
355*cdf0e10cSrcweir 				 rtl::OUStringToOString (rEx.Message, RTL_TEXTENCODING_UTF8).getStr());
356*cdf0e10cSrcweir 		}
357*cdf0e10cSrcweir             }
358*cdf0e10cSrcweir         }
359*cdf0e10cSrcweir 
360*cdf0e10cSrcweir         return true;
361*cdf0e10cSrcweir     }
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir     bool removeChild( Widget *pChild )
364*cdf0e10cSrcweir     {
365*cdf0e10cSrcweir         if ( !mxContainer.is() || pChild->mpParent != this )
366*cdf0e10cSrcweir             return false;
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir         mxContainer->removeChild( pChild->mxWidget );
369*cdf0e10cSrcweir 
370*cdf0e10cSrcweir         unsigned int pos = getChildPos( pChild );
371*cdf0e10cSrcweir         if ( pos < maChildren.size() )
372*cdf0e10cSrcweir             maChildren.erase( maChildren.begin()+pos );
373*cdf0e10cSrcweir         pChild->mpParent = NULL;
374*cdf0e10cSrcweir 
375*cdf0e10cSrcweir         return true;
376*cdf0e10cSrcweir     }
377*cdf0e10cSrcweir 
378*cdf0e10cSrcweir     bool swapWithChild( Widget *pChild )
379*cdf0e10cSrcweir     {
380*cdf0e10cSrcweir         if ( !pChild->isContainer() )
381*cdf0e10cSrcweir             return false;
382*cdf0e10cSrcweir 
383*cdf0e10cSrcweir         // remove all child's childrens, and try to add them here
384*cdf0e10cSrcweir         removeChild( pChild );
385*cdf0e10cSrcweir 
386*cdf0e10cSrcweir         // keep a copy for failure
387*cdf0e10cSrcweir         std::vector< Widget *> aChildren = maChildren;
388*cdf0e10cSrcweir         std::vector< Widget *> aChildChildren = pChild->maChildren;
389*cdf0e10cSrcweir 
390*cdf0e10cSrcweir         for ( std::vector< Widget *>::const_iterator it = aChildChildren.begin();
391*cdf0e10cSrcweir               it != aChildChildren.end(); it++ )
392*cdf0e10cSrcweir             pChild->removeChild( *it );
393*cdf0e10cSrcweir 
394*cdf0e10cSrcweir         for ( std::vector< Widget *>::const_iterator it = aChildChildren.begin();
395*cdf0e10cSrcweir               it != aChildChildren.end(); it++ )
396*cdf0e10cSrcweir             if ( !addChild( *it ) )
397*cdf0e10cSrcweir             {    // failure
398*cdf0e10cSrcweir                 for ( std::vector< Widget *>::const_iterator jt = aChildChildren.begin();
399*cdf0e10cSrcweir                       jt != it; jt++ )
400*cdf0e10cSrcweir                     removeChild( *jt );
401*cdf0e10cSrcweir                 for ( std::vector< Widget *>::const_iterator jt = aChildChildren.begin();
402*cdf0e10cSrcweir                       jt != aChildChildren.end(); jt++ )
403*cdf0e10cSrcweir                     pChild->addChild( *jt );
404*cdf0e10cSrcweir                 return false;
405*cdf0e10cSrcweir             }
406*cdf0e10cSrcweir 
407*cdf0e10cSrcweir         Widget *pParent = up();
408*cdf0e10cSrcweir 
409*cdf0e10cSrcweir         if ( pParent )
410*cdf0e10cSrcweir         {
411*cdf0e10cSrcweir             pParent->removeChild( this );
412*cdf0e10cSrcweir             pParent->addChild( pChild );
413*cdf0e10cSrcweir         }
414*cdf0e10cSrcweir         pChild->addChild( this );
415*cdf0e10cSrcweir         return true;
416*cdf0e10cSrcweir     }
417*cdf0e10cSrcweir 
418*cdf0e10cSrcweir     unsigned int getChildPos( Widget *pChild )
419*cdf0e10cSrcweir     {
420*cdf0e10cSrcweir         int i = 0;
421*cdf0e10cSrcweir         for ( std::vector< Widget *>::const_iterator it = maChildren.begin();
422*cdf0e10cSrcweir               it != maChildren.end(); it++, i++ )
423*cdf0e10cSrcweir             if ( *it == pChild )
424*cdf0e10cSrcweir                 break;
425*cdf0e10cSrcweir         return i;
426*cdf0e10cSrcweir     }
427*cdf0e10cSrcweir 
428*cdf0e10cSrcweir     Widget *getChild( int pos )
429*cdf0e10cSrcweir     {
430*cdf0e10cSrcweir         if ( pos >= 0 && pos < (signed) maChildren.size() )
431*cdf0e10cSrcweir             return *(maChildren.begin() + pos);
432*cdf0e10cSrcweir         return NULL;
433*cdf0e10cSrcweir     }
434*cdf0e10cSrcweir 
435*cdf0e10cSrcweir     bool isContainer()
436*cdf0e10cSrcweir     { return mxContainer.is(); }
437*cdf0e10cSrcweir     unsigned int getChildrenLen()
438*cdf0e10cSrcweir     { return maChildren.size(); }
439*cdf0e10cSrcweir 
440*cdf0e10cSrcweir     rtl::OUString getLabel() const
441*cdf0e10cSrcweir     { return mrLabel; }
442*cdf0e10cSrcweir     rtl::OUString getUnoName() const
443*cdf0e10cSrcweir     { return mrUnoName; }
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir     int getDepth()
446*cdf0e10cSrcweir     {
447*cdf0e10cSrcweir         int depth = 0;
448*cdf0e10cSrcweir         for ( Widget *pWidget = mpParent; pWidget; pWidget = pWidget->mpParent )
449*cdf0e10cSrcweir             depth++;
450*cdf0e10cSrcweir         return depth;
451*cdf0e10cSrcweir     }
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir     enum PropertyKind {
454*cdf0e10cSrcweir         WINDOW_PROPERTY, CONTAINER_PROPERTY, WINBITS_PROPERTY
455*cdf0e10cSrcweir     };
456*cdf0e10cSrcweir 
457*cdf0e10cSrcweir     static rtl::OUString findProperty( const PropList &props, rtl::OUString propName )
458*cdf0e10cSrcweir     {
459*cdf0e10cSrcweir         for ( PropList::const_iterator it = props.begin(); it != props.end(); it++ )
460*cdf0e10cSrcweir             if ( it->first.equalsIgnoreAsciiCase( propName ) )
461*cdf0e10cSrcweir                 return it->second;
462*cdf0e10cSrcweir #if DEBUG_PRINT
463*cdf0e10cSrcweir         fprintf(stderr, "Serious error: property '%s' not found\n", OUSTRING_CSTR(propName));
464*cdf0e10cSrcweir #endif
465*cdf0e10cSrcweir         return rtl::OUString();
466*cdf0e10cSrcweir     }
467*cdf0e10cSrcweir 
468*cdf0e10cSrcweir     rtl::OUString getOriginalProperty( rtl::OUString rPropName, PropertyKind rKind )
469*cdf0e10cSrcweir     {
470*cdf0e10cSrcweir         rtl::OUString rValue;
471*cdf0e10cSrcweir         switch ( rKind ) {
472*cdf0e10cSrcweir             case WINDOW_PROPERTY:
473*cdf0e10cSrcweir                 rValue = findProperty( maOriProps, rPropName );
474*cdf0e10cSrcweir                 break;
475*cdf0e10cSrcweir             case CONTAINER_PROPERTY:
476*cdf0e10cSrcweir                 rValue = findProperty( maOriChildProps, rPropName );
477*cdf0e10cSrcweir                 break;
478*cdf0e10cSrcweir             case WINBITS_PROPERTY:
479*cdf0e10cSrcweir                 // TODO
480*cdf0e10cSrcweir                 break;
481*cdf0e10cSrcweir         }
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir         return rValue;
484*cdf0e10cSrcweir     }
485*cdf0e10cSrcweir 
486*cdf0e10cSrcweir     rtl::OUString getProperty( rtl::OUString rPropName, PropertyKind rKind )
487*cdf0e10cSrcweir     {
488*cdf0e10cSrcweir         rtl::OUString rValue;
489*cdf0e10cSrcweir         switch ( rKind ) {
490*cdf0e10cSrcweir             case WINDOW_PROPERTY:
491*cdf0e10cSrcweir                 rValue = anyToString( layoutimpl::prophlp::getProperty( mxWidget, rPropName ) );
492*cdf0e10cSrcweir                 break;
493*cdf0e10cSrcweir             case CONTAINER_PROPERTY:
494*cdf0e10cSrcweir                 if ( mpParent )
495*cdf0e10cSrcweir                     rValue = anyToString( layoutimpl::prophlp::getProperty(
496*cdf0e10cSrcweir                                               mpParent->mxContainer->getChildProperties( mxWidget ), rPropName ) );
497*cdf0e10cSrcweir                 break;
498*cdf0e10cSrcweir             case WINBITS_PROPERTY:
499*cdf0e10cSrcweir                 // TODO
500*cdf0e10cSrcweir                 break;
501*cdf0e10cSrcweir         }
502*cdf0e10cSrcweir 
503*cdf0e10cSrcweir         return rValue;
504*cdf0e10cSrcweir     }
505*cdf0e10cSrcweir 
506*cdf0e10cSrcweir     bool isPropertyTouched( rtl::OUString propName, PropertyKind rKind )
507*cdf0e10cSrcweir     {
508*cdf0e10cSrcweir         rtl::OUString oriValue = getOriginalProperty( propName, rKind );
509*cdf0e10cSrcweir         rtl::OUString newValue = getProperty( propName, rKind );
510*cdf0e10cSrcweir         bool isTouched = oriValue != newValue;
511*cdf0e10cSrcweir #if DEBUG_PRINT
512*cdf0e10cSrcweir         fprintf(stderr, "is property '%s' touched? %s  (%s vs %s)\n", OUSTRING_CSTR(propName), isTouched ? "yes" : "no", OUSTRING_CSTR(oriValue), OUSTRING_CSTR(newValue));
513*cdf0e10cSrcweir #endif
514*cdf0e10cSrcweir         return isTouched;
515*cdf0e10cSrcweir     }
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir     using LayoutWidget::setProperty;
518*cdf0e10cSrcweir 
519*cdf0e10cSrcweir     void setProperty( rtl::OUString rPropName, PropertyKind rKind, uno::Any rValue )
520*cdf0e10cSrcweir     {
521*cdf0e10cSrcweir         switch ( rKind ) {
522*cdf0e10cSrcweir             case WINDOW_PROPERTY:
523*cdf0e10cSrcweir                 layoutimpl::prophlp::setProperty( mxWidget, rPropName, rValue );
524*cdf0e10cSrcweir                 break;
525*cdf0e10cSrcweir             case CONTAINER_PROPERTY:
526*cdf0e10cSrcweir                 if ( mpParent )
527*cdf0e10cSrcweir                     layoutimpl::prophlp::setProperty(
528*cdf0e10cSrcweir                         mpParent->mxContainer->getChildProperties( mxWidget ), rPropName, rValue );
529*cdf0e10cSrcweir                 break;
530*cdf0e10cSrcweir             case WINBITS_PROPERTY:
531*cdf0e10cSrcweir                 // TODO
532*cdf0e10cSrcweir                 break;
533*cdf0e10cSrcweir         }
534*cdf0e10cSrcweir     }
535*cdf0e10cSrcweir 
536*cdf0e10cSrcweir     struct PropertyIterator {
537*cdf0e10cSrcweir         friend class Widget;
538*cdf0e10cSrcweir         PropertyKind mrKind;
539*cdf0e10cSrcweir         uno::Sequence< beans::Property > maProps;
540*cdf0e10cSrcweir         int nPropIt;
541*cdf0e10cSrcweir 
542*cdf0e10cSrcweir         PropertyIterator( Widget *pWidget, PropertyKind rKind )
543*cdf0e10cSrcweir             : mrKind( rKind ), nPropIt( 0 )
544*cdf0e10cSrcweir         {
545*cdf0e10cSrcweir             switch ( rKind )
546*cdf0e10cSrcweir             {
547*cdf0e10cSrcweir                 case WINDOW_PROPERTY:
548*cdf0e10cSrcweir                     if ( layoutimpl::prophlp::canHandleProps( pWidget->mxWidget ) )
549*cdf0e10cSrcweir                     {
550*cdf0e10cSrcweir                         uno::Reference< beans::XPropertySetInfo > xInfo
551*cdf0e10cSrcweir                             = layoutimpl::prophlp::queryPropertyInfo( pWidget->mxWidget );
552*cdf0e10cSrcweir                         if ( !xInfo.is() )
553*cdf0e10cSrcweir                             return;
554*cdf0e10cSrcweir 
555*cdf0e10cSrcweir                         maProps = xInfo->getProperties();
556*cdf0e10cSrcweir                     }
557*cdf0e10cSrcweir                     break;
558*cdf0e10cSrcweir                 case CONTAINER_PROPERTY:
559*cdf0e10cSrcweir                     if ( pWidget->mpParent )
560*cdf0e10cSrcweir                     {
561*cdf0e10cSrcweir                         uno::Reference< beans::XPropertySet >xParentSet(
562*cdf0e10cSrcweir                             pWidget->mpParent->mxContainer->getChildProperties( pWidget->mxWidget ) );
563*cdf0e10cSrcweir                         if ( xParentSet.is())
564*cdf0e10cSrcweir                         {
565*cdf0e10cSrcweir                             uno::Reference< beans::XPropertySetInfo > xInfo( xParentSet->getPropertySetInfo() );
566*cdf0e10cSrcweir                             if ( xInfo.is() )
567*cdf0e10cSrcweir                                 maProps = xInfo->getProperties();
568*cdf0e10cSrcweir                         }
569*cdf0e10cSrcweir                     }
570*cdf0e10cSrcweir                     break;
571*cdf0e10cSrcweir                 case WINBITS_PROPERTY:
572*cdf0e10cSrcweir                     // TODO
573*cdf0e10cSrcweir                     break;
574*cdf0e10cSrcweir             }
575*cdf0e10cSrcweir         }
576*cdf0e10cSrcweir 
577*cdf0e10cSrcweir         bool hasNext()
578*cdf0e10cSrcweir         {
579*cdf0e10cSrcweir             return nPropIt < maProps.getLength();
580*cdf0e10cSrcweir         }
581*cdf0e10cSrcweir 
582*cdf0e10cSrcweir         beans::Property next()
583*cdf0e10cSrcweir         {
584*cdf0e10cSrcweir /*            rtl::OUString propName, propValue;
585*cdf0e10cSrcweir               propName = maProps[ nPropIt ];
586*cdf0e10cSrcweir               propValue = getProperty( propName, mrKind, false);
587*cdf0e10cSrcweir               nPropIt++;
588*cdf0e10cSrcweir               return std::pair< rtl::OUString, rtl::OUString > propPair( propName, propValue );*/
589*cdf0e10cSrcweir             return maProps[ nPropIt++ ];
590*cdf0e10cSrcweir         }
591*cdf0e10cSrcweir     };
592*cdf0e10cSrcweir };
593*cdf0e10cSrcweir 
594*cdf0e10cSrcweir class EditorRoot : public layoutimpl::LayoutRoot {
595*cdf0e10cSrcweir     Widget *mpParent;
596*cdf0e10cSrcweir 
597*cdf0e10cSrcweir public:
598*cdf0e10cSrcweir     EditorRoot( const uno::Reference< lang::XMultiServiceFactory >& xFactory,
599*cdf0e10cSrcweir                 Widget *pParent )
600*cdf0e10cSrcweir         : layoutimpl::LayoutRoot( xFactory ), mpParent( pParent )
601*cdf0e10cSrcweir     {
602*cdf0e10cSrcweir     }
603*cdf0e10cSrcweir 
604*cdf0e10cSrcweir     // generation
605*cdf0e10cSrcweir     virtual layoutimpl::LayoutWidget *create( rtl::OUString id, const rtl::OUString unoName,
606*cdf0e10cSrcweir                                               long attrbs, uno::Reference< awt::XLayoutContainer > xParent )
607*cdf0e10cSrcweir     {
608*cdf0e10cSrcweir         if ( unoName.compareToAscii( "dialog" ) == 0 )
609*cdf0e10cSrcweir             return mpParent;
610*cdf0e10cSrcweir 
611*cdf0e10cSrcweir         // TODO: go through specs to map unoName to a more human-readable label
612*cdf0e10cSrcweir         Widget *pWidget = new Widget( id, mxToolkit, xParent, unoName, attrbs );
613*cdf0e10cSrcweir         if ( !mxWindow.is() )
614*cdf0e10cSrcweir             mxWindow = uno::Reference< awt::XWindow >( pWidget->getPeer(), uno::UNO_QUERY );
615*cdf0e10cSrcweir 
616*cdf0e10cSrcweir         if ( pWidget->mxContainer.is() )
617*cdf0e10cSrcweir             pWidget->mxContainer->setLayoutUnit( mpParent->mxContainer->getLayoutUnit() );
618*cdf0e10cSrcweir 
619*cdf0e10cSrcweir         return pWidget;
620*cdf0e10cSrcweir     }
621*cdf0e10cSrcweir };
622*cdf0e10cSrcweir 
623*cdf0e10cSrcweir /* Working with the layout in 1D, as if it was a flat list. */
624*cdf0e10cSrcweir namespace FlatLayout
625*cdf0e10cSrcweir {
626*cdf0e10cSrcweir Widget *next( Widget *pWidget )
627*cdf0e10cSrcweir {
628*cdf0e10cSrcweir     Widget *pNext;
629*cdf0e10cSrcweir     pNext = pWidget->down();
630*cdf0e10cSrcweir     if ( pNext ) return pNext;
631*cdf0e10cSrcweir     pNext = pWidget->next();
632*cdf0e10cSrcweir     if ( pNext ) return pNext;
633*cdf0e10cSrcweir     for ( Widget *pUp = pWidget->up(); pUp != NULL; pUp = pUp->up() )
634*cdf0e10cSrcweir         if ( (pNext = pUp->next()) != NULL )
635*cdf0e10cSrcweir             return pNext;
636*cdf0e10cSrcweir     return NULL;
637*cdf0e10cSrcweir }
638*cdf0e10cSrcweir 
639*cdf0e10cSrcweir /*
640*cdf0e10cSrcweir   Widget *prev( Widget *pWidget )
641*cdf0e10cSrcweir   {
642*cdf0e10cSrcweir   Widget *pPrev;
643*cdf0e10cSrcweir   pPrev = pWidget->prev();
644*cdf0e10cSrcweir   if ( !pPrev )
645*cdf0e10cSrcweir   return pWidget->up();
646*cdf0e10cSrcweir 
647*cdf0e10cSrcweir   Widget *pBottom = pPrev->down();
648*cdf0e10cSrcweir   if ( pBottom )
649*cdf0e10cSrcweir   {
650*cdf0e10cSrcweir   while ( pBottom->down() || pBottom->next() )
651*cdf0e10cSrcweir   {
652*cdf0e10cSrcweir   for ( Widget *pNext = pBottom->next(); pNext; pNext = pNext->next() )
653*cdf0e10cSrcweir   pBottom = pNext;
654*cdf0e10cSrcweir   Widget *pDown = pBottom->down();
655*cdf0e10cSrcweir   if ( pDown )
656*cdf0e10cSrcweir   pBottom = pDown;
657*cdf0e10cSrcweir   }
658*cdf0e10cSrcweir   return pBottom;
659*cdf0e10cSrcweir   }
660*cdf0e10cSrcweir   return pPrev;
661*cdf0e10cSrcweir   }
662*cdf0e10cSrcweir */
663*cdf0e10cSrcweir 
664*cdf0e10cSrcweir bool moveWidget( Widget *pWidget, bool up /*or down*/ )
665*cdf0e10cSrcweir {
666*cdf0e10cSrcweir     // Keep child parent&pos for in case of failure
667*cdf0e10cSrcweir     Widget *pOriContainer = pWidget->up();
668*cdf0e10cSrcweir     unsigned int oriChildPos = pOriContainer->getChildPos( pWidget );
669*cdf0e10cSrcweir 
670*cdf0e10cSrcweir     // Get parent&sibling before removing it, since relations get cut
671*cdf0e10cSrcweir     Widget *pSibling = up ? pWidget->prev() : pWidget->next();
672*cdf0e10cSrcweir     Widget *pContainer = pWidget->up();
673*cdf0e10cSrcweir     if ( !pContainer )
674*cdf0e10cSrcweir         return false;
675*cdf0e10cSrcweir 
676*cdf0e10cSrcweir     // try to swap with parent or child
677*cdf0e10cSrcweir     // We need to allow for this at least for the root node...
678*cdf0e10cSrcweir     if ( !pSibling )
679*cdf0e10cSrcweir     {
680*cdf0e10cSrcweir         if ( up )
681*cdf0e10cSrcweir         {
682*cdf0e10cSrcweir             if ( pContainer->swapWithChild( pWidget ) )
683*cdf0e10cSrcweir                 return true;
684*cdf0e10cSrcweir         }
685*cdf0e10cSrcweir         else
686*cdf0e10cSrcweir         {
687*cdf0e10cSrcweir // TODO: this is a nice feature, but we probably want to do it explicitely...
688*cdf0e10cSrcweir #if 0
689*cdf0e10cSrcweir             if ( pWidget->down() && pWidget->swapWithChild( pWidget->down() ) )
690*cdf0e10cSrcweir                 return true;
691*cdf0e10cSrcweir #endif
692*cdf0e10cSrcweir         }
693*cdf0e10cSrcweir     }
694*cdf0e10cSrcweir 
695*cdf0e10cSrcweir     pContainer->removeChild( pWidget );
696*cdf0e10cSrcweir 
697*cdf0e10cSrcweir     // if has up sibling -- append to it, else swap with it
698*cdf0e10cSrcweir     if ( pSibling )
699*cdf0e10cSrcweir     {
700*cdf0e10cSrcweir         if ( pSibling->addChild( pWidget, up ? 0xffff : 0 ) )
701*cdf0e10cSrcweir             return true;
702*cdf0e10cSrcweir 
703*cdf0e10cSrcweir         unsigned int childPos = pContainer->getChildPos( pSibling );
704*cdf0e10cSrcweir         if ( pContainer->addChild( pWidget, childPos + (up ? 0 : 1) ) )
705*cdf0e10cSrcweir             return true;  // should always be succesful
706*cdf0e10cSrcweir     }
707*cdf0e10cSrcweir     // go through parents -- try to get prepended to them
708*cdf0e10cSrcweir     else
709*cdf0e10cSrcweir     {
710*cdf0e10cSrcweir         for ( ; pContainer && pContainer->up(); pContainer = pContainer->up() )
711*cdf0e10cSrcweir         {
712*cdf0e10cSrcweir             unsigned int childPos = pContainer->up()->getChildPos( pContainer );
713*cdf0e10cSrcweir             if ( pContainer->up()->addChild( pWidget, childPos + (up ? 0 : 1) ) )
714*cdf0e10cSrcweir                 return true;
715*cdf0e10cSrcweir         }
716*cdf0e10cSrcweir     }
717*cdf0e10cSrcweir 
718*cdf0e10cSrcweir     // failed -- try to get it to its old position
719*cdf0e10cSrcweir     if ( !pOriContainer->addChild( pWidget, oriChildPos ) )
720*cdf0e10cSrcweir     {
721*cdf0e10cSrcweir         // a parent should never reject a child back. but if it ever
722*cdf0e10cSrcweir         // happens, just kill it, we don't run an orphanate here ;P
723*cdf0e10cSrcweir         delete pWidget;
724*cdf0e10cSrcweir         return true;
725*cdf0e10cSrcweir     }
726*cdf0e10cSrcweir     return false;
727*cdf0e10cSrcweir }
728*cdf0e10cSrcweir 
729*cdf0e10cSrcweir // NOTE: root is considered to be number -1
730*cdf0e10cSrcweir Widget *get( Widget *pRoot, int nb )
731*cdf0e10cSrcweir {
732*cdf0e10cSrcweir     Widget *it;
733*cdf0e10cSrcweir     for ( it = pRoot; it != NULL && nb >= 0; it = next( it ) )
734*cdf0e10cSrcweir         nb--;
735*cdf0e10cSrcweir     return it;
736*cdf0e10cSrcweir }
737*cdf0e10cSrcweir 
738*cdf0e10cSrcweir int get( Widget *pRoot, Widget *pWidget )
739*cdf0e10cSrcweir {
740*cdf0e10cSrcweir     int nRet = -1;
741*cdf0e10cSrcweir     Widget *it;
742*cdf0e10cSrcweir     for ( it = pRoot; it != NULL && it != pWidget; it = next( it ) )
743*cdf0e10cSrcweir         nRet++;
744*cdf0e10cSrcweir     return nRet;
745*cdf0e10cSrcweir }
746*cdf0e10cSrcweir }
747*cdf0e10cSrcweir 
748*cdf0e10cSrcweir //** PropertiesList widget
749*cdf0e10cSrcweir 
750*cdf0e10cSrcweir class PropertiesList : public layout::Table
751*cdf0e10cSrcweir {
752*cdf0e10cSrcweir     class PropertyEntry
753*cdf0e10cSrcweir     {
754*cdf0e10cSrcweir         friend class PropertiesList;
755*cdf0e10cSrcweir 
756*cdf0e10cSrcweir         /* wrapper between the widget and Any */
757*cdf0e10cSrcweir         struct AnyWidget
758*cdf0e10cSrcweir         {
759*cdf0e10cSrcweir             DECL_LINK( ApplyPropertyHdl, layout::Window* );
760*cdf0e10cSrcweir             DECL_LINK( FlagToggledHdl, layout::CheckBox* );
761*cdf0e10cSrcweir 
762*cdf0e10cSrcweir             AnyWidget( Widget *pWidget, rtl::OUString aPropName, Widget::PropertyKind aPropKind )
763*cdf0e10cSrcweir                 : mpWidget( pWidget ), maPropName( aPropName ), maPropKind( aPropKind )
764*cdf0e10cSrcweir             {
765*cdf0e10cSrcweir                 mpFlag = 0;
766*cdf0e10cSrcweir                 mbBlockFlagCallback = false;
767*cdf0e10cSrcweir                 bFirstGet = true;
768*cdf0e10cSrcweir             }
769*cdf0e10cSrcweir 
770*cdf0e10cSrcweir             virtual ~AnyWidget()
771*cdf0e10cSrcweir             {
772*cdf0e10cSrcweir #if DEBUG_PRINT
773*cdf0e10cSrcweir                 fprintf(stderr, "~AnyWidget\n");
774*cdf0e10cSrcweir #endif
775*cdf0e10cSrcweir             }
776*cdf0e10cSrcweir 
777*cdf0e10cSrcweir             void save( uno::Any aValue )
778*cdf0e10cSrcweir             {
779*cdf0e10cSrcweir                 mpWidget->setProperty( maPropName, maPropKind, aValue );
780*cdf0e10cSrcweir                 checkProperty();
781*cdf0e10cSrcweir             }
782*cdf0e10cSrcweir 
783*cdf0e10cSrcweir             void checkProperty()
784*cdf0e10cSrcweir             {
785*cdf0e10cSrcweir                 bool flag = mpWidget->isPropertyTouched( maPropName, maPropKind );
786*cdf0e10cSrcweir 
787*cdf0e10cSrcweir                 if ( mpFlag && mpFlag->IsChecked() != (BOOL)flag )
788*cdf0e10cSrcweir                 {
789*cdf0e10cSrcweir                     CheckFlag( flag, true );
790*cdf0e10cSrcweir                 }
791*cdf0e10cSrcweir             }
792*cdf0e10cSrcweir 
793*cdf0e10cSrcweir             void CheckFlag( bool bValue, bool bBlockCallback )
794*cdf0e10cSrcweir             {
795*cdf0e10cSrcweir                 if ( bBlockCallback )
796*cdf0e10cSrcweir                     mbBlockFlagCallback = true;
797*cdf0e10cSrcweir                 mpFlag->Check( bValue );
798*cdf0e10cSrcweir                 mbBlockFlagCallback = false;
799*cdf0e10cSrcweir             }
800*cdf0e10cSrcweir 
801*cdf0e10cSrcweir             bool bFirstGet;  // HACK
802*cdf0e10cSrcweir             rtl::OUString getValue()
803*cdf0e10cSrcweir             {
804*cdf0e10cSrcweir //                return mpWidget->getOriProperty( maPropName );
805*cdf0e10cSrcweir                 rtl::OUString value;
806*cdf0e10cSrcweir                 if ( bFirstGet )    // king of ugliness
807*cdf0e10cSrcweir                     value = mpWidget->getProperty( maPropName, maPropKind );
808*cdf0e10cSrcweir                 else
809*cdf0e10cSrcweir                     value = mpWidget->getOriginalProperty( maPropName, maPropKind );
810*cdf0e10cSrcweir                 bFirstGet = false;
811*cdf0e10cSrcweir                 return value;
812*cdf0e10cSrcweir             }
813*cdf0e10cSrcweir 
814*cdf0e10cSrcweir             // FIXME: wrapper should have a base class for this...
815*cdf0e10cSrcweir             virtual layout::Window *getWindow() = 0;
816*cdf0e10cSrcweir             virtual layout::Container *getContainer() { return NULL; }
817*cdf0e10cSrcweir 
818*cdf0e10cSrcweir             virtual void load() = 0;
819*cdf0e10cSrcweir             virtual void store() = 0;
820*cdf0e10cSrcweir 
821*cdf0e10cSrcweir             Widget *mpWidget;
822*cdf0e10cSrcweir             rtl::OUString maPropName;
823*cdf0e10cSrcweir             Widget::PropertyKind maPropKind;
824*cdf0e10cSrcweir             layout::CheckBox *mpFlag;
825*cdf0e10cSrcweir             bool mbBlockFlagCallback;
826*cdf0e10cSrcweir         };
827*cdf0e10cSrcweir 
828*cdf0e10cSrcweir         struct AnyEdit : public AnyWidget, layout::HBox
829*cdf0e10cSrcweir         {
830*cdf0e10cSrcweir             layout::Edit *mpEdit;
831*cdf0e10cSrcweir             bool mbMultiLine;
832*cdf0e10cSrcweir             layout::PushButton *mpExpand;
833*cdf0e10cSrcweir             DECL_LINK( ExpandEditHdl, layout::PushButton* );
834*cdf0e10cSrcweir 
835*cdf0e10cSrcweir             // so we can create widgets (like transforming the Edit into a
836*cdf0e10cSrcweir             // MultiLineEdit)
837*cdf0e10cSrcweir             layout::Window *mpWinParent;
838*cdf0e10cSrcweir 
839*cdf0e10cSrcweir             AnyEdit( Widget *pWidget, rtl::OUString aPropName,
840*cdf0e10cSrcweir                      Widget::PropertyKind aPropKind, layout::Window *pWinParent )
841*cdf0e10cSrcweir                 : AnyWidget( pWidget, aPropName, aPropKind ), layout::HBox( 0, false ), mpWinParent( pWinParent )
842*cdf0e10cSrcweir             {
843*cdf0e10cSrcweir                 mpEdit = NULL;
844*cdf0e10cSrcweir                 mpExpand = new layout::PushButton( pWinParent, WB_TOGGLE );
845*cdf0e10cSrcweir                 mpExpand->SetToggleHdl( LINK( this, AnyEdit, ExpandEditHdl ) );
846*cdf0e10cSrcweir                 setAsMultiLine( false );
847*cdf0e10cSrcweir 
848*cdf0e10cSrcweir                 load();
849*cdf0e10cSrcweir             }
850*cdf0e10cSrcweir 
851*cdf0e10cSrcweir             virtual ~AnyEdit()
852*cdf0e10cSrcweir             {
853*cdf0e10cSrcweir                 delete mpEdit;
854*cdf0e10cSrcweir                 delete mpExpand;
855*cdf0e10cSrcweir             }
856*cdf0e10cSrcweir 
857*cdf0e10cSrcweir             virtual layout::Window *getWindow()
858*cdf0e10cSrcweir             { return NULL; }
859*cdf0e10cSrcweir             virtual layout::Container *getContainer()
860*cdf0e10cSrcweir             { return this; }
861*cdf0e10cSrcweir 
862*cdf0e10cSrcweir             void setAsMultiLine( bool bMultiLine )
863*cdf0e10cSrcweir             {
864*cdf0e10cSrcweir                 Clear();
865*cdf0e10cSrcweir                 XubString text;
866*cdf0e10cSrcweir                 if ( mpEdit )
867*cdf0e10cSrcweir                 {
868*cdf0e10cSrcweir                     text = mpEdit->GetText();
869*cdf0e10cSrcweir                     printf("Remove mpEdit and expand\n");
870*cdf0e10cSrcweir                     Remove( mpEdit );
871*cdf0e10cSrcweir                     Remove( mpExpand );
872*cdf0e10cSrcweir                     delete mpEdit;
873*cdf0e10cSrcweir                 }
874*cdf0e10cSrcweir 
875*cdf0e10cSrcweir                 if ( bMultiLine )
876*cdf0e10cSrcweir                 {
877*cdf0e10cSrcweir                     mpEdit = new layout::Edit( mpWinParent, WB_BORDER );
878*cdf0e10cSrcweir                     mpExpand->SetText( String::CreateFromAscii( "-" ) );
879*cdf0e10cSrcweir                 }
880*cdf0e10cSrcweir                 else
881*cdf0e10cSrcweir                 {
882*cdf0e10cSrcweir                     mpEdit = new layout::Edit( mpWinParent, WB_BORDER );
883*cdf0e10cSrcweir                     mpExpand->SetText( String::CreateFromAscii( "+" ) );
884*cdf0e10cSrcweir                 }
885*cdf0e10cSrcweir 
886*cdf0e10cSrcweir                 mpEdit->SetText( text );
887*cdf0e10cSrcweir                 mpEdit->SetModifyHdl( LINK( this, AnyEdit, ApplyPropertyHdl ) );
888*cdf0e10cSrcweir 
889*cdf0e10cSrcweir                 Add( mpEdit, true, true, 0 );
890*cdf0e10cSrcweir                 Add( mpExpand, false, true, 0 );
891*cdf0e10cSrcweir 
892*cdf0e10cSrcweir                 mbMultiLine = bMultiLine;
893*cdf0e10cSrcweir             }
894*cdf0e10cSrcweir 
895*cdf0e10cSrcweir #if 0
896*cdf0e10cSrcweir             // TODO: make this global... We'll likely need it for export...
897*cdf0e10cSrcweir             struct Translate {
898*cdf0e10cSrcweir                 const char *ori, *dest;
899*cdf0e10cSrcweir             };
900*cdf0e10cSrcweir             static rtl::OUString stringReplace( rtl::OUString _str,
901*cdf0e10cSrcweir                                                 Translate *trans )
902*cdf0e10cSrcweir             {
903*cdf0e10cSrcweir                 const sal_Unicode *str = _str.getStr();
904*cdf0e10cSrcweir                 rtl::OUStringBuffer buf;
905*cdf0e10cSrcweir                 int i, j, k;
906*cdf0e10cSrcweir                 for ( i = 0; i < _str.getLength(); i++ )
907*cdf0e10cSrcweir                 {
908*cdf0e10cSrcweir                     for ( j = 0; trans[ j ].ori; j++ )
909*cdf0e10cSrcweir                     {
910*cdf0e10cSrcweir                         const char *ori = trans[ j ].ori;
911*cdf0e10cSrcweir                         for ( k = 0; ori[ k ] && i+k < _str.getLength(); k++ )
912*cdf0e10cSrcweir                             if ( ori[ k ] != str[ i+k ] )
913*cdf0e10cSrcweir                                 break;
914*cdf0e10cSrcweir                         if ( !ori[ k ] )
915*cdf0e10cSrcweir                         {
916*cdf0e10cSrcweir                             // found substring
917*cdf0e10cSrcweir                             buf.appendAscii( trans[ j ].dest );
918*cdf0e10cSrcweir                             i += k;
919*cdf0e10cSrcweir                             continue;
920*cdf0e10cSrcweir                         }
921*cdf0e10cSrcweir                     }
922*cdf0e10cSrcweir                     buf.append( str[ i ] );
923*cdf0e10cSrcweir                 }
924*cdf0e10cSrcweir                 return buf.makeStringAndClear();
925*cdf0e10cSrcweir             }
926*cdf0e10cSrcweir #endif
927*cdf0e10cSrcweir 
928*cdf0e10cSrcweir             virtual void load()
929*cdf0e10cSrcweir             {
930*cdf0e10cSrcweir #if 0
931*cdf0e10cSrcweir                 // replace end of lines by "\\n" strings
932*cdf0e10cSrcweir                 Translate trans[] = {
933*cdf0e10cSrcweir                     { "\\", "\\\\" }, { "\n", "\\n" }, { 0, 0 }
934*cdf0e10cSrcweir                 };
935*cdf0e10cSrcweir                 rtl::OUString str = anyToString( getValue() );
936*cdf0e10cSrcweir                 str = stringReplace( str, trans );
937*cdf0e10cSrcweir                 SetText( str );
938*cdf0e10cSrcweir #endif
939*cdf0e10cSrcweir                 mpEdit->SetText( getValue() );
940*cdf0e10cSrcweir                 checkProperty();
941*cdf0e10cSrcweir             }
942*cdf0e10cSrcweir 
943*cdf0e10cSrcweir             virtual void store()
944*cdf0e10cSrcweir             {
945*cdf0e10cSrcweir #if 0
946*cdf0e10cSrcweir                 // replace "\\n" strings by actual end of lines
947*cdf0e10cSrcweir                 Translate trans[] = {
948*cdf0e10cSrcweir                     { "\\\\", "\\"  }, { "\\n", "\n" },
949*cdf0e10cSrcweir                     { "\\", "" }, { 0, 0 }
950*cdf0e10cSrcweir                 };
951*cdf0e10cSrcweir                 rtl::OUString str = GetText();
952*cdf0e10cSrcweir                 str = stringReplace( str, trans );
953*cdf0e10cSrcweir                 save( uno::makeAny( str ) );
954*cdf0e10cSrcweir #endif
955*cdf0e10cSrcweir                 save( uno::makeAny( (rtl::OUString) mpEdit->GetText() ) );
956*cdf0e10cSrcweir             }
957*cdf0e10cSrcweir         };
958*cdf0e10cSrcweir 
959*cdf0e10cSrcweir         struct AnyInteger : public AnyWidget, NumericField
960*cdf0e10cSrcweir         {
961*cdf0e10cSrcweir             AnyInteger( Widget *pWidget, rtl::OUString aPropName,
962*cdf0e10cSrcweir                         Widget::PropertyKind aPropKind, Window *pWinParent )
963*cdf0e10cSrcweir                 : AnyWidget( pWidget, aPropName, aPropKind ), NumericField( pWinParent, WB_SPIN|WB_BORDER )
964*cdf0e10cSrcweir             {
965*cdf0e10cSrcweir                 load();
966*cdf0e10cSrcweir                 SetModifyHdl( LINK( this, AnyInteger, ApplyPropertyHdl ) );
967*cdf0e10cSrcweir             }
968*cdf0e10cSrcweir 
969*cdf0e10cSrcweir             virtual Window *getWindow()
970*cdf0e10cSrcweir             { return this; }
971*cdf0e10cSrcweir 
972*cdf0e10cSrcweir             virtual void load()
973*cdf0e10cSrcweir             {
974*cdf0e10cSrcweir                 OUString text = getValue();
975*cdf0e10cSrcweir                 SetText( text.getStr() );
976*cdf0e10cSrcweir                 checkProperty();
977*cdf0e10cSrcweir             }
978*cdf0e10cSrcweir 
979*cdf0e10cSrcweir             virtual void store()
980*cdf0e10cSrcweir             {
981*cdf0e10cSrcweir #if DEBUG_PRINT
982*cdf0e10cSrcweir                 fprintf(stderr, "store number: %ld\n", rtl::OUString( GetText() ).toInt64());
983*cdf0e10cSrcweir #endif
984*cdf0e10cSrcweir                 save( uno::makeAny( rtl::OUString( GetText() ).toInt64() ) );
985*cdf0e10cSrcweir             }
986*cdf0e10cSrcweir         };
987*cdf0e10cSrcweir 
988*cdf0e10cSrcweir         struct AnyFloat : public AnyInteger
989*cdf0e10cSrcweir         {
990*cdf0e10cSrcweir             AnyFloat( Widget *pWidget, rtl::OUString aPropName,
991*cdf0e10cSrcweir                       Widget::PropertyKind aPropKind, Window *pWinParent )
992*cdf0e10cSrcweir                 : AnyInteger( pWidget, aPropName, aPropKind, pWinParent )
993*cdf0e10cSrcweir             {}
994*cdf0e10cSrcweir 
995*cdf0e10cSrcweir             virtual void store()
996*cdf0e10cSrcweir             {
997*cdf0e10cSrcweir                 save( uno::makeAny( rtl::OUString( GetText() ).toDouble() ) );
998*cdf0e10cSrcweir             }
999*cdf0e10cSrcweir         };
1000*cdf0e10cSrcweir 
1001*cdf0e10cSrcweir         struct AnyCheckBox : public AnyWidget, layout::CheckBox
1002*cdf0e10cSrcweir         {
1003*cdf0e10cSrcweir             AnyCheckBox( Widget *pWidget, rtl::OUString aPropName,
1004*cdf0e10cSrcweir                          Widget::PropertyKind aPropKind, layout::Window *pWinParent )
1005*cdf0e10cSrcweir                 : AnyWidget( pWidget, aPropName, aPropKind ), layout::CheckBox( pWinParent )
1006*cdf0e10cSrcweir             {
1007*cdf0e10cSrcweir                 // adding some whitespaces to make the hit area larger
1008*cdf0e10cSrcweir //                SetText( String::CreateFromAscii( "" ) );
1009*cdf0e10cSrcweir                 load();
1010*cdf0e10cSrcweir                 SetToggleHdl( LINK( this, AnyWidget, ApplyPropertyHdl ) );
1011*cdf0e10cSrcweir             }
1012*cdf0e10cSrcweir 
1013*cdf0e10cSrcweir             virtual ~AnyCheckBox()
1014*cdf0e10cSrcweir             {
1015*cdf0e10cSrcweir #if DEBUG_PRINT
1016*cdf0e10cSrcweir                 fprintf(stderr, "~AnyCheckBox\n");
1017*cdf0e10cSrcweir #endif
1018*cdf0e10cSrcweir             }
1019*cdf0e10cSrcweir 
1020*cdf0e10cSrcweir             virtual layout::Window *getWindow()
1021*cdf0e10cSrcweir             { return this; }
1022*cdf0e10cSrcweir 
1023*cdf0e10cSrcweir             virtual void load()
1024*cdf0e10cSrcweir             {
1025*cdf0e10cSrcweir #if DEBUG_PRINT
1026*cdf0e10cSrcweir                 fprintf(stderr, "loading boolean value\n");
1027*cdf0e10cSrcweir #endif
1028*cdf0e10cSrcweir                 Check( getValue().toInt64() != 0 );
1029*cdf0e10cSrcweir                 setLabel();
1030*cdf0e10cSrcweir                 checkProperty();
1031*cdf0e10cSrcweir             }
1032*cdf0e10cSrcweir 
1033*cdf0e10cSrcweir             virtual void store()
1034*cdf0e10cSrcweir             {
1035*cdf0e10cSrcweir                 save( uno::makeAny( IsChecked() ) );
1036*cdf0e10cSrcweir                 setLabel();
1037*cdf0e10cSrcweir             }
1038*cdf0e10cSrcweir 
1039*cdf0e10cSrcweir             void setLabel()
1040*cdf0e10cSrcweir             {
1041*cdf0e10cSrcweir                 SetText( String::CreateFromAscii( IsChecked() ? "true" : "false" ) );
1042*cdf0e10cSrcweir             }
1043*cdf0e10cSrcweir         };
1044*cdf0e10cSrcweir 
1045*cdf0e10cSrcweir         struct AnyListBox : public AnyWidget, layout::ListBox
1046*cdf0e10cSrcweir         {
1047*cdf0e10cSrcweir             AnyListBox( Widget *pWidget, rtl::OUString aPropName,
1048*cdf0e10cSrcweir                         Widget::PropertyKind aPropKind, Window *pWinParent )
1049*cdf0e10cSrcweir                 : AnyWidget( pWidget, aPropName, aPropKind ), layout::ListBox( pWinParent, WB_DROPDOWN )
1050*cdf0e10cSrcweir             {
1051*cdf0e10cSrcweir                 SetSelectHdl( LINK( this, AnyWidget, ApplyPropertyHdl ) );
1052*cdf0e10cSrcweir             }
1053*cdf0e10cSrcweir 
1054*cdf0e10cSrcweir             virtual layout::Window *getWindow()
1055*cdf0e10cSrcweir             { return this; }
1056*cdf0e10cSrcweir 
1057*cdf0e10cSrcweir             virtual void load()
1058*cdf0e10cSrcweir             {
1059*cdf0e10cSrcweir                 SelectEntryPos( sal::static_int_cast< USHORT >( getValue().toInt32() ) );
1060*cdf0e10cSrcweir                 checkProperty();
1061*cdf0e10cSrcweir             }
1062*cdf0e10cSrcweir 
1063*cdf0e10cSrcweir             virtual void store()
1064*cdf0e10cSrcweir             {
1065*cdf0e10cSrcweir                 save( uno::makeAny( (short) GetSelectEntryPos() ) );
1066*cdf0e10cSrcweir             }
1067*cdf0e10cSrcweir         };
1068*cdf0e10cSrcweir 
1069*cdf0e10cSrcweir         struct AnyAlign : public AnyListBox
1070*cdf0e10cSrcweir         {
1071*cdf0e10cSrcweir             AnyAlign( Widget *pWidget, rtl::OUString aPropName,
1072*cdf0e10cSrcweir                       Widget::PropertyKind aPropKind, Window *pWinParent )
1073*cdf0e10cSrcweir                 : AnyListBox( pWidget, aPropName, aPropKind, pWinParent )
1074*cdf0e10cSrcweir             {
1075*cdf0e10cSrcweir                 InsertEntry( XubString::CreateFromAscii( "Left" ) );
1076*cdf0e10cSrcweir                 InsertEntry( XubString::CreateFromAscii( "Center" ) );
1077*cdf0e10cSrcweir                 InsertEntry( XubString::CreateFromAscii( "Right" ) );
1078*cdf0e10cSrcweir                 load();
1079*cdf0e10cSrcweir             }
1080*cdf0e10cSrcweir         };
1081*cdf0e10cSrcweir 
1082*cdf0e10cSrcweir         /* AnyListBox and AnyComboBox different in that a ComboBox allows the user
1083*cdf0e10cSrcweir            to add other options, operating in strings, instead of constants.
1084*cdf0e10cSrcweir            (its more like a suggestive AnyEdit) */
1085*cdf0e10cSrcweir         struct AnyComboBox : public AnyWidget, layout::ComboBox
1086*cdf0e10cSrcweir         {
1087*cdf0e10cSrcweir             AnyComboBox( Widget *pWidget, rtl::OUString aPropName,
1088*cdf0e10cSrcweir                          Widget::PropertyKind aPropKind, Window *pWinParent )
1089*cdf0e10cSrcweir                 : AnyWidget( pWidget, aPropName, aPropKind ), layout::ComboBox( pWinParent, WB_DROPDOWN )
1090*cdf0e10cSrcweir             {
1091*cdf0e10cSrcweir                 SetModifyHdl( LINK( this, AnyComboBox, ApplyPropertyHdl ) );
1092*cdf0e10cSrcweir             }
1093*cdf0e10cSrcweir 
1094*cdf0e10cSrcweir             virtual layout::Window *getWindow()
1095*cdf0e10cSrcweir             { return this; }
1096*cdf0e10cSrcweir 
1097*cdf0e10cSrcweir             virtual void load()
1098*cdf0e10cSrcweir             {
1099*cdf0e10cSrcweir                 SetText( getValue() );
1100*cdf0e10cSrcweir                 checkProperty();
1101*cdf0e10cSrcweir             }
1102*cdf0e10cSrcweir 
1103*cdf0e10cSrcweir             virtual void store()
1104*cdf0e10cSrcweir             {
1105*cdf0e10cSrcweir                 save( uno::makeAny( (rtl::OUString) GetText() ) );
1106*cdf0e10cSrcweir             }
1107*cdf0e10cSrcweir         };
1108*cdf0e10cSrcweir 
1109*cdf0e10cSrcweir         struct AnyFontStyle : public AnyComboBox
1110*cdf0e10cSrcweir         {
1111*cdf0e10cSrcweir             AnyFontStyle( Widget *pWidget, rtl::OUString aPropName,
1112*cdf0e10cSrcweir                           Widget::PropertyKind aPropKind, Window *pWinParent )
1113*cdf0e10cSrcweir                 : AnyComboBox( pWidget, aPropName, aPropKind, pWinParent )
1114*cdf0e10cSrcweir             {
1115*cdf0e10cSrcweir                 InsertEntry( XubString::CreateFromAscii( "Bold" ) );
1116*cdf0e10cSrcweir                 InsertEntry( XubString::CreateFromAscii( "Italic" ) );
1117*cdf0e10cSrcweir                 InsertEntry( XubString::CreateFromAscii( "Bold Italic" ) );
1118*cdf0e10cSrcweir                 InsertEntry( XubString::CreateFromAscii( "Fett" ) );
1119*cdf0e10cSrcweir                 load();
1120*cdf0e10cSrcweir             }
1121*cdf0e10cSrcweir         };
1122*cdf0e10cSrcweir 
1123*cdf0e10cSrcweir         layout::FixedText *mpLabel;
1124*cdf0e10cSrcweir         layout::CheckBox *mpFlag;
1125*cdf0e10cSrcweir         AnyWidget *mpValue;
1126*cdf0e10cSrcweir 
1127*cdf0e10cSrcweir     public:
1128*cdf0e10cSrcweir         PropertyEntry( layout::Window *pWinParent, AnyWidget *pAnyWidget )
1129*cdf0e10cSrcweir         {
1130*cdf0e10cSrcweir             mpLabel = new layout::FixedText( pWinParent );
1131*cdf0e10cSrcweir             {
1132*cdf0e10cSrcweir                 // append ':' to aPropName
1133*cdf0e10cSrcweir                 rtl::OUStringBuffer buf( pAnyWidget->maPropName );
1134*cdf0e10cSrcweir                 buf.append( sal_Unicode (':') );
1135*cdf0e10cSrcweir                 mpLabel->SetText( buf.makeStringAndClear() );
1136*cdf0e10cSrcweir             }
1137*cdf0e10cSrcweir             mpValue = pAnyWidget;
1138*cdf0e10cSrcweir             mpFlag = new layout::CheckBox( pWinParent );
1139*cdf0e10cSrcweir             mpFlag->SetToggleHdl( LINK( mpValue, AnyWidget, FlagToggledHdl ) );
1140*cdf0e10cSrcweir             mpValue->mpFlag = mpFlag;
1141*cdf0e10cSrcweir         }
1142*cdf0e10cSrcweir 
1143*cdf0e10cSrcweir         ~PropertyEntry()
1144*cdf0e10cSrcweir         {
1145*cdf0e10cSrcweir #if DEBUG_PRINT
1146*cdf0e10cSrcweir                 fprintf(stderr, "REMOVING label, flag and value\n");
1147*cdf0e10cSrcweir #endif
1148*cdf0e10cSrcweir             delete mpLabel;
1149*cdf0e10cSrcweir             delete mpFlag;
1150*cdf0e10cSrcweir             delete mpValue;
1151*cdf0e10cSrcweir         }
1152*cdf0e10cSrcweir 
1153*cdf0e10cSrcweir         // Use this factory rather than the constructor -- check for NULL
1154*cdf0e10cSrcweir         static PropertyEntry *construct( Widget *pWidget, rtl::OUString aPropName,
1155*cdf0e10cSrcweir                                          Widget::PropertyKind aPropKind, sal_uInt16 nType,
1156*cdf0e10cSrcweir                                          layout::Window *pWinParent )
1157*cdf0e10cSrcweir         {
1158*cdf0e10cSrcweir             AnyWidget *pAnyWidget;
1159*cdf0e10cSrcweir             switch (nType) {
1160*cdf0e10cSrcweir                 case uno::TypeClass_STRING:
1161*cdf0e10cSrcweir                     if ( aPropName.compareToAscii( "FontStyleName" ) == 0 )
1162*cdf0e10cSrcweir                     {
1163*cdf0e10cSrcweir                         pAnyWidget = new AnyFontStyle( pWidget, aPropName, aPropKind, pWinParent );
1164*cdf0e10cSrcweir                         break;
1165*cdf0e10cSrcweir                     }
1166*cdf0e10cSrcweir                     pAnyWidget = new AnyEdit( pWidget, aPropName, aPropKind, pWinParent );
1167*cdf0e10cSrcweir                     break;
1168*cdf0e10cSrcweir                 case uno::TypeClass_SHORT:
1169*cdf0e10cSrcweir                     if ( aPropName.compareToAscii( "Align" ) == 0 )
1170*cdf0e10cSrcweir                     {
1171*cdf0e10cSrcweir                         pAnyWidget = new AnyAlign( pWidget, aPropName, aPropKind, pWinParent );
1172*cdf0e10cSrcweir                         break;
1173*cdf0e10cSrcweir                     }
1174*cdf0e10cSrcweir                     // otherwise, treat as any other number...
1175*cdf0e10cSrcweir                 case uno::TypeClass_LONG:
1176*cdf0e10cSrcweir                 case uno::TypeClass_UNSIGNED_LONG:
1177*cdf0e10cSrcweir                     pAnyWidget = new AnyInteger( pWidget, aPropName, aPropKind, pWinParent );
1178*cdf0e10cSrcweir                     break;
1179*cdf0e10cSrcweir                 case uno::TypeClass_FLOAT:
1180*cdf0e10cSrcweir                 case uno::TypeClass_DOUBLE:
1181*cdf0e10cSrcweir                     pAnyWidget = new AnyFloat( pWidget, aPropName, aPropKind, pWinParent );
1182*cdf0e10cSrcweir                     break;
1183*cdf0e10cSrcweir                 case uno::TypeClass_BOOLEAN:
1184*cdf0e10cSrcweir                     pAnyWidget = new AnyCheckBox( pWidget, aPropName, aPropKind, pWinParent );
1185*cdf0e10cSrcweir                     break;
1186*cdf0e10cSrcweir                 default:
1187*cdf0e10cSrcweir                     return NULL;
1188*cdf0e10cSrcweir             }
1189*cdf0e10cSrcweir             return new PropertyEntry( pWinParent, pAnyWidget );
1190*cdf0e10cSrcweir         }
1191*cdf0e10cSrcweir     };
1192*cdf0e10cSrcweir 
1193*cdf0e10cSrcweir     layout::Window *mpParentWindow;
1194*cdf0e10cSrcweir 
1195*cdf0e10cSrcweir     std::list< PropertyEntry* > maPropertiesList;
1196*cdf0e10cSrcweir     layout::FixedLine *mpSeparator;
1197*cdf0e10cSrcweir 
1198*cdf0e10cSrcweir     // some properties are obscure, or simply don't make sense in this
1199*cdf0e10cSrcweir     // context. Let's just ignore them.
1200*cdf0e10cSrcweir     // Maybe we could offer them in an expander or something...
1201*cdf0e10cSrcweir     static bool toIgnore( rtl::OUString prop )
1202*cdf0e10cSrcweir     {
1203*cdf0e10cSrcweir         // binary search -- keep the list sorted alphabetically
1204*cdf0e10cSrcweir         static char const *toIgnoreList[] = {
1205*cdf0e10cSrcweir             "DefaultControl", "FocusOnClick", "FontCharWidth", "FontCharset",
1206*cdf0e10cSrcweir             "FontEmphasisMark", "FontFamily", "FontHeight", "FontKerning", "FontName",
1207*cdf0e10cSrcweir             "FontOrientation", "FontPitch", "FontRelief", "FontSlant", "FontStrikeout",
1208*cdf0e10cSrcweir             "FontType", "FontWordLineMode", "HelpText", "HelpURL", "MultiLine",
1209*cdf0e10cSrcweir             "Printable", "Repeat", "RepeatDelay", "Tabstop"
1210*cdf0e10cSrcweir         };
1211*cdf0e10cSrcweir 
1212*cdf0e10cSrcweir #if 0
1213*cdf0e10cSrcweir         // checks list sanity -- enable this when you add some entries...
1214*cdf0e10cSrcweir         for ( unsigned int i = 1; i < sizeof( toIgnoreList )/sizeof( char * ); i++ )
1215*cdf0e10cSrcweir         {
1216*cdf0e10cSrcweir             if ( strcmp(toIgnoreList[i-1], toIgnoreList[i]) >= 0 )
1217*cdf0e10cSrcweir             {
1218*cdf0e10cSrcweir                 printf("ignore list not ordered properly: "
1219*cdf0e10cSrcweir                        "'%s' should come before '%s'\n",
1220*cdf0e10cSrcweir                        toIgnoreList[i], toIgnoreList[i-1]);
1221*cdf0e10cSrcweir                 exit(-1);
1222*cdf0e10cSrcweir             }
1223*cdf0e10cSrcweir         }
1224*cdf0e10cSrcweir #endif
1225*cdf0e10cSrcweir 
1226*cdf0e10cSrcweir         int min = 0, max = sizeof( toIgnoreList )/sizeof( char * ) - 1, mid, cmp;
1227*cdf0e10cSrcweir         do {
1228*cdf0e10cSrcweir             mid = min + (max - min)/2;
1229*cdf0e10cSrcweir             cmp = prop.compareToAscii( toIgnoreList[ mid ] );
1230*cdf0e10cSrcweir             if ( cmp > 0 )
1231*cdf0e10cSrcweir                 min = mid+1;
1232*cdf0e10cSrcweir             else if ( cmp < 0 )
1233*cdf0e10cSrcweir                 max = mid-1;
1234*cdf0e10cSrcweir             else
1235*cdf0e10cSrcweir                 return true;
1236*cdf0e10cSrcweir         } while ( min <= max );
1237*cdf0e10cSrcweir         return false;
1238*cdf0e10cSrcweir     }
1239*cdf0e10cSrcweir 
1240*cdf0e10cSrcweir public:
1241*cdf0e10cSrcweir     PropertiesList( layout::Dialog *dialog )
1242*cdf0e10cSrcweir         : layout::Table( dialog, "properties-box" )
1243*cdf0e10cSrcweir         , mpParentWindow( dialog ), mpSeparator( 0 )
1244*cdf0e10cSrcweir     {
1245*cdf0e10cSrcweir     }
1246*cdf0e10cSrcweir 
1247*cdf0e10cSrcweir     ~PropertiesList()
1248*cdf0e10cSrcweir     {
1249*cdf0e10cSrcweir         clear();
1250*cdf0e10cSrcweir     }
1251*cdf0e10cSrcweir 
1252*cdf0e10cSrcweir private:
1253*cdf0e10cSrcweir     // auxiliary, add properties from the peer to the list
1254*cdf0e10cSrcweir     void addProperties( Widget *pWidget, Widget::PropertyKind rKind )
1255*cdf0e10cSrcweir     {
1256*cdf0e10cSrcweir         Widget::PropertyIterator it( pWidget, rKind );
1257*cdf0e10cSrcweir         while ( it.hasNext() )
1258*cdf0e10cSrcweir         {
1259*cdf0e10cSrcweir             beans::Property prop = it.next();
1260*cdf0e10cSrcweir             rtl::OUString name( prop.Name );
1261*cdf0e10cSrcweir             if ( toIgnore( name ) )
1262*cdf0e10cSrcweir                 continue;
1263*cdf0e10cSrcweir             sal_uInt16 type = static_cast< sal_uInt16 >( prop.Type.getTypeClass() );
1264*cdf0e10cSrcweir 
1265*cdf0e10cSrcweir             PropertyEntry *propEntry = PropertyEntry::construct(
1266*cdf0e10cSrcweir                 pWidget, name, rKind, type, mpParentWindow );
1267*cdf0e10cSrcweir 
1268*cdf0e10cSrcweir             if ( propEntry )
1269*cdf0e10cSrcweir             {
1270*cdf0e10cSrcweir                 Add( propEntry->mpLabel, false, false );
1271*cdf0e10cSrcweir 
1272*cdf0e10cSrcweir                 // HACK: one of these will return Null...
1273*cdf0e10cSrcweir                 Add( propEntry->mpValue->getWindow(), true, false );
1274*cdf0e10cSrcweir                 Add( propEntry->mpValue->getContainer(), true, false );
1275*cdf0e10cSrcweir 
1276*cdf0e10cSrcweir                 Add( propEntry->mpFlag, false, false );
1277*cdf0e10cSrcweir                 maPropertiesList.push_back( propEntry );
1278*cdf0e10cSrcweir             }
1279*cdf0e10cSrcweir         }
1280*cdf0e10cSrcweir     }
1281*cdf0e10cSrcweir 
1282*cdf0e10cSrcweir public:
1283*cdf0e10cSrcweir     void selectedWidget( Widget *pWidget )
1284*cdf0e10cSrcweir     {
1285*cdf0e10cSrcweir         clear();
1286*cdf0e10cSrcweir 
1287*cdf0e10cSrcweir         if ( !pWidget )
1288*cdf0e10cSrcweir             return;
1289*cdf0e10cSrcweir 
1290*cdf0e10cSrcweir         addProperties( pWidget, Widget::CONTAINER_PROPERTY );
1291*cdf0e10cSrcweir 
1292*cdf0e10cSrcweir         mpSeparator = new layout::FixedLine( mpParentWindow );
1293*cdf0e10cSrcweir         // TODO: we may want to have to separate list widgets here...
1294*cdf0e10cSrcweir         Add( mpSeparator, false, false, 3, 1 );
1295*cdf0e10cSrcweir 
1296*cdf0e10cSrcweir         addProperties( pWidget, Widget::WINDOW_PROPERTY );
1297*cdf0e10cSrcweir 
1298*cdf0e10cSrcweir         ShowAll( true );
1299*cdf0e10cSrcweir     }
1300*cdf0e10cSrcweir 
1301*cdf0e10cSrcweir     void clear()
1302*cdf0e10cSrcweir     {
1303*cdf0e10cSrcweir         ///FIXME: crash
1304*cdf0e10cSrcweir         Container::Clear();
1305*cdf0e10cSrcweir 
1306*cdf0e10cSrcweir         for ( std::list< PropertyEntry* >::iterator it = maPropertiesList.begin();
1307*cdf0e10cSrcweir               it != maPropertiesList.end(); it++)
1308*cdf0e10cSrcweir             delete *it;
1309*cdf0e10cSrcweir         maPropertiesList.clear();
1310*cdf0e10cSrcweir 
1311*cdf0e10cSrcweir         delete mpSeparator;
1312*cdf0e10cSrcweir         mpSeparator = NULL;
1313*cdf0e10cSrcweir     }
1314*cdf0e10cSrcweir };
1315*cdf0e10cSrcweir 
1316*cdf0e10cSrcweir IMPL_LINK( PropertiesList::PropertyEntry::AnyWidget, ApplyPropertyHdl, layout::Window *, pWin )
1317*cdf0e10cSrcweir {
1318*cdf0e10cSrcweir     (void) pWin;
1319*cdf0e10cSrcweir     store();
1320*cdf0e10cSrcweir     return 0;
1321*cdf0e10cSrcweir }
1322*cdf0e10cSrcweir 
1323*cdf0e10cSrcweir IMPL_LINK( PropertiesList::PropertyEntry::AnyWidget, FlagToggledHdl, layout::CheckBox *, pCheck )
1324*cdf0e10cSrcweir {
1325*cdf0e10cSrcweir #if DEBUG_PRINT
1326*cdf0e10cSrcweir     fprintf(stderr, "Property flag pressed -- is: %d\n", pCheck->IsChecked());
1327*cdf0e10cSrcweir #endif
1328*cdf0e10cSrcweir     if ( !mbBlockFlagCallback )
1329*cdf0e10cSrcweir     {
1330*cdf0e10cSrcweir         bool checked = pCheck->IsChecked();
1331*cdf0e10cSrcweir         if ( !checked )  // revert
1332*cdf0e10cSrcweir         {
1333*cdf0e10cSrcweir #if DEBUG_PRINT
1334*cdf0e10cSrcweir             fprintf(stderr, "revert\n");
1335*cdf0e10cSrcweir #endif
1336*cdf0e10cSrcweir             load();
1337*cdf0e10cSrcweir         }
1338*cdf0e10cSrcweir         else
1339*cdf0e10cSrcweir         {
1340*cdf0e10cSrcweir #if DEBUG_PRINT
1341*cdf0e10cSrcweir             fprintf(stderr, "user can't dirty the flag!\n");
1342*cdf0e10cSrcweir #endif
1343*cdf0e10cSrcweir             // User can't flag the property as dirty
1344*cdf0e10cSrcweir             // Actually, we may want to allow the designer to force a property to be stored.
1345*cdf0e10cSrcweir             // Could be useful when the default value of some new property wasn't yet decided...
1346*cdf0e10cSrcweir             CheckFlag( false, true );
1347*cdf0e10cSrcweir         }
1348*cdf0e10cSrcweir     }
1349*cdf0e10cSrcweir #if DEBUG_PRINT
1350*cdf0e10cSrcweir     else
1351*cdf0e10cSrcweir         fprintf(stderr, "Property flag pressed -- BLOCKED\n");
1352*cdf0e10cSrcweir #endif
1353*cdf0e10cSrcweir     return 0;
1354*cdf0e10cSrcweir }
1355*cdf0e10cSrcweir 
1356*cdf0e10cSrcweir IMPL_LINK( PropertiesList::PropertyEntry::AnyEdit, ExpandEditHdl, layout::PushButton *, pBtn )
1357*cdf0e10cSrcweir {
1358*cdf0e10cSrcweir     setAsMultiLine( pBtn->IsChecked() );
1359*cdf0e10cSrcweir     return 0;
1360*cdf0e10cSrcweir }
1361*cdf0e10cSrcweir 
1362*cdf0e10cSrcweir //** SortListBox auxiliary widget
1363*cdf0e10cSrcweir 
1364*cdf0e10cSrcweir class SortListBox
1365*cdf0e10cSrcweir {        // For a manual sort ListBox; asks for a ListBox and Up/Down/Remove
1366*cdf0e10cSrcweir          // buttons to wrap
1367*cdf0e10cSrcweir     DECL_LINK( ItemSelectedHdl, layout::ListBox* );
1368*cdf0e10cSrcweir     DECL_LINK( UpPressedHdl, layout::Button* );
1369*cdf0e10cSrcweir     DECL_LINK( DownPressedHdl, layout::Button* );
1370*cdf0e10cSrcweir     DECL_LINK( RemovePressedHdl, layout::Button* );
1371*cdf0e10cSrcweir     layout::PushButton *mpUpButton, *mpDownButton, *mpRemoveButton;
1372*cdf0e10cSrcweir 
1373*cdf0e10cSrcweir protected:
1374*cdf0e10cSrcweir     layout::ListBox *mpListBox;
1375*cdf0e10cSrcweir 
1376*cdf0e10cSrcweir     virtual void upPressed( USHORT nPos )
1377*cdf0e10cSrcweir     {
1378*cdf0e10cSrcweir         XubString str = mpListBox->GetSelectEntry();
1379*cdf0e10cSrcweir         mpListBox->RemoveEntry( nPos );
1380*cdf0e10cSrcweir         nPos = mpListBox->InsertEntry( str, nPos-1 );
1381*cdf0e10cSrcweir         mpListBox->SelectEntryPos( nPos );
1382*cdf0e10cSrcweir     }
1383*cdf0e10cSrcweir 
1384*cdf0e10cSrcweir     virtual void downPressed( USHORT nPos )
1385*cdf0e10cSrcweir     {
1386*cdf0e10cSrcweir         XubString str = mpListBox->GetSelectEntry();
1387*cdf0e10cSrcweir         mpListBox->RemoveEntry( nPos );
1388*cdf0e10cSrcweir         nPos = mpListBox->InsertEntry( str, nPos+1 );
1389*cdf0e10cSrcweir         mpListBox->SelectEntryPos( nPos );
1390*cdf0e10cSrcweir     }
1391*cdf0e10cSrcweir 
1392*cdf0e10cSrcweir     virtual void removePressed( USHORT nPos )
1393*cdf0e10cSrcweir     {
1394*cdf0e10cSrcweir         mpListBox->RemoveEntry( nPos );
1395*cdf0e10cSrcweir     }
1396*cdf0e10cSrcweir 
1397*cdf0e10cSrcweir     virtual void itemSelected( USHORT nPos )
1398*cdf0e10cSrcweir     {
1399*cdf0e10cSrcweir         // if we had some XLayoutContainer::canAdd() or maxChildren() function
1400*cdf0e10cSrcweir         // we could make a function to check if we can move selected and enable/
1401*cdf0e10cSrcweir         // /disable the move buttons as appropriate
1402*cdf0e10cSrcweir 
1403*cdf0e10cSrcweir         if ( nPos == LISTBOX_ENTRY_NOTFOUND )
1404*cdf0e10cSrcweir         {
1405*cdf0e10cSrcweir             mpUpButton->Disable();
1406*cdf0e10cSrcweir             mpDownButton->Disable();
1407*cdf0e10cSrcweir             mpRemoveButton->Disable();
1408*cdf0e10cSrcweir         }
1409*cdf0e10cSrcweir         else
1410*cdf0e10cSrcweir         {
1411*cdf0e10cSrcweir             mpUpButton->Enable();
1412*cdf0e10cSrcweir             mpDownButton->Enable();
1413*cdf0e10cSrcweir             mpRemoveButton->Enable();
1414*cdf0e10cSrcweir         }
1415*cdf0e10cSrcweir     }
1416*cdf0e10cSrcweir 
1417*cdf0e10cSrcweir public:
1418*cdf0e10cSrcweir     SortListBox( layout::ListBox *pListBox, layout::PushButton *pUpButton, layout::PushButton *pDownButton,
1419*cdf0e10cSrcweir                  layout::PushButton *pRemoveButton )
1420*cdf0e10cSrcweir         : mpUpButton( pUpButton), mpDownButton( pDownButton), mpRemoveButton( pRemoveButton ),
1421*cdf0e10cSrcweir           mpListBox( pListBox )
1422*cdf0e10cSrcweir     {
1423*cdf0e10cSrcweir         mpListBox->SetSelectHdl( LINK( this, SortListBox, ItemSelectedHdl ) );
1424*cdf0e10cSrcweir 
1425*cdf0e10cSrcweir         mpUpButton->SetModeImage( layout::Image ( "res/commandimagelist/lc_moveup.png" ) );
1426*cdf0e10cSrcweir         mpUpButton->SetImageAlign( IMAGEALIGN_LEFT );
1427*cdf0e10cSrcweir         mpUpButton->SetClickHdl( LINK( this, SortListBox, UpPressedHdl ) );
1428*cdf0e10cSrcweir 
1429*cdf0e10cSrcweir         mpDownButton->SetModeImage( layout::Image ( "res/commandimagelist/lc_movedown.png" ) );
1430*cdf0e10cSrcweir         mpDownButton->SetImageAlign( IMAGEALIGN_LEFT );
1431*cdf0e10cSrcweir         mpDownButton->SetClickHdl( LINK( this, SortListBox, DownPressedHdl ) );
1432*cdf0e10cSrcweir 
1433*cdf0e10cSrcweir         // "res/commandimagelist/lch_delete.png", "res/commandimagelist/lc_delete.png"
1434*cdf0e10cSrcweir         mpRemoveButton->SetModeImage( layout::Image ( "res/commandimagelist/sc_closedoc.png" ) );
1435*cdf0e10cSrcweir         mpRemoveButton->SetImageAlign( IMAGEALIGN_LEFT );
1436*cdf0e10cSrcweir         mpRemoveButton->SetClickHdl( LINK( this, SortListBox, RemovePressedHdl ) );
1437*cdf0e10cSrcweir 
1438*cdf0e10cSrcweir         // fire an un-select event
1439*cdf0e10cSrcweir         itemSelected( LISTBOX_ENTRY_NOTFOUND );
1440*cdf0e10cSrcweir     }
1441*cdf0e10cSrcweir 
1442*cdf0e10cSrcweir     virtual ~SortListBox();
1443*cdf0e10cSrcweir };
1444*cdf0e10cSrcweir 
1445*cdf0e10cSrcweir SortListBox::~SortListBox()
1446*cdf0e10cSrcweir {
1447*cdf0e10cSrcweir     delete mpListBox;
1448*cdf0e10cSrcweir     delete mpUpButton;
1449*cdf0e10cSrcweir     delete mpDownButton;
1450*cdf0e10cSrcweir     delete mpRemoveButton;
1451*cdf0e10cSrcweir }
1452*cdf0e10cSrcweir 
1453*cdf0e10cSrcweir IMPL_LINK( SortListBox, UpPressedHdl, layout::Button *, pBtn )
1454*cdf0e10cSrcweir {
1455*cdf0e10cSrcweir     (void) pBtn;
1456*cdf0e10cSrcweir     USHORT pos = mpListBox->GetSelectEntryPos();
1457*cdf0e10cSrcweir     if ( pos > 0 && pos != LISTBOX_ENTRY_NOTFOUND )
1458*cdf0e10cSrcweir         upPressed( pos );
1459*cdf0e10cSrcweir     return 0;
1460*cdf0e10cSrcweir }
1461*cdf0e10cSrcweir 
1462*cdf0e10cSrcweir IMPL_LINK( SortListBox, DownPressedHdl, layout::Button *, pBtn )
1463*cdf0e10cSrcweir {
1464*cdf0e10cSrcweir     (void) pBtn;
1465*cdf0e10cSrcweir     USHORT pos = mpListBox->GetSelectEntryPos();
1466*cdf0e10cSrcweir     if ( pos < mpListBox->GetEntryCount() && pos != LISTBOX_ENTRY_NOTFOUND )
1467*cdf0e10cSrcweir         downPressed( pos );
1468*cdf0e10cSrcweir     return 0;
1469*cdf0e10cSrcweir }
1470*cdf0e10cSrcweir 
1471*cdf0e10cSrcweir IMPL_LINK( SortListBox, RemovePressedHdl, layout::Button *, pBtn )
1472*cdf0e10cSrcweir {
1473*cdf0e10cSrcweir     (void) pBtn;
1474*cdf0e10cSrcweir     USHORT pos = mpListBox->GetSelectEntryPos();
1475*cdf0e10cSrcweir     if ( pos != LISTBOX_ENTRY_NOTFOUND )
1476*cdf0e10cSrcweir         removePressed( pos );
1477*cdf0e10cSrcweir     return 0;
1478*cdf0e10cSrcweir }
1479*cdf0e10cSrcweir 
1480*cdf0e10cSrcweir IMPL_LINK( SortListBox, ItemSelectedHdl, layout::ListBox *, pList )
1481*cdf0e10cSrcweir {
1482*cdf0e10cSrcweir     (void) pList;
1483*cdf0e10cSrcweir     USHORT pos = mpListBox->GetSelectEntryPos();
1484*cdf0e10cSrcweir     itemSelected( pos );
1485*cdf0e10cSrcweir     return 0;
1486*cdf0e10cSrcweir }
1487*cdf0e10cSrcweir 
1488*cdf0e10cSrcweir //** LayoutTree widget
1489*cdf0e10cSrcweir 
1490*cdf0e10cSrcweir class LayoutTree : public SortListBox
1491*cdf0e10cSrcweir {
1492*cdf0e10cSrcweir public:
1493*cdf0e10cSrcweir     struct Listener
1494*cdf0e10cSrcweir     {
1495*cdf0e10cSrcweir         virtual void widgetSelected( Widget *pWidget ) = 0;
1496*cdf0e10cSrcweir     };
1497*cdf0e10cSrcweir 
1498*cdf0e10cSrcweir private:
1499*cdf0e10cSrcweir     Listener *mpListener;
1500*cdf0e10cSrcweir 
1501*cdf0e10cSrcweir public:
1502*cdf0e10cSrcweir     Widget *mpRootWidget;
1503*cdf0e10cSrcweir 
1504*cdf0e10cSrcweir     LayoutTree( layout::Dialog *dialog )
1505*cdf0e10cSrcweir         : SortListBox( new layout::ListBox( dialog, "layout-tree" ),
1506*cdf0e10cSrcweir                        new layout::PushButton( dialog, "layout-up-button" ),
1507*cdf0e10cSrcweir                        new layout::PushButton( dialog, "layout-down-button" ),
1508*cdf0e10cSrcweir                        new layout::PushButton( dialog, "layout-remove-button" ) )
1509*cdf0e10cSrcweir     {
1510*cdf0e10cSrcweir         layout::PeerHandle handle = dialog->GetPeerHandle( "preview-box" );
1511*cdf0e10cSrcweir         uno::Reference< awt::XLayoutConstrains > xWidget( handle, uno::UNO_QUERY );
1512*cdf0e10cSrcweir         mpRootWidget = new Widget( xWidget, "root" );
1513*cdf0e10cSrcweir     }
1514*cdf0e10cSrcweir 
1515*cdf0e10cSrcweir     virtual ~LayoutTree();
1516*cdf0e10cSrcweir 
1517*cdf0e10cSrcweir     Widget *getWidget( int nPos )
1518*cdf0e10cSrcweir     {
1519*cdf0e10cSrcweir         if ( nPos != LISTBOX_ENTRY_NOTFOUND )
1520*cdf0e10cSrcweir             return FlatLayout::get( mpRootWidget, nPos );
1521*cdf0e10cSrcweir         return NULL;
1522*cdf0e10cSrcweir     }
1523*cdf0e10cSrcweir 
1524*cdf0e10cSrcweir     Widget *getSelectedWidget()
1525*cdf0e10cSrcweir     {
1526*cdf0e10cSrcweir         Widget *pWidget = getWidget( mpListBox->GetSelectEntryPos() );
1527*cdf0e10cSrcweir         if ( !pWidget )  // return root, if none selected
1528*cdf0e10cSrcweir             pWidget = mpRootWidget;
1529*cdf0e10cSrcweir         return pWidget;
1530*cdf0e10cSrcweir     }
1531*cdf0e10cSrcweir 
1532*cdf0e10cSrcweir     void selectWidget( Widget *pWidget )
1533*cdf0e10cSrcweir     {
1534*cdf0e10cSrcweir         int pos = FlatLayout::get( mpRootWidget, pWidget );
1535*cdf0e10cSrcweir         if ( pos == -1 )
1536*cdf0e10cSrcweir             // if asked to select hidden root, select visible root
1537*cdf0e10cSrcweir             pos = 0;
1538*cdf0e10cSrcweir         mpListBox->SelectEntryPos( sal::static_int_cast< USHORT >( pos ) );
1539*cdf0e10cSrcweir     }
1540*cdf0e10cSrcweir 
1541*cdf0e10cSrcweir     void rebuild()
1542*cdf0e10cSrcweir     {
1543*cdf0e10cSrcweir         struct inner
1544*cdf0e10cSrcweir         {
1545*cdf0e10cSrcweir             // pads a string with whitespaces
1546*cdf0e10cSrcweir             static rtl::OUString padString( rtl::OUString name, int depth )
1547*cdf0e10cSrcweir             {
1548*cdf0e10cSrcweir                 rtl::OStringBuffer aBuf( depth * 4 + name.getLength() + 2 );
1549*cdf0e10cSrcweir                 for (int i = 0; i < depth; i++)
1550*cdf0e10cSrcweir                     aBuf.append( "    " );
1551*cdf0e10cSrcweir                 aBuf.append( rtl::OUStringToOString( name, RTL_TEXTENCODING_ASCII_US ) );
1552*cdf0e10cSrcweir                 return rtl::OUString( aBuf.getStr(), aBuf.getLength(),
1553*cdf0e10cSrcweir                                       RTL_TEXTENCODING_UTF8 );
1554*cdf0e10cSrcweir             }
1555*cdf0e10cSrcweir         };
1556*cdf0e10cSrcweir 
1557*cdf0e10cSrcweir         mpListBox->Clear();
1558*cdf0e10cSrcweir         for ( Widget *i = FlatLayout::next( mpRootWidget ); i; i = FlatLayout::next( i ) )
1559*cdf0e10cSrcweir             mpListBox->InsertEntry( inner::padString( i->getLabel(), i->getDepth()-1 ) );
1560*cdf0e10cSrcweir 
1561*cdf0e10cSrcweir         // any selection, no longer is. ListBox doesn't fire the event on this case;
1562*cdf0e10cSrcweir         // force it.
1563*cdf0e10cSrcweir         itemSelected( LISTBOX_ENTRY_NOTFOUND );
1564*cdf0e10cSrcweir     }
1565*cdf0e10cSrcweir 
1566*cdf0e10cSrcweir     void setListener( Listener *pListener )
1567*cdf0e10cSrcweir     { mpListener = pListener; }
1568*cdf0e10cSrcweir 
1569*cdf0e10cSrcweir     // print in XML format...
1570*cdf0e10cSrcweir 
1571*cdf0e10cSrcweir     static rtl::OUString toXMLNaming (const rtl::OUString &string)
1572*cdf0e10cSrcweir     {
1573*cdf0e10cSrcweir         rtl::OUStringBuffer buffer (string.getLength());
1574*cdf0e10cSrcweir         sal_Unicode *str = string.pData->buffer;
1575*cdf0e10cSrcweir         for (int i = 0; i < string.getLength(); i++) {
1576*cdf0e10cSrcweir             if ( str[i] >= 'A' && str[i] <= 'Z' )
1577*cdf0e10cSrcweir             {
1578*cdf0e10cSrcweir                 if ( i > 0 )
1579*cdf0e10cSrcweir                     buffer.append ((sal_Unicode) '-');
1580*cdf0e10cSrcweir                 buffer.append ((sal_Unicode) (str[i] - 'A' + 'a'));
1581*cdf0e10cSrcweir             }
1582*cdf0e10cSrcweir             else
1583*cdf0e10cSrcweir                 buffer.append ((sal_Unicode) str[i]);
1584*cdf0e10cSrcweir         }
1585*cdf0e10cSrcweir 
1586*cdf0e10cSrcweir         return buffer.makeStringAndClear();
1587*cdf0e10cSrcweir     }
1588*cdf0e10cSrcweir 
1589*cdf0e10cSrcweir     void print()
1590*cdf0e10cSrcweir     {
1591*cdf0e10cSrcweir         printf("\t\tExport:\n");
1592*cdf0e10cSrcweir         printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
1593*cdf0e10cSrcweir                "<dialog xmlns=\"http://openoffice.org/2007/layout\"\n"
1594*cdf0e10cSrcweir                "        xmlns:cnt=\"http://openoffice.org/2007/layout/container\"\n"
1595*cdf0e10cSrcweir                "        id=\"dialog\" title=\"Unnamed\" sizeable=\"true\" >\n");
1596*cdf0e10cSrcweir 
1597*cdf0e10cSrcweir         for ( Widget *i = FlatLayout::next( mpRootWidget ); i; i = FlatLayout::next( i ) )
1598*cdf0e10cSrcweir         {
1599*cdf0e10cSrcweir             for ( int d = i->getDepth(); d > 0; d-- )
1600*cdf0e10cSrcweir                 printf("    ");
1601*cdf0e10cSrcweir             printf("<%s ", OUSTRING_CSTR( i->getUnoName() ) );
1602*cdf0e10cSrcweir 
1603*cdf0e10cSrcweir             for ( int kind = 0; kind < 2; kind++ )
1604*cdf0e10cSrcweir             {
1605*cdf0e10cSrcweir                 Widget::PropertyKind wKind = kind == 0 ? Widget::WINDOW_PROPERTY
1606*cdf0e10cSrcweir                     : Widget::CONTAINER_PROPERTY;
1607*cdf0e10cSrcweir                 Widget::PropertyIterator it( i, wKind );
1608*cdf0e10cSrcweir                 while ( it.hasNext() )
1609*cdf0e10cSrcweir                 {
1610*cdf0e10cSrcweir                     beans::Property prop = it.next();
1611*cdf0e10cSrcweir                     if ( !i->isPropertyTouched( prop.Name, wKind ) )
1612*cdf0e10cSrcweir                         continue;
1613*cdf0e10cSrcweir 
1614*cdf0e10cSrcweir                     rtl::OUString value = i->getProperty( prop.Name, wKind );
1615*cdf0e10cSrcweir                     if ( prop.Type.getTypeClass() == uno::TypeClass_BOOLEAN )
1616*cdf0e10cSrcweir                     {
1617*cdf0e10cSrcweir                         if ( value.compareToAscii( "0" ) )
1618*cdf0e10cSrcweir                             value = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("false") );
1619*cdf0e10cSrcweir                         else
1620*cdf0e10cSrcweir                             value = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("true") );
1621*cdf0e10cSrcweir                     }
1622*cdf0e10cSrcweir 
1623*cdf0e10cSrcweir                     if ( value.getLength() > 0 )
1624*cdf0e10cSrcweir                         printf("%s%s=\"%s\" ",
1625*cdf0e10cSrcweir                                kind == 0 ? "" : "cnt:",
1626*cdf0e10cSrcweir                                OUSTRING_CSTR( toXMLNaming( prop.Name ) ), OUSTRING_CSTR( value )
1627*cdf0e10cSrcweir                             );
1628*cdf0e10cSrcweir 
1629*cdf0e10cSrcweir                 }
1630*cdf0e10cSrcweir             }
1631*cdf0e10cSrcweir             printf("/>\n");
1632*cdf0e10cSrcweir         }
1633*cdf0e10cSrcweir         printf("</dialog>\n");
1634*cdf0e10cSrcweir     }
1635*cdf0e10cSrcweir 
1636*cdf0e10cSrcweir protected:
1637*cdf0e10cSrcweir     virtual void upPressed( USHORT nPos )
1638*cdf0e10cSrcweir     {
1639*cdf0e10cSrcweir         Widget *pWidget = getWidget( nPos );
1640*cdf0e10cSrcweir         if ( FlatLayout::moveWidget( pWidget, true ) )
1641*cdf0e10cSrcweir             rebuild();
1642*cdf0e10cSrcweir         selectWidget( pWidget );
1643*cdf0e10cSrcweir     }
1644*cdf0e10cSrcweir 
1645*cdf0e10cSrcweir     virtual void downPressed( USHORT nPos )
1646*cdf0e10cSrcweir     {
1647*cdf0e10cSrcweir         Widget *pWidget = getWidget( nPos );
1648*cdf0e10cSrcweir         if ( FlatLayout::moveWidget( pWidget, false ) )
1649*cdf0e10cSrcweir             rebuild();
1650*cdf0e10cSrcweir         selectWidget( pWidget );
1651*cdf0e10cSrcweir     }
1652*cdf0e10cSrcweir 
1653*cdf0e10cSrcweir     virtual void removePressed( USHORT nPos )
1654*cdf0e10cSrcweir     {
1655*cdf0e10cSrcweir         Widget *pWidget = getWidget( nPos );
1656*cdf0e10cSrcweir         if ( pWidget )
1657*cdf0e10cSrcweir         {
1658*cdf0e10cSrcweir             pWidget->up()->removeChild( pWidget );
1659*cdf0e10cSrcweir             delete pWidget;
1660*cdf0e10cSrcweir             rebuild();
1661*cdf0e10cSrcweir         }
1662*cdf0e10cSrcweir     }
1663*cdf0e10cSrcweir 
1664*cdf0e10cSrcweir     virtual void itemSelected( USHORT nPos )
1665*cdf0e10cSrcweir     {
1666*cdf0e10cSrcweir         mpListener->widgetSelected( getWidget( nPos ) );
1667*cdf0e10cSrcweir         SortListBox::itemSelected( nPos );
1668*cdf0e10cSrcweir     }
1669*cdf0e10cSrcweir };
1670*cdf0e10cSrcweir 
1671*cdf0e10cSrcweir LayoutTree::~LayoutTree()
1672*cdf0e10cSrcweir {
1673*cdf0e10cSrcweir     delete mpRootWidget;
1674*cdf0e10cSrcweir }
1675*cdf0e10cSrcweir 
1676*cdf0e10cSrcweir //** EditorImpl
1677*cdf0e10cSrcweir 
1678*cdf0e10cSrcweir class EditorImpl : public LayoutTree::Listener
1679*cdf0e10cSrcweir {
1680*cdf0e10cSrcweir     void createWidget( const char *unoName );
1681*cdf0e10cSrcweir 
1682*cdf0e10cSrcweir     PropertiesList *mpPropertiesList;
1683*cdf0e10cSrcweir     LayoutTree *mpLayoutTree;
1684*cdf0e10cSrcweir 
1685*cdf0e10cSrcweir     layout::PushButton *pImportButton, *pExportButton;
1686*cdf0e10cSrcweir #ifdef FILEDLG
1687*cdf0e10cSrcweir     FileDialog *pImportDialog;
1688*cdf0e10cSrcweir #endif
1689*cdf0e10cSrcweir     DECL_LINK( ImportButtonHdl, layout::PushButton* );
1690*cdf0e10cSrcweir     DECL_LINK( ExportButtonHdl, layout::PushButton* );
1691*cdf0e10cSrcweir #ifdef FILEDLG
1692*cdf0e10cSrcweir     DECL_LINK( ImportDialogHdl, FileDialog* );
1693*cdf0e10cSrcweir #endif
1694*cdf0e10cSrcweir 
1695*cdf0e10cSrcweir     // framework stuff
1696*cdf0e10cSrcweir     uno::Reference< lang::XMultiServiceFactory > mxFactory;
1697*cdf0e10cSrcweir     uno::Reference< awt::XToolkit > mxToolkit;
1698*cdf0e10cSrcweir     uno::Reference< awt::XWindow > mxToplevel;
1699*cdf0e10cSrcweir 
1700*cdf0e10cSrcweir     virtual void widgetSelected( Widget *pWidget );
1701*cdf0e10cSrcweir     DECL_LINK( CreateWidgetHdl, layout::Button* );
1702*cdf0e10cSrcweir 
1703*cdf0e10cSrcweir     std::list< layout::PushButton *> maCreateButtons;
1704*cdf0e10cSrcweir 
1705*cdf0e10cSrcweir public:
1706*cdf0e10cSrcweir 
1707*cdf0e10cSrcweir     EditorImpl( layout::Dialog *dialog,
1708*cdf0e10cSrcweir                 // we should probable open this channel (or whatever its called) ourselves
1709*cdf0e10cSrcweir                 uno::Reference< lang::XMultiServiceFactory > xMSF );
1710*cdf0e10cSrcweir     virtual ~EditorImpl();
1711*cdf0e10cSrcweir 
1712*cdf0e10cSrcweir     void loadFile( const rtl::OUString &aTestFile );
1713*cdf0e10cSrcweir };
1714*cdf0e10cSrcweir 
1715*cdf0e10cSrcweir EditorImpl::EditorImpl( layout::Dialog *dialog,
1716*cdf0e10cSrcweir                         uno::Reference< lang::XMultiServiceFactory > xFactory )
1717*cdf0e10cSrcweir     : mxFactory( xFactory )
1718*cdf0e10cSrcweir     , mxToplevel( dialog->GetPeerHandle( "dialog" ), uno::UNO_QUERY )
1719*cdf0e10cSrcweir     // FIXME: any of these should work
1720*cdf0e10cSrcweir     //dialog->getContext()->getRoot(), uno::UNO_QUERY )
1721*cdf0e10cSrcweir     // dialog->GetPeer(), uno::UNO_QUERY )
1722*cdf0e10cSrcweir {
1723*cdf0e10cSrcweir #if DEBUG_PRINT
1724*cdf0e10cSrcweir     fprintf (stderr, "EditorImpl()\n");
1725*cdf0e10cSrcweir #endif
1726*cdf0e10cSrcweir     // framework
1727*cdf0e10cSrcweir     mxToolkit = uno::Reference< awt::XToolkit >(
1728*cdf0e10cSrcweir         mxFactory->createInstance(
1729*cdf0e10cSrcweir             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.Toolkit" ) ) ),
1730*cdf0e10cSrcweir         uno::UNO_QUERY );
1731*cdf0e10cSrcweir     OSL_ASSERT( mxToolkit.is() );
1732*cdf0e10cSrcweir 
1733*cdf0e10cSrcweir     // custom widgets
1734*cdf0e10cSrcweir #if DEBUG_PRINT
1735*cdf0e10cSrcweir     fprintf (stderr, "custom widgets\n");
1736*cdf0e10cSrcweir #endif
1737*cdf0e10cSrcweir     mpPropertiesList = new PropertiesList( dialog );
1738*cdf0e10cSrcweir 
1739*cdf0e10cSrcweir     mpLayoutTree = new LayoutTree( dialog );
1740*cdf0e10cSrcweir     mpLayoutTree->setListener( this );
1741*cdf0e10cSrcweir 
1742*cdf0e10cSrcweir /*    if ( xImport.is() )
1743*cdf0e10cSrcweir       mpLayoutTree->getWidget( -1 )->addChild( new Widget( xImport, "import" ) );*/
1744*cdf0e10cSrcweir 
1745*cdf0e10cSrcweir     // create buttons
1746*cdf0e10cSrcweir     layout::Container aWidgets( dialog, "create-widget" );
1747*cdf0e10cSrcweir     layout::Container aContainers( dialog, "create-container" );
1748*cdf0e10cSrcweir     for ( int i = 0; i < WIDGETS_SPECS_LEN; i++ )
1749*cdf0e10cSrcweir     {
1750*cdf0e10cSrcweir         layout::PushButton *pBtn = new layout::PushButton( (layout::Window *) dialog );
1751*cdf0e10cSrcweir         pBtn->SetText( rtl::OUString::createFromAscii( WIDGETS_SPECS[ i ].pLabel ) );
1752*cdf0e10cSrcweir         pBtn->SetClickHdl( LINK( this, EditorImpl, CreateWidgetHdl ) );
1753*cdf0e10cSrcweir         if ( WIDGETS_SPECS[ i ].pIconName != NULL )
1754*cdf0e10cSrcweir         {
1755*cdf0e10cSrcweir             rtl::OString aPath ("res/commandimagelist/");
1756*cdf0e10cSrcweir             aPath += WIDGETS_SPECS[ i ].pIconName;
1757*cdf0e10cSrcweir             layout::Image aImg( aPath );
1758*cdf0e10cSrcweir             pBtn->SetModeImage( aImg );
1759*cdf0e10cSrcweir             pBtn->SetImageAlign( IMAGEALIGN_LEFT );
1760*cdf0e10cSrcweir         }
1761*cdf0e10cSrcweir         pBtn->Show();
1762*cdf0e10cSrcweir         maCreateButtons.push_back( pBtn );
1763*cdf0e10cSrcweir         layout::Container *pBox = WIDGETS_SPECS[ i ].bIsContainer ? &aContainers : &aWidgets;
1764*cdf0e10cSrcweir         pBox->Add( pBtn );
1765*cdf0e10cSrcweir     }
1766*cdf0e10cSrcweir 
1767*cdf0e10cSrcweir #ifdef FILEDLG
1768*cdf0e10cSrcweir     fprintf(stderr,"creating file dialog\n");
1769*cdf0e10cSrcweir     pImportDialog = new FileDialog( NULL/*(layout::Window *) dialog*/, 0 );
1770*cdf0e10cSrcweir     fprintf(stderr,"connecting it\n");
1771*cdf0e10cSrcweir     pImportDialog->SetFileSelectHdl( LINK( this, EditorImpl, ImportDialogHdl ) );
1772*cdf0e10cSrcweir     fprintf(stderr,"done file dialog\n");
1773*cdf0e10cSrcweir #endif
1774*cdf0e10cSrcweir 
1775*cdf0e10cSrcweir /*    pImportButton = new layout::PushButton( dialog, "import-button" );
1776*cdf0e10cSrcweir     pImportButton->SetClickHdl( LINK( this, EditorImpl, ImportButtonHdl ) );*/
1777*cdf0e10cSrcweir     pExportButton = new layout::PushButton( dialog, "export-button" );
1778*cdf0e10cSrcweir     pExportButton->SetClickHdl( LINK( this, EditorImpl, ExportButtonHdl ) );
1779*cdf0e10cSrcweir }
1780*cdf0e10cSrcweir 
1781*cdf0e10cSrcweir EditorImpl::~EditorImpl()
1782*cdf0e10cSrcweir {
1783*cdf0e10cSrcweir     delete mpPropertiesList;
1784*cdf0e10cSrcweir     delete mpLayoutTree;
1785*cdf0e10cSrcweir     for ( std::list< layout::PushButton * >::const_iterator i = maCreateButtons.begin();
1786*cdf0e10cSrcweir           i != maCreateButtons.end(); i++)
1787*cdf0e10cSrcweir         delete *i;
1788*cdf0e10cSrcweir     delete pImportButton;
1789*cdf0e10cSrcweir     delete pExportButton;
1790*cdf0e10cSrcweir #ifdef FILEDLG
1791*cdf0e10cSrcweir     delete pImportDialog;
1792*cdf0e10cSrcweir #endif
1793*cdf0e10cSrcweir }
1794*cdf0e10cSrcweir 
1795*cdf0e10cSrcweir void EditorImpl::loadFile( const rtl::OUString &aTestFile )
1796*cdf0e10cSrcweir {
1797*cdf0e10cSrcweir     fprintf( stderr, "TEST: layout instance\n" );
1798*cdf0e10cSrcweir     uno::Reference< awt::XLayoutRoot > xRoot
1799*cdf0e10cSrcweir         ( new EditorRoot( mxFactory, mpLayoutTree->mpRootWidget ) );
1800*cdf0e10cSrcweir 
1801*cdf0e10cSrcweir /*
1802*cdf0e10cSrcweir   mxMSF->createInstance
1803*cdf0e10cSrcweir   ( ::rtl::OUString::createFromAscii( "com.sun.star.awt.Layout" ) ),
1804*cdf0e10cSrcweir   uno::UNO_QUERY );
1805*cdf0e10cSrcweir */
1806*cdf0e10cSrcweir     if ( !xRoot.is() )
1807*cdf0e10cSrcweir     {
1808*cdf0e10cSrcweir         throw uno::RuntimeException(
1809*cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM("could not create awt Layout component!") ),
1810*cdf0e10cSrcweir             uno::Reference< uno::XInterface >() );
1811*cdf0e10cSrcweir     }
1812*cdf0e10cSrcweir 
1813*cdf0e10cSrcweir #if DEBUG_PRINT
1814*cdf0e10cSrcweir     fprintf( stderr, "TEST: initing root\n" );
1815*cdf0e10cSrcweir #endif
1816*cdf0e10cSrcweir 
1817*cdf0e10cSrcweir     uno::Reference< lang::XInitialization > xInit( xRoot, uno::UNO_QUERY );
1818*cdf0e10cSrcweir     if ( !xInit.is() )
1819*cdf0e10cSrcweir     {
1820*cdf0e10cSrcweir         throw uno::RuntimeException(
1821*cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM("Layout has no XInitialization!") ),
1822*cdf0e10cSrcweir             uno::Reference< uno::XInterface >() );
1823*cdf0e10cSrcweir     }
1824*cdf0e10cSrcweir 
1825*cdf0e10cSrcweir #if DEBUG_PRINT
1826*cdf0e10cSrcweir     fprintf( stderr, "TEST: running parser\n" );
1827*cdf0e10cSrcweir #endif
1828*cdf0e10cSrcweir     uno::Sequence< uno::Any > aParams( 1 );
1829*cdf0e10cSrcweir     aParams[0] <<= aTestFile;
1830*cdf0e10cSrcweir #if DEBUG_PRINT
1831*cdf0e10cSrcweir     fprintf( stderr, "TEST: do it\n" );
1832*cdf0e10cSrcweir #endif
1833*cdf0e10cSrcweir     xInit->initialize( aParams );
1834*cdf0e10cSrcweir #if DEBUG_PRINT
1835*cdf0e10cSrcweir     fprintf( stderr, "TEST: file loaded\n" );
1836*cdf0e10cSrcweir #endif
1837*cdf0e10cSrcweir 
1838*cdf0e10cSrcweir     mpLayoutTree->rebuild();
1839*cdf0e10cSrcweir }
1840*cdf0e10cSrcweir 
1841*cdf0e10cSrcweir void EditorImpl::createWidget( const char *name )
1842*cdf0e10cSrcweir {
1843*cdf0e10cSrcweir     Widget *pWidget = mpLayoutTree->getSelectedWidget();
1844*cdf0e10cSrcweir 
1845*cdf0e10cSrcweir     Widget *pChild = new Widget( rtl::OUString(), mxToolkit, uno::Reference< awt::XLayoutContainer >( mxToplevel, uno::UNO_QUERY ), rtl::OUString::createFromAscii( name ), awt::WindowAttribute::SHOW );
1846*cdf0e10cSrcweir     if ( !pWidget->addChild( pChild ) )
1847*cdf0e10cSrcweir     {
1848*cdf0e10cSrcweir         delete pChild;
1849*cdf0e10cSrcweir         // we may want to popup an error message
1850*cdf0e10cSrcweir     }
1851*cdf0e10cSrcweir     else
1852*cdf0e10cSrcweir     {
1853*cdf0e10cSrcweir         mpLayoutTree->rebuild();
1854*cdf0e10cSrcweir         mpLayoutTree->selectWidget( pWidget );
1855*cdf0e10cSrcweir     }
1856*cdf0e10cSrcweir }
1857*cdf0e10cSrcweir 
1858*cdf0e10cSrcweir void EditorImpl::widgetSelected( Widget *pWidget )
1859*cdf0e10cSrcweir {
1860*cdf0e10cSrcweir     // we know can't add widget to a non-container, so let's disable the create
1861*cdf0e10cSrcweir     // buttons then. Would be nice to have a method to check if a container is
1862*cdf0e10cSrcweir     // full as well...
1863*cdf0e10cSrcweir     if ( !pWidget || pWidget->isContainer() )
1864*cdf0e10cSrcweir     {
1865*cdf0e10cSrcweir         for ( std::list< layout::PushButton *>::const_iterator it = maCreateButtons.begin();
1866*cdf0e10cSrcweir               it != maCreateButtons.end(); it++)
1867*cdf0e10cSrcweir             (*it)->Enable();
1868*cdf0e10cSrcweir     }
1869*cdf0e10cSrcweir     else
1870*cdf0e10cSrcweir     {
1871*cdf0e10cSrcweir         for ( std::list< layout::PushButton *>::const_iterator it = maCreateButtons.begin();
1872*cdf0e10cSrcweir               it != maCreateButtons.end(); it++)
1873*cdf0e10cSrcweir             (*it)->Disable();
1874*cdf0e10cSrcweir     }
1875*cdf0e10cSrcweir 
1876*cdf0e10cSrcweir     mpPropertiesList->selectedWidget( pWidget );
1877*cdf0e10cSrcweir }
1878*cdf0e10cSrcweir 
1879*cdf0e10cSrcweir IMPL_LINK( EditorImpl, CreateWidgetHdl, layout::Button *, pBtn )
1880*cdf0e10cSrcweir {
1881*cdf0e10cSrcweir     int i = 0;
1882*cdf0e10cSrcweir     for ( std::list< layout::PushButton *>::const_iterator it = maCreateButtons.begin();
1883*cdf0e10cSrcweir           it != maCreateButtons.end(); it++, i++ )
1884*cdf0e10cSrcweir     {
1885*cdf0e10cSrcweir         if ( pBtn == *it )
1886*cdf0e10cSrcweir             break;
1887*cdf0e10cSrcweir     }
1888*cdf0e10cSrcweir     OSL_ASSERT( i < WIDGETS_SPECS_LEN );
1889*cdf0e10cSrcweir     createWidget( WIDGETS_SPECS[i].pName );
1890*cdf0e10cSrcweir     return 0;
1891*cdf0e10cSrcweir }
1892*cdf0e10cSrcweir 
1893*cdf0e10cSrcweir IMPL_LINK( EditorImpl, ImportButtonHdl, layout::PushButton *, pBtn )
1894*cdf0e10cSrcweir {
1895*cdf0e10cSrcweir     (void) pBtn;
1896*cdf0e10cSrcweir #if DEBUG_PRINT
1897*cdf0e10cSrcweir     fprintf(stderr, "IMPORT!\n");
1898*cdf0e10cSrcweir #endif
1899*cdf0e10cSrcweir #ifdef FILEDLG
1900*cdf0e10cSrcweir     pImportDialog->Execute();
1901*cdf0e10cSrcweir #endif
1902*cdf0e10cSrcweir 
1903*cdf0e10cSrcweir     return 0;
1904*cdf0e10cSrcweir }
1905*cdf0e10cSrcweir 
1906*cdf0e10cSrcweir #ifdef FILEDLG
1907*cdf0e10cSrcweir IMPL_LINK( EditorImpl, ImportDialogHdl, FileDialog *, pDialog )
1908*cdf0e10cSrcweir {
1909*cdf0e10cSrcweir     UniString path = pDialog->GetPath();
1910*cdf0e10cSrcweir //fprintf(stderr, "Executing import dialog!\n");
1911*cdf0e10cSrcweir 
1912*cdf0e10cSrcweir #if DEBUG_PRINT
1913*cdf0e10cSrcweir     fprintf(stderr, "got import file: %s\n",rtl::OUStringToOString( path, RTL_TEXTENCODING_ASCII_US ).getStr() );
1914*cdf0e10cSrcweir #endif
1915*cdf0e10cSrcweir 
1916*cdf0e10cSrcweir     return 0;
1917*cdf0e10cSrcweir }
1918*cdf0e10cSrcweir #endif
1919*cdf0e10cSrcweir 
1920*cdf0e10cSrcweir IMPL_LINK( EditorImpl, ExportButtonHdl, layout::PushButton *, pBtn )
1921*cdf0e10cSrcweir {
1922*cdf0e10cSrcweir     (void) pBtn;
1923*cdf0e10cSrcweir     mpLayoutTree->print();
1924*cdf0e10cSrcweir     return 0;
1925*cdf0e10cSrcweir }
1926*cdf0e10cSrcweir 
1927*cdf0e10cSrcweir //** Editor, the Dialog
1928*cdf0e10cSrcweir 
1929*cdf0e10cSrcweir Editor::Editor( uno::Reference< lang::XMultiServiceFactory > xFactory,
1930*cdf0e10cSrcweir                 rtl::OUString aFile )
1931*cdf0e10cSrcweir     : layout::Dialog( (Window*) (NULL), "editor.xml", "dialog" )
1932*cdf0e10cSrcweir     , mpImpl( new EditorImpl( this, xFactory ) )
1933*cdf0e10cSrcweir {
1934*cdf0e10cSrcweir     if ( aFile.getLength() )
1935*cdf0e10cSrcweir         mpImpl->loadFile( aFile );
1936*cdf0e10cSrcweir 
1937*cdf0e10cSrcweir     // parent:
1938*cdf0e10cSrcweir     FreeResource();
1939*cdf0e10cSrcweir }
1940*cdf0e10cSrcweir 
1941*cdf0e10cSrcweir Editor::~Editor()
1942*cdf0e10cSrcweir {
1943*cdf0e10cSrcweir     delete mpImpl;
1944*cdf0e10cSrcweir }
1945