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