diff options
Diffstat (limited to 'toolkit/workben/layout/editor.cxx')
-rw-r--r-- | toolkit/workben/layout/editor.cxx | 1853 |
1 files changed, 0 insertions, 1853 deletions
diff --git a/toolkit/workben/layout/editor.cxx b/toolkit/workben/layout/editor.cxx deleted file mode 100644 index 34f35c619c..0000000000 --- a/toolkit/workben/layout/editor.cxx +++ /dev/null @@ -1,1853 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include "editor.hxx" - -#undef NDEBUG - -/* -#include <stdio.h> -#include <string.h> -*/ - -#include <cassert> -#include <cstdio> -#include <cstring> -#include <list> -#include <vector> - -#include <com/sun/star/awt/WindowAttribute.hpp> -#include <com/sun/star/awt/XLayoutConstrains.hpp> -#include <com/sun/star/awt/XLayoutContainer.hpp> -#include <com/sun/star/awt/XToolkit.hpp> -#include <com/sun/star/awt/XVclWindowPeer.hpp> -#include <com/sun/star/awt/XWindow.hpp> -#include <com/sun/star/awt/XWindowPeer.hpp> -#include <rtl/strbuf.hxx> -#include <rtl/ustrbuf.hxx> -#include <toolkit/helper/property.hxx> -#include <vcl/lstbox.h> - -using namespace layout::css; - -using rtl::OUString; - -// FIXME: -//#define FILEDLG - -#include <layout/core/helper.hxx> -#include <layout/core/root.hxx> -#include <layout/core/helper.hxx> - -// TODO: automatically generated -struct WidgetSpec { - const char *pLabel, *pName, *pIconName; - bool bIsContainer; }; -static const WidgetSpec WIDGETS_SPECS[] = { - { "Label", "fixedtext" , "sc_label.png", false }, - { "Button", "pushbutton" , "sc_pushbutton.png", false }, - { "Radio Button", "radiobutton" , "sc_radiobutton.png", false }, - { "Check Box", "checkbox" , "sc_checkbox.png", false }, - { "Line Edit", "edit" , "sc_edit.png", false }, - { "Numeric Field", "numericfield", "sc_numericfield.png", false }, - { "List Box ", "listbox" , NULL, false }, - // containers - { "Hor Box", "hbox" , NULL, true }, - { "Ver Box", "vbox" , NULL, true }, - { "Table", "table" , NULL, true }, - { "Alignment", "align" , NULL, true }, - { "Tab Control", "tabcontrol" , NULL, true }, - { "Hor Splitter", "hsplitter" , NULL, true }, - { "Ver Splitter", "vsplitter" , NULL, true }, - { "Scroller", "scroller" , NULL, true }, -}; -const int WIDGETS_SPECS_LEN = sizeof (WIDGETS_SPECS) / sizeof (WidgetSpec); - -using namespace layout; -using namespace layoutimpl; -namespace css = ::com::sun::star; - -static rtl::OUString anyToString (uno::Any value) -{ - try - { - switch (value.getValueTypeClass()) { - case uno::TypeClass_STRING: - return value.get<rtl::OUString>(); - case uno::TypeClass_CONSTANT: - return rtl::OUString::valueOf (value.get<sal_Int32>()); - case uno::TypeClass_LONG: - return rtl::OUString::valueOf (value.get<sal_Int64>()); - case uno::TypeClass_SHORT: - // FIXME: seems broken - return rtl::OUString::valueOf ((sal_Int32) value.get<short>()); - - case uno::TypeClass_FLOAT: - return rtl::OUString::valueOf (value.get<float>()); - case uno::TypeClass_DOUBLE: - return rtl::OUString::valueOf (value.get<double>()); - - case uno::TypeClass_BOOLEAN: - { - bool val = value.get<sal_Bool>(); - return rtl::OUString( val ? "1" : "0", 1, RTL_TEXTENCODING_ASCII_US ); -/* if ( val ) - return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) ); - else - return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) );*/ - } - default: - break; - } - } - catch(...) {} - return rtl::OUString(); -} - -static inline long anyToNatural (uno::Any value) -{ return sal::static_int_cast<long>(anyToString( value ).toInt64()); } -static inline double anyToDecimal (uno::Any value) -{ return anyToString( value ).toDouble(); } - -/* XLayoutContainer/XLayoutConstrains are a bit of a hasle to work with. - Let's wrap them. */ -class Widget : public layoutimpl::LayoutWidget -{ - friend class EditorRoot; - - Widget *mpParent; - std::vector< Widget *> maChildren; - bool mbForeign; - - rtl::OUString mrId; - rtl::OUString mrLabel, mrUnoName; - -// TODO: store original properties. And some property handling methods. - long mnOriAttrbs; - layoutimpl::PropList maOriProps, maOriChildProps; - -public: - - // to be used to wrap the root - Widget( uno::Reference< awt::XLayoutConstrains > xImport, const char *label ) - : mpParent( 0 ), mbForeign( true ) - { - mxWidget = xImport; - mxContainer = uno::Reference< awt::XLayoutContainer >( mxWidget, uno::UNO_QUERY ); - - mrLabel = rtl::OUString( label, strlen( label ), RTL_TEXTENCODING_UTF8 ); - } - - Widget( rtl::OUString id, uno::Reference< awt::XToolkit > xToolkit, - uno::Reference< awt::XLayoutContainer > xParent, - rtl::OUString unoName, long nAttrbs ) - : mpParent( 0 ), mbForeign( false ), mrId( id ), - mnOriAttrbs( nAttrbs ) - { - while ( xParent.is() && !uno::Reference< awt::XWindow >( xParent, uno::UNO_QUERY ).is() ) - { - uno::Reference< awt::XLayoutContainer > xContainer( xParent, uno::UNO_QUERY ); - OSL_ASSERT( xContainer.is() ); - xParent = uno::Reference< awt::XLayoutContainer >( xContainer->getParent(), uno::UNO_QUERY ); - } - - mxWidget = WidgetFactory::createWidget( xToolkit, xParent, unoName, nAttrbs ); - OSL_ASSERT( mxWidget.is() ); - mxContainer = uno::Reference< awt::XLayoutContainer >( mxWidget, uno::UNO_QUERY ); - - mrLabel = mrUnoName = unoName; - // try to get a nicer label for the widget - for ( int i = 0; i < WIDGETS_SPECS_LEN; i++ ) - if ( unoName.equalsAscii( WIDGETS_SPECS[ i ].pName ) ) - { - const char *label = WIDGETS_SPECS[ i ].pLabel; - mrLabel = rtl::OUString( label, strlen( label ), RTL_TEXTENCODING_UTF8 ); - break; - } - - // set default Text property - // TODO: disable editing of text fields, check boxes selected, etc... - - - // store original properties - { - PropertyIterator it( this, WINDOW_PROPERTY ); - while ( it.hasNext() ) - { - beans::Property prop = it.next(); - rtl::OUString name( prop.Name ); - rtl::OUString value( getProperty( name, WINDOW_PROPERTY ) ); -#if DEBUG_PRINT - fprintf(stderr, "original property: %s = %s\n", OUSTRING_CSTR(name), OUSTRING_CSTR(value)); -#endif - std::pair< rtl::OUString, rtl::OUString > pair( name, value ); - maOriProps.push_back( pair ); - } - } - - } - - ~Widget() - { - for ( std::vector< Widget *>::const_iterator it = maChildren.begin(); - it != maChildren.end(); ++it ) - delete *it; - if ( !mbForeign ) - { - uno::Reference< lang::XComponent > xComp( mxWidget, uno::UNO_QUERY ); - if ( xComp.is() ) - // some widgets, like our containers, don't implement this interface... - xComp->dispose(); - } - } - - uno::Reference< awt::XLayoutConstrains > impl() - { - return mxWidget; - } - - // LayoutWidget - virtual bool addChild( LayoutWidget *pChild ) - { - return addChild( static_cast< Widget * >( pChild ) ); - } - - virtual void setProperties( const PropList &rProps ) - { -// maOriProps = rProps; - LayoutWidget::setProperties( rProps ); - } - - virtual void setChildProperties( LayoutWidget *pChild, const PropList &rProps ) - { - maOriChildProps = rProps; - LayoutWidget::setChildProperties( pChild, rProps ); - } - - // tree travel - Widget *up() - { - return mpParent; - } - - Widget *down() - { - if ( maChildren.empty() ) - return NULL; - return maChildren.front(); - } - - Widget *next() - { - if ( mpParent ) - { - int pos = mpParent->getChildPos( this ); - return mpParent->getChild( pos+1 ); - } - return NULL; - } - - Widget *prev() - { - if ( mpParent ) - { - int pos = mpParent->getChildPos( this ); - return mpParent->getChild( pos-1 ); - } - return NULL; - } - - // handle - bool addChild( Widget *pChild, int pos = 0xffff ) - { - if ( !mxContainer.is() ) - return false; - - uno::Sequence< uno::Reference < awt::XLayoutConstrains > > aChildren; - aChildren = mxContainer->getChildren(); - int nChildrenLen = aChildren.getLength(); - - // ugly, but let's check if the container is next to full... - try { - mxContainer->addChild( pChild->mxWidget ); - } - catch( awt::MaxChildrenException ex ) { - return false; - } - - if ( pos < nChildrenLen ) - { // if its on the middle, we need to make space for it - mxContainer->removeChild( pChild->mxWidget ); - for ( int i = pos; i < nChildrenLen; i++ ) - mxContainer->removeChild( aChildren[ i ] ); - mxContainer->addChild( pChild->mxWidget ); - for ( int i = pos; i < nChildrenLen; i++ ) - mxContainer->addChild( aChildren[ i ] ); - maChildren.insert( maChildren.begin()+pos, pChild ); - } - else - maChildren.push_back( pChild ); - - OSL_ASSERT( pChild->mpParent == NULL ); - pChild->mpParent = this; - - // store container props - { - pChild->maOriChildProps.clear(); - PropertyIterator it( pChild, CONTAINER_PROPERTY ); - while ( it.hasNext() ) - { - beans::Property prop = it.next(); - rtl::OUString name( prop.Name ); - try { - rtl::OUString value( pChild->getProperty( name, CONTAINER_PROPERTY ) ); - std::pair< rtl::OUString, rtl::OUString > pair( name, value ); - pChild->maOriChildProps.push_back( pair ); - } catch ( beans::UnknownPropertyException &rEx ) { - 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", - rtl::OUStringToOString (rEx.Message, RTL_TEXTENCODING_UTF8).getStr()); - } - } - } - - return true; - } - - bool removeChild( Widget *pChild ) - { - if ( !mxContainer.is() || pChild->mpParent != this ) - return false; - - mxContainer->removeChild( pChild->mxWidget ); - - unsigned int pos = getChildPos( pChild ); - if ( pos < maChildren.size() ) - maChildren.erase( maChildren.begin()+pos ); - pChild->mpParent = NULL; - - return true; - } - - bool swapWithChild( Widget *pChild ) - { - if ( !pChild->isContainer() ) - return false; - - // remove all child's childrens, and try to add them here - removeChild( pChild ); - - // keep a copy for failure - std::vector< Widget *> aChildren = maChildren; - std::vector< Widget *> aChildChildren = pChild->maChildren; - - for ( std::vector< Widget *>::const_iterator it = aChildChildren.begin(); - it != aChildChildren.end(); ++it ) - pChild->removeChild( *it ); - - for ( std::vector< Widget *>::const_iterator it = aChildChildren.begin(); - it != aChildChildren.end(); ++it ) - if ( !addChild( *it ) ) - { // failure - for ( std::vector< Widget *>::const_iterator jt = aChildChildren.begin(); - jt != it; ++jt ) - removeChild( *jt ); - for ( std::vector< Widget *>::const_iterator jt = aChildChildren.begin(); - jt != aChildChildren.end(); ++jt ) - pChild->addChild( *jt ); - return false; - } - - Widget *pParent = up(); - - if ( pParent ) - { - pParent->removeChild( this ); - pParent->addChild( pChild ); - } - pChild->addChild( this ); - return true; - } - - unsigned int getChildPos( Widget *pChild ) - { - int i = 0; - for ( std::vector< Widget *>::const_iterator it = maChildren.begin(); - it != maChildren.end(); ++it, ++i ) - if ( *it == pChild ) - break; - return i; - } - - Widget *getChild( int pos ) - { - if ( pos >= 0 && pos < (signed) maChildren.size() ) - return *(maChildren.begin() + pos); - return NULL; - } - - bool isContainer() - { return mxContainer.is(); } - unsigned int getChildrenLen() - { return maChildren.size(); } - - rtl::OUString getLabel() const - { return mrLabel; } - rtl::OUString getUnoName() const - { return mrUnoName; } - - int getDepth() - { - int depth = 0; - for ( Widget *pWidget = mpParent; pWidget; pWidget = pWidget->mpParent ) - depth++; - return depth; - } - - enum PropertyKind { - WINDOW_PROPERTY, CONTAINER_PROPERTY, WINBITS_PROPERTY - }; - - static rtl::OUString findProperty( const PropList &props, rtl::OUString propName ) - { - for ( PropList::const_iterator it = props.begin(); it != props.end(); ++it ) - if ( it->first.equalsIgnoreAsciiCase( propName ) ) - return it->second; -#if DEBUG_PRINT - fprintf(stderr, "Serious error: property '%s' not found\n", OUSTRING_CSTR(propName)); -#endif - return rtl::OUString(); - } - - rtl::OUString getOriginalProperty( rtl::OUString rPropName, PropertyKind rKind ) - { - rtl::OUString rValue; - switch ( rKind ) { - case WINDOW_PROPERTY: - rValue = findProperty( maOriProps, rPropName ); - break; - case CONTAINER_PROPERTY: - rValue = findProperty( maOriChildProps, rPropName ); - break; - case WINBITS_PROPERTY: - // TODO - break; - } - - return rValue; - } - - rtl::OUString getProperty( rtl::OUString rPropName, PropertyKind rKind ) - { - rtl::OUString rValue; - switch ( rKind ) { - case WINDOW_PROPERTY: - rValue = anyToString( layoutimpl::prophlp::getProperty( mxWidget, rPropName ) ); - break; - case CONTAINER_PROPERTY: - if ( mpParent ) - rValue = anyToString( layoutimpl::prophlp::getProperty( - mpParent->mxContainer->getChildProperties( mxWidget ), rPropName ) ); - break; - case WINBITS_PROPERTY: - // TODO - break; - } - - return rValue; - } - - bool isPropertyTouched( rtl::OUString propName, PropertyKind rKind ) - { - rtl::OUString oriValue = getOriginalProperty( propName, rKind ); - rtl::OUString newValue = getProperty( propName, rKind ); - bool isTouched = oriValue != newValue; -#if DEBUG_PRINT - fprintf(stderr, "is property '%s' touched? %s (%s vs %s)\n", OUSTRING_CSTR(propName), isTouched ? "yes" : "no", OUSTRING_CSTR(oriValue), OUSTRING_CSTR(newValue)); -#endif - return isTouched; - } - - using LayoutWidget::setProperty; - - void setProperty( rtl::OUString rPropName, PropertyKind rKind, uno::Any rValue ) - { - switch ( rKind ) { - case WINDOW_PROPERTY: - layoutimpl::prophlp::setProperty( mxWidget, rPropName, rValue ); - break; - case CONTAINER_PROPERTY: - if ( mpParent ) - layoutimpl::prophlp::setProperty( - mpParent->mxContainer->getChildProperties( mxWidget ), rPropName, rValue ); - break; - case WINBITS_PROPERTY: - // TODO - break; - } - } - - struct PropertyIterator { - friend class Widget; - PropertyKind mrKind; - uno::Sequence< beans::Property > maProps; - int nPropIt; - - PropertyIterator( Widget *pWidget, PropertyKind rKind ) - : mrKind( rKind ), nPropIt( 0 ) - { - switch ( rKind ) - { - case WINDOW_PROPERTY: - if ( layoutimpl::prophlp::canHandleProps( pWidget->mxWidget ) ) - { - uno::Reference< beans::XPropertySetInfo > xInfo - = layoutimpl::prophlp::queryPropertyInfo( pWidget->mxWidget ); - if ( !xInfo.is() ) - return; - - maProps = xInfo->getProperties(); - } - break; - case CONTAINER_PROPERTY: - if ( pWidget->mpParent ) - { - uno::Reference< beans::XPropertySet >xParentSet( - pWidget->mpParent->mxContainer->getChildProperties( pWidget->mxWidget ) ); - if ( xParentSet.is()) - { - uno::Reference< beans::XPropertySetInfo > xInfo( xParentSet->getPropertySetInfo() ); - if ( xInfo.is() ) - maProps = xInfo->getProperties(); - } - } - break; - case WINBITS_PROPERTY: - // TODO - break; - } - } - - bool hasNext() - { - return nPropIt < maProps.getLength(); - } - - beans::Property next() - { -/* rtl::OUString propName, propValue; - propName = maProps[ nPropIt ]; - propValue = getProperty( propName, mrKind, false); - nPropIt++; - return std::pair< rtl::OUString, rtl::OUString > propPair( propName, propValue );*/ - return maProps[ nPropIt++ ]; - } - }; -}; - -class EditorRoot : public layoutimpl::LayoutRoot { - Widget *mpParent; - -public: - EditorRoot( const uno::Reference< lang::XMultiServiceFactory >& xFactory, - Widget *pParent ) - : layoutimpl::LayoutRoot( xFactory ), mpParent( pParent ) - { - } - - // generation - virtual layoutimpl::LayoutWidget *create( rtl::OUString id, const rtl::OUString unoName, - long attrbs, uno::Reference< awt::XLayoutContainer > xParent ) - { - if ( unoName.compareToAscii( "dialog" ) == 0 ) - return mpParent; - - // TODO: go through specs to map unoName to a more human-readable label - Widget *pWidget = new Widget( id, mxToolkit, xParent, unoName, attrbs ); - if ( !mxWindow.is() ) - mxWindow = uno::Reference< awt::XWindow >( pWidget->getPeer(), uno::UNO_QUERY ); - - if ( pWidget->mxContainer.is() ) - pWidget->mxContainer->setLayoutUnit( mpParent->mxContainer->getLayoutUnit() ); - - return pWidget; - } -}; - -/* Working with the layout in 1D, as if it was a flat list. */ -namespace FlatLayout -{ -Widget *next( Widget *pWidget ) -{ - Widget *pNext; - pNext = pWidget->down(); - if ( pNext ) return pNext; - pNext = pWidget->next(); - if ( pNext ) return pNext; - for ( Widget *pUp = pWidget->up(); pUp != NULL; pUp = pUp->up() ) - if ( (pNext = pUp->next()) != NULL ) - return pNext; - return NULL; -} - -/* - Widget *prev( Widget *pWidget ) - { - Widget *pPrev; - pPrev = pWidget->prev(); - if ( !pPrev ) - return pWidget->up(); - - Widget *pBottom = pPrev->down(); - if ( pBottom ) - { - while ( pBottom->down() || pBottom->next() ) - { - for ( Widget *pNext = pBottom->next(); pNext; pNext = pNext->next() ) - pBottom = pNext; - Widget *pDown = pBottom->down(); - if ( pDown ) - pBottom = pDown; - } - return pBottom; - } - return pPrev; - } -*/ - -bool moveWidget( Widget *pWidget, bool up /*or down*/ ) -{ - // Keep child parent&pos for in case of failure - Widget *pOriContainer = pWidget->up(); - unsigned int oriChildPos = pOriContainer->getChildPos( pWidget ); - - // Get parent&sibling before removing it, since relations get cut - Widget *pSibling = up ? pWidget->prev() : pWidget->next(); - Widget *pContainer = pWidget->up(); - if ( !pContainer ) - return false; - - // try to swap with parent or child - // We need to allow for this at least for the root node... - if ( !pSibling ) - { - if ( up ) - { - if ( pContainer->swapWithChild( pWidget ) ) - return true; - } - else - { - } - } - - pContainer->removeChild( pWidget ); - - // if has up sibling -- append to it, else swap with it - if ( pSibling ) - { - if ( pSibling->addChild( pWidget, up ? 0xffff : 0 ) ) - return true; - - unsigned int childPos = pContainer->getChildPos( pSibling ); - if ( pContainer->addChild( pWidget, childPos + (up ? 0 : 1) ) ) - return true; // should always be succesful - } - // go through parents -- try to get prepended to them - else - { - for ( ; pContainer && pContainer->up(); pContainer = pContainer->up() ) - { - unsigned int childPos = pContainer->up()->getChildPos( pContainer ); - if ( pContainer->up()->addChild( pWidget, childPos + (up ? 0 : 1) ) ) - return true; - } - } - - // failed -- try to get it to its old position - if ( !pOriContainer->addChild( pWidget, oriChildPos ) ) - { - // a parent should never reject a child back. but if it ever - // happens, just kill it, we don't run an orphanate here ;P - delete pWidget; - return true; - } - return false; -} - -// NOTE: root is considered to be number -1 -Widget *get( Widget *pRoot, int nb ) -{ - Widget *it; - for ( it = pRoot; it != NULL && nb >= 0; it = next( it ) ) - nb--; - return it; -} - -int get( Widget *pRoot, Widget *pWidget ) -{ - int nRet = -1; - Widget *it; - for ( it = pRoot; it != NULL && it != pWidget; it = next( it ) ) - nRet++; - return nRet; -} -} - -//** PropertiesList widget - -class PropertiesList : public layout::Table -{ - class PropertyEntry - { - friend class PropertiesList; - - /* wrapper between the widget and Any */ - struct AnyWidget - { - DECL_LINK( ApplyPropertyHdl, layout::Window* ); - DECL_LINK( FlagToggledHdl, layout::CheckBox* ); - - AnyWidget( Widget *pWidget, rtl::OUString aPropName, Widget::PropertyKind aPropKind ) - : mpWidget( pWidget ), maPropName( aPropName ), maPropKind( aPropKind ) - { - mpFlag = 0; - mbBlockFlagCallback = false; - bFirstGet = true; - } - - virtual ~AnyWidget() - { -#if DEBUG_PRINT - fprintf(stderr, "~AnyWidget\n"); -#endif - } - - void save( uno::Any aValue ) - { - mpWidget->setProperty( maPropName, maPropKind, aValue ); - checkProperty(); - } - - void checkProperty() - { - bool flag = mpWidget->isPropertyTouched( maPropName, maPropKind ); - - if ( mpFlag && mpFlag->IsChecked() != (BOOL)flag ) - { - CheckFlag( flag, true ); - } - } - - void CheckFlag( bool bValue, bool bBlockCallback ) - { - if ( bBlockCallback ) - mbBlockFlagCallback = true; - mpFlag->Check( bValue ); - mbBlockFlagCallback = false; - } - - bool bFirstGet; // HACK - rtl::OUString getValue() - { -// return mpWidget->getOriProperty( maPropName ); - rtl::OUString value; - if ( bFirstGet ) // king of ugliness - value = mpWidget->getProperty( maPropName, maPropKind ); - else - value = mpWidget->getOriginalProperty( maPropName, maPropKind ); - bFirstGet = false; - return value; - } - - // FIXME: wrapper should have a base class for this... - virtual layout::Window *getWindow() = 0; - virtual layout::Container *getContainer() { return NULL; } - - virtual void load() = 0; - virtual void store() = 0; - - Widget *mpWidget; - rtl::OUString maPropName; - Widget::PropertyKind maPropKind; - layout::CheckBox *mpFlag; - bool mbBlockFlagCallback; - }; - - struct AnyEdit : public AnyWidget, layout::HBox - { - layout::Edit *mpEdit; - bool mbMultiLine; - layout::PushButton *mpExpand; - DECL_LINK( ExpandEditHdl, layout::PushButton* ); - - // so we can create widgets (like transforming the Edit into a - // MultiLineEdit) - layout::Window *mpWinParent; - - AnyEdit( Widget *pWidget, rtl::OUString aPropName, - Widget::PropertyKind aPropKind, layout::Window *pWinParent ) - : AnyWidget( pWidget, aPropName, aPropKind ), layout::HBox( 0, false ), mpWinParent( pWinParent ) - { - mpEdit = NULL; - mpExpand = new layout::PushButton( pWinParent, WB_TOGGLE ); - mpExpand->SetToggleHdl( LINK( this, AnyEdit, ExpandEditHdl ) ); - setAsMultiLine( false ); - - load(); - } - - virtual ~AnyEdit() - { - delete mpEdit; - delete mpExpand; - } - - virtual layout::Window *getWindow() - { return NULL; } - virtual layout::Container *getContainer() - { return this; } - - void setAsMultiLine( bool bMultiLine ) - { - Clear(); - XubString text; - if ( mpEdit ) - { - text = mpEdit->GetText(); - printf("Remove mpEdit and expand\n"); - Remove( mpEdit ); - Remove( mpExpand ); - delete mpEdit; - } - - if ( bMultiLine ) - { - mpEdit = new layout::Edit( mpWinParent, WB_BORDER ); - mpExpand->SetText( String::CreateFromAscii( "-" ) ); - } - else - { - mpEdit = new layout::Edit( mpWinParent, WB_BORDER ); - mpExpand->SetText( String::CreateFromAscii( "+" ) ); - } - - mpEdit->SetText( text ); - mpEdit->SetModifyHdl( LINK( this, AnyEdit, ApplyPropertyHdl ) ); - - Add( mpEdit, true, true, 0 ); - Add( mpExpand, false, true, 0 ); - - mbMultiLine = bMultiLine; - } - - virtual void load() - { - mpEdit->SetText( getValue() ); - checkProperty(); - } - - virtual void store() - { - save( uno::makeAny( (rtl::OUString) mpEdit->GetText() ) ); - } - }; - - struct AnyInteger : public AnyWidget, NumericField - { - AnyInteger( Widget *pWidget, rtl::OUString aPropName, - Widget::PropertyKind aPropKind, Window *pWinParent ) - : AnyWidget( pWidget, aPropName, aPropKind ), NumericField( pWinParent, WB_SPIN|WB_BORDER ) - { - load(); - SetModifyHdl( LINK( this, AnyInteger, ApplyPropertyHdl ) ); - } - - virtual Window *getWindow() - { return this; } - - virtual void load() - { - OUString text = getValue(); - SetText( text.getStr() ); - checkProperty(); - } - - virtual void store() - { -#if DEBUG_PRINT - fprintf(stderr, "store number: %ld\n", rtl::OUString( GetText() ).toInt64()); -#endif - save( uno::makeAny( rtl::OUString( GetText() ).toInt64() ) ); - } - }; - - struct AnyFloat : public AnyInteger - { - AnyFloat( Widget *pWidget, rtl::OUString aPropName, - Widget::PropertyKind aPropKind, Window *pWinParent ) - : AnyInteger( pWidget, aPropName, aPropKind, pWinParent ) - {} - - virtual void store() - { - save( uno::makeAny( rtl::OUString( GetText() ).toDouble() ) ); - } - }; - - struct AnyCheckBox : public AnyWidget, layout::CheckBox - { - AnyCheckBox( Widget *pWidget, rtl::OUString aPropName, - Widget::PropertyKind aPropKind, layout::Window *pWinParent ) - : AnyWidget( pWidget, aPropName, aPropKind ), layout::CheckBox( pWinParent ) - { - // adding some whitespaces to make the hit area larger -// SetText( String::CreateFromAscii( "" ) ); - load(); - SetToggleHdl( LINK( this, AnyWidget, ApplyPropertyHdl ) ); - } - - virtual ~AnyCheckBox() - { -#if DEBUG_PRINT - fprintf(stderr, "~AnyCheckBox\n"); -#endif - } - - virtual layout::Window *getWindow() - { return this; } - - virtual void load() - { -#if DEBUG_PRINT - fprintf(stderr, "loading boolean value\n"); -#endif - Check( getValue().toInt64() != 0 ); - setLabel(); - checkProperty(); - } - - virtual void store() - { - save( uno::makeAny( IsChecked() ) ); - setLabel(); - } - - void setLabel() - { - SetText( String::CreateFromAscii( IsChecked() ? "true" : "false" ) ); - } - }; - - struct AnyListBox : public AnyWidget, layout::ListBox - { - AnyListBox( Widget *pWidget, rtl::OUString aPropName, - Widget::PropertyKind aPropKind, Window *pWinParent ) - : AnyWidget( pWidget, aPropName, aPropKind ), layout::ListBox( pWinParent, WB_DROPDOWN ) - { - SetSelectHdl( LINK( this, AnyWidget, ApplyPropertyHdl ) ); - } - - virtual layout::Window *getWindow() - { return this; } - - virtual void load() - { - SelectEntryPos( sal::static_int_cast< USHORT >( getValue().toInt32() ) ); - checkProperty(); - } - - virtual void store() - { - save( uno::makeAny( (short) GetSelectEntryPos() ) ); - } - }; - - struct AnyAlign : public AnyListBox - { - AnyAlign( Widget *pWidget, rtl::OUString aPropName, - Widget::PropertyKind aPropKind, Window *pWinParent ) - : AnyListBox( pWidget, aPropName, aPropKind, pWinParent ) - { - InsertEntry( XubString::CreateFromAscii( "Left" ) ); - InsertEntry( XubString::CreateFromAscii( "Center" ) ); - InsertEntry( XubString::CreateFromAscii( "Right" ) ); - load(); - } - }; - - /* AnyListBox and AnyComboBox different in that a ComboBox allows the user - to add other options, operating in strings, instead of constants. - (its more like a suggestive AnyEdit) */ - struct AnyComboBox : public AnyWidget, layout::ComboBox - { - AnyComboBox( Widget *pWidget, rtl::OUString aPropName, - Widget::PropertyKind aPropKind, Window *pWinParent ) - : AnyWidget( pWidget, aPropName, aPropKind ), layout::ComboBox( pWinParent, WB_DROPDOWN ) - { - SetModifyHdl( LINK( this, AnyComboBox, ApplyPropertyHdl ) ); - } - - virtual layout::Window *getWindow() - { return this; } - - virtual void load() - { - SetText( getValue() ); - checkProperty(); - } - - virtual void store() - { - save( uno::makeAny( (rtl::OUString) GetText() ) ); - } - }; - - struct AnyFontStyle : public AnyComboBox - { - AnyFontStyle( Widget *pWidget, rtl::OUString aPropName, - Widget::PropertyKind aPropKind, Window *pWinParent ) - : AnyComboBox( pWidget, aPropName, aPropKind, pWinParent ) - { - InsertEntry( XubString::CreateFromAscii( "Bold" ) ); - InsertEntry( XubString::CreateFromAscii( "Italic" ) ); - InsertEntry( XubString::CreateFromAscii( "Bold Italic" ) ); - InsertEntry( XubString::CreateFromAscii( "Fett" ) ); - load(); - } - }; - - layout::FixedText *mpLabel; - layout::CheckBox *mpFlag; - AnyWidget *mpValue; - - public: - PropertyEntry( layout::Window *pWinParent, AnyWidget *pAnyWidget ) - { - mpLabel = new layout::FixedText( pWinParent ); - { - // append ':' to aPropName - rtl::OUStringBuffer buf( pAnyWidget->maPropName ); - buf.append( sal_Unicode (':') ); - mpLabel->SetText( buf.makeStringAndClear() ); - } - mpValue = pAnyWidget; - mpFlag = new layout::CheckBox( pWinParent ); - mpFlag->SetToggleHdl( LINK( mpValue, AnyWidget, FlagToggledHdl ) ); - mpValue->mpFlag = mpFlag; - } - - ~PropertyEntry() - { -#if DEBUG_PRINT - fprintf(stderr, "REMOVING label, flag and value\n"); -#endif - delete mpLabel; - delete mpFlag; - delete mpValue; - } - - // Use this factory rather than the constructor -- check for NULL - static PropertyEntry *construct( Widget *pWidget, rtl::OUString aPropName, - Widget::PropertyKind aPropKind, sal_uInt16 nType, - layout::Window *pWinParent ) - { - AnyWidget *pAnyWidget; - switch (nType) { - case uno::TypeClass_STRING: - if ( aPropName.compareToAscii( "FontStyleName" ) == 0 ) - { - pAnyWidget = new AnyFontStyle( pWidget, aPropName, aPropKind, pWinParent ); - break; - } - pAnyWidget = new AnyEdit( pWidget, aPropName, aPropKind, pWinParent ); - break; - case uno::TypeClass_SHORT: - if ( aPropName.compareToAscii( "Align" ) == 0 ) - { - pAnyWidget = new AnyAlign( pWidget, aPropName, aPropKind, pWinParent ); - break; - } - // otherwise, treat as any other number... - case uno::TypeClass_LONG: - case uno::TypeClass_UNSIGNED_LONG: - pAnyWidget = new AnyInteger( pWidget, aPropName, aPropKind, pWinParent ); - break; - case uno::TypeClass_FLOAT: - case uno::TypeClass_DOUBLE: - pAnyWidget = new AnyFloat( pWidget, aPropName, aPropKind, pWinParent ); - break; - case uno::TypeClass_BOOLEAN: - pAnyWidget = new AnyCheckBox( pWidget, aPropName, aPropKind, pWinParent ); - break; - default: - return NULL; - } - return new PropertyEntry( pWinParent, pAnyWidget ); - } - }; - - layout::Window *mpParentWindow; - - std::list< PropertyEntry* > maPropertiesList; - layout::FixedLine *mpSeparator; - - // some properties are obscure, or simply don't make sense in this - // context. Let's just ignore them. - // Maybe we could offer them in an expander or something... - static bool toIgnore( rtl::OUString prop ) - { - // binary search -- keep the list sorted alphabetically - static char const *toIgnoreList[] = { - "DefaultControl", "FocusOnClick", "FontCharWidth", "FontCharset", - "FontEmphasisMark", "FontFamily", "FontHeight", "FontKerning", "FontName", - "FontOrientation", "FontPitch", "FontRelief", "FontSlant", "FontStrikeout", - "FontType", "FontWordLineMode", "HelpText", "HelpURL", "MultiLine", - "Printable", "Repeat", "RepeatDelay", "Tabstop" - }; - - int min = 0, max = sizeof( toIgnoreList )/sizeof( char * ) - 1, mid, cmp; - do { - mid = min + (max - min)/2; - cmp = prop.compareToAscii( toIgnoreList[ mid ] ); - if ( cmp > 0 ) - min = mid+1; - else if ( cmp < 0 ) - max = mid-1; - else - return true; - } while ( min <= max ); - return false; - } - -public: - PropertiesList( layout::Dialog *dialog ) - : layout::Table( dialog, "properties-box" ) - , mpParentWindow( dialog ), mpSeparator( 0 ) - { - } - - ~PropertiesList() - { - clear(); - } - -private: - // auxiliary, add properties from the peer to the list - void addProperties( Widget *pWidget, Widget::PropertyKind rKind ) - { - Widget::PropertyIterator it( pWidget, rKind ); - while ( it.hasNext() ) - { - beans::Property prop = it.next(); - rtl::OUString name( prop.Name ); - if ( toIgnore( name ) ) - continue; - sal_uInt16 type = static_cast< sal_uInt16 >( prop.Type.getTypeClass() ); - - PropertyEntry *propEntry = PropertyEntry::construct( - pWidget, name, rKind, type, mpParentWindow ); - - if ( propEntry ) - { - Add( propEntry->mpLabel, false, false ); - - // HACK: one of these will return Null... - Add( propEntry->mpValue->getWindow(), true, false ); - Add( propEntry->mpValue->getContainer(), true, false ); - - Add( propEntry->mpFlag, false, false ); - maPropertiesList.push_back( propEntry ); - } - } - } - -public: - void selectedWidget( Widget *pWidget ) - { - clear(); - - if ( !pWidget ) - return; - - addProperties( pWidget, Widget::CONTAINER_PROPERTY ); - - mpSeparator = new layout::FixedLine( mpParentWindow ); - // TODO: we may want to have to separate list widgets here... - Add( mpSeparator, false, false, 3, 1 ); - - addProperties( pWidget, Widget::WINDOW_PROPERTY ); - - ShowAll( true ); - } - - void clear() - { - ///FIXME: crash - Container::Clear(); - - for ( std::list< PropertyEntry* >::iterator it = maPropertiesList.begin(); - it != maPropertiesList.end(); ++it) - delete *it; - maPropertiesList.clear(); - - delete mpSeparator; - mpSeparator = NULL; - } -}; - -IMPL_LINK( PropertiesList::PropertyEntry::AnyWidget, ApplyPropertyHdl, layout::Window *, pWin ) -{ - (void) pWin; - store(); - return 0; -} - -IMPL_LINK( PropertiesList::PropertyEntry::AnyWidget, FlagToggledHdl, layout::CheckBox *, pCheck ) -{ -#if DEBUG_PRINT - fprintf(stderr, "Property flag pressed -- is: %d\n", pCheck->IsChecked()); -#endif - if ( !mbBlockFlagCallback ) - { - bool checked = pCheck->IsChecked(); - if ( !checked ) // revert - { -#if DEBUG_PRINT - fprintf(stderr, "revert\n"); -#endif - load(); - } - else - { -#if DEBUG_PRINT - fprintf(stderr, "user can't dirty the flag!\n"); -#endif - // User can't flag the property as dirty - // Actually, we may want to allow the designer to force a property to be stored. - // Could be useful when the default value of some new property wasn't yet decided... - CheckFlag( false, true ); - } - } -#if DEBUG_PRINT - else - fprintf(stderr, "Property flag pressed -- BLOCKED\n"); -#endif - return 0; -} - -IMPL_LINK( PropertiesList::PropertyEntry::AnyEdit, ExpandEditHdl, layout::PushButton *, pBtn ) -{ - setAsMultiLine( pBtn->IsChecked() ); - return 0; -} - -//** SortListBox auxiliary widget - -class SortListBox -{ // For a manual sort ListBox; asks for a ListBox and Up/Down/Remove - // buttons to wrap - DECL_LINK( ItemSelectedHdl, layout::ListBox* ); - DECL_LINK( UpPressedHdl, layout::Button* ); - DECL_LINK( DownPressedHdl, layout::Button* ); - DECL_LINK( RemovePressedHdl, layout::Button* ); - layout::PushButton *mpUpButton, *mpDownButton, *mpRemoveButton; - -protected: - layout::ListBox *mpListBox; - - virtual void upPressed( USHORT nPos ) - { - XubString str = mpListBox->GetSelectEntry(); - mpListBox->RemoveEntry( nPos ); - nPos = mpListBox->InsertEntry( str, nPos-1 ); - mpListBox->SelectEntryPos( nPos ); - } - - virtual void downPressed( USHORT nPos ) - { - XubString str = mpListBox->GetSelectEntry(); - mpListBox->RemoveEntry( nPos ); - nPos = mpListBox->InsertEntry( str, nPos+1 ); - mpListBox->SelectEntryPos( nPos ); - } - - virtual void removePressed( USHORT nPos ) - { - mpListBox->RemoveEntry( nPos ); - } - - virtual void itemSelected( USHORT nPos ) - { - // if we had some XLayoutContainer::canAdd() or maxChildren() function - // we could make a function to check if we can move selected and enable/ - // /disable the move buttons as appropriate - - if ( nPos == LISTBOX_ENTRY_NOTFOUND ) - { - mpUpButton->Disable(); - mpDownButton->Disable(); - mpRemoveButton->Disable(); - } - else - { - mpUpButton->Enable(); - mpDownButton->Enable(); - mpRemoveButton->Enable(); - } - } - -public: - SortListBox( layout::ListBox *pListBox, layout::PushButton *pUpButton, layout::PushButton *pDownButton, - layout::PushButton *pRemoveButton ) - : mpUpButton( pUpButton), mpDownButton( pDownButton), mpRemoveButton( pRemoveButton ), - mpListBox( pListBox ) - { - mpListBox->SetSelectHdl( LINK( this, SortListBox, ItemSelectedHdl ) ); - - mpUpButton->SetModeImage( layout::Image ( "cmd/lc_moveup.png" ) ); - mpUpButton->SetImageAlign( IMAGEALIGN_LEFT ); - mpUpButton->SetClickHdl( LINK( this, SortListBox, UpPressedHdl ) ); - - mpDownButton->SetModeImage( layout::Image ( "cmd/lc_movedown.png" ) ); - mpDownButton->SetImageAlign( IMAGEALIGN_LEFT ); - mpDownButton->SetClickHdl( LINK( this, SortListBox, DownPressedHdl ) ); - - // "cmd/lch_delete.png", "cmd/lc_delete.png" - mpRemoveButton->SetModeImage( layout::Image ( "cmd/sc_closedoc.png" ) ); - mpRemoveButton->SetImageAlign( IMAGEALIGN_LEFT ); - mpRemoveButton->SetClickHdl( LINK( this, SortListBox, RemovePressedHdl ) ); - - // fire an un-select event - itemSelected( LISTBOX_ENTRY_NOTFOUND ); - } - - virtual ~SortListBox(); -}; - -SortListBox::~SortListBox() -{ - delete mpListBox; - delete mpUpButton; - delete mpDownButton; - delete mpRemoveButton; -} - -IMPL_LINK( SortListBox, UpPressedHdl, layout::Button *, pBtn ) -{ - (void) pBtn; - USHORT pos = mpListBox->GetSelectEntryPos(); - if ( pos > 0 && pos != LISTBOX_ENTRY_NOTFOUND ) - upPressed( pos ); - return 0; -} - -IMPL_LINK( SortListBox, DownPressedHdl, layout::Button *, pBtn ) -{ - (void) pBtn; - USHORT pos = mpListBox->GetSelectEntryPos(); - if ( pos < mpListBox->GetEntryCount() && pos != LISTBOX_ENTRY_NOTFOUND ) - downPressed( pos ); - return 0; -} - -IMPL_LINK( SortListBox, RemovePressedHdl, layout::Button *, pBtn ) -{ - (void) pBtn; - USHORT pos = mpListBox->GetSelectEntryPos(); - if ( pos != LISTBOX_ENTRY_NOTFOUND ) - removePressed( pos ); - return 0; -} - -IMPL_LINK( SortListBox, ItemSelectedHdl, layout::ListBox *, pList ) -{ - (void) pList; - USHORT pos = mpListBox->GetSelectEntryPos(); - itemSelected( pos ); - return 0; -} - -//** LayoutTree widget - -class LayoutTree : public SortListBox -{ -public: - struct Listener - { - virtual void widgetSelected( Widget *pWidget ) = 0; - }; - -private: - Listener *mpListener; - -public: - Widget *mpRootWidget; - - LayoutTree( layout::Dialog *dialog ) - : SortListBox( new layout::ListBox( dialog, "layout-tree" ), - new layout::PushButton( dialog, "layout-up-button" ), - new layout::PushButton( dialog, "layout-down-button" ), - new layout::PushButton( dialog, "layout-remove-button" ) ) - { - layout::PeerHandle handle = dialog->GetPeerHandle( "preview-box" ); - uno::Reference< awt::XLayoutConstrains > xWidget( handle, uno::UNO_QUERY ); - mpRootWidget = new Widget( xWidget, "root" ); - } - - virtual ~LayoutTree(); - - Widget *getWidget( int nPos ) - { - if ( nPos != LISTBOX_ENTRY_NOTFOUND ) - return FlatLayout::get( mpRootWidget, nPos ); - return NULL; - } - - Widget *getSelectedWidget() - { - Widget *pWidget = getWidget( mpListBox->GetSelectEntryPos() ); - if ( !pWidget ) // return root, if none selected - pWidget = mpRootWidget; - return pWidget; - } - - void selectWidget( Widget *pWidget ) - { - int pos = FlatLayout::get( mpRootWidget, pWidget ); - if ( pos == -1 ) - // if asked to select hidden root, select visible root - pos = 0; - mpListBox->SelectEntryPos( sal::static_int_cast< USHORT >( pos ) ); - } - - void rebuild() - { - struct inner - { - // pads a string with whitespaces - static rtl::OUString padString( rtl::OUString name, int depth ) - { - rtl::OStringBuffer aBuf( depth * 4 + name.getLength() + 2 ); - for (int i = 0; i < depth; i++) - aBuf.append( " " ); - aBuf.append( rtl::OUStringToOString( name, RTL_TEXTENCODING_ASCII_US ) ); - return rtl::OUString( aBuf.getStr(), aBuf.getLength(), - RTL_TEXTENCODING_UTF8 ); - } - }; - - mpListBox->Clear(); - for ( Widget *i = FlatLayout::next( mpRootWidget ); i; i = FlatLayout::next( i ) ) - mpListBox->InsertEntry( inner::padString( i->getLabel(), i->getDepth()-1 ) ); - - // any selection, no longer is. ListBox doesn't fire the event on this case; - // force it. - itemSelected( LISTBOX_ENTRY_NOTFOUND ); - } - - void setListener( Listener *pListener ) - { mpListener = pListener; } - - // print in XML format... - - static rtl::OUString toXMLNaming (const rtl::OUString &string) - { - rtl::OUStringBuffer buffer (string.getLength()); - sal_Unicode *str = string.pData->buffer; - for (int i = 0; i < string.getLength(); i++) { - if ( str[i] >= 'A' && str[i] <= 'Z' ) - { - if ( i > 0 ) - buffer.append ((sal_Unicode) '-'); - buffer.append ((sal_Unicode) (str[i] - 'A' + 'a')); - } - else - buffer.append ((sal_Unicode) str[i]); - } - - return buffer.makeStringAndClear(); - } - - void print() - { - printf("\t\tExport:\n"); - printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<dialog xmlns=\"http://openoffice.org/2007/layout\"\n" - " xmlns:cnt=\"http://openoffice.org/2007/layout/container\"\n" - " id=\"dialog\" title=\"Unnamed\" sizeable=\"true\" >\n"); - - for ( Widget *i = FlatLayout::next( mpRootWidget ); i; i = FlatLayout::next( i ) ) - { - for ( int d = i->getDepth(); d > 0; d-- ) - printf(" "); - printf("<%s ", OUSTRING_CSTR( i->getUnoName() ) ); - - for ( int kind = 0; kind < 2; kind++ ) - { - Widget::PropertyKind wKind = kind == 0 ? Widget::WINDOW_PROPERTY - : Widget::CONTAINER_PROPERTY; - Widget::PropertyIterator it( i, wKind ); - while ( it.hasNext() ) - { - beans::Property prop = it.next(); - if ( !i->isPropertyTouched( prop.Name, wKind ) ) - continue; - - rtl::OUString value = i->getProperty( prop.Name, wKind ); - if ( prop.Type.getTypeClass() == uno::TypeClass_BOOLEAN ) - { - if ( value.compareToAscii( "0" ) ) - value = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("false") ); - else - value = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("true") ); - } - - if ( value.getLength() > 0 ) - printf("%s%s=\"%s\" ", - kind == 0 ? "" : "cnt:", - OUSTRING_CSTR( toXMLNaming( prop.Name ) ), OUSTRING_CSTR( value ) - ); - - } - } - printf("/>\n"); - } - printf("</dialog>\n"); - } - -protected: - virtual void upPressed( USHORT nPos ) - { - Widget *pWidget = getWidget( nPos ); - if ( FlatLayout::moveWidget( pWidget, true ) ) - rebuild(); - selectWidget( pWidget ); - } - - virtual void downPressed( USHORT nPos ) - { - Widget *pWidget = getWidget( nPos ); - if ( FlatLayout::moveWidget( pWidget, false ) ) - rebuild(); - selectWidget( pWidget ); - } - - virtual void removePressed( USHORT nPos ) - { - Widget *pWidget = getWidget( nPos ); - if ( pWidget ) - { - pWidget->up()->removeChild( pWidget ); - delete pWidget; - rebuild(); - } - } - - virtual void itemSelected( USHORT nPos ) - { - mpListener->widgetSelected( getWidget( nPos ) ); - SortListBox::itemSelected( nPos ); - } -}; - -LayoutTree::~LayoutTree() -{ - delete mpRootWidget; -} - -//** EditorImpl - -class EditorImpl : public LayoutTree::Listener -{ - void createWidget( const char *unoName ); - - PropertiesList *mpPropertiesList; - LayoutTree *mpLayoutTree; - - layout::PushButton *pImportButton, *pExportButton; -#ifdef FILEDLG - FileDialog *pImportDialog; -#endif - DECL_LINK( ImportButtonHdl, layout::PushButton* ); - DECL_LINK( ExportButtonHdl, layout::PushButton* ); -#ifdef FILEDLG - DECL_LINK( ImportDialogHdl, FileDialog* ); -#endif - - // framework stuff - uno::Reference< lang::XMultiServiceFactory > mxFactory; - uno::Reference< awt::XToolkit > mxToolkit; - uno::Reference< awt::XWindow > mxToplevel; - - virtual void widgetSelected( Widget *pWidget ); - DECL_LINK( CreateWidgetHdl, layout::Button* ); - - std::list< layout::PushButton *> maCreateButtons; - -public: - - EditorImpl( layout::Dialog *dialog, - // we should probable open this channel (or whatever its called) ourselves - uno::Reference< lang::XMultiServiceFactory > xMSF ); - virtual ~EditorImpl(); - - void loadFile( const rtl::OUString &aTestFile ); -}; - -EditorImpl::EditorImpl( layout::Dialog *dialog, - uno::Reference< lang::XMultiServiceFactory > xFactory ) - : mxFactory( xFactory ) - , mxToplevel( dialog->GetPeerHandle( "dialog" ), uno::UNO_QUERY ) - // FIXME: any of these should work - //dialog->getContext()->getRoot(), uno::UNO_QUERY ) - // dialog->GetPeer(), uno::UNO_QUERY ) -{ -#if DEBUG_PRINT - fprintf (stderr, "EditorImpl()\n"); -#endif - // framework - mxToolkit = uno::Reference< awt::XToolkit >( - mxFactory->createInstance( - rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.Toolkit" ) ) ), - uno::UNO_QUERY ); - OSL_ASSERT( mxToolkit.is() ); - - // custom widgets -#if DEBUG_PRINT - fprintf (stderr, "custom widgets\n"); -#endif - mpPropertiesList = new PropertiesList( dialog ); - - mpLayoutTree = new LayoutTree( dialog ); - mpLayoutTree->setListener( this ); - -/* if ( xImport.is() ) - mpLayoutTree->getWidget( -1 )->addChild( new Widget( xImport, "import" ) );*/ - - // create buttons - layout::Container aWidgets( dialog, "create-widget" ); - layout::Container aContainers( dialog, "create-container" ); - for ( int i = 0; i < WIDGETS_SPECS_LEN; i++ ) - { - layout::PushButton *pBtn = new layout::PushButton( (layout::Window *) dialog ); - pBtn->SetText( rtl::OUString::createFromAscii( WIDGETS_SPECS[ i ].pLabel ) ); - pBtn->SetClickHdl( LINK( this, EditorImpl, CreateWidgetHdl ) ); - if ( WIDGETS_SPECS[ i ].pIconName != NULL ) - { - rtl::OString aPath ("cmd/"); - aPath += WIDGETS_SPECS[ i ].pIconName; - layout::Image aImg( aPath ); - pBtn->SetModeImage( aImg ); - pBtn->SetImageAlign( IMAGEALIGN_LEFT ); - } - pBtn->Show(); - maCreateButtons.push_back( pBtn ); - layout::Container *pBox = WIDGETS_SPECS[ i ].bIsContainer ? &aContainers : &aWidgets; - pBox->Add( pBtn ); - } - -#ifdef FILEDLG - fprintf(stderr,"creating file dialog\n"); - pImportDialog = new FileDialog( NULL/*(layout::Window *) dialog*/, 0 ); - fprintf(stderr,"connecting it\n"); - pImportDialog->SetFileSelectHdl( LINK( this, EditorImpl, ImportDialogHdl ) ); - fprintf(stderr,"done file dialog\n"); -#endif - -/* pImportButton = new layout::PushButton( dialog, "import-button" ); - pImportButton->SetClickHdl( LINK( this, EditorImpl, ImportButtonHdl ) );*/ - pExportButton = new layout::PushButton( dialog, "export-button" ); - pExportButton->SetClickHdl( LINK( this, EditorImpl, ExportButtonHdl ) ); -} - -EditorImpl::~EditorImpl() -{ - delete mpPropertiesList; - delete mpLayoutTree; - for ( std::list< layout::PushButton * >::const_iterator i = maCreateButtons.begin(); - i != maCreateButtons.end(); ++i) - delete *i; - delete pImportButton; - delete pExportButton; -#ifdef FILEDLG - delete pImportDialog; -#endif -} - -void EditorImpl::loadFile( const rtl::OUString &aTestFile ) -{ - fprintf( stderr, "TEST: layout instance\n" ); - uno::Reference< awt::XLayoutRoot > xRoot - ( new EditorRoot( mxFactory, mpLayoutTree->mpRootWidget ) ); - -/* - mxMSF->createInstance - ( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.Layout")) ), - uno::UNO_QUERY ); -*/ - if ( !xRoot.is() ) - { - throw uno::RuntimeException( - OUString( RTL_CONSTASCII_USTRINGPARAM("could not create awt Layout component!") ), - uno::Reference< uno::XInterface >() ); - } - -#if DEBUG_PRINT - fprintf( stderr, "TEST: initing root\n" ); -#endif - - uno::Reference< lang::XInitialization > xInit( xRoot, uno::UNO_QUERY ); - if ( !xInit.is() ) - { - throw uno::RuntimeException( - OUString( RTL_CONSTASCII_USTRINGPARAM("Layout has no XInitialization!") ), - uno::Reference< uno::XInterface >() ); - } - -#if DEBUG_PRINT - fprintf( stderr, "TEST: running parser\n" ); -#endif - uno::Sequence< uno::Any > aParams( 1 ); - aParams[0] <<= aTestFile; -#if DEBUG_PRINT - fprintf( stderr, "TEST: do it\n" ); -#endif - xInit->initialize( aParams ); -#if DEBUG_PRINT - fprintf( stderr, "TEST: file loaded\n" ); -#endif - - mpLayoutTree->rebuild(); -} - -void EditorImpl::createWidget( const char *name ) -{ - Widget *pWidget = mpLayoutTree->getSelectedWidget(); - - Widget *pChild = new Widget( rtl::OUString(), mxToolkit, uno::Reference< awt::XLayoutContainer >( mxToplevel, uno::UNO_QUERY ), rtl::OUString::createFromAscii( name ), awt::WindowAttribute::SHOW ); - if ( !pWidget->addChild( pChild ) ) - { - delete pChild; - // we may want to popup an error message - } - else - { - mpLayoutTree->rebuild(); - mpLayoutTree->selectWidget( pWidget ); - } -} - -void EditorImpl::widgetSelected( Widget *pWidget ) -{ - // we know can't add widget to a non-container, so let's disable the create - // buttons then. Would be nice to have a method to check if a container is - // full as well... - if ( !pWidget || pWidget->isContainer() ) - { - for ( std::list< layout::PushButton *>::const_iterator it = maCreateButtons.begin(); - it != maCreateButtons.end(); ++it) - (*it)->Enable(); - } - else - { - for ( std::list< layout::PushButton *>::const_iterator it = maCreateButtons.begin(); - it != maCreateButtons.end(); ++it) - (*it)->Disable(); - } - - mpPropertiesList->selectedWidget( pWidget ); -} - -IMPL_LINK( EditorImpl, CreateWidgetHdl, layout::Button *, pBtn ) -{ - int i = 0; - for ( std::list< layout::PushButton *>::const_iterator it = maCreateButtons.begin(); - it != maCreateButtons.end(); ++it, ++i ) - { - if ( pBtn == *it ) - break; - } - OSL_ASSERT( i < WIDGETS_SPECS_LEN ); - createWidget( WIDGETS_SPECS[i].pName ); - return 0; -} - -IMPL_LINK( EditorImpl, ImportButtonHdl, layout::PushButton *, pBtn ) -{ - (void) pBtn; -#if DEBUG_PRINT - fprintf(stderr, "IMPORT!\n"); -#endif -#ifdef FILEDLG - pImportDialog->Execute(); -#endif - - return 0; -} - -#ifdef FILEDLG -IMPL_LINK( EditorImpl, ImportDialogHdl, FileDialog *, pDialog ) -{ - UniString path = pDialog->GetPath(); -//fprintf(stderr, "Executing import dialog!\n"); - -#if DEBUG_PRINT - fprintf(stderr, "got import file: %s\n",rtl::OUStringToOString( path, RTL_TEXTENCODING_ASCII_US ).getStr() ); -#endif - - return 0; -} -#endif - -IMPL_LINK( EditorImpl, ExportButtonHdl, layout::PushButton *, pBtn ) -{ - (void) pBtn; - mpLayoutTree->print(); - return 0; -} - -//** Editor, the Dialog - -Editor::Editor( uno::Reference< lang::XMultiServiceFactory > xFactory, - rtl::OUString aFile ) - : layout::Dialog( (Window*) (NULL), "editor.xml", "dialog" ) - , mpImpl( new EditorImpl( this, xFactory ) ) -{ - if ( aFile.getLength() ) - mpImpl->loadFile( aFile ); - - // parent: - FreeResource(); -} - -Editor::~Editor() -{ - delete mpImpl; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |