xref: /AOO41X/main/sd/source/ui/docshell/docshel4.cxx (revision ff0525f24f03981d56b7579b645949f111420994)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26 
27 #include "DrawDocShell.hxx"
28 #include <com/sun/star/document/PrinterIndependentLayout.hpp>
29 #include <tools/urlobj.hxx>
30 #include <sfx2/progress.hxx>
31 #include <vcl/waitobj.hxx>
32 #ifndef _SVXIDS_HRC
33 #include <svx/svxids.hrc>
34 #endif
35 #include <editeng/flstitem.hxx>
36 #include <editeng/eeitem.hxx>
37 #include <svl/aeitem.hxx>
38 #include <svl/flagitem.hxx>
39 #include <sot/storage.hxx>
40 #include <sfx2/docfile.hxx>
41 #include <sfx2/docfilt.hxx>
42 #ifndef _DISPATCH_HXX //autogen
43 #include <sfx2/dispatch.hxx>
44 #endif
45 #include <svx/svdotext.hxx>
46 #include <svl/style.hxx>
47 #include <sfx2/printer.hxx>
48 #include <svtools/ctrltool.hxx>
49 #ifndef _SFX_ECODE_HXX //autogen
50 #include <svtools/sfxecode.hxx>
51 #endif
52 #include <sot/clsids.hxx>
53 #include <sot/formats.hxx>
54 #include <sfx2/request.hxx>
55 #ifdef TF_STARONE
56 #include "unomodel.hxx"
57 #endif
58 
59 #include <unotools/fltrcfg.hxx>
60 #include <sfx2/frame.hxx>
61 #include <sfx2/viewfrm.hxx>
62 //#include <svx/svxmsbas.hxx>
63 #include <unotools/saveopt.hxx>
64 #include <com/sun/star/drawing/XDrawPage.hpp>
65 #include <com/sun/star/drawing/XDrawView.hpp>
66 #include <comphelper/processfactory.hxx>
67 
68 #include "app.hrc"
69 #include "glob.hrc"
70 #include "strings.hrc"
71 #include "strmname.h"
72 #ifndef SD_FRAMW_VIEW_HXX
73 #include "FrameView.hxx"
74 #endif
75 #include "optsitem.hxx"
76 #include "Outliner.hxx"
77 #include "sdattr.hxx"
78 #include "drawdoc.hxx"
79 #include "ViewShell.hxx"
80 #include "app.hxx"
81 #include "View.hxx"
82 #include "sdpage.hxx"
83 #include "sdresid.hxx"
84 #include "DrawViewShell.hxx"
85 #include "ViewShellBase.hxx"
86 #include "Window.hxx"
87 #include "sdmod.hxx"
88 #include "OutlineViewShell.hxx"
89 #include "sdxmlwrp.hxx"
90 #include "sdpptwrp.hxx"
91 #include "sdcgmfilter.hxx"
92 #include "sdgrffilter.hxx"
93 #include "sdhtmlfilter.hxx"
94 #include "framework/FrameworkHelper.hxx"
95 
96 using namespace ::com::sun::star;
97 using namespace ::com::sun::star::uno;
98 using ::sd::framework::FrameworkHelper;
99 
100 
101 namespace sd {
102 
103 /*************************************************************************
104 |*
105 |* SfxPrinter ggf. erzeugen und zurueckgeben
106 |*
107 \************************************************************************/
108 
109 SfxPrinter* DrawDocShell::GetPrinter(sal_Bool bCreate)
110 {
111     if (bCreate && !mpPrinter)
112     {
113         // ItemSet mit speziellem Poolbereich anlegen
114         SfxItemSet* pSet = new SfxItemSet( GetPool(),
115                             SID_PRINTER_NOTFOUND_WARN,  SID_PRINTER_NOTFOUND_WARN,
116                             SID_PRINTER_CHANGESTODOC,   SID_PRINTER_CHANGESTODOC,
117                             ATTR_OPTIONS_PRINT,         ATTR_OPTIONS_PRINT,
118                             0 );
119         // PrintOptionsSet setzen
120         SdOptionsPrintItem aPrintItem( ATTR_OPTIONS_PRINT,
121                             SD_MOD()->GetSdOptions(mpDoc->GetDocumentType()));
122         SfxFlagItem aFlagItem( SID_PRINTER_CHANGESTODOC );
123         sal_uInt16      nFlags = 0;
124 
125         nFlags =  (aPrintItem.GetOptionsPrint().IsWarningSize() ? SFX_PRINTER_CHG_SIZE : 0) |
126                 (aPrintItem.GetOptionsPrint().IsWarningOrientation() ? SFX_PRINTER_CHG_ORIENTATION : 0);
127         aFlagItem.SetValue( nFlags );
128 
129         pSet->Put( aPrintItem );
130         pSet->Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN, aPrintItem.GetOptionsPrint().IsWarningPrinter() ) );
131         pSet->Put( aFlagItem );
132 
133         mpPrinter = new SfxPrinter(pSet);
134         mbOwnPrinter = sal_True;
135 
136         // Ausgabequalitaet setzen
137         sal_uInt16 nQuality = aPrintItem.GetOptionsPrint().GetOutputQuality();
138 
139         sal_uLong nMode = DRAWMODE_DEFAULT;
140 
141         if( nQuality == 1 )
142             nMode = DRAWMODE_GRAYLINE | DRAWMODE_GRAYFILL | DRAWMODE_BLACKTEXT | DRAWMODE_GRAYBITMAP | DRAWMODE_GRAYGRADIENT;
143         else if( nQuality == 2 )
144             nMode = DRAWMODE_BLACKLINE | DRAWMODE_BLACKTEXT | DRAWMODE_WHITEFILL | DRAWMODE_GRAYBITMAP | DRAWMODE_WHITEGRADIENT;
145 
146         mpPrinter->SetDrawMode( nMode );
147 
148         MapMode aMM (mpPrinter->GetMapMode());
149         aMM.SetMapUnit(MAP_100TH_MM);
150         mpPrinter->SetMapMode(aMM);
151         UpdateRefDevice();
152     }
153     return mpPrinter;
154 }
155 
156 /*************************************************************************
157 |*
158 |* neuen SfxPrinter setzen (Eigentuemeruebergang)
159 |*
160 \************************************************************************/
161 
162 void DrawDocShell::SetPrinter(SfxPrinter *pNewPrinter)
163 {
164     if ( mpViewShell )
165     {
166         ::sd::View* pView = mpViewShell->GetView();
167         if ( pView->IsTextEdit() )
168             pView->SdrEndTextEdit();
169     }
170 
171     if ( mpPrinter && mbOwnPrinter && (mpPrinter != pNewPrinter) )
172     {
173         delete mpPrinter;
174     }
175 
176     mpPrinter = pNewPrinter;
177     mbOwnPrinter = sal_True;
178     if ( mpDoc->GetPrinterIndependentLayout() == ::com::sun::star::document::PrinterIndependentLayout::DISABLED )
179         UpdateFontList();
180     UpdateRefDevice();
181 }
182 
183 void DrawDocShell::UpdateFontList()
184 {
185     delete mpFontList;
186     OutputDevice* pRefDevice = NULL;
187     if ( mpDoc->GetPrinterIndependentLayout() == ::com::sun::star::document::PrinterIndependentLayout::DISABLED )
188         pRefDevice = GetPrinter(sal_True);
189     else
190         pRefDevice = SD_MOD()->GetVirtualRefDevice();
191     mpFontList = new FontList( pRefDevice, NULL, sal_False );
192     SvxFontListItem aFontListItem( mpFontList, SID_ATTR_CHAR_FONTLIST );
193     PutItem( aFontListItem );
194 }
195 
196 /*************************************************************************
197 |*
198 |*
199 |*
200 \************************************************************************/
201 Printer* DrawDocShell::GetDocumentPrinter()
202 {
203     return GetPrinter(sal_False);
204 }
205 
206 /*************************************************************************
207 |*
208 |*
209 |*
210 \************************************************************************/
211 void DrawDocShell::OnDocumentPrinterChanged(Printer* pNewPrinter)
212 {
213     // if we already have a printer, see if its the same
214     if( mpPrinter )
215     {
216         // easy case
217         if( mpPrinter == pNewPrinter )
218             return;
219 
220         // compare if its the same printer with the same job setup
221         if( (mpPrinter->GetName() == pNewPrinter->GetName()) &&
222             (mpPrinter->GetJobSetup() == pNewPrinter->GetJobSetup()))
223             return;
224     }
225 
226     //  if (mpPrinter->IsA(SfxPrinter))
227     {
228         // Da kein RTTI verfuegbar, wird hart gecasted (...)
229         SetPrinter((SfxPrinter*) pNewPrinter);
230 
231         // Printer gehoert dem Container
232         mbOwnPrinter = sal_False;
233     }
234 }
235 
236 /*************************************************************************
237 |*
238 |*
239 |*
240 \************************************************************************/
241 void DrawDocShell::UpdateRefDevice()
242 {
243     if( mpDoc )
244     {
245         // Determine the device for which the output will be formatted.
246         OutputDevice* pRefDevice = NULL;
247         switch (mpDoc->GetPrinterIndependentLayout())
248         {
249             case ::com::sun::star::document::PrinterIndependentLayout::DISABLED:
250                 pRefDevice = mpPrinter;
251                 break;
252 
253             case ::com::sun::star::document::PrinterIndependentLayout::ENABLED:
254                 pRefDevice = SD_MOD()->GetVirtualRefDevice();
255                 break;
256 
257             default:
258                 // We are confronted with an invalid or un-implemented
259                 // layout mode.  Use the printer as formatting device
260                 // as a fall-back.
261                 DBG_ASSERT(false, "DrawDocShell::UpdateRefDevice(): Unexpected printer layout mode");
262 
263                 pRefDevice = mpPrinter;
264                 break;
265         }
266         mpDoc->SetRefDevice( pRefDevice );
267 
268         ::sd::Outliner* pOutl = mpDoc->GetOutliner( sal_False );
269 
270         if( pOutl )
271             pOutl->SetRefDevice( pRefDevice );
272 
273         ::sd::Outliner* pInternalOutl = mpDoc->GetInternalOutliner( sal_False );
274 
275         if( pInternalOutl )
276             pInternalOutl->SetRefDevice( pRefDevice );
277     }
278 }
279 
280 /*************************************************************************
281 |*
282 |* InitNew, (Dokument wird neu erzeugt): Streams oeffnen
283 |*
284 \************************************************************************/
285 
286 sal_Bool DrawDocShell::InitNew( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage )
287 {
288     sal_Bool bRet = sal_False;
289 
290     bRet = SfxObjectShell::InitNew( xStorage );
291 
292     Rectangle aVisArea( Point(0, 0), Size(14100, 10000) );
293     SetVisArea(aVisArea);
294 
295     if (bRet)
296     {
297         mpDoc->SetDrawingLayerPoolDefaults();
298         if( !mbSdDataObj )
299             mpDoc->NewOrLoadCompleted(NEW_DOC);  // otherwise calling
300                                                 // NewOrLoadCompleted(NEW_LOADED) in
301                                                 // SdDrawDocument::AllocModel()
302     }
303     return bRet;
304 }
305 
306 /*************************************************************************
307 |*
308 |* Load: Pools und Dokument laden
309 |*
310 \************************************************************************/
311 
312 sal_Bool DrawDocShell::Load( SfxMedium& rMedium )
313 {
314     mbNewDocument = sal_False;
315 
316     sal_Bool    bRet = sal_False;
317     bool    bStartPresentation = false;
318     ErrCode nError = ERRCODE_NONE;
319 
320     SfxItemSet* pSet = rMedium.GetItemSet();
321 
322 
323     if( pSet )
324     {
325         if( (  SFX_ITEM_SET == pSet->GetItemState(SID_PREVIEW ) ) && ( (SfxBoolItem&) ( pSet->Get( SID_PREVIEW ) ) ).GetValue() )
326         {
327             mpDoc->SetStarDrawPreviewMode( sal_True );
328         }
329 
330         if( SFX_ITEM_SET == pSet->GetItemState(SID_DOC_STARTPRESENTATION)&&
331             ( (SfxBoolItem&) ( pSet->Get( SID_DOC_STARTPRESENTATION ) ) ).GetValue() )
332         {
333             bStartPresentation = true;
334             mpDoc->SetStartWithPresentation( true );
335         }
336     }
337 
338     bRet = SfxObjectShell::Load( rMedium );
339     if( bRet )
340     {
341         bRet = SdXMLFilter( rMedium, *this, sal_True, SDXMLMODE_Normal, SotStorage::GetVersion( rMedium.GetStorage() ) ).Import( nError );
342     }
343 
344     if( bRet )
345     {
346         UpdateTablePointers();
347 
348         // #108451# If we're an embedded OLE object, use tight bounds
349         // for our visArea. No point in showing the user lots of empty
350         // space. Had to remove the check for empty VisArea below,
351         // since XML load always sets a VisArea before.
352         //TODO/LATER: looks a little bit strange!
353         if( ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ) && SfxObjectShell::GetVisArea( ASPECT_CONTENT ).IsEmpty() )
354         {
355             SdPage* pPage = mpDoc->GetSdPage( 0, PK_STANDARD );
356 
357             if( pPage )
358                 SetVisArea( Rectangle( pPage->GetAllObjBoundRect() ) );
359         }
360 
361         FinishedLoading( SFX_LOADED_ALL );
362 
363         const INetURLObject aUrl;
364         SfxObjectShell::SetAutoLoad( aUrl, 0, sal_False );
365     }
366     else
367     {
368         if( nError == ERRCODE_IO_BROKENPACKAGE )
369             SetError( ERRCODE_IO_BROKENPACKAGE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
370 
371         // TODO/LATER: correct error handling?!
372         //pStore->SetError( SVSTREAM_WRONGVERSION, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
373         else
374             SetError( ERRCODE_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
375     }
376 
377     // tell SFX to change viewshell when in preview mode
378     if( IsPreview() || bStartPresentation )
379     {
380         SfxItemSet *pMediumSet = GetMedium()->GetItemSet();
381         if( pMediumSet )
382             pMediumSet->Put( SfxUInt16Item( SID_VIEW_ID, bStartPresentation ? 1 : 5 ) );
383     }
384 
385     return bRet;
386 }
387 
388 /*************************************************************************
389 |*
390 |* LoadFrom: Inhalte fuer Organizer laden
391 |*
392 \************************************************************************/
393 
394 sal_Bool DrawDocShell::LoadFrom( SfxMedium& rMedium )
395 {
396     mbNewDocument = sal_False;
397 
398     WaitObject* pWait = NULL;
399     if( mpViewShell )
400         pWait = new WaitObject( (Window*) mpViewShell->GetActiveWindow() );
401 
402     sal_Bool bRet = sal_False;
403 
404         /*
405         // #90691# return to old behaviour (before #80365#): construct own medium
406         SfxMedium aMedium(xStorage);
407 
408         // #90691# for having a progress bar nonetheless for XML copy it
409         // from the local DocShell medium (GetMedium()) to the constructed one
410         SfxMedium* pLocalMedium = GetMedium();
411         if(pLocalMedium)
412         {
413             SfxItemSet* pLocalItemSet = pLocalMedium->GetItemSet();
414             SfxItemSet* pDestItemSet = aMedium.GetItemSet();
415 
416             if(pLocalItemSet && pDestItemSet)
417             {
418                 const SfxUnoAnyItem* pItem = static_cast<
419                     const SfxUnoAnyItem*>(
420                         pLocalItemSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL));
421 
422                 if(pItem)
423                 {
424                     pDestItemSet->Put(*pItem);
425                 }
426             }
427         }                           */
428 
429         mpDoc->NewOrLoadCompleted( NEW_DOC );
430         mpDoc->CreateFirstPages();
431         mpDoc->StopWorkStartupDelay();
432 
433         // TODO/LATER: nobody is interested in the error code?!
434         ErrCode nError = ERRCODE_NONE;
435         bRet = SdXMLFilter( rMedium, *this, sal_True, SDXMLMODE_Organizer, SotStorage::GetVersion( rMedium.GetStorage() ) ).Import( nError );
436 
437 
438     // tell SFX to change viewshell when in preview mode
439     if( IsPreview() )
440     {
441         SfxItemSet *pSet = GetMedium()->GetItemSet();
442 
443         if( pSet )
444             pSet->Put( SfxUInt16Item( SID_VIEW_ID, 5 ) );
445     }
446 
447     delete pWait;
448 
449     return bRet;
450 }
451 
452 /*************************************************************************
453 |*
454 |* ConvertFrom: aus Fremdformat laden
455 |*
456 \************************************************************************/
457 
458 sal_Bool DrawDocShell::ConvertFrom( SfxMedium& rMedium )
459 {
460     mbNewDocument = sal_False;
461 
462     const String    aFilterName( rMedium.GetFilter()->GetFilterName() );
463     sal_Bool            bRet = sal_False;
464     bool    bStartPresentation = false;
465 
466     SetWaitCursor( sal_True );
467 
468     SfxItemSet* pSet = rMedium.GetItemSet();
469     if( pSet )
470     {
471         if( (  SFX_ITEM_SET == pSet->GetItemState(SID_PREVIEW ) ) && ( (SfxBoolItem&) ( pSet->Get( SID_PREVIEW ) ) ).GetValue() )
472         {
473             mpDoc->SetStarDrawPreviewMode( sal_True );
474         }
475 
476         if( SFX_ITEM_SET == pSet->GetItemState(SID_DOC_STARTPRESENTATION)&&
477             ( (SfxBoolItem&) ( pSet->Get( SID_DOC_STARTPRESENTATION ) ) ).GetValue() )
478         {
479             bStartPresentation = true;
480             mpDoc->SetStartWithPresentation( true );
481         }
482     }
483 
484     if( aFilterName == pFilterPowerPoint97 || aFilterName == pFilterPowerPoint97Template)
485     {
486         mpDoc->StopWorkStartupDelay();
487         bRet = SdPPTFilter( rMedium, *this, sal_True ).Import();
488     }
489     else if (aFilterName.SearchAscii("impress8" )  != STRING_NOTFOUND ||
490              aFilterName.SearchAscii("draw8")  != STRING_NOTFOUND )
491     {
492         // TODO/LATER: nobody is interested in the error code?!
493         mpDoc->CreateFirstPages();
494         mpDoc->StopWorkStartupDelay();
495         ErrCode nError = ERRCODE_NONE;
496         bRet = SdXMLFilter( rMedium, *this, sal_True ).Import( nError );
497 
498     }
499     else if (aFilterName.SearchAscii("StarOffice XML (Draw)" )  != STRING_NOTFOUND || aFilterName.SearchAscii("StarOffice XML (Impress)")  != STRING_NOTFOUND )
500     {
501         // TODO/LATER: nobody is interested in the error code?!
502         mpDoc->CreateFirstPages();
503         mpDoc->StopWorkStartupDelay();
504         ErrCode nError = ERRCODE_NONE;
505         bRet = SdXMLFilter( rMedium, *this, sal_True, SDXMLMODE_Normal, SOFFICE_FILEFORMAT_60 ).Import( nError );
506     }
507     else if( aFilterName.EqualsAscii( "CGM - Computer Graphics Metafile" ) )
508     {
509         mpDoc->CreateFirstPages();
510         mpDoc->StopWorkStartupDelay();
511         bRet = SdCGMFilter( rMedium, *this, sal_True ).Import();
512     }
513     else
514     {
515         mpDoc->CreateFirstPages();
516         mpDoc->StopWorkStartupDelay();
517         bRet = SdGRFFilter( rMedium, *this ).Import();
518     }
519 
520     FinishedLoading( SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES );
521 
522     // tell SFX to change viewshell when in preview mode
523     if( IsPreview() )
524     {
525         SfxItemSet *pMediumSet = GetMedium()->GetItemSet();
526 
527         if( pMediumSet )
528             pMediumSet->Put( SfxUInt16Item( SID_VIEW_ID, 5 ) );
529     }
530     SetWaitCursor( sal_False );
531 
532     // tell SFX to change viewshell when in preview mode
533     if( IsPreview() || bStartPresentation )
534     {
535         SfxItemSet *pMediumSet = GetMedium()->GetItemSet();
536         if( pMediumSet )
537             pMediumSet->Put( SfxUInt16Item( SID_VIEW_ID, bStartPresentation ? 1 : 5 ) );
538     }
539 
540     return bRet;
541 }
542 
543 /*************************************************************************
544 |*
545 |* Save: Pools und Dokument in die offenen Streams schreiben
546 |*
547 \************************************************************************/
548 
549 sal_Bool DrawDocShell::Save()
550 {
551     mpDoc->StopWorkStartupDelay();
552 
553     //TODO/LATER: why this?!
554     if( GetCreateMode() == SFX_CREATE_MODE_STANDARD )
555         SfxObjectShell::SetVisArea( Rectangle() );
556 
557     sal_Bool bRet = SfxObjectShell::Save();
558 
559     if( bRet )
560     {
561         // #86834# Call UpdateDocInfoForSave() before export
562         UpdateDocInfoForSave();
563 
564         bRet = SdXMLFilter( *GetMedium(), *this, sal_True, SDXMLMODE_Normal, SotStorage::GetVersion( GetMedium()->GetStorage() ) ).Export();
565     }
566 
567     return bRet;
568 }
569 
570 /*************************************************************************
571 |*
572 |* SaveAs: Pools und Dokument in den angegebenen Storage sichern
573 |*
574 \************************************************************************/
575 
576 sal_Bool DrawDocShell::SaveAs( SfxMedium& rMedium )
577 {
578     mpDoc->StopWorkStartupDelay();
579 
580     //TODO/LATER: why this?!
581     if( GetCreateMode() == SFX_CREATE_MODE_STANDARD )
582         SfxObjectShell::SetVisArea( Rectangle() );
583 
584     sal_uInt32  nVBWarning = ERRCODE_NONE;
585     sal_Bool    bRet = SfxObjectShell::SaveAs( rMedium );
586 
587     if( bRet )
588     {
589         // #86834# Call UpdateDocInfoForSave() before export
590         UpdateDocInfoForSave();
591         bRet = SdXMLFilter( rMedium, *this, sal_True, SDXMLMODE_Normal, SotStorage::GetVersion( rMedium.GetStorage() ) ).Export();
592     }
593 
594     if( GetError() == ERRCODE_NONE )
595         SetError( nVBWarning, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
596 
597     return bRet;
598 }
599 
600 /*************************************************************************
601 |*
602 |* ConvertTo: im Fremdformat speichern
603 |*
604 \************************************************************************/
605 
606 sal_Bool DrawDocShell::ConvertTo( SfxMedium& rMedium )
607 {
608     sal_Bool bRet = sal_False;
609 
610     if( mpDoc->GetPageCount() )
611     {
612         const SfxFilter*    pMediumFilter = rMedium.GetFilter();
613         const String        aTypeName( pMediumFilter->GetTypeName() );
614         SdFilter*           pFilter = NULL;
615 
616         if( aTypeName.SearchAscii( "graphic_HTML" ) != STRING_NOTFOUND )
617         {
618             pFilter = new SdHTMLFilter( rMedium, *this, sal_True );
619         }
620         else if( aTypeName.SearchAscii( "MS_PowerPoint_97" ) != STRING_NOTFOUND )
621         {
622             pFilter = new SdPPTFilter( rMedium, *this, sal_True );
623             ((SdPPTFilter*)pFilter)->PreSaveBasic();
624         }
625         else if ( aTypeName.SearchAscii( "CGM_Computer_Graphics_Metafile" ) != STRING_NOTFOUND )
626         {
627             pFilter = new SdCGMFilter( rMedium, *this, sal_True );
628         }
629         else if( ( aTypeName.SearchAscii( "draw8" ) != STRING_NOTFOUND ) ||
630                  ( aTypeName.SearchAscii( "impress8" ) != STRING_NOTFOUND ) )
631         {
632             pFilter = new SdXMLFilter( rMedium, *this, sal_True );
633             UpdateDocInfoForSave();
634         }
635         else if( ( aTypeName.SearchAscii( "StarOffice_XML_Impress" ) != STRING_NOTFOUND ) ||
636                  ( aTypeName.SearchAscii( "StarOffice_XML_Draw" ) != STRING_NOTFOUND ) )
637         {
638             pFilter = new SdXMLFilter( rMedium, *this, sal_True, SDXMLMODE_Normal, SOFFICE_FILEFORMAT_60 );
639             UpdateDocInfoForSave();
640         }
641         else
642         {
643             pFilter = new SdGRFFilter( rMedium, *this );
644         }
645 
646         if( pFilter )
647         {
648             const sal_uLong nOldSwapMode = mpDoc->GetSwapGraphicsMode();
649 
650             mpDoc->SetSwapGraphicsMode( SDR_SWAPGRAPHICSMODE_TEMP );
651 
652             bRet = pFilter->Export();
653             if( !bRet )
654                 mpDoc->SetSwapGraphicsMode( nOldSwapMode );
655 
656             delete pFilter;
657         }
658     }
659 
660     return  bRet;
661 }
662 
663 /*************************************************************************
664 |*
665 |* SaveCompleted: die eigenen Streams wieder oeffnen, damit kein anderer
666 |*                                sie "besetzt"
667 |*
668 \************************************************************************/
669 
670 sal_Bool DrawDocShell::SaveCompleted( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage )
671 {
672     sal_Bool bRet = sal_False;
673 
674     if( SfxObjectShell::SaveCompleted(xStorage) )
675     {
676         mpDoc->NbcSetChanged( sal_False );
677 
678         if( mpViewShell )
679         {
680             if( mpViewShell->ISA( OutlineViewShell ) )
681                 static_cast<OutlineView*>(mpViewShell->GetView())
682                     ->GetOutliner()->ClearModifyFlag();
683 
684             SdrOutliner* pOutl = mpViewShell->GetView()->GetTextEditOutliner();
685             if( pOutl )
686             {
687                 SdrObject* pObj = mpViewShell->GetView()->GetTextEditObject();
688                 if( pObj )
689                     pObj->NbcSetOutlinerParaObject( pOutl->CreateParaObject() );
690 
691                 pOutl->ClearModifyFlag();
692             }
693         }
694 
695         bRet = sal_True;
696 
697         SfxViewFrame* pFrame = ( mpViewShell && mpViewShell->GetViewFrame() ) ?
698                                mpViewShell->GetViewFrame() :
699                                SfxViewFrame::Current();
700 
701         if( pFrame )
702             pFrame->GetBindings().Invalidate( SID_NAVIGATOR_STATE, sal_True, sal_False );
703     }
704     return bRet;
705 }
706 
707 /*************************************************************************
708 |*
709 |* Referenz auf Dokument
710 |*
711 \************************************************************************/
712 
713 SdDrawDocument* DrawDocShell::GetDoc()
714 {
715     return mpDoc;
716 }
717 
718 /*************************************************************************
719 |*
720 |* Referenz auf Dokument
721 |*
722 \************************************************************************/
723 
724 SfxStyleSheetBasePool* DrawDocShell::GetStyleSheetPool()
725 {
726     return( (SfxStyleSheetBasePool*) mpDoc->GetStyleSheetPool() );
727 }
728 
729 /*************************************************************************
730 |*
731 |* Sprung zu Bookmark
732 |*
733 \************************************************************************/
734 
735 sal_Bool DrawDocShell::GotoBookmark(const String& rBookmark)
736 {
737     sal_Bool bFound = sal_False;
738 
739     if (mpViewShell && mpViewShell->ISA(DrawViewShell))
740     {
741         DrawViewShell* pDrawViewShell = static_cast<DrawViewShell*>(mpViewShell);
742         ViewShellBase& rBase (mpViewShell->GetViewShellBase());
743 
744         sal_Bool bIsMasterPage = sal_False;
745         sal_uInt16 nPageNumber = SDRPAGE_NOTFOUND;
746         SdrObject* pObj = NULL;
747 
748         rtl::OUString sBookmark( rBookmark );
749         const rtl::OUString sInteraction( RTL_CONSTASCII_USTRINGPARAM( "action?" ) );
750         if ( sBookmark.match( sInteraction ) )
751         {
752             const rtl::OUString sJump( RTL_CONSTASCII_USTRINGPARAM( "jump=" ) );
753             if ( sBookmark.match( sJump, sInteraction.getLength() ) )
754             {
755                 rtl::OUString aDestination( sBookmark.copy( sInteraction.getLength() + sJump.getLength() ) );
756                 if ( aDestination.match( String( RTL_CONSTASCII_USTRINGPARAM( "firstslide" ) ) ) )
757                 {
758                     nPageNumber = 1;
759                 }
760                 else if ( aDestination.match( String( RTL_CONSTASCII_USTRINGPARAM( "lastslide" ) ) ) )
761                 {
762                     nPageNumber = mpDoc->GetPageCount() - 2;
763                 }
764                 else if ( aDestination.match( String( RTL_CONSTASCII_USTRINGPARAM( "previousslide" ) ) ) )
765                 {
766                     SdPage* pPage = pDrawViewShell->GetActualPage();
767                     nPageNumber = pPage->GetPageNum();
768                     nPageNumber = nPageNumber > 2 ? nPageNumber - 2 : SDRPAGE_NOTFOUND;
769                 }
770                 else if ( aDestination.match( String( RTL_CONSTASCII_USTRINGPARAM( "nextslide" ) ) ) )
771                 {
772                     SdPage* pPage = pDrawViewShell->GetActualPage();
773                     nPageNumber = pPage->GetPageNum() + 2;
774                     if ( nPageNumber >= mpDoc->GetPageCount() )
775                         nPageNumber = SDRPAGE_NOTFOUND;
776                 }
777             }
778         }
779         else
780         {
781             String aBookmark( rBookmark );
782 
783             // Ist das Bookmark eine Seite?
784             nPageNumber = mpDoc->GetPageByName( aBookmark, bIsMasterPage );
785 
786             if (nPageNumber == SDRPAGE_NOTFOUND)
787             {
788                 // Ist das Bookmark ein Objekt?
789                 pObj = mpDoc->GetObj(aBookmark);
790 
791                 if (pObj)
792                 {
793                     nPageNumber = pObj->GetPage()->GetPageNum();
794                 }
795             }
796         }
797         if (nPageNumber != SDRPAGE_NOTFOUND)
798         {
799             // Jump to the bookmarked page.  This is done in three steps.
800 
801             bFound = sal_True;
802             SdPage* pPage;
803             if (bIsMasterPage)
804                 pPage = (SdPage*) mpDoc->GetMasterPage(nPageNumber);
805             else
806                 pPage = (SdPage*) mpDoc->GetPage(nPageNumber);
807 
808             // 1.) Change the view shell to the edit view, the notes view,
809             // or the handout view.
810             PageKind eNewPageKind = pPage->GetPageKind();
811 
812             if( (eNewPageKind != PK_STANDARD) && (mpDoc->GetDocumentType() == DOCUMENT_TYPE_DRAW) )
813                 return sal_False;
814 
815             if (eNewPageKind != pDrawViewShell->GetPageKind())
816             {
817                 // Arbeitsbereich wechseln
818                 GetFrameView()->SetPageKind(eNewPageKind);
819                 ::rtl::OUString sViewURL;
820                 switch (eNewPageKind)
821                 {
822                     case PK_STANDARD:
823                         sViewURL = FrameworkHelper::msImpressViewURL;
824                         break;
825                     case PK_NOTES:
826                         sViewURL = FrameworkHelper::msNotesViewURL;
827                         break;
828                     case PK_HANDOUT:
829                         sViewURL = FrameworkHelper::msHandoutViewURL;
830                         break;
831                     default:
832                         break;
833                 }
834                 if (sViewURL.getLength() > 0)
835                 {
836                     ::boost::shared_ptr<FrameworkHelper> pHelper (
837                         FrameworkHelper::Instance(rBase));
838                     pHelper->RequestView(
839                         sViewURL,
840                         FrameworkHelper::msCenterPaneURL);
841                     pHelper->WaitForUpdate();
842 
843                     // Get the new DrawViewShell.
844                     mpViewShell = pHelper->GetViewShell(FrameworkHelper::msCenterPaneURL).get();
845                     pDrawViewShell = dynamic_cast<sd::DrawViewShell*>(mpViewShell);
846                 }
847                 else
848                 {
849                     pDrawViewShell = NULL;
850                 }
851             }
852 
853             if (pDrawViewShell != NULL)
854             {
855                 // Set the edit mode to either the normal edit mode or the
856                 // master page mode.
857                 EditMode eNewEditMode = EM_PAGE;
858                 if (bIsMasterPage)
859                 {
860                     eNewEditMode = EM_MASTERPAGE;
861                 }
862 
863                 if (eNewEditMode != pDrawViewShell->GetEditMode())
864                 {
865                     // EditMode setzen
866                     pDrawViewShell->ChangeEditMode(eNewEditMode, sal_False);
867                 }
868 
869                 // Make the bookmarked page the current page.  This is done
870                 // by using the API because this takes care of all the
871                 // little things to be done.  Especially writing the view
872                 // data to the frame view (see bug #107803#).
873                 sal_uInt16 nSdPgNum = (nPageNumber - 1) / 2;
874                 Reference<drawing::XDrawView> xController (rBase.GetController(), UNO_QUERY);
875                 if (xController.is())
876                 {
877                     Reference<drawing::XDrawPage> xDrawPage (pPage->getUnoPage(), UNO_QUERY);
878                     xController->setCurrentPage (xDrawPage);
879                 }
880                 else
881                 {
882                     // As a fall back switch to the page via the core.
883                     DBG_ASSERT (xController.is(),
884                         "DrawDocShell::GotoBookmark: can't switch page via API");
885                     pDrawViewShell->SwitchPage(nSdPgNum);
886                 }
887 
888                 if (pObj != NULL)
889                 {
890                     // Objekt einblenden und selektieren
891                     pDrawViewShell->MakeVisible(pObj->GetLogicRect(),
892                         *pDrawViewShell->GetActiveWindow());
893                     pDrawViewShell->GetView()->UnmarkAll();
894                     pDrawViewShell->GetView()->MarkObj(
895                         pObj,
896                         pDrawViewShell->GetView()->GetSdrPageView(), sal_False);
897                 }
898             }
899         }
900 
901         SfxBindings& rBindings = (pDrawViewShell->GetViewFrame()!=NULL
902             ? pDrawViewShell->GetViewFrame()
903             : SfxViewFrame::Current() )->GetBindings();
904 
905         rBindings.Invalidate(SID_NAVIGATOR_STATE, sal_True, sal_False);
906         rBindings.Invalidate(SID_NAVIGATOR_PAGENAME);
907     }
908 
909     return (bFound);
910 }
911 
912 /*************************************************************************
913 |*
914 |* SaveAsOwnFormat: wenn es eine Dokumentvorlage werden soll,
915 |*
916 \************************************************************************/
917 #include <tools/urlobj.hxx>
918 
919 sal_Bool DrawDocShell::SaveAsOwnFormat( SfxMedium& rMedium )
920 {
921 
922     const SfxFilter* pFilter = rMedium.GetFilter();
923 
924     if (pFilter->IsOwnTemplateFormat())
925     {
926         // jetzt die StarDraw-Spezialitaeten:
927         // die Layoutvorlagen der ersten Seite werden mit dem jetzt
928         // bekannten Layoutnamen versehen, die Layoutnamen der betroffenen
929         // Masterpages und Seiten werden gesetzt;
930         // alle Textobjekte der betroffenen Standard-, Notiz- und
931         // Masterpages werden ueber die Namensaenderung informiert
932 
933         String aLayoutName;
934 
935         SfxStringItem* pLayoutItem;
936         if( rMedium.GetItemSet()->GetItemState(SID_TEMPLATE_NAME, sal_False, (const SfxPoolItem**) & pLayoutItem ) == SFX_ITEM_SET )
937         {
938             aLayoutName = pLayoutItem->GetValue();
939         }
940         else
941         {
942             INetURLObject aURL( rMedium.GetName() );
943             aURL.removeExtension();
944             aLayoutName = aURL.getName();
945         }
946 
947         if( aLayoutName.Len() )
948         {
949             sal_uInt32 nCount = mpDoc->GetMasterSdPageCount(PK_STANDARD);
950             for(sal_uInt32 i = 0; i < nCount; i++)
951             {
952                 String aOldPageLayoutName = mpDoc->GetMasterSdPage(i, PK_STANDARD)->GetLayoutName();
953                 String aNewLayoutName = aLayoutName;
954                 // Don't add suffix for the first master page
955                 if( i > 0 )
956                     aNewLayoutName += String::CreateFromInt32(i);
957 
958                 mpDoc->RenameLayoutTemplate(aOldPageLayoutName, aNewLayoutName);
959             }
960         }
961     }
962 
963     return SfxObjectShell::SaveAsOwnFormat(rMedium);
964 }
965 
966 /*************************************************************************
967 |*
968 |* FillClass
969 |*
970 \************************************************************************/
971 
972 void DrawDocShell::FillClass(SvGlobalName* pClassName,
973                                         sal_uInt32*  pFormat,
974                                         String* ,
975                                         String* pFullTypeName,
976                                         String* pShortTypeName,
977                                         sal_Int32 nFileFormat,
978                                         sal_Bool bTemplate /* = sal_False */) const
979 {
980     if (nFileFormat == SOFFICE_FILEFORMAT_60)
981     {
982         if ( meDocType == DOCUMENT_TYPE_DRAW )
983         {
984                 *pClassName = SvGlobalName(SO3_SDRAW_CLASSID_60);
985                 *pFormat = SOT_FORMATSTR_ID_STARDRAW_60;
986                 *pFullTypeName = String(SdResId(STR_GRAPHIC_DOCUMENT_FULLTYPE_60));
987         }
988         else
989         {
990                 *pClassName = SvGlobalName(SO3_SIMPRESS_CLASSID_60);
991                 *pFormat = SOT_FORMATSTR_ID_STARIMPRESS_60;
992                 *pFullTypeName = String(SdResId(STR_IMPRESS_DOCUMENT_FULLTYPE_60));
993         }
994     }
995     else if (nFileFormat == SOFFICE_FILEFORMAT_8)
996     {
997         if ( meDocType == DOCUMENT_TYPE_DRAW )
998         {
999                 *pClassName = SvGlobalName(SO3_SDRAW_CLASSID_60);
1000                 *pFormat = bTemplate ? SOT_FORMATSTR_ID_STARDRAW_8_TEMPLATE : SOT_FORMATSTR_ID_STARDRAW_8;
1001                 *pFullTypeName = String(RTL_CONSTASCII_USTRINGPARAM("Draw 8")); // HACK: method will be removed with new storage API
1002         }
1003         else
1004         {
1005                 *pClassName = SvGlobalName(SO3_SIMPRESS_CLASSID_60);
1006                 *pFormat = bTemplate ? SOT_FORMATSTR_ID_STARIMPRESS_8_TEMPLATE : SOT_FORMATSTR_ID_STARIMPRESS_8;
1007                 *pFullTypeName = String(RTL_CONSTASCII_USTRINGPARAM("Impress 8")); // HACK: method will be removed with new storage API
1008         }
1009     }
1010 
1011     *pShortTypeName = String(SdResId( (meDocType == DOCUMENT_TYPE_DRAW) ?
1012                                       STR_GRAPHIC_DOCUMENT : STR_IMPRESS_DOCUMENT ));
1013 }
1014 
1015 OutputDevice* DrawDocShell::GetDocumentRefDev (void)
1016 {
1017     OutputDevice* pReferenceDevice = SfxObjectShell::GetDocumentRefDev ();
1018     // Only when our parent does not have a reference device then we return
1019     // our own.
1020     if (pReferenceDevice == NULL && mpDoc != NULL)
1021         pReferenceDevice = mpDoc->GetRefDevice ();
1022     return pReferenceDevice;
1023 }
1024 
1025 /** executes the SID_OPENDOC slot to let the framework open a document
1026     with the given URL and this document as a referer */
1027 void DrawDocShell::OpenBookmark( const String& rBookmarkURL )
1028 {
1029     SfxStringItem   aStrItem( SID_FILE_NAME, rBookmarkURL );
1030     SfxStringItem   aReferer( SID_REFERER, GetMedium()->GetName() );
1031     const SfxPoolItem* ppArgs[] = { &aStrItem, &aReferer, 0 };
1032     ( mpViewShell ? mpViewShell->GetViewFrame() : SfxViewFrame::Current() )->GetBindings().Execute( SID_OPENHYPERLINK, ppArgs );
1033 }
1034 
1035 } // end of namespace sd
1036