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 .
21 #include <com/sun/star/uno/Reference.hxx>
23 #include <com/sun/star/document/DocumentProperties.hpp>
24 #include <com/sun/star/document/XDocumentProperties.hpp>
25 #include <com/sun/star/document/UpdateDocMode.hpp>
26 #include <com/sun/star/frame/XLayoutManager.hpp>
27 #include <com/sun/star/embed/ElementModes.hpp>
28 #include <vcl/msgbox.hxx>
29 #include <svl/style.hxx>
30 #include <vcl/wrkwin.hxx>
32 #include <svl/stritem.hxx>
33 #include <svl/intitem.hxx>
34 #include <svl/rectitem.hxx>
35 #include <svl/eitem.hxx>
36 #include <svl/urihelper.hxx>
37 #include <svl/ctloptions.hxx>
38 #include <comphelper/storagehelper.hxx>
39 #include <comphelper/processfactory.hxx>
40 #include <unotools/securityoptions.hxx>
41 #include <svtools/sfxecode.hxx>
42 #include <svtools/ehdl.hxx>
43 #include <tools/datetime.hxx>
44 #include <rtl/logfile.hxx>
45 #include <rtl/uri.hxx>
48 #include <unotools/saveopt.hxx>
49 #include <unotools/useroptions.hxx>
50 #include <unotools/localfilehelper.hxx>
51 #include <vcl/virdev.hxx>
52 #include <vcl/oldprintadaptor.hxx>
54 #include <sfx2/app.hxx>
55 #include "sfx2/sfxresid.hxx"
56 #include "appdata.hxx"
57 #include <sfx2/dinfdlg.hxx>
59 #include <sfx2/docfac.hxx>
60 #include <sfx2/viewsh.hxx>
61 #include <sfx2/objsh.hxx>
62 #include "objshimp.hxx"
63 #include <sfx2/evntconf.hxx>
64 #include "sfx2/sfxhelp.hxx"
65 #include <sfx2/dispatch.hxx>
66 #include <sfx2/printer.hxx>
67 #include <basic/basmgr.hxx>
68 #include <svtools/svtools.hrc>
69 #include <sfx2/viewfrm.hxx>
70 #include <sfx2/doctempl.hxx>
72 #include <sfx2/sfxbasemodel.hxx>
73 #include <sfx2/docfile.hxx>
74 #include <sfx2/request.hxx>
75 #include "openflag.hxx"
76 #include "querytemplate.hxx"
78 using namespace ::com::sun::star
;
79 using namespace ::com::sun::star::uno
;
81 //====================================================================
84 bool operator> (const util::DateTime
& i_rLeft
, const util::DateTime
& i_rRight
)
86 if ( i_rLeft
.Year
!= i_rRight
.Year
)
87 return i_rLeft
.Year
> i_rRight
.Year
;
89 if ( i_rLeft
.Month
!= i_rRight
.Month
)
90 return i_rLeft
.Month
> i_rRight
.Month
;
92 if ( i_rLeft
.Day
!= i_rRight
.Day
)
93 return i_rLeft
.Day
> i_rRight
.Day
;
95 if ( i_rLeft
.Hours
!= i_rRight
.Hours
)
96 return i_rLeft
.Hours
> i_rRight
.Hours
;
98 if ( i_rLeft
.Minutes
!= i_rRight
.Minutes
)
99 return i_rLeft
.Minutes
> i_rRight
.Minutes
;
101 if ( i_rLeft
.Seconds
!= i_rRight
.Seconds
)
102 return i_rLeft
.Seconds
> i_rRight
.Seconds
;
104 if ( i_rLeft
.NanoSeconds
!= i_rRight
.NanoSeconds
)
105 return i_rLeft
.NanoSeconds
> i_rRight
.NanoSeconds
;
110 ::boost::shared_ptr
<GDIMetaFile
>
111 SfxObjectShell::GetPreviewMetaFile( sal_Bool bFullContent
) const
113 return CreatePreviewMetaFile_Impl( bFullContent
);
116 ::boost::shared_ptr
<GDIMetaFile
>
117 SfxObjectShell::CreatePreviewMetaFile_Impl( sal_Bool bFullContent
) const
119 // DoDraw can only be called when no printing is done, otherwise
120 // the printer may be turned off
121 SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( this );
122 if ( pFrame
&& pFrame
->GetViewShell() &&
123 pFrame
->GetViewShell()->GetPrinter() &&
124 pFrame
->GetViewShell()->GetPrinter()->IsPrinting() )
125 return ::boost::shared_ptr
<GDIMetaFile
>();
127 ::boost::shared_ptr
<GDIMetaFile
> pFile(new GDIMetaFile
);
129 VirtualDevice aDevice
;
130 aDevice
.EnableOutput( sal_False
);
132 MapMode
aMode( ((SfxObjectShell
*)this)->GetMapUnit() );
133 aDevice
.SetMapMode( aMode
);
134 pFile
->SetPrefMapMode( aMode
);
140 nAspect
= ASPECT_CONTENT
;
141 aTmpSize
= GetVisArea( nAspect
).GetSize();
145 nAspect
= ASPECT_THUMBNAIL
;
146 aTmpSize
= ((SfxObjectShell
*)this)->GetFirstPageSize();
149 pFile
->SetPrefSize( aTmpSize
);
150 DBG_ASSERT( aTmpSize
.Height()*aTmpSize
.Width(),
151 "size of first page is 0, overload GetFirstPageSize or set vis-area!" );
153 pFile
->Record( &aDevice
);
156 SvtCTLOptions aCTLOptions
;
157 if ( SvtCTLOptions::NUMERALS_HINDI
== aCTLOptions
.GetCTLTextNumerals() )
158 eLang
= LANGUAGE_ARABIC_SAUDI_ARABIA
;
159 else if ( SvtCTLOptions::NUMERALS_ARABIC
== aCTLOptions
.GetCTLTextNumerals() )
160 eLang
= LANGUAGE_ENGLISH
;
162 eLang
= (LanguageType
) Application::GetSettings().GetLanguageTag().getLanguageType();
164 aDevice
.SetDigitLanguage( eLang
);
167 RTL_LOGFILE_PRODUCT_CONTEXT( aLog
, "PERFORMANCE SfxObjectShell::CreatePreviewMetaFile_Impl" );
168 ((SfxObjectShell
*)this)->DoDraw( &aDevice
, Point(0,0), aTmpSize
, JobSetup(), nAspect
);
175 //====================================================================
177 void SfxObjectShell::UpdateDocInfoForSave()
179 uno::Reference
<document::XDocumentProperties
> xDocProps(getDocProperties());
181 // clear user data if recommend (see 'Tools - Options - Open/StarOffice - Security')
182 if ( SvtSecurityOptions().IsOptionSet(
183 SvtSecurityOptions::E_DOCWARN_REMOVEPERSONALINFO
) )
185 xDocProps
->resetUserData( OUString() );
187 else if ( IsModified() )
189 String aUserName
= SvtUserOptions().GetFullName();
190 if ( !IsUseUserData() )
192 // remove all data pointing to the current user
193 if (xDocProps
->getAuthor().equals(aUserName
)) {
194 xDocProps
->setAuthor( OUString() );
196 xDocProps
->setModifiedBy( OUString() );
197 if (xDocProps
->getPrintedBy().equals(aUserName
)) {
198 xDocProps
->setPrintedBy( OUString() );
203 // update ModificationAuthor, revision and editing time
204 ::DateTime
now( ::DateTime::SYSTEM
);
205 xDocProps
->setModificationDate( util::DateTime(
206 now
.GetNanoSec(), now
.GetSec(), now
.GetMin(),
207 now
.GetHour(), now
.GetDay(), now
.GetMonth(),
208 now
.GetYear(), false) );
209 xDocProps
->setModifiedBy( aUserName
);
210 if ( !HasName() || pImp
->bIsSaving
)
211 // QUESTION: not in case of "real" SaveAs as this is meant to create a new document
212 UpdateTime_Impl( xDocProps
);
217 //--------------------------------------------------------------------
220 lcl_add(util::Duration
& rDur
, Time
const& rTime
)
222 // here we don't care about overflow: rDur is converted back to seconds
223 // anyway, and Time cannot store more than ~4000 hours
224 rDur
.Hours
+= rTime
.GetHour();
225 rDur
.Minutes
+= rTime
.GetMin();
226 rDur
.Seconds
+= rTime
.GetSec();
229 // Update the processing time
230 void SfxObjectShell::UpdateTime_Impl(
231 const uno::Reference
<document::XDocumentProperties
> & i_xDocProps
)
233 // Get old time from documentinfo
234 const sal_Int32 secs
= i_xDocProps
->getEditingDuration();
235 util::Duration
editDuration(sal_False
, 0, 0, 0,
236 secs
/3600, (secs
%3600)/60, secs
%60, 0);
238 // Initialize some local member! Its necessary for wollow operations!
239 DateTime
aNow( DateTime::SYSTEM
); // Date and time at current moment
240 Time
n24Time (24,0,0,0) ; // Time-value for 24 hours - see follow calculation
241 sal_uIntPtr nDays
= 0 ; // Count of days between now and last editing
242 Time
nAddTime (0) ; // Value to add on aOldTime
244 // Safe impossible cases!
245 // User has changed time to the past between last editing and now ... its not possible!!!
246 DBG_ASSERT( !(aNow
.GetDate()<pImp
->nTime
.GetDate()), "Timestamp of last change is in the past ?!..." );
248 // Do the follow only, if user has NOT changed time to the past.
249 // Else add a time of 0 to aOldTime ... !!!
250 if (aNow
.GetDate()>=pImp
->nTime
.GetDate())
252 // Get count of days last editing.
253 nDays
= aNow
.GetSecFromDateTime(pImp
->nTime
.GetDate())/86400 ;
257 // If no day between now and last editing - calculate time directly.
258 nAddTime
= (const Time
&)aNow
- (const Time
&)pImp
->nTime
;
262 // If time of working without save greater then 1 month (!) ....
263 // we add 0 to aOldTime!
265 // If 1 or up to 31 days between now and last editing - calculate time indirectly.
266 // nAddTime = (24h - nTime) + (nDays * 24h) + aNow
268 nAddTime
= nDays
*n24Time
.GetTime() ;
269 nAddTime
+= n24Time
-(const Time
&)pImp
->nTime
;
273 lcl_add(editDuration
, nAddTime
);
278 const sal_Int32
newSecs( (editDuration
.Hours
*3600)
279 + (editDuration
.Minutes
*60) + editDuration
.Seconds
);
280 i_xDocProps
->setEditingDuration(newSecs
);
281 i_xDocProps
->setEditingCycles(i_xDocProps
->getEditingCycles() + 1);
283 catch (const lang::IllegalArgumentException
&)
289 //--------------------------------------------------------------------
291 SfxDocumentInfoDialog
* SfxObjectShell::CreateDocumentInfoDialog
294 const SfxItemSet
& rSet
297 return new SfxDocumentInfoDialog(pParent
, rSet
);
300 //--------------------------------------------------------------------
302 SfxStyleSheetBasePool
* SfxObjectShell::GetStyleSheetPool()
307 void SfxObjectShell::SetOrganizerSearchMask(
308 SfxStyleSheetBasePool
* pStylePool
) const
310 pStylePool
->SetSearchMask(
311 SFX_STYLE_FAMILY_ALL
,
312 SFXSTYLEBIT_USERDEF
| SFXSTYLEBIT_USED
);
315 //--------------------------------------------------------------------
317 sal_Bool
SfxObjectShell::CanHaveChildren(sal_uInt16 nIdx1
, sal_uInt16 nIdx2
)
324 return INDEX_IGNORE
== nIdx2
|| !GetStyleSheetPool() ? false : true;
331 //--------------------------------------------------------------------
333 void SfxObjectShell::GetContent(String
&rText
,
334 Bitmap
&rClosedBitmap
,
335 Bitmap
&rOpenedBitmap
,
347 sal_uInt16 nTextResId
= 0;
348 sal_uInt16 nClosedBitmapResId
= 0; // evtl. sp"ater mal unterschiedliche
349 sal_uInt16 nOpenedBitmapResId
= 0; // " " " "
353 nTextResId
= STR_STYLES
;
354 nClosedBitmapResId
= BMP_STYLES_CLOSED
;
355 nOpenedBitmapResId
= BMP_STYLES_OPENED
;
358 nTextResId
= STR_MACROS
;
359 nClosedBitmapResId
= BMP_STYLES_CLOSED
;
360 nOpenedBitmapResId
= BMP_STYLES_OPENED
;
366 rText
= SfxResId(nTextResId
).toString();
367 rClosedBitmap
= Bitmap(SfxResId(nClosedBitmapResId
));
368 rOpenedBitmap
= Bitmap(SfxResId(nOpenedBitmapResId
));
375 SfxStyleSheetBasePool
*pStylePool
= GetStyleSheetPool();
376 SetOrganizerSearchMask(pStylePool
);
377 SfxStyleSheetBase
*pStyle
= (*pStylePool
)[i
];
378 rText
= pStyle
->GetName();
379 bCanDel
=((pStyle
->GetMask() & SFXSTYLEBIT_USERDEF
)
380 == SFXSTYLEBIT_USERDEF
);
381 rClosedBitmap
= rOpenedBitmap
=
382 GetStyleFamilyBitmap(pStyle
->GetFamily());
390 //--------------------------------------------------------------------
392 Bitmap
SfxObjectShell::GetStyleFamilyBitmap(SfxStyleFamily eFamily
)
394 sal_uInt16 nResId
= 0;
397 case SFX_STYLE_FAMILY_CHAR
:
398 nResId
= BMP_STYLES_FAMILY1
;
400 case SFX_STYLE_FAMILY_PARA
:
401 nResId
= BMP_STYLES_FAMILY2
;
403 case SFX_STYLE_FAMILY_FRAME
:
404 nResId
= BMP_STYLES_FAMILY3
;
406 case SFX_STYLE_FAMILY_PAGE
:
407 nResId
= BMP_STYLES_FAMILY4
;
409 case SFX_STYLE_FAMILY_PSEUDO
:
410 case SFX_STYLE_FAMILY_ALL
:
415 return Bitmap(SfxResId(nResId
));
421 //--------------------------------------------------------------------
423 sal_Bool
SfxObjectShell::Insert(SfxObjectShell
&rSource
,
424 sal_uInt16 nSourceIdx1
,
425 sal_uInt16 nSourceIdx2
,
426 sal_uInt16
/*nSourceIdx3*/,
429 sal_uInt16
&/*nIdx3*/,
430 sal_uInt16
&/*nDeleted*/)
432 sal_Bool bRet
= sal_False
;
434 if (INDEX_IGNORE
== nIdx1
&& CONTENT_STYLE
== nSourceIdx1
)
435 nIdx1
= CONTENT_STYLE
;
437 if (CONTENT_STYLE
== nSourceIdx1
&& CONTENT_STYLE
== nIdx1
)
439 SfxStyleSheetBasePool
* pHisPool
= rSource
.GetStyleSheetPool();
440 SfxStyleSheetBasePool
* pMyPool
= GetStyleSheetPool();
441 SetOrganizerSearchMask(pHisPool
);
442 SetOrganizerSearchMask(pMyPool
);
443 SfxStyleSheetBase
* pHisSheet
= NULL
;
445 if ( pHisPool
&& pHisPool
->Count() > nSourceIdx2
)
446 pHisSheet
= (*pHisPool
)[nSourceIdx2
];
448 // Pasting is only needed if a style sheet is moved between
449 // different (!) Pools
451 if ( pHisSheet
&& pMyPool
!= pHisPool
)
453 if (INDEX_IGNORE
== nIdx2
)
455 nIdx2
= pMyPool
->Count();
458 // if such a template already exists: delete!
459 OUString
aOldName(pHisSheet
->GetName());
460 SfxStyleFamily eOldFamily
= pHisSheet
->GetFamily();
462 SfxStyleSheetBase
* pExist
= pMyPool
->Find(aOldName
, eOldFamily
);
463 sal_Bool bUsedOrUserDefined
;
467 pExist
->IsUsed() || pExist
->IsUserDefined();
468 if( ErrorHandler::HandleError(
469 *new MessageInfo( ERRCODE_SFXMSG_STYLEREPLACE
, aOldName
) )
470 != ERRCODE_BUTTON_OK
)
474 pMyPool
->Replace( *pHisSheet
, *pExist
);
475 SetModified( sal_True
);
476 nIdx2
= nIdx1
= INDEX_IGNORE
;
481 SfxStyleSheetBase
& rNewSheet
= pMyPool
->Make(
482 aOldName
, eOldFamily
,
483 pHisSheet
->GetMask(), nIdx2
);
485 // Fill the Itemset of the new template
486 rNewSheet
.GetItemSet().Set(pHisSheet
->GetItemSet());
488 // Who gets the new one as a Parent?
489 // Who is using the new one as Follow?
490 SfxStyleSheetBase
* pTestSheet
= pMyPool
->First();
493 if (pTestSheet
->GetFamily() == eOldFamily
&&
494 pTestSheet
->HasParentSupport() &&
495 pTestSheet
->GetParent() == aOldName
)
497 pTestSheet
->SetParent(aOldName
);
501 if (pTestSheet
->GetFamily() == eOldFamily
&&
502 pTestSheet
->HasFollowSupport() &&
503 pTestSheet
->GetFollow() == aOldName
)
505 pTestSheet
->SetFollow(aOldName
);
509 pTestSheet
= pMyPool
->Next();
512 rNewSheet
.IsUsed() || rNewSheet
.IsUserDefined();
515 // has a New Parent? if so, start search with the same name
516 if (pHisSheet
->HasParentSupport())
518 const String
& rParentName
= pHisSheet
->GetParent();
519 if (0 != rParentName
.Len())
521 SfxStyleSheetBase
* pParentOfNew
=
522 pMyPool
->Find(rParentName
, eOldFamily
);
524 rNewSheet
.SetParent(rParentName
);
528 // Has the new got a Follow? if so start search
529 // with the same name.
530 if (pHisSheet
->HasFollowSupport())
532 const String
& rFollowName
= pHisSheet
->GetFollow();
533 if (0 != rFollowName
.Len())
535 SfxStyleSheetBase
* pFollowOfNew
=
536 pMyPool
->Find(rFollowName
, eOldFamily
);
538 rNewSheet
.SetFollow(rFollowName
);
542 SetModified( sal_True
);
543 if( !bUsedOrUserDefined
) nIdx2
= nIdx1
= INDEX_IGNORE
;
554 //--------------------------------------------------------------------
556 sal_Bool
SfxObjectShell::Remove
563 sal_Bool bRet
= sal_False
;
565 if (CONTENT_STYLE
== nIdx1
)
567 SfxStyleSheetBasePool
* pMyPool
= GetStyleSheetPool();
569 SetOrganizerSearchMask(pMyPool
);
571 SfxStyleSheetBase
* pMySheet
= (*pMyPool
)[nIdx2
];
572 OUString
aName(pMySheet
->GetName());
574 SfxStyleFamily eFamily
= pMySheet
->GetFamily();
575 pMyPool
->Remove(pMySheet
);
578 SfxStyleSheetBase
* pTestSheet
= pMyPool
->First();
581 if (pTestSheet
->GetFamily() == eFamily
&&
582 pTestSheet
->HasParentSupport() &&
583 pTestSheet
->GetParent() == aName
)
585 pTestSheet
->SetParent(aEmpty
); // Remove link
588 if (pTestSheet
->GetFamily() == eFamily
&&
589 pTestSheet
->HasFollowSupport() &&
590 pTestSheet
->GetFollow() == aName
)
592 pTestSheet
->SetFollow(aEmpty
); // Remove link
595 pTestSheet
= pMyPool
->Next();
598 SetModified( sal_True
);
604 void SfxObjectShell::LoadStyles
606 SfxObjectShell
&rSource
/* the document template from which
607 the styles are to be loaded */
612 This method is called by the SFx if template styles are to be loaded.
613 Existing styles are in this case overwritten. The document has then to be
614 newly formatted. Therefore, the application of this method is usually
615 overloaded and its implementation is calling the implementation in
622 SfxStyleSheetBase
*pSource
;
623 SfxStyleSheetBase
*pDest
;
626 SfxStyleSheetBasePool
*pSourcePool
= rSource
.GetStyleSheetPool();
627 DBG_ASSERT(pSourcePool
, "Source-DocumentShell ohne StyleSheetPool");
628 SfxStyleSheetBasePool
*pMyPool
= GetStyleSheetPool();
629 DBG_ASSERT(pMyPool
, "Dest-DocumentShell ohne StyleSheetPool");
630 pSourcePool
->SetSearchMask(SFX_STYLE_FAMILY_ALL
, SFXSTYLEBIT_ALL
);
631 Styles_Impl
*pFound
= new Styles_Impl
[pSourcePool
->Count()];
632 sal_uInt16 nFound
= 0;
634 SfxStyleSheetBase
*pSource
= pSourcePool
->First();
637 SfxStyleSheetBase
*pDest
=
638 pMyPool
->Find( pSource
->GetName(), pSource
->GetFamily() );
641 pDest
= &pMyPool
->Make( pSource
->GetName(),
642 pSource
->GetFamily(), pSource
->GetMask());
643 // Setting of Parents, the next style
645 pFound
[nFound
].pSource
= pSource
;
646 pFound
[nFound
].pDest
= pDest
;
648 pSource
= pSourcePool
->Next();
651 for ( sal_uInt16 i
= 0; i
< nFound
; ++i
)
653 pFound
[i
].pDest
->GetItemSet().PutExtended(pFound
[i
].pSource
->GetItemSet(), SFX_ITEM_DONTCARE
, SFX_ITEM_DEFAULT
);
654 if(pFound
[i
].pSource
->HasParentSupport())
655 pFound
[i
].pDest
->SetParent(pFound
[i
].pSource
->GetParent());
656 if(pFound
[i
].pSource
->HasFollowSupport())
657 pFound
[i
].pDest
->SetFollow(pFound
[i
].pSource
->GetParent());
662 //--------------------------------------------------------------------
664 void SfxObjectShell::UpdateFromTemplate_Impl( )
668 This internal method checks whether the document was created from a
669 template, and if this is newer than the document. If this is the case,
670 the user is asked if the Templates (StyleSheets) should be updated.
671 If this is answered positively, the StyleSheets are updated.
676 SfxMedium
*pFile
= GetMedium();
677 DBG_ASSERT( pFile
, "cannot UpdateFromTemplate without medium" );
681 if ( !::utl::LocalFileHelper::IsLocalFile( pFile
->GetName() ) )
682 // update only for documents loaded from the local file system
685 // only for own storage formats
686 uno::Reference
< embed::XStorage
> xDocStor
= pFile
->GetStorage();
687 if ( !pFile
->GetFilter() || !pFile
->GetFilter()->IsOwnFormat() )
690 SFX_ITEMSET_ARG( pFile
->GetItemSet(), pUpdateDocItem
, SfxUInt16Item
, SID_UPDATEDOCMODE
, sal_False
);
691 sal_Int16 bCanUpdateFromTemplate
= pUpdateDocItem
? pUpdateDocItem
->GetValue() : document::UpdateDocMode::NO_UPDATE
;
693 // created from template?
694 uno::Reference
<document::XDocumentProperties
> xDocProps(getDocProperties());
695 OUString
aTemplName( xDocProps
->getTemplateName() );
696 OUString
aTemplURL( xDocProps
->getTemplateURL() );
699 if ( !aTemplName
.isEmpty() || (!aTemplURL
.isEmpty() && !IsReadOnly()) )
701 // try to locate template, first using filename this must be done
702 // because writer global document uses this "great" idea to manage
703 // the templates of all parts in the master document but it is NOT
704 // an error if the template filename points not to a valid file
705 SfxDocumentTemplates aTempl
;
707 if (!aTemplURL
.isEmpty())
710 aFoundName
= ::rtl::Uri::convertRelToAbs(GetMedium()->GetName(),
712 } catch (::rtl::MalformedUriException
const&) {
713 assert(false); // don't think that's supposed to happen?
717 if( !aFoundName
.Len() && !aTemplName
.isEmpty() )
718 // if the template filename did not lead to success,
719 // try to get a file name for the logical template name
720 aTempl
.GetFull( String(), aTemplName
, aFoundName
);
723 if ( aFoundName
.Len() )
725 // check existence of template storage
726 aTemplURL
= aFoundName
;
727 sal_Bool bLoad
= sal_False
;
729 // should the document checked against changes in the template ?
730 if ( IsQueryLoadTemplate() )
732 // load document properties of template
734 util::DateTime aTemplDate
;
737 Reference
<document::XDocumentProperties
> const
738 xTemplateDocProps( document::DocumentProperties::create(
739 ::comphelper::getProcessComponentContext()));
740 xTemplateDocProps
->loadFromMedium(aTemplURL
,
741 Sequence
<beans::PropertyValue
>());
742 aTemplDate
= xTemplateDocProps
->getModificationDate();
745 catch (const Exception
& e
)
747 SAL_INFO("sfx2.doc", "caught exception" << e
.Message
);
750 // if modify date was read successfully
753 // compare modify data of template with the last check date of the document
754 const util::DateTime
aInfoDate( xDocProps
->getTemplateDate() );
755 if ( aTemplDate
> aInfoDate
)
758 if( bCanUpdateFromTemplate
== document::UpdateDocMode::QUIET_UPDATE
759 || bCanUpdateFromTemplate
== document::UpdateDocMode::FULL_UPDATE
)
761 else if ( bCanUpdateFromTemplate
== document::UpdateDocMode::ACCORDING_TO_CONFIG
)
763 String
sMessage( SfxResId(STR_QRYTEMPL_MESSAGE
).toString() );
764 sMessage
.SearchAndReplace( OUString("$(ARG1)"), aTemplName
);
765 sfx2::QueryTemplateBox
aBox( GetDialogParent(), sMessage
);
766 if ( RET_YES
== aBox
.Execute() )
772 // user refuses, so don't ask again for this document
773 SetQueryLoadTemplate(sal_False
);
774 SetModified( sal_True
);
781 // styles should be updated, create document in organizer mode to read in the styles
783 SfxObjectShellLock xTemplDoc
= CreateObjectByFactoryName( GetFactory().GetFactoryName(), SFX_CREATE_MODE_ORGANIZER
);
784 xTemplDoc
->DoInitNew(0);
786 // TODO/MBA: do we need a BaseURL? Then LoadFrom must be extended!
787 //xTemplDoc->SetBaseURL( aFoundName );
789 // TODO/LATER: make sure that we don't use binary templates!
790 SfxMedium
aMedium( aFoundName
, STREAM_STD_READ
);
791 if ( xTemplDoc
->LoadFrom( aMedium
) )
793 // transfer styles from xTemplDoc to this document
794 // TODO/MBA: make sure that no BaseURL is needed in *this* document
795 LoadStyles(*xTemplDoc
);
797 // remember date/time of check
798 xDocProps
->setTemplateDate(aTemplDate
);
799 // TODO/LATER: new functionality to store document info is required ( didn't work for SO7 XML format )
806 sal_Bool
SfxObjectShell::IsHelpDocument() const
808 const SfxFilter
* pFilter
= GetMedium()->GetFilter();
809 return (pFilter
&& pFilter
->GetFilterName() == "writer_web_HTML_help");
812 void SfxObjectShell::ResetFromTemplate( const String
& rTemplateName
, const String
& rFileName
)
814 // only care about reseting this data for openoffice formats otherwise
815 if ( IsOwnStorageFormat_Impl( *GetMedium()) )
817 uno::Reference
<document::XDocumentProperties
> xDocProps(getDocProperties());
818 xDocProps
->setTemplateURL( OUString() );
819 xDocProps
->setTemplateName( OUString() );
820 xDocProps
->setTemplateDate( util::DateTime() );
821 xDocProps
->resetUserData( OUString() );
826 if( ::utl::LocalFileHelper::IsLocalFile( rFileName
) )
829 if( SFX_APP()->Get_Impl()->GetDocumentTemplates()->GetFull( String(), rTemplateName
, aFoundName
) )
831 INetURLObject
aObj( rFileName
);
832 xDocProps
->setTemplateURL( aObj
.GetMainURL(INetURLObject::DECODE_TO_IURI
) );
833 xDocProps
->setTemplateName( rTemplateName
);
835 ::DateTime
now( ::DateTime::SYSTEM
);
836 xDocProps
->setTemplateDate( util::DateTime(
837 now
.GetNanoSec(), now
.GetSec(), now
.GetMin(),
838 now
.GetHour(), now
.GetDay(), now
.GetMonth(),
839 now
.GetYear(), false) );
841 SetQueryLoadTemplate( sal_True
);
847 sal_Bool
SfxObjectShell::IsQueryLoadTemplate() const
849 return pImp
->bQueryLoadTemplate
;
852 sal_Bool
SfxObjectShell::IsUseUserData() const
854 return pImp
->bUseUserData
;
857 void SfxObjectShell::SetQueryLoadTemplate( sal_Bool bNew
)
859 if ( pImp
->bQueryLoadTemplate
!= bNew
)
860 SetModified( sal_True
);
861 pImp
->bQueryLoadTemplate
= bNew
;
864 void SfxObjectShell::SetUseUserData( sal_Bool bNew
)
866 if ( pImp
->bUseUserData
!= bNew
)
867 SetModified( sal_True
);
868 pImp
->bUseUserData
= bNew
;
871 sal_Bool
SfxObjectShell::IsLoadReadonly() const
873 return pImp
->bLoadReadonly
;
876 sal_Bool
SfxObjectShell::IsSaveVersionOnClose() const
878 return pImp
->bSaveVersionOnClose
;
881 void SfxObjectShell::SetLoadReadonly( sal_Bool bNew
)
883 if ( pImp
->bLoadReadonly
!= bNew
)
884 SetModified( sal_True
);
885 pImp
->bLoadReadonly
= bNew
;
888 void SfxObjectShell::SetSaveVersionOnClose( sal_Bool bNew
)
890 if ( pImp
->bSaveVersionOnClose
!= bNew
)
891 SetModified( sal_True
);
892 pImp
->bSaveVersionOnClose
= bNew
;
895 sal_uInt32
SfxObjectShell::GetModifyPasswordHash() const
897 return pImp
->m_nModifyPasswordHash
;
900 sal_Bool
SfxObjectShell::SetModifyPasswordHash( sal_uInt32 nHash
)
902 if ( ( !IsReadOnly() && !IsReadOnlyUI() )
903 || !(pImp
->nFlagsInProgress
& SFX_LOADED_MAINDOCUMENT
) )
905 // the hash can be changed only in editable documents,
906 // or during loading of document
907 pImp
->m_nModifyPasswordHash
= nHash
;
914 uno::Sequence
< beans::PropertyValue
> SfxObjectShell::GetModifyPasswordInfo() const
916 return pImp
->m_aModifyPasswordInfo
;
919 sal_Bool
SfxObjectShell::SetModifyPasswordInfo( const uno::Sequence
< beans::PropertyValue
>& aInfo
)
921 if ( ( !IsReadOnly() && !IsReadOnlyUI() )
922 || !(pImp
->nFlagsInProgress
& SFX_LOADED_MAINDOCUMENT
) )
924 // the hash can be changed only in editable documents,
925 // or during loading of document
926 pImp
->m_aModifyPasswordInfo
= aInfo
;
933 void SfxObjectShell::SetModifyPasswordEntered( sal_Bool bEntered
)
935 pImp
->m_bModifyPasswordEntered
= bEntered
;
938 sal_Bool
SfxObjectShell::IsModifyPasswordEntered()
940 return pImp
->m_bModifyPasswordEntered
;
943 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */