1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "DrawCommandDispatch.hxx"
21 #include "DrawCommandDispatch.h"
22 #include <ChartController.hxx>
23 #include <DrawViewWrapper.hxx>
24 #include <chartview/DrawModelWrapper.hxx>
26 #include <com/sun/star/frame/CommandGroup.hpp>
27 #include <vcl/svapp.hxx>
28 #include <svl/itempool.hxx>
29 #include <editeng/adjustitem.hxx>
30 #include <svx/dialogs.hrc>
31 #include <svx/strings.hrc>
32 #include <svx/dialmgr.hxx>
33 #include <svx/fmmodel.hxx>
34 #include <svx/gallery.hxx>
35 #include <svx/svdoashp.hxx>
36 #include <svx/svdocapt.hxx>
37 #include <svx/svdopath.hxx>
38 #include <svx/svdpage.hxx>
39 #include <svx/unoapi.hxx>
40 #include <svx/xlnedit.hxx>
41 #include <svx/xlnedwit.hxx>
42 #include <svx/xlnwtit.hxx>
43 #include <svx/xtable.hxx>
44 #include <basegfx/polygon/b2dpolygon.hxx>
48 using namespace ::com::sun::star
;
49 using namespace ::com::sun::star::frame
;
51 using ::com::sun::star::uno::Reference
;
52 using ::com::sun::star::uno::Sequence
;
58 DrawCommandDispatch::DrawCommandDispatch( const Reference
< uno::XComponentContext
>& rxContext
,
59 ChartController
* pController
)
60 :FeatureCommandDispatchBase( rxContext
)
61 ,m_pChartController( pController
)
65 DrawCommandDispatch::~DrawCommandDispatch()
69 bool DrawCommandDispatch::isFeatureSupported( const OUString
& rCommandURL
)
71 sal_uInt16 nFeatureId
= 0;
72 OUString aBaseCommand
;
73 OUString aCustomShapeType
;
74 return parseCommandURL( rCommandURL
, &nFeatureId
, &aBaseCommand
, &aCustomShapeType
);
77 ::basegfx::B2DPolyPolygon
getPolygon(const char* pResId
, const SdrModel
& rModel
)
79 ::basegfx::B2DPolyPolygon aReturn
;
80 XLineEndListRef pLineEndList
= rModel
.GetLineEndList();
81 if ( pLineEndList
.is() )
83 OUString
aName(SvxResId(pResId
));
84 long nCount
= pLineEndList
->Count();
85 for ( long nIndex
= 0; nIndex
< nCount
; ++nIndex
)
87 const XLineEndEntry
* pEntry
= pLineEndList
->GetLineEnd(nIndex
);
88 if ( pEntry
->GetName() == aName
)
90 aReturn
= pEntry
->GetLineEnd();
98 void DrawCommandDispatch::setAttributes( SdrObject
* pObj
)
100 if ( m_pChartController
)
102 DrawModelWrapper
* pDrawModelWrapper
= m_pChartController
->GetDrawModelWrapper();
103 DrawViewWrapper
* pDrawViewWrapper
= m_pChartController
->GetDrawViewWrapper();
104 if ( pDrawModelWrapper
&& pDrawViewWrapper
&& pDrawViewWrapper
->GetCurrentObjIdentifier() == OBJ_CUSTOMSHAPE
)
106 bool bAttributesAppliedFromGallery
= false;
107 if ( GalleryExplorer::GetSdrObjCount( GALLERY_THEME_POWERPOINT
) )
109 std::vector
< OUString
> aObjList
;
110 if ( GalleryExplorer::FillObjListTitle( GALLERY_THEME_POWERPOINT
, aObjList
) )
112 for ( size_t i
= 0; i
< aObjList
.size(); ++i
)
114 if ( aObjList
[ i
].equalsIgnoreAsciiCase( m_aCustomShapeType
) )
117 SfxItemPool
& rPool
= aModel
.GetItemPool();
118 rPool
.FreezeIdRanges();
119 if ( GalleryExplorer::GetSdrObj( GALLERY_THEME_POWERPOINT
, i
, &aModel
) )
121 const SdrObject
* pSourceObj
= aModel
.GetPage( 0 )->GetObj( 0 );
124 const SfxItemSet
& rSource
= pSourceObj
->GetMergedItemSet();
126 pObj
->getSdrModelFromSdrObject().GetItemPool(),
128 // Ranges from SdrAttrObj:
129 SDRATTR_START
, SDRATTR_SHADOW_LAST
,
132 SDRATTR_TEXTDIRECTION
,
133 SDRATTR_TEXTDIRECTION
,
134 // Graphic attributes, 3D
135 // properties, CustomShape
138 SDRATTR_CUSTOMSHAPE_LAST
,
139 // Range from SdrTextObj:
140 EE_ITEMS_START
, EE_ITEMS_END
>{});
141 aDest
.Set( rSource
);
142 pObj
->SetMergedItemSet( aDest
);
143 sal_Int32 nAngle
= pSourceObj
->GetRotateAngle();
146 double a
= nAngle
* F_PI18000
;
147 pObj
->NbcRotate( pObj
->GetSnapRect().Center(), nAngle
, sin( a
), cos( a
) );
149 bAttributesAppliedFromGallery
= true;
157 if ( !bAttributesAppliedFromGallery
)
159 pObj
->SetMergedItem( SvxAdjustItem( SvxAdjust::Center
, 0 ) );
160 pObj
->SetMergedItem( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_CENTER
) );
161 pObj
->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_BLOCK
) );
162 pObj
->SetMergedItem( makeSdrTextAutoGrowHeightItem( false ) );
164 SdrObjCustomShape
* pShape(dynamic_cast< SdrObjCustomShape
* >( pObj
));
168 pShape
->MergeDefaultAttributes( &m_aCustomShapeType
);
175 void DrawCommandDispatch::setLineEnds( SfxItemSet
& rAttr
)
177 if ( m_nFeatureId
== COMMAND_ID_LINE_ARROW_END
&& m_pChartController
)
179 DrawModelWrapper
* pDrawModelWrapper
= m_pChartController
->GetDrawModelWrapper();
180 DrawViewWrapper
* pDrawViewWrapper
= m_pChartController
->GetDrawViewWrapper();
181 if ( pDrawModelWrapper
&& pDrawViewWrapper
)
183 ::basegfx::B2DPolyPolygon
aArrow( getPolygon( RID_SVXSTR_ARROW
, pDrawModelWrapper
->getSdrModel() ) );
184 if ( !aArrow
.count() )
186 ::basegfx::B2DPolygon aNewArrow
;
187 aNewArrow
.append( ::basegfx::B2DPoint( 10.0, 0.0 ) );
188 aNewArrow
.append( ::basegfx::B2DPoint( 0.0, 30.0) );
189 aNewArrow
.append( ::basegfx::B2DPoint( 20.0, 30.0 ) );
190 aNewArrow
.setClosed( true );
191 aArrow
.append( aNewArrow
);
194 SfxItemSet
aSet( pDrawViewWrapper
->GetModel()->GetItemPool() );
195 pDrawViewWrapper
->GetAttributes( aSet
);
197 long nWidth
= 300; // (1/100th mm)
198 if ( aSet
.GetItemState( XATTR_LINEWIDTH
) != SfxItemState::DONTCARE
)
200 long nValue
= aSet
.Get( XATTR_LINEWIDTH
).GetValue();
207 rAttr
.Put( XLineEndItem( SvxResId( RID_SVXSTR_ARROW
), aArrow
) );
208 rAttr
.Put( XLineEndWidthItem( nWidth
) );
213 // WeakComponentImplHelperBase
214 void DrawCommandDispatch::disposing()
219 void DrawCommandDispatch::disposing( const lang::EventObject
& /* Source */ )
223 FeatureState
DrawCommandDispatch::getState( const OUString
& rCommand
)
225 FeatureState aReturn
;
226 aReturn
.bEnabled
= false;
227 aReturn
.aState
<<= false;
229 sal_uInt16 nFeatureId
= 0;
230 OUString aBaseCommand
;
231 OUString aCustomShapeType
;
232 if ( parseCommandURL( rCommand
, &nFeatureId
, &aBaseCommand
, &aCustomShapeType
) )
234 switch ( nFeatureId
)
236 case COMMAND_ID_OBJECT_SELECT
:
237 case COMMAND_ID_DRAW_LINE
:
238 case COMMAND_ID_LINE_ARROW_END
:
239 case COMMAND_ID_DRAW_RECT
:
240 case COMMAND_ID_DRAW_ELLIPSE
:
241 case COMMAND_ID_DRAW_FREELINE_NOFILL
:
242 case COMMAND_ID_DRAW_TEXT
:
243 case COMMAND_ID_DRAW_CAPTION
:
244 case COMMAND_ID_DRAWTBX_CS_BASIC
:
245 case COMMAND_ID_DRAWTBX_CS_SYMBOL
:
246 case COMMAND_ID_DRAWTBX_CS_ARROW
:
247 case COMMAND_ID_DRAWTBX_CS_FLOWCHART
:
248 case COMMAND_ID_DRAWTBX_CS_CALLOUT
:
249 case COMMAND_ID_DRAWTBX_CS_STAR
:
251 aReturn
.bEnabled
= true;
252 aReturn
.aState
<<= false;
257 aReturn
.bEnabled
= false;
258 aReturn
.aState
<<= false;
267 void DrawCommandDispatch::execute( const OUString
& rCommand
, const Sequence
< beans::PropertyValue
>& rArgs
)
269 ChartDrawMode eDrawMode
= CHARTDRAW_SELECT
;
270 SdrObjKind eKind
= OBJ_NONE
;
272 sal_uInt16 nFeatureId
= 0;
273 OUString aBaseCommand
;
274 OUString aCustomShapeType
;
275 if ( parseCommandURL( rCommand
, &nFeatureId
, &aBaseCommand
, &aCustomShapeType
) )
277 bool bCreate
= false;
278 m_nFeatureId
= nFeatureId
;
279 m_aCustomShapeType
= aCustomShapeType
;
281 switch ( nFeatureId
)
283 case COMMAND_ID_OBJECT_SELECT
:
285 eDrawMode
= CHARTDRAW_SELECT
;
289 case COMMAND_ID_DRAW_LINE
:
290 case COMMAND_ID_LINE_ARROW_END
:
292 eDrawMode
= CHARTDRAW_INSERT
;
296 case COMMAND_ID_DRAW_RECT
:
298 eDrawMode
= CHARTDRAW_INSERT
;
302 case COMMAND_ID_DRAW_ELLIPSE
:
304 eDrawMode
= CHARTDRAW_INSERT
;
308 case COMMAND_ID_DRAW_FREELINE_NOFILL
:
310 eDrawMode
= CHARTDRAW_INSERT
;
311 eKind
= OBJ_FREELINE
;
314 case COMMAND_ID_DRAW_TEXT
:
316 eDrawMode
= CHARTDRAW_INSERT
;
321 case COMMAND_ID_DRAW_CAPTION
:
323 eDrawMode
= CHARTDRAW_INSERT
;
327 case COMMAND_ID_DRAWTBX_CS_BASIC
:
328 case COMMAND_ID_DRAWTBX_CS_SYMBOL
:
329 case COMMAND_ID_DRAWTBX_CS_ARROW
:
330 case COMMAND_ID_DRAWTBX_CS_FLOWCHART
:
331 case COMMAND_ID_DRAWTBX_CS_CALLOUT
:
332 case COMMAND_ID_DRAWTBX_CS_STAR
:
334 eDrawMode
= CHARTDRAW_INSERT
;
335 eKind
= OBJ_CUSTOMSHAPE
;
340 eDrawMode
= CHARTDRAW_SELECT
;
346 if ( m_pChartController
)
348 DrawViewWrapper
* pDrawViewWrapper
= m_pChartController
->GetDrawViewWrapper();
349 if ( pDrawViewWrapper
)
351 SolarMutexGuard aGuard
;
352 m_pChartController
->setDrawMode( eDrawMode
);
353 setInsertObj( sal::static_int_cast
< sal_uInt16
>( eKind
) );
356 pDrawViewWrapper
->SetCreateMode();
359 const OUString
sKeyModifier( "KeyModifier" );
360 const beans::PropertyValue
* pIter
= rArgs
.getConstArray();
361 const beans::PropertyValue
* pEnd
= pIter
+ rArgs
.getLength();
362 const beans::PropertyValue
* pKeyModifier
= std::find_if(pIter
, pEnd
,
363 [&sKeyModifier
](const beans::PropertyValue
& lhs
)
364 {return lhs
.Name
== sKeyModifier
;} );
365 sal_Int16 nKeyModifier
= 0;
366 if ( pKeyModifier
!= pEnd
&& ( pKeyModifier
->Value
>>= nKeyModifier
) && nKeyModifier
== KEY_MOD1
)
368 if ( eDrawMode
== CHARTDRAW_INSERT
)
370 SdrObject
* pObj
= createDefaultObject( nFeatureId
);
373 SdrPageView
* pPageView
= pDrawViewWrapper
->GetSdrPageView();
374 pDrawViewWrapper
->InsertObjectAtView( pObj
, *pPageView
);
375 m_pChartController
->SetAndApplySelection(Reference
<drawing::XShape
>(pObj
->getUnoShape(), uno::UNO_QUERY
));
376 if ( nFeatureId
== COMMAND_ID_DRAW_TEXT
)
378 m_pChartController
->StartTextEdit();
388 void DrawCommandDispatch::describeSupportedFeatures()
390 implDescribeSupportedFeature( ".uno:SelectObject", COMMAND_ID_OBJECT_SELECT
, CommandGroup::INSERT
);
391 implDescribeSupportedFeature( ".uno:Line", COMMAND_ID_DRAW_LINE
, CommandGroup::INSERT
);
392 implDescribeSupportedFeature( ".uno:LineArrowEnd", COMMAND_ID_LINE_ARROW_END
, CommandGroup::INSERT
);
393 implDescribeSupportedFeature( ".uno:Rect", COMMAND_ID_DRAW_RECT
, CommandGroup::INSERT
);
394 implDescribeSupportedFeature( ".uno:Ellipse", COMMAND_ID_DRAW_ELLIPSE
, CommandGroup::INSERT
);
395 implDescribeSupportedFeature( ".uno:Freeline_Unfilled", COMMAND_ID_DRAW_FREELINE_NOFILL
, CommandGroup::INSERT
);
396 implDescribeSupportedFeature( ".uno:DrawText", COMMAND_ID_DRAW_TEXT
, CommandGroup::INSERT
);
397 implDescribeSupportedFeature( ".uno:DrawCaption", COMMAND_ID_DRAW_CAPTION
, CommandGroup::INSERT
);
398 implDescribeSupportedFeature( ".uno:BasicShapes", COMMAND_ID_DRAWTBX_CS_BASIC
, CommandGroup::INSERT
);
399 implDescribeSupportedFeature( ".uno:SymbolShapes", COMMAND_ID_DRAWTBX_CS_SYMBOL
, CommandGroup::INSERT
);
400 implDescribeSupportedFeature( ".uno:ArrowShapes", COMMAND_ID_DRAWTBX_CS_ARROW
, CommandGroup::INSERT
);
401 implDescribeSupportedFeature( ".uno:FlowChartShapes", COMMAND_ID_DRAWTBX_CS_FLOWCHART
, CommandGroup::INSERT
);
402 implDescribeSupportedFeature( ".uno:CalloutShapes", COMMAND_ID_DRAWTBX_CS_CALLOUT
, CommandGroup::INSERT
);
403 implDescribeSupportedFeature( ".uno:StarShapes", COMMAND_ID_DRAWTBX_CS_STAR
, CommandGroup::INSERT
);
406 void DrawCommandDispatch::setInsertObj( sal_uInt16 eObj
)
408 DrawViewWrapper
* pDrawViewWrapper
= ( m_pChartController
? m_pChartController
->GetDrawViewWrapper() : nullptr );
409 if ( pDrawViewWrapper
)
411 pDrawViewWrapper
->SetCurrentObj( eObj
/*, Inventor */);
415 SdrObject
* DrawCommandDispatch::createDefaultObject( const sal_uInt16 nID
)
417 SdrObject
* pObj
= nullptr;
418 DrawViewWrapper
* pDrawViewWrapper
= ( m_pChartController
? m_pChartController
->GetDrawViewWrapper() : nullptr );
419 DrawModelWrapper
* pDrawModelWrapper
= ( m_pChartController
? m_pChartController
->GetDrawModelWrapper() : nullptr );
421 if ( pDrawViewWrapper
&& pDrawModelWrapper
)
423 Reference
< drawing::XDrawPage
> xDrawPage( pDrawModelWrapper
->getMainDrawPage() );
424 SdrPage
* pPage
= GetSdrPageFromXDrawPage( xDrawPage
);
427 SolarMutexGuard aGuard
;
429 pObj
= SdrObjFactory::MakeNewObject(
430 pDrawModelWrapper
->getSdrModel(),
431 pDrawViewWrapper
->GetCurrentObjInventor(),
432 pDrawViewWrapper
->GetCurrentObjIdentifier());
436 Size
aObjectSize( 4000, 2500 );
437 tools::Rectangle
aPageRect( tools::Rectangle( Point( 0, 0 ), pPage
->GetSize() ) );
438 Point aObjectPos
= aPageRect
.Center();
439 aObjectPos
.AdjustX( -(aObjectSize
.Width() / 2) );
440 aObjectPos
.AdjustY( -(aObjectSize
.Height() / 2) );
441 tools::Rectangle
aRect( aObjectPos
, aObjectSize
);
445 case COMMAND_ID_DRAW_LINE
:
446 case COMMAND_ID_LINE_ARROW_END
:
448 if ( dynamic_cast<const SdrPathObj
*>( pObj
) != nullptr )
450 Point aStart
= aRect
.TopLeft();
451 Point aEnd
= aRect
.BottomRight();
452 sal_Int32
nYMiddle( ( aRect
.Top() + aRect
.Bottom() ) / 2 );
453 basegfx::B2DPolygon aPoly
;
454 aPoly
.append( basegfx::B2DPoint( aStart
.X(), nYMiddle
) );
455 aPoly
.append( basegfx::B2DPoint( aEnd
.X(), nYMiddle
) );
456 dynamic_cast<SdrPathObj
&>(*pObj
).SetPathPoly(basegfx::B2DPolyPolygon(aPoly
));
457 SfxItemSet
aSet( pDrawModelWrapper
->GetItemPool() );
459 pObj
->SetMergedItemSet( aSet
);
463 case COMMAND_ID_DRAW_FREELINE_NOFILL
:
465 if ( dynamic_cast<const SdrPathObj
*>( pObj
) != nullptr )
467 basegfx::B2DPolygon aInnerPoly
;
468 aInnerPoly
.append( basegfx::B2DPoint( aRect
.Left(), aRect
.Bottom() ) );
469 aInnerPoly
.appendBezierSegment(
470 basegfx::B2DPoint( aRect
.Left(), aRect
.Top() ),
471 basegfx::B2DPoint( aRect
.Center().X(), aRect
.Top() ),
472 basegfx::B2DPoint( aRect
.Center().X(), aRect
.Center().Y() ) );
473 aInnerPoly
.appendBezierSegment(
474 basegfx::B2DPoint( aRect
.Center().X(), aRect
.Bottom() ),
475 basegfx::B2DPoint( aRect
.Right(), aRect
.Bottom() ),
476 basegfx::B2DPoint( aRect
.Right(), aRect
.Top() ) );
477 basegfx::B2DPolyPolygon aPoly
;
478 aPoly
.append( aInnerPoly
);
479 dynamic_cast<SdrPathObj
&>(*pObj
).SetPathPoly(aPoly
);
483 case COMMAND_ID_DRAW_TEXT
:
484 case COMMAND_ID_DRAW_TEXT_VERTICAL
:
486 if ( dynamic_cast<const SdrTextObj
*>( pObj
) != nullptr )
488 SdrTextObj
* pTextObj
= dynamic_cast< SdrTextObj
* >( pObj
);
491 pTextObj
->SetLogicRect( aRect
);
492 bool bVertical
= ( nID
== COMMAND_ID_DRAW_TEXT_VERTICAL
);
493 pTextObj
->SetVerticalWriting( bVertical
);
496 SfxItemSet
aSet( pDrawModelWrapper
->GetItemPool() );
497 aSet
.Put( makeSdrTextAutoGrowWidthItem( true ) );
498 aSet
.Put( makeSdrTextAutoGrowHeightItem( false ) );
499 aSet
.Put( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_TOP
) );
500 aSet
.Put( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_RIGHT
) );
501 pTextObj
->SetMergedItemSet( aSet
);
507 case COMMAND_ID_DRAW_CAPTION
:
508 case COMMAND_ID_DRAW_CAPTION_VERTICAL
:
510 if ( dynamic_cast<const SdrCaptionObj
*>( pObj
) != nullptr )
512 bool bIsVertical( nID
== COMMAND_ID_DRAW_CAPTION_VERTICAL
);
513 SdrTextObj
* pTextObj
= dynamic_cast< SdrTextObj
* >( pObj
);
516 pTextObj
->SetVerticalWriting( bIsVertical
);
520 SfxItemSet
aSet( pObj
->GetMergedItemSet() );
521 aSet
.Put( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_CENTER
) );
522 aSet
.Put( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_RIGHT
) );
523 pObj
->SetMergedItemSet( aSet
);
525 SdrCaptionObj
* pCaptionObj
= dynamic_cast< SdrCaptionObj
* >( pObj
);
528 pCaptionObj
->SetLogicRect( aRect
);
529 pCaptionObj
->SetTailPos(
530 aRect
.TopLeft() - Point( aRect
.GetWidth() / 2, aRect
.GetHeight() / 2 ) );
537 pObj
->SetLogicRect( aRect
);
538 SfxItemSet
aSet( pDrawModelWrapper
->GetItemPool() );
539 setAttributes( pObj
);
540 pObj
->SetMergedItemSet( aSet
);
551 bool DrawCommandDispatch::parseCommandURL( const OUString
& rCommandURL
, sal_uInt16
* pnFeatureId
,
552 OUString
* pBaseCommand
, OUString
* pCustomShapeType
)
555 sal_uInt16 nFeatureId
= 0;
556 OUString aBaseCommand
;
559 sal_Int32 nIndex
= 1;
560 OUString aToken
= rCommandURL
.getToken( 0, '.', nIndex
);
561 if ( nIndex
== -1 || aToken
.isEmpty() )
563 aBaseCommand
= rCommandURL
;
564 SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.find( aBaseCommand
);
565 if ( aIter
!= m_aSupportedFeatures
.end() )
567 nFeatureId
= aIter
->second
.nFeatureId
;
569 switch ( nFeatureId
)
571 case COMMAND_ID_DRAWTBX_CS_BASIC
:
576 case COMMAND_ID_DRAWTBX_CS_SYMBOL
:
581 case COMMAND_ID_DRAWTBX_CS_ARROW
:
583 aType
= "left-right-arrow";
586 case COMMAND_ID_DRAWTBX_CS_FLOWCHART
:
588 aType
= "flowchart-internal-storage";
591 case COMMAND_ID_DRAWTBX_CS_CALLOUT
:
593 aType
= "round-rectangular-callout";
596 case COMMAND_ID_DRAWTBX_CS_STAR
:
614 aBaseCommand
= rCommandURL
.copy( 0, nIndex
- 1 );
615 SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.find( aBaseCommand
);
616 if ( aIter
!= m_aSupportedFeatures
.end() )
618 nFeatureId
= aIter
->second
.nFeatureId
;
619 aType
= rCommandURL
.getToken( 0, '.', nIndex
);
627 *pnFeatureId
= nFeatureId
;
628 *pBaseCommand
= aBaseCommand
;
629 *pCustomShapeType
= aType
;
636 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */