xref: /trunk/main/sd/source/ui/view/outlnvs2.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sd.hxx"
30 
31 #include "OutlineViewShell.hxx"
32 
33 #include <com/sun/star/presentation/XPresentation2.hpp>
34 
35 #include "app.hrc"
36 #include <svx/hlnkitem.hxx>
37 #include <sfx2/docfile.hxx>
38 #include <sfx2/dispatch.hxx>
39 #include <sfx2/request.hxx>
40 #include <svl/eitem.hxx>
41 #ifndef _ZOOMITEM_HXX //autogen
42 #include <svx/zoomitem.hxx>
43 #endif
44 #include <vcl/msgbox.hxx>
45 #include <editeng/eeitem.hxx>
46 #include <editeng/flditem.hxx>
47 #include <editeng/editstat.hxx>
48 #include "optsitem.hxx"
49 #include <unotools/useroptions.hxx>
50 
51 #include <sfx2/viewfrm.hxx>
52 #include "Outliner.hxx"
53 #include "Window.hxx"
54 #include "OutlineViewShell.hxx"
55 #include "fubullet.hxx"
56 #include "fuolbull.hxx"
57 #include "FrameView.hxx"
58 #include "fuzoom.hxx"
59 #include "fuscale.hxx"
60 #include "fuchar.hxx"
61 #include "fuinsfil.hxx"
62 #include "fuprobjs.hxx"
63 #include "futhes.hxx"
64 #include "futempl.hxx"
65 #include "fusldlg.hxx"
66 #include "zoomlist.hxx"
67 #include "fuexpand.hxx"
68 #include "fusumry.hxx"
69 #include "fucushow.hxx"
70 #include "drawdoc.hxx"
71 #include "sdattr.hxx"
72 #include "ViewShellBase.hxx"
73 #include "sdabstdlg.hxx"
74 #include "framework/FrameworkHelper.hxx"
75 #include "DrawViewShell.hxx"
76 
77 using namespace ::com::sun::star::uno;
78 using namespace ::com::sun::star::presentation;
79 
80 namespace sd {
81 
82 
83 /************************************************************************/
84 
85 /*************************************************************************
86 |*
87 |* SfxRequests fuer temporaere Funktionen
88 |*
89 \************************************************************************/
90 
91 void OutlineViewShell::FuTemporary(SfxRequest &rReq)
92 {
93     DeactivateCurrentFunction();
94 
95     OutlinerView* pOutlinerView = pOlView->GetViewByWindow( GetActiveWindow() );
96     sal_uInt16 nSId = rReq.GetSlot();
97 
98     switch( nSId )
99     {
100         case SID_ATTR_ZOOM:
101         {
102             const SfxItemSet* pArgs = rReq.GetArgs();
103 
104             if ( pArgs )
105             {
106                 SvxZoomType eZT = ( ( const SvxZoomItem& ) pArgs->
107                                             Get( SID_ATTR_ZOOM ) ).GetType();
108                 switch( eZT )
109                 {
110                     case SVX_ZOOM_PERCENT:
111                         SetZoom( (long) ( ( const SvxZoomItem& ) pArgs->
112                                             Get( SID_ATTR_ZOOM ) ).GetValue() );
113                         Invalidate( SID_ATTR_ZOOM );
114                         Invalidate( SID_ATTR_ZOOMSLIDER );
115                         break;
116                     default:
117                         break;
118                 }
119                 rReq.Done();
120             }
121             else
122             {
123                 // hier den Zoom-Dialog oeffnen
124                 SetCurrentFunction( FuScale::Create( this, GetActiveWindow(), pOlView, GetDoc(), rReq ) );
125             }
126             Cancel();
127         }
128         break;
129 
130         case SID_ATTR_ZOOMSLIDER:
131         {
132             const SfxItemSet* pArgs = rReq.GetArgs();
133 
134             if (pArgs && pArgs->Count () == 1 )
135             {
136                 SFX_REQUEST_ARG (rReq, pScale, SfxUInt16Item, SID_ATTR_ZOOMSLIDER, sal_False);
137                 if (CHECK_RANGE (5, pScale->GetValue (), 3000))
138                 {
139                     SetZoom (pScale->GetValue ());
140 
141                     SfxBindings& rBindings = GetViewFrame()->GetBindings();
142                     rBindings.Invalidate( SID_ATTR_ZOOM );
143                     rBindings.Invalidate( SID_ZOOM_IN );
144                     rBindings.Invalidate( SID_ZOOM_OUT );
145                     rBindings.Invalidate( SID_ATTR_ZOOMSLIDER );
146 
147                 }
148             }
149 
150             Cancel();
151             rReq.Done ();
152             break;
153         }
154 
155         case SID_ZOOM_OUT:
156         {
157             SetCurrentFunction( FuZoom::Create(this, GetActiveWindow(), pOlView, GetDoc(), rReq) );
158             // Beendet sich selbst, kein Cancel() notwendig!
159             rReq.Done();
160         }
161         break;
162 
163         case SID_SIZE_REAL:
164         {
165             SetZoom( 100 );
166             Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( Rectangle( Point(0,0),
167                                              GetActiveWindow()->GetOutputSizePixel()) );
168             mpZoomList->InsertZoomRect(aVisAreaWin);
169             Invalidate( SID_ATTR_ZOOM );
170             Invalidate( SID_ATTR_ZOOMSLIDER );
171             Cancel();
172             rReq.Done();
173         }
174         break;
175 
176         case SID_ZOOM_IN:
177         {
178             SetZoom( Max( (long) ( GetActiveWindow()->GetZoom() / 2 ), (long) GetActiveWindow()->GetMinZoom() ) );
179             Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( Rectangle( Point(0,0),
180                                              GetActiveWindow()->GetOutputSizePixel()) );
181             mpZoomList->InsertZoomRect(aVisAreaWin);
182             Invalidate( SID_ATTR_ZOOM );
183             Invalidate( SID_ZOOM_OUT);
184             Invalidate( SID_ZOOM_IN );
185             Invalidate( SID_ATTR_ZOOMSLIDER );
186             Cancel();
187             rReq.Done();
188         }
189         break;
190 
191         case SID_OUTLINE_COLLAPSE_ALL:
192         {
193             pOutlinerView->CollapseAll();
194             Cancel();
195             rReq.Done();
196         }
197         break;
198 
199         case SID_OUTLINE_COLLAPSE:
200         {
201             pOutlinerView->Collapse();
202             Cancel();
203             rReq.Done();
204         }
205         break;
206 
207         case SID_OUTLINE_EXPAND_ALL:
208         {
209             pOutlinerView->ExpandAll();
210             Cancel();
211             rReq.Done();
212         }
213         break;
214 
215         case SID_OUTLINE_EXPAND:
216         {
217             pOutlinerView->Expand();
218             Cancel();
219             rReq.Done();
220         }
221         break;
222 
223         case SID_OUTLINE_FORMAT:
224         {
225             ::Outliner* pOutl = pOutlinerView->GetOutliner();
226             pOutl->SetFlatMode( !pOutl->IsFlatMode() );
227             Invalidate( SID_COLORVIEW );
228             Cancel();
229             rReq.Done();
230         }
231         break;
232 
233         case SID_SELECTALL:
234         {
235             ::Outliner* pOutl = pOlView->GetOutliner();
236             sal_uLong nParaCount = pOutl->GetParagraphCount();
237             if (nParaCount > 0)
238             {
239                 pOutlinerView->SelectRange( 0, (sal_uInt16) nParaCount );
240             }
241             Cancel();
242         }
243         break;
244 
245         case SID_PRESENTATION:
246         case SID_REHEARSE_TIMINGS:
247         {
248             pOlView->PrepareClose();
249 
250             Reference< XPresentation2 > xPresentation( GetDoc()->getPresentation() );
251             if( xPresentation.is() )
252             {
253                 if( ( SID_REHEARSE_TIMINGS != rReq.GetSlot() ) )
254                     xPresentation->start();
255                 else
256                     xPresentation->rehearseTimings();
257             }
258             rReq.Done();
259         }
260         break;
261 
262         case SID_COLORVIEW:
263         {
264             ::Outliner* pOutl = pOutlinerView->GetOutliner();
265             sal_uLong nCntrl = pOutl->GetControlWord();
266 
267             if ( !(nCntrl & EE_CNTRL_NOCOLORS) )
268             {
269                 // Farbansicht ist eingeschaltet: ausschalten
270                 pOutl->SetControlWord(nCntrl | EE_CNTRL_NOCOLORS);
271             }
272             else
273             {
274                 // Farbansicht ist ausgeschaltet: einschalten
275                 pOutl->SetControlWord(nCntrl & ~EE_CNTRL_NOCOLORS);
276             }
277 
278             InvalidateWindows();
279             Invalidate( SID_COLORVIEW );
280             Cancel();
281             rReq.Done();
282         }
283         break;
284 
285         case SID_STYLE_EDIT:
286         case SID_STYLE_UPDATE_BY_EXAMPLE:
287         {
288             if( rReq.GetArgs() )
289             {
290                 SetCurrentFunction( FuTemplate::Create( this, GetActiveWindow(), pOlView, GetDoc(), rReq ) );
291                 Cancel();
292             }
293 
294             rReq.Ignore ();
295         }
296         break;
297 
298         case SID_PRESENTATION_DLG:
299         {
300             SetCurrentFunction( FuSlideShowDlg::Create( this, GetActiveWindow(), pOlView, GetDoc(), rReq ) );
301             Cancel();
302         }
303         break;
304 
305         case SID_CUSTOMSHOW_DLG:
306         {
307             SetCurrentFunction( FuCustomShowDlg::Create( this, GetActiveWindow(), pOlView, GetDoc(), rReq ) );
308             Cancel();
309         }
310         break;
311     }
312 
313     if(HasCurrentFunction())
314         GetCurrentFunction()->Activate();
315 
316     Invalidate( SID_OUTLINE_COLLAPSE_ALL );
317     Invalidate( SID_OUTLINE_COLLAPSE );
318     Invalidate( SID_OUTLINE_EXPAND_ALL );
319     Invalidate( SID_OUTLINE_EXPAND );
320 
321     SfxBindings& rBindings = GetViewFrame()->GetBindings();
322     rBindings.Invalidate( SID_OUTLINE_LEFT );
323     rBindings.Invalidate( SID_OUTLINE_RIGHT );
324     rBindings.Invalidate( SID_OUTLINE_UP );
325     rBindings.Invalidate( SID_OUTLINE_DOWN );
326 
327     Invalidate( SID_OUTLINE_FORMAT );
328     Invalidate( SID_COLORVIEW );
329     Invalidate(SID_CUT);
330     Invalidate(SID_COPY);
331     Invalidate(SID_PASTE);
332 }
333 
334 void OutlineViewShell::FuTemporaryModify(SfxRequest &rReq)
335 {
336     OutlineViewModelChangeGuard aGuard( *pOlView );
337 
338     DeactivateCurrentFunction();
339 
340     OutlinerView* pOutlinerView = pOlView->GetViewByWindow( GetActiveWindow() );
341     sal_uInt16 nSId = rReq.GetSlot();
342 
343     switch( nSId )
344     {
345         case SID_HYPERLINK_SETLINK:
346         {
347             const SfxItemSet* pReqArgs = rReq.GetArgs();
348 
349             if (pReqArgs)
350             {
351                 SvxHyperlinkItem* pHLItem =
352                 (SvxHyperlinkItem*) &pReqArgs->Get(SID_HYPERLINK_SETLINK);
353 
354                 SvxFieldItem aURLItem(SvxURLField(pHLItem->GetURL(),
355                                                   pHLItem->GetName(),
356                                                   SVXURLFORMAT_REPR), EE_FEATURE_FIELD);
357                 ESelection aSel( pOutlinerView->GetSelection() );
358                 pOutlinerView->InsertField(aURLItem);
359                 if ( aSel.nStartPos <= aSel.nEndPos )
360                     aSel.nEndPos = aSel.nStartPos + 1;
361                 else
362                     aSel.nStartPos = aSel.nEndPos + 1;
363                 pOutlinerView->SetSelection( aSel );
364             }
365 
366             Cancel();
367             rReq.Ignore ();
368         }
369         break;
370 
371         case FN_INSERT_SOFT_HYPHEN:
372         case FN_INSERT_HARDHYPHEN:
373         case FN_INSERT_HARD_SPACE:
374         case SID_INSERT_RLM :
375         case SID_INSERT_LRM :
376         case SID_INSERT_ZWNBSP :
377         case SID_INSERT_ZWSP:
378         case SID_CHARMAP:
379         {
380             SetCurrentFunction( FuBullet::Create( this, GetActiveWindow(), pOlView, GetDoc(), rReq ) );
381             Cancel();
382         }
383         break;
384 
385         case SID_OUTLINE_BULLET:
386         {
387             SetCurrentFunction( FuOutlineBullet::Create( this, GetActiveWindow(), pOlView, GetDoc(), rReq ) );
388             Cancel();
389         }
390         break;
391 
392         case SID_THESAURUS:
393         {
394             SetCurrentFunction( FuThesaurus::Create( this, GetActiveWindow(), pOlView, GetDoc(), rReq ) );
395             Cancel();
396             rReq.Ignore ();
397         }
398         break;
399 
400         case SID_CHAR_DLG:
401         {
402             SetCurrentFunction( FuChar::Create( this, GetActiveWindow(), pOlView, GetDoc(), rReq ) );
403             Cancel();
404         }
405         break;
406 
407         case SID_INSERTFILE:
408         {
409             SetCurrentFunction( FuInsertFile::Create(this, GetActiveWindow(), pOlView, GetDoc(), rReq) );
410             Cancel();
411         }
412         break;
413 
414         case SID_PRESENTATIONOBJECT:
415         {
416             SetCurrentFunction( FuPresentationObjects::Create(this, GetActiveWindow(), pOlView, GetDoc(), rReq) );
417             Cancel();
418         }
419         break;
420 
421         case SID_SET_DEFAULT:
422         {
423             // 1. Selektion merken (kriegt die eselige EditEngine nicht selbst
424             //    auf die Reihe!)
425             // 2. Update auf False (sonst flackert's noch staerker
426             // an allen selektierten Absaetzen:
427             //  a. deren Vorlage nochmal setzen, um absatzweite harte Attribute
428             //     zu entfernen
429             //  b. harte Zeichenattribute loeschen
430             // 3. Update auf True und Selektion wieder setzen
431             /*
432             ESelection aEsel= pOutlinerView->GetSelection();
433             Outliner* pOutl = pOutlinerView->GetOutliner();
434             pOutl->SetUpdateMode(sal_False);
435             List* pSelectedParas = pOutlinerView->CreateSelectionList();
436             Paragraph* pPara = (Paragraph*)pSelectedParas->First();
437             while (pPara)
438             {
439                 sal_uLong nParaPos = pOutl->GetAbsPos(pPara);
440                 String aName;
441                 SfxStyleFamily aFamily;
442                 pOutl->GetStyleSheet(nParaPos, aName, aFamily);
443                 pOutl->SetStyleSheet(nParaPos, aName, aFamily);
444                 pOutl->QuickRemoveCharAttribs(nParaPos);
445                 pPara = (Paragraph*)pSelectedParas->Next();
446             }
447             delete pSelectedParas;
448             pOutl->SetUpdateMode(sal_True);
449             pOutlinerView->SetSelection(aEsel);
450             */
451             pOutlinerView->RemoveAttribs(sal_True); // sal_True = auch Absatzattribute
452             Cancel();
453             rReq.Done();
454         }
455         break;
456 
457         case SID_SUMMARY_PAGE:
458         {
459             pOlView->SetSelectedPages();
460             SetCurrentFunction( FuSummaryPage::Create( this, GetActiveWindow(), pOlView, GetDoc(), rReq ) );
461             pOlView->GetOutliner()->Clear();
462             pOlView->FillOutliner();
463             pOlView->GetActualPage();
464             Cancel();
465         }
466         break;
467 
468         case SID_EXPAND_PAGE:
469         {
470             pOlView->SetSelectedPages();
471             SetCurrentFunction( FuExpandPage::Create( this, GetActiveWindow(), pOlView, GetDoc(), rReq ) );
472             pOlView->GetOutliner()->Clear();
473             pOlView->FillOutliner();
474             pOlView->GetActualPage();
475             Cancel();
476         }
477         break;
478 
479         case SID_INSERT_FLD_DATE_FIX:
480         case SID_INSERT_FLD_DATE_VAR:
481         case SID_INSERT_FLD_TIME_FIX:
482         case SID_INSERT_FLD_TIME_VAR:
483         case SID_INSERT_FLD_AUTHOR:
484         case SID_INSERT_FLD_PAGE:
485         case SID_INSERT_FLD_PAGES:
486         case SID_INSERT_FLD_FILE:
487         {
488             SvxFieldItem* pFieldItem = 0;
489 
490             switch( nSId )
491             {
492                 case SID_INSERT_FLD_DATE_FIX:
493                     pFieldItem = new SvxFieldItem(
494                         SvxDateField( Date(), SVXDATETYPE_FIX ), EE_FEATURE_FIELD );
495                 break;
496 
497                 case SID_INSERT_FLD_DATE_VAR:
498                     pFieldItem = new SvxFieldItem( SvxDateField(), EE_FEATURE_FIELD );
499                 break;
500 
501                 case SID_INSERT_FLD_TIME_FIX:
502                     pFieldItem = new SvxFieldItem(
503                         SvxExtTimeField( Time(), SVXTIMETYPE_FIX ), EE_FEATURE_FIELD );
504                 break;
505 
506                 case SID_INSERT_FLD_TIME_VAR:
507                     pFieldItem = new SvxFieldItem( SvxExtTimeField(), EE_FEATURE_FIELD );
508                 break;
509 
510                 case SID_INSERT_FLD_AUTHOR:
511                 {
512                     SvtUserOptions aUserOptions;
513                     pFieldItem = new SvxFieldItem(
514                             SvxAuthorField(
515                                 aUserOptions.GetFirstName(), aUserOptions.GetLastName(), aUserOptions.GetID() )
516                                 , EE_FEATURE_FIELD );
517                 }
518                 break;
519 
520                 case SID_INSERT_FLD_PAGE:
521                     pFieldItem = new SvxFieldItem( SvxPageField(), EE_FEATURE_FIELD );
522                 break;
523 
524                 case SID_INSERT_FLD_PAGES:
525                     pFieldItem = new SvxFieldItem( SvxPagesField(), EE_FEATURE_FIELD );
526                 break;
527 
528                 case SID_INSERT_FLD_FILE:
529                 {
530                     String aName;
531                     if( GetDocSh()->HasName() )
532                         aName = GetDocSh()->GetMedium()->GetName();
533                     //else
534                     //  aName = GetDocSh()->GetName();
535                     pFieldItem = new SvxFieldItem( SvxExtFileField( aName ), EE_FEATURE_FIELD );
536                 }
537                 break;
538             }
539 
540             const SvxFieldItem* pOldFldItem = pOutlinerView->GetFieldAtSelection();
541 
542             if( pOldFldItem && ( pOldFldItem->GetField()->ISA( SvxURLField ) ||
543                                 pOldFldItem->GetField()->ISA( SvxDateField ) ||
544                                 pOldFldItem->GetField()->ISA( SvxTimeField ) ||
545                                 pOldFldItem->GetField()->ISA( SvxExtTimeField ) ||
546                                 pOldFldItem->GetField()->ISA( SvxExtFileField ) ||
547                                 pOldFldItem->GetField()->ISA( SvxAuthorField ) ||
548                                 pOldFldItem->GetField()->ISA( SvxPageField ) ||
549                                 pOldFldItem->GetField()->ISA( SvxPagesField )) )
550             {
551                 // Feld selektieren, so dass es beim Insert geloescht wird
552                 ESelection aSel = pOutlinerView->GetSelection();
553                 if( aSel.nStartPos == aSel.nEndPos )
554                     aSel.nEndPos++;
555                 pOutlinerView->SetSelection( aSel );
556             }
557 
558             if( pFieldItem )
559                 pOutlinerView->InsertField( *pFieldItem );
560 
561             delete pFieldItem;
562 
563             Cancel();
564             rReq.Ignore ();
565         }
566         break;
567 
568         case SID_MODIFY_FIELD:
569         {
570             const SvxFieldItem* pFldItem = pOutlinerView->GetFieldAtSelection();
571 
572             if( pFldItem && (pFldItem->GetField()->ISA( SvxDateField ) ||
573                                 pFldItem->GetField()->ISA( SvxAuthorField ) ||
574                                 pFldItem->GetField()->ISA( SvxExtFileField ) ||
575                                 pFldItem->GetField()->ISA( SvxExtTimeField ) ) )
576             {
577                 // Dialog...
578                 SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();
579                 AbstractSdModifyFieldDlg* pDlg = pFact ? pFact->CreateSdModifyFieldDlg(GetActiveWindow(), pFldItem->GetField(), pOutlinerView->GetAttribs() ) : 0;
580                 if( pDlg && (pDlg->Execute() == RET_OK) )
581                 {
582                     SvxFieldData* pField = pDlg->GetField();
583                     if( pField )
584                     {
585                         SvxFieldItem aFieldItem( *pField, EE_FEATURE_FIELD );
586                         //pOLV->DeleteSelected(); <-- fehlt leider !
587                         // Feld selektieren, so dass es beim Insert geloescht wird
588                         ESelection aSel = pOutlinerView->GetSelection();
589                         sal_Bool bSel = sal_True;
590                         if( aSel.nStartPos == aSel.nEndPos )
591                         {
592                             bSel = sal_False;
593                             aSel.nEndPos++;
594                         }
595                         pOutlinerView->SetSelection( aSel );
596 
597                         pOutlinerView->InsertField( aFieldItem );
598 
599                         // Selektion wird wieder in den Ursprungszustand gebracht
600                         if( !bSel )
601                             aSel.nEndPos--;
602                         pOutlinerView->SetSelection( aSel );
603 
604                         delete pField;
605                     }
606 
607                     SfxItemSet aSet( pDlg->GetItemSet() );
608                     if( aSet.Count() )
609                     {
610                         pOutlinerView->SetAttribs( aSet );
611 
612                         ::Outliner* pOutliner = pOutlinerView->GetOutliner();
613                         if( pOutliner )
614                             pOutliner->UpdateFields();
615                     }
616                 }
617                 delete pDlg;
618             }
619 
620             Cancel();
621             rReq.Ignore ();
622         }
623         break;
624     }
625 
626     if(HasCurrentFunction())
627         GetCurrentFunction()->Activate();
628 
629     Invalidate( SID_OUTLINE_COLLAPSE_ALL );
630     Invalidate( SID_OUTLINE_COLLAPSE );
631     Invalidate( SID_OUTLINE_EXPAND_ALL );
632     Invalidate( SID_OUTLINE_EXPAND );
633 
634     SfxBindings& rBindings = GetViewFrame()->GetBindings();
635     rBindings.Invalidate( SID_OUTLINE_LEFT );
636     rBindings.Invalidate( SID_OUTLINE_RIGHT );
637     rBindings.Invalidate( SID_OUTLINE_UP );
638     rBindings.Invalidate( SID_OUTLINE_DOWN );
639 
640     Invalidate( SID_OUTLINE_FORMAT );
641     Invalidate( SID_COLORVIEW );
642     Invalidate(SID_CUT);
643     Invalidate(SID_COPY);
644     Invalidate(SID_PASTE);
645 }
646 
647 
648 } // end of namespace sd
649