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 <comphelper/fileurl.hxx>
27 #include <vcl/svapp.hxx>
28 #include <vcl/weld.hxx>
29 #include <svl/style.hxx>
31 #include <svl/intitem.hxx>
32 #include <svl/ctloptions.hxx>
33 #include <comphelper/processfactory.hxx>
34 #include <unotools/securityoptions.hxx>
35 #include <tools/datetime.hxx>
36 #include <comphelper/diagnose_ex.hxx>
37 #include <tools/helpers.hxx>
38 #include <rtl/uri.hxx>
40 #include <unotools/useroptions.hxx>
41 #include <vcl/virdev.hxx>
42 #include <vcl/settings.hxx>
43 #include <vcl/gdimtf.hxx>
45 #include <sfx2/app.hxx>
46 #include <sfx2/dinfdlg.hxx>
47 #include <sfx2/sfxresid.hxx>
48 #include <appdata.hxx>
49 #include <sfx2/docfac.hxx>
50 #include <sfx2/viewsh.hxx>
51 #include <sfx2/objsh.hxx>
52 #include <objshimp.hxx>
53 #include <sfx2/printer.hxx>
54 #include <sfx2/viewfrm.hxx>
55 #include <sfx2/doctempl.hxx>
56 #include <sfx2/sfxsids.hrc>
57 #include <sfx2/strings.hrc>
58 #include <sfx2/docfile.hxx>
59 #include <sfx2/docfilt.hxx>
60 #include <sfx2/IDocumentModelAccessor.hxx>
64 using namespace ::com::sun::star
;
65 using namespace ::com::sun::star::uno
;
69 bool operator> (const util::DateTime
& i_rLeft
, const util::DateTime
& i_rRight
)
71 if ( i_rLeft
.Year
!= i_rRight
.Year
)
72 return i_rLeft
.Year
> i_rRight
.Year
;
74 if ( i_rLeft
.Month
!= i_rRight
.Month
)
75 return i_rLeft
.Month
> i_rRight
.Month
;
77 if ( i_rLeft
.Day
!= i_rRight
.Day
)
78 return i_rLeft
.Day
> i_rRight
.Day
;
80 if ( i_rLeft
.Hours
!= i_rRight
.Hours
)
81 return i_rLeft
.Hours
> i_rRight
.Hours
;
83 if ( i_rLeft
.Minutes
!= i_rRight
.Minutes
)
84 return i_rLeft
.Minutes
> i_rRight
.Minutes
;
86 if ( i_rLeft
.Seconds
!= i_rRight
.Seconds
)
87 return i_rLeft
.Seconds
> i_rRight
.Seconds
;
89 if ( i_rLeft
.NanoSeconds
!= i_rRight
.NanoSeconds
)
90 return i_rLeft
.NanoSeconds
> i_rRight
.NanoSeconds
;
95 std::shared_ptr
<GDIMetaFile
>
96 SfxObjectShell::GetPreviewMetaFile( bool bFullContent
) const
98 auto xFile
= std::make_shared
<GDIMetaFile
>();
99 ScopedVclPtrInstance
< VirtualDevice
> pDevice
;
100 pDevice
->EnableOutput( false );
101 if(!CreatePreview_Impl(bFullContent
, pDevice
, xFile
.get()))
102 return std::shared_ptr
<GDIMetaFile
>();
106 BitmapEx
SfxObjectShell::GetPreviewBitmap() const
108 ScopedVclPtrInstance
< VirtualDevice
> pDevice
;
109 pDevice
->SetAntialiasing(AntialiasingFlags::Enable
| pDevice
->GetAntialiasing());
110 if(!CreatePreview_Impl(/*bFullContent*/false, pDevice
, nullptr))
112 Size size
= pDevice
->GetOutputSizePixel();
113 BitmapEx aBitmap
= pDevice
->GetBitmapEx( Point(), size
);
114 // Scale down the image to the desired size from the 4*size from CreatePreview_Impl().
115 size
= Size( size
.Width() / 4, size
.Height() / 4 );
116 aBitmap
.Scale(size
, BmpScaleFlag::BestQuality
);
117 if (!aBitmap
.IsEmpty())
118 aBitmap
.Convert(BmpConversion::N24Bit
);
122 bool SfxObjectShell::CreatePreview_Impl( bool bFullContent
, VirtualDevice
* pDevice
, GDIMetaFile
* pFile
) const
124 // DoDraw can only be called when no printing is done, otherwise
125 // the printer may be turned off
126 SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( this );
127 if ( pFrame
&& pFrame
->GetViewShell() &&
128 pFrame
->GetViewShell()->GetPrinter() &&
129 pFrame
->GetViewShell()->GetPrinter()->IsPrinting() )
132 MapMode
aMode( GetMapUnit() );
137 nAspect
= ASPECT_CONTENT
;
138 aTmpSize
= GetVisArea( nAspect
).GetSize();
142 nAspect
= ASPECT_THUMBNAIL
;
143 aTmpSize
= GetFirstPageSize();
146 DBG_ASSERT( !aTmpSize
.IsEmpty(),
147 "size of first page is 0, override GetFirstPageSize or set visible-area!" );
151 pDevice
->SetMapMode( aMode
);
152 pFile
->SetPrefMapMode( aMode
);
153 pFile
->SetPrefSize( aTmpSize
);
154 pFile
->Record( pDevice
);
158 // Use pixel size, that's also what DoDraw() requires in this case,
159 // despite the metafile case (needlessly?) setting mapmode.
160 Size aSizePix
= pDevice
->LogicToPixel( aTmpSize
, aMode
);
161 // Code based on GDIMetaFile::CreateThumbnail().
162 sal_uInt32 nMaximumExtent
= 512;
163 // determine size that has the same aspect ratio as image size and
164 // fits into the rectangle determined by nMaximumExtent
165 if ( aSizePix
.Width() && aSizePix
.Height()
166 && ( sal::static_int_cast
< tools::ULong
>(aSizePix
.Width()) >
168 sal::static_int_cast
< tools::ULong
>(aSizePix
.Height()) >
171 double fWH
= static_cast< double >( aSizePix
.Width() ) / aSizePix
.Height();
174 aSizePix
.setWidth( FRound( nMaximumExtent
* fWH
) );
175 aSizePix
.setHeight( nMaximumExtent
);
179 aSizePix
.setWidth( nMaximumExtent
);
180 aSizePix
.setHeight( FRound( nMaximumExtent
/ fWH
) );
183 // do it 4x larger to be able to scale it down & get beautiful antialias
184 aTmpSize
= Size( aSizePix
.Width() * 4, aSizePix
.Height() * 4 );
185 pDevice
->SetOutputSizePixel( aTmpSize
);
189 if ( SvtCTLOptions::NUMERALS_HINDI
== SvtCTLOptions::GetCTLTextNumerals() )
190 eLang
= LANGUAGE_ARABIC_SAUDI_ARABIA
;
191 else if ( SvtCTLOptions::NUMERALS_ARABIC
== SvtCTLOptions::GetCTLTextNumerals() )
192 eLang
= LANGUAGE_ENGLISH
;
194 eLang
= Application::GetSettings().GetLanguageTag().getLanguageType();
196 pDevice
->SetDigitLanguage( eLang
);
198 const_cast<SfxObjectShell
*>(this)->DoDraw( pDevice
, Point(0,0), aTmpSize
, JobSetup(), nAspect
);
207 void SfxObjectShell::UpdateDocInfoForSave()
209 uno::Reference
<document::XDocumentProperties
> xDocProps(getDocProperties());
211 // clear user data if recommend (see 'Tools - Options - LibreOffice - Security')
212 if ( SvtSecurityOptions::IsOptionSet(
213 SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo
) && !SvtSecurityOptions::IsOptionSet(
214 SvtSecurityOptions::EOption::DocWarnKeepDocUserInfo
))
216 xDocProps
->resetUserData( OUString() );
218 else if ( IsModified() )
220 const OUString aUserName
= SvtUserOptions().GetFullName();
221 if ( !IsUseUserData() )
223 // remove all data pointing to the current user
224 if (xDocProps
->getAuthor() == aUserName
) {
225 xDocProps
->setAuthor( OUString() );
227 xDocProps
->setModifiedBy( OUString() );
228 if (xDocProps
->getPrintedBy() == aUserName
) {
229 xDocProps
->setPrintedBy( OUString() );
234 // update ModificationAuthor, revision and editing time
235 ::DateTime
now( ::DateTime::SYSTEM
);
236 xDocProps
->setModificationDate( now
.GetUNODateTime() );
237 xDocProps
->setModifiedBy( aUserName
);
238 UpdateTime_Impl( xDocProps
);
245 lcl_add(util::Duration
& rDur
, tools::Time
const& rTime
)
247 // here we don't care about overflow: rDur is converted back to seconds
248 // anyway, and tools::Time cannot store more than ~4000 hours
249 rDur
.Hours
+= rTime
.GetHour();
250 rDur
.Minutes
+= rTime
.GetMin();
251 rDur
.Seconds
+= rTime
.GetSec();
254 // Update the processing time
255 void SfxObjectShell::UpdateTime_Impl(
256 const uno::Reference
<document::XDocumentProperties
> & i_xDocProps
)
258 // Get old time from documentinfo
259 const sal_Int32 secs
= i_xDocProps
->getEditingDuration();
260 util::Duration
editDuration(false, 0, 0, 0,
261 secs
/3600, (secs
%3600)/60, secs
%60, 0);
263 // Initialize some local member! It's necessary for follow operations!
264 DateTime
aNow( DateTime::SYSTEM
); // Date and time at current moment
265 tools::Time
n24Time (24,0,0,0) ; // Time-value for 24 hours - see follow calculation
266 tools::Time
nAddTime (0) ; // Value to add on aOldTime
268 // Save impossible cases!
269 // User has changed time to the past between last editing and now... it's not possible!!!
270 DBG_ASSERT( !(aNow
.GetDate()<pImpl
->nTime
.GetDate()), "Timestamp of last change is in the past!?..." );
272 // Do the follow only, if user has NOT changed time to the past.
273 // Else add a time of 0 to aOldTime... !!!
274 if (aNow
.GetDate()>=pImpl
->nTime
.GetDate())
276 // Count of days between now and last editing
277 sal_Int32 nDays
= aNow
.GetSecFromDateTime(Date(pImpl
->nTime
.GetDate()))/86400 ;
281 // If no day between now and last editing - calculate time directly.
282 nAddTime
= static_cast<const tools::Time
&>(aNow
) - static_cast<const tools::Time
&>(pImpl
->nTime
);
286 // If time of working without save greater than 1 month (!)...
287 // we add 0 to aOldTime!
289 // If 1 or up to 31 days between now and last editing - calculate time indirectly.
290 // nAddTime = (24h - nTime) + (nDays * 24h) + aNow
292 nAddTime
= tools::Time( nDays
* n24Time
.GetTime());
293 nAddTime
+= n24Time
-static_cast<const tools::Time
&>(pImpl
->nTime
);
297 lcl_add(editDuration
, nAddTime
);
302 const sal_Int32
newSecs( (editDuration
.Hours
*3600)
303 + (editDuration
.Minutes
*60) + editDuration
.Seconds
);
304 i_xDocProps
->setEditingDuration(newSecs
);
305 i_xDocProps
->setEditingCycles(i_xDocProps
->getEditingCycles() + 1);
307 catch (const lang::IllegalArgumentException
&)
313 std::shared_ptr
<SfxDocumentInfoDialog
> SfxObjectShell::CreateDocumentInfoDialog(weld::Window
* pParent
,
314 const SfxItemSet
& rSet
)
316 return std::make_shared
<SfxDocumentInfoDialog
>(pParent
, rSet
);
319 std::optional
<NamedColor
> SfxObjectShell::GetRecentColor(sal_uInt16 nSlotId
)
321 auto it
= pImpl
->m_aRecentColors
.find(nSlotId
);
322 if (it
!= pImpl
->m_aRecentColors
.end())
328 void SfxObjectShell::SetRecentColor(sal_uInt16 nSlotId
, const NamedColor
& rColor
)
330 pImpl
->m_aRecentColors
[nSlotId
] = rColor
;
331 Broadcast(SfxHint(SfxHintId::ColorsChanged
));
334 std::set
<Color
> SfxObjectShell::GetDocColors()
336 std::set
<Color
> empty
;
340 std::shared_ptr
<model::ColorSet
> SfxObjectShell::GetThemeColors() { return {}; }
342 std::shared_ptr
<sfx::IDocumentModelAccessor
> SfxObjectShell::GetDocumentModelAccessor() const
347 sfx::AccessibilityIssueCollection
SfxObjectShell::runAccessibilityCheck()
349 sfx::AccessibilityIssueCollection aCollection
;
353 SfxStyleSheetBasePool
* SfxObjectShell::GetStyleSheetPool()
362 SfxStyleSheetBase
*pSource
;
363 SfxStyleSheetBase
*pDest
;
368 void SfxObjectShell::LoadStyles
370 SfxObjectShell
&rSource
/* the document template from which
371 the styles are to be loaded */
376 This method is called by the SFx if styles are to be loaded from a template.
377 Existing styles are in this case overwritten. The document must then be
378 re-formatted. Therefore, applications usually override this method
379 and call the implementation in the base class.
383 SfxStyleSheetBasePool
*pSourcePool
= rSource
.GetStyleSheetPool();
384 DBG_ASSERT(pSourcePool
, "Source-DocumentShell without StyleSheetPool");
385 SfxStyleSheetBasePool
*pMyPool
= GetStyleSheetPool();
386 DBG_ASSERT(pMyPool
, "Dest-DocumentShell without StyleSheetPool");
387 auto xIter
= pSourcePool
->CreateIterator(SfxStyleFamily::All
);
388 std::unique_ptr
<Styles_Impl
[]> pFound(new Styles_Impl
[xIter
->Count()]);
389 sal_uInt16 nFound
= 0;
391 SfxStyleSheetBase
*pSource
= xIter
->First();
394 SfxStyleSheetBase
*pDest
=
395 pMyPool
->Find( pSource
->GetName(), pSource
->GetFamily() );
398 pDest
= &pMyPool
->Make( pSource
->GetName(),
399 pSource
->GetFamily(), pSource
->GetMask());
400 // Setting of parents, the next style
402 pFound
[nFound
].pSource
= pSource
;
403 pFound
[nFound
].pDest
= pDest
;
405 pSource
= xIter
->Next();
408 for ( sal_uInt16 i
= 0; i
< nFound
; ++i
)
410 pFound
[i
].pDest
->GetItemSet().PutExtended(pFound
[i
].pSource
->GetItemSet(), SfxItemState::DONTCARE
, SfxItemState::DEFAULT
);
411 if(pFound
[i
].pSource
->HasParentSupport())
412 pFound
[i
].pDest
->SetParent(pFound
[i
].pSource
->GetParent());
413 if(pFound
[i
].pSource
->HasFollowSupport())
414 pFound
[i
].pDest
->SetFollow(pFound
[i
].pSource
->GetParent());
418 sfx2::StyleManager
* SfxObjectShell::GetStyleManager()
425 class QueryTemplateBox
428 std::unique_ptr
<weld::MessageDialog
> m_xQueryBox
;
430 QueryTemplateBox(weld::Window
* pParent
, const OUString
& rMessage
)
431 : m_xQueryBox(Application::CreateMessageDialog(pParent
, VclMessageType::Question
, VclButtonsType::NONE
, rMessage
))
433 m_xQueryBox
->add_button(SfxResId(STR_QRYTEMPL_UPDATE_BTN
), RET_YES
);
434 m_xQueryBox
->add_button(SfxResId(STR_QRYTEMPL_KEEP_BTN
), RET_NO
);
435 m_xQueryBox
->set_default_response(RET_YES
);
436 m_xQueryBox
->set_help_id(HID_QUERY_LOAD_TEMPLATE
);
438 short run() { return m_xQueryBox
->run(); }
442 void SfxObjectShell::UpdateFromTemplate_Impl( )
446 This internal method checks whether the document was created from a
447 template, and if this is newer than the document. If this is the case,
448 the user is asked if the Templates (StyleSheets) should be updated.
449 If this is answered positively, the StyleSheets are updated.
454 SfxMedium
*pFile
= GetMedium();
455 DBG_ASSERT( pFile
, "cannot UpdateFromTemplate without medium" );
459 if ( !comphelper::isFileUrl( pFile
->GetName() ) )
460 // update only for documents loaded from the local file system
463 // tdf#113935 - do not remove this line - somehow, it makes the process
464 // of switching from viewing a read-only document to opening it in writable
466 uno::Reference
< embed::XStorage
> xDocStor
= pFile
->GetStorage(false);
468 // only for own storage formats
469 if ( !pFile
->GetFilter() || !pFile
->GetFilter()->IsOwnFormat() )
472 const SfxUInt16Item
* pUpdateDocItem
= pFile
->GetItemSet().GetItem(SID_UPDATEDOCMODE
, false);
473 sal_Int16 bCanUpdateFromTemplate
= pUpdateDocItem
? pUpdateDocItem
->GetValue() : document::UpdateDocMode::NO_UPDATE
;
475 // created from template?
476 uno::Reference
<document::XDocumentProperties
> xDocProps(getDocProperties());
477 const OUString
aTemplName( xDocProps
->getTemplateName() );
478 OUString
aTemplURL( xDocProps
->getTemplateURL() );
481 if ( !aTemplName
.isEmpty() || (!aTemplURL
.isEmpty() && !IsReadOnly()) )
483 // try to locate template, first using filename this must be done
484 // because writer global document uses this "great" idea to manage
485 // the templates of all parts in the master document but it is NOT
486 // an error if the template filename points not to a valid file
487 SfxDocumentTemplates aTempl
;
488 if (!aTemplURL
.isEmpty())
491 aFoundName
= ::rtl::Uri::convertRelToAbs(GetMedium()->GetName(),
493 } catch (::rtl::MalformedUriException
const&) {
494 assert(false); // don't think that's supposed to happen?
498 if( aFoundName
.isEmpty() && !aTemplName
.isEmpty() )
499 // if the template filename did not lead to success,
500 // try to get a file name for the logical template name
501 aTempl
.GetFull( u
"", aTemplName
, aFoundName
);
504 if ( aFoundName
.isEmpty() )
507 // check existence of template storage
508 aTemplURL
= aFoundName
;
510 // should the document checked against changes in the template ?
511 if ( !IsQueryLoadTemplate() )
516 // load document properties of template
518 util::DateTime aTemplDate
;
521 Reference
<document::XDocumentProperties
> const
522 xTemplateDocProps( document::DocumentProperties::create(
523 ::comphelper::getProcessComponentContext()));
524 xTemplateDocProps
->loadFromMedium(aTemplURL
,
525 Sequence
<beans::PropertyValue
>());
526 aTemplDate
= xTemplateDocProps
->getModificationDate();
529 catch (const Exception
&)
531 TOOLS_INFO_EXCEPTION("sfx.doc", "");
534 // if modify date was read successfully
537 // compare modify data of template with the last check date of the document
538 const util::DateTime
aInfoDate( xDocProps
->getTemplateDate() );
539 if ( aTemplDate
> aInfoDate
)
542 if( bCanUpdateFromTemplate
== document::UpdateDocMode::QUIET_UPDATE
543 || bCanUpdateFromTemplate
== document::UpdateDocMode::FULL_UPDATE
)
545 else if ( bCanUpdateFromTemplate
== document::UpdateDocMode::ACCORDING_TO_CONFIG
)
547 const OUString
sMessage( SfxResId(STR_QRYTEMPL_MESSAGE
).replaceAll( "$(ARG1)", aTemplName
) );
548 QueryTemplateBox
aBox(Application::GetFrameWeld(GetDialogParent()), sMessage
);
549 if (RET_YES
== aBox
.run())
555 // user refuses, so don't ask again for this document
556 SetQueryLoadTemplate(false);
565 // styles should be updated, create document in organizer mode to read in the styles
567 SfxObjectShellLock xTemplDoc
= CreateObjectByFactoryName( GetFactory().GetFactoryName(), SfxObjectCreateMode::ORGANIZER
);
568 xTemplDoc
->DoInitNew();
570 // TODO/MBA: do we need a BaseURL? Then LoadFrom must be extended!
571 //xTemplDoc->SetBaseURL( aFoundName );
573 // TODO/LATER: make sure that we don't use binary templates!
574 SfxMedium
aMedium( aFoundName
, StreamMode::STD_READ
);
575 if ( xTemplDoc
->LoadFrom( aMedium
) )
577 // transfer styles from xTemplDoc to this document
578 // TODO/MBA: make sure that no BaseURL is needed in *this* document
579 LoadStyles(*xTemplDoc
);
581 // remember date/time of check
582 xDocProps
->setTemplateDate(aTemplDate
);
583 // TODO/LATER: new functionality to store document info is required ( didn't work for SO7 XML format )
587 bool SfxObjectShell::IsHelpDocument() const
589 std::shared_ptr
<const SfxFilter
> pFilter
= GetMedium()->GetFilter();
590 return (pFilter
&& pFilter
->GetFilterName() == "writer_web_HTML_help");
593 void SfxObjectShell::ResetFromTemplate( const OUString
& rTemplateName
, std::u16string_view rFileName
)
595 // only care about resetting this data for LibreOffice formats otherwise
596 if ( !IsOwnStorageFormat( *GetMedium()) )
599 uno::Reference
<document::XDocumentProperties
> xDocProps(getDocProperties());
600 xDocProps
->setTemplateURL( OUString() );
601 xDocProps
->setTemplateName( OUString() );
602 xDocProps
->setTemplateDate( util::DateTime() );
603 xDocProps
->resetUserData( OUString() );
608 if( !comphelper::isFileUrl( rFileName
) )
612 if( SfxGetpApp()->Get_Impl()->GetDocumentTemplates()->GetFull( u
"", rTemplateName
, aFoundName
) )
614 INetURLObject
aObj( rFileName
);
615 xDocProps
->setTemplateURL( aObj
.GetMainURL(INetURLObject::DecodeMechanism::ToIUri
) );
616 xDocProps
->setTemplateName( rTemplateName
);
618 ::DateTime
now( ::DateTime::SYSTEM
);
619 xDocProps
->setTemplateDate( now
.GetUNODateTime() );
621 SetQueryLoadTemplate( true );
625 bool SfxObjectShell::IsQueryLoadTemplate() const
627 return pImpl
->bQueryLoadTemplate
;
630 bool SfxObjectShell::IsUseUserData() const
632 return pImpl
->bUseUserData
;
635 bool SfxObjectShell::IsUseThumbnailSave() const
637 return pImpl
->bUseThumbnailSave
;
640 void SfxObjectShell::SetQueryLoadTemplate( bool bNew
)
642 if ( pImpl
->bQueryLoadTemplate
!= bNew
)
644 pImpl
->bQueryLoadTemplate
= bNew
;
647 void SfxObjectShell::SetUseUserData( bool bNew
)
649 if ( pImpl
->bUseUserData
!= bNew
)
651 pImpl
->bUseUserData
= bNew
;
654 void SfxObjectShell::SetUseThumbnailSave( bool _bNew
)
656 if ( pImpl
->bUseThumbnailSave
!= _bNew
)
658 pImpl
->bUseThumbnailSave
= _bNew
;
661 bool SfxObjectShell::IsLoadReadonly() const
663 return pImpl
->bLoadReadonly
;
666 bool SfxObjectShell::IsSaveVersionOnClose() const
668 return pImpl
->bSaveVersionOnClose
;
671 void SfxObjectShell::SetLoadReadonly( bool bNew
)
673 if ( pImpl
->bLoadReadonly
!= bNew
)
675 pImpl
->bLoadReadonly
= bNew
;
678 void SfxObjectShell::SetSaveVersionOnClose( bool bNew
)
680 if ( pImpl
->bSaveVersionOnClose
!= bNew
)
682 pImpl
->bSaveVersionOnClose
= bNew
;
685 sal_uInt32
SfxObjectShell::GetModifyPasswordHash() const
687 return pImpl
->m_nModifyPasswordHash
;
690 bool SfxObjectShell::SetModifyPasswordHash( sal_uInt32 nHash
)
692 if ( ( !IsReadOnly() && !IsReadOnlyUI() )
693 || !(pImpl
->nFlagsInProgress
& SfxLoadedFlags::MAINDOCUMENT
) )
695 // the hash can be changed only in editable documents,
696 // or during loading of document
697 pImpl
->m_nModifyPasswordHash
= nHash
;
704 const uno::Sequence
< beans::PropertyValue
>& SfxObjectShell::GetModifyPasswordInfo() const
706 return pImpl
->m_aModifyPasswordInfo
;
709 bool SfxObjectShell::SetModifyPasswordInfo( const uno::Sequence
< beans::PropertyValue
>& aInfo
)
711 if ( ( !IsReadOnly() && !IsReadOnlyUI() )
712 || !(pImpl
->nFlagsInProgress
& SfxLoadedFlags::MAINDOCUMENT
) )
714 // the hash can be changed only in editable documents,
715 // or during loading of document
716 pImpl
->m_aModifyPasswordInfo
= aInfo
;
723 void SfxObjectShell::SetModifyPasswordEntered( bool bEntered
)
725 pImpl
->m_bModifyPasswordEntered
= bEntered
;
728 bool SfxObjectShell::IsModifyPasswordEntered() const
730 return pImpl
->m_bModifyPasswordEntered
;
733 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */