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 <tools/diagnose_ex.h>
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>
63 using namespace ::com::sun::star
;
64 using namespace ::com::sun::star::uno
;
68 bool operator> (const util::DateTime
& i_rLeft
, const util::DateTime
& i_rRight
)
70 if ( i_rLeft
.Year
!= i_rRight
.Year
)
71 return i_rLeft
.Year
> i_rRight
.Year
;
73 if ( i_rLeft
.Month
!= i_rRight
.Month
)
74 return i_rLeft
.Month
> i_rRight
.Month
;
76 if ( i_rLeft
.Day
!= i_rRight
.Day
)
77 return i_rLeft
.Day
> i_rRight
.Day
;
79 if ( i_rLeft
.Hours
!= i_rRight
.Hours
)
80 return i_rLeft
.Hours
> i_rRight
.Hours
;
82 if ( i_rLeft
.Minutes
!= i_rRight
.Minutes
)
83 return i_rLeft
.Minutes
> i_rRight
.Minutes
;
85 if ( i_rLeft
.Seconds
!= i_rRight
.Seconds
)
86 return i_rLeft
.Seconds
> i_rRight
.Seconds
;
88 if ( i_rLeft
.NanoSeconds
!= i_rRight
.NanoSeconds
)
89 return i_rLeft
.NanoSeconds
> i_rRight
.NanoSeconds
;
94 std::shared_ptr
<GDIMetaFile
>
95 SfxObjectShell::GetPreviewMetaFile( bool bFullContent
) const
97 auto xFile
= std::make_shared
<GDIMetaFile
>();
98 ScopedVclPtrInstance
< VirtualDevice
> pDevice
;
99 pDevice
->EnableOutput( false );
100 if(!CreatePreview_Impl(bFullContent
, pDevice
, xFile
.get()))
101 return std::shared_ptr
<GDIMetaFile
>();
105 BitmapEx
SfxObjectShell::GetPreviewBitmap() const
107 ScopedVclPtrInstance
< VirtualDevice
> pDevice
;
108 pDevice
->SetAntialiasing(AntialiasingFlags::Enable
| pDevice
->GetAntialiasing());
109 if(!CreatePreview_Impl(/*bFullContent*/false, pDevice
, nullptr))
111 Size size
= pDevice
->GetOutputSizePixel();
112 BitmapEx aBitmap
= pDevice
->GetBitmapEx( Point(), size
);
113 // Scale down the image to the desired size from the 4*size from CreatePreview_Impl().
114 size
= Size( size
.Width() / 4, size
.Height() / 4 );
115 aBitmap
.Scale(size
, BmpScaleFlag::BestQuality
);
116 if (!aBitmap
.IsEmpty())
117 aBitmap
.Convert(BmpConversion::N24Bit
);
121 bool SfxObjectShell::CreatePreview_Impl( bool bFullContent
, VirtualDevice
* pDevice
, GDIMetaFile
* pFile
) const
123 // DoDraw can only be called when no printing is done, otherwise
124 // the printer may be turned off
125 SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( this );
126 if ( pFrame
&& pFrame
->GetViewShell() &&
127 pFrame
->GetViewShell()->GetPrinter() &&
128 pFrame
->GetViewShell()->GetPrinter()->IsPrinting() )
131 MapMode
aMode( GetMapUnit() );
136 nAspect
= ASPECT_CONTENT
;
137 aTmpSize
= GetVisArea( nAspect
).GetSize();
141 nAspect
= ASPECT_THUMBNAIL
;
142 aTmpSize
= GetFirstPageSize();
145 DBG_ASSERT( !aTmpSize
.IsEmpty(),
146 "size of first page is 0, override GetFirstPageSize or set visible-area!" );
150 pDevice
->SetMapMode( aMode
);
151 pFile
->SetPrefMapMode( aMode
);
152 pFile
->SetPrefSize( aTmpSize
);
153 pFile
->Record( pDevice
);
157 // Use pixel size, that's also what DoDraw() requires in this case,
158 // despite the metafile case (needlessly?) setting mapmode.
159 Size aSizePix
= pDevice
->LogicToPixel( aTmpSize
, aMode
);
160 // Code based on GDIMetaFile::CreateThumbnail().
161 sal_uInt32 nMaximumExtent
= 512;
162 // determine size that has the same aspect ratio as image size and
163 // fits into the rectangle determined by nMaximumExtent
164 if ( aSizePix
.Width() && aSizePix
.Height()
165 && ( sal::static_int_cast
< tools::ULong
>(aSizePix
.Width()) >
167 sal::static_int_cast
< tools::ULong
>(aSizePix
.Height()) >
170 double fWH
= static_cast< double >( aSizePix
.Width() ) / aSizePix
.Height();
173 aSizePix
.setWidth( FRound( nMaximumExtent
* fWH
) );
174 aSizePix
.setHeight( nMaximumExtent
);
178 aSizePix
.setWidth( nMaximumExtent
);
179 aSizePix
.setHeight( FRound( nMaximumExtent
/ fWH
) );
182 // do it 4x larger to be able to scale it down & get beautiful antialias
183 aTmpSize
= Size( aSizePix
.Width() * 4, aSizePix
.Height() * 4 );
184 pDevice
->SetOutputSizePixel( aTmpSize
);
188 SvtCTLOptions aCTLOptions
;
189 if ( SvtCTLOptions::NUMERALS_HINDI
== aCTLOptions
.GetCTLTextNumerals() )
190 eLang
= LANGUAGE_ARABIC_SAUDI_ARABIA
;
191 else if ( SvtCTLOptions::NUMERALS_ARABIC
== aCTLOptions
.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
) )
215 xDocProps
->resetUserData( OUString() );
217 else if ( IsModified() )
219 const OUString aUserName
= SvtUserOptions().GetFullName();
220 if ( !IsUseUserData() )
222 // remove all data pointing to the current user
223 if (xDocProps
->getAuthor() == aUserName
) {
224 xDocProps
->setAuthor( OUString() );
226 xDocProps
->setModifiedBy( OUString() );
227 if (xDocProps
->getPrintedBy() == aUserName
) {
228 xDocProps
->setPrintedBy( OUString() );
233 // update ModificationAuthor, revision and editing time
234 ::DateTime
now( ::DateTime::SYSTEM
);
235 xDocProps
->setModificationDate( now
.GetUNODateTime() );
236 xDocProps
->setModifiedBy( aUserName
);
237 UpdateTime_Impl( xDocProps
);
244 lcl_add(util::Duration
& rDur
, tools::Time
const& rTime
)
246 // here we don't care about overflow: rDur is converted back to seconds
247 // anyway, and tools::Time cannot store more than ~4000 hours
248 rDur
.Hours
+= rTime
.GetHour();
249 rDur
.Minutes
+= rTime
.GetMin();
250 rDur
.Seconds
+= rTime
.GetSec();
253 // Update the processing time
254 void SfxObjectShell::UpdateTime_Impl(
255 const uno::Reference
<document::XDocumentProperties
> & i_xDocProps
)
257 // Get old time from documentinfo
258 const sal_Int32 secs
= i_xDocProps
->getEditingDuration();
259 util::Duration
editDuration(false, 0, 0, 0,
260 secs
/3600, (secs
%3600)/60, secs
%60, 0);
262 // Initialize some local member! It's necessary for follow operations!
263 DateTime
aNow( DateTime::SYSTEM
); // Date and time at current moment
264 tools::Time
n24Time (24,0,0,0) ; // Time-value for 24 hours - see follow calculation
265 tools::Time
nAddTime (0) ; // Value to add on aOldTime
267 // Save impossible cases!
268 // User has changed time to the past between last editing and now... it's not possible!!!
269 DBG_ASSERT( !(aNow
.GetDate()<pImpl
->nTime
.GetDate()), "Timestamp of last change is in the past!?..." );
271 // Do the follow only, if user has NOT changed time to the past.
272 // Else add a time of 0 to aOldTime... !!!
273 if (aNow
.GetDate()>=pImpl
->nTime
.GetDate())
275 // Count of days between now and last editing
276 sal_Int32 nDays
= aNow
.GetSecFromDateTime(Date(pImpl
->nTime
.GetDate()))/86400 ;
280 // If no day between now and last editing - calculate time directly.
281 nAddTime
= static_cast<const tools::Time
&>(aNow
) - static_cast<const tools::Time
&>(pImpl
->nTime
);
285 // If time of working without save greater than 1 month (!)...
286 // we add 0 to aOldTime!
288 // If 1 or up to 31 days between now and last editing - calculate time indirectly.
289 // nAddTime = (24h - nTime) + (nDays * 24h) + aNow
291 nAddTime
= tools::Time( nDays
* n24Time
.GetTime());
292 nAddTime
+= n24Time
-static_cast<const tools::Time
&>(pImpl
->nTime
);
296 lcl_add(editDuration
, nAddTime
);
301 const sal_Int32
newSecs( (editDuration
.Hours
*3600)
302 + (editDuration
.Minutes
*60) + editDuration
.Seconds
);
303 i_xDocProps
->setEditingDuration(newSecs
);
304 i_xDocProps
->setEditingCycles(i_xDocProps
->getEditingCycles() + 1);
306 catch (const lang::IllegalArgumentException
&)
312 std::shared_ptr
<SfxDocumentInfoDialog
> SfxObjectShell::CreateDocumentInfoDialog(weld::Window
* pParent
,
313 const SfxItemSet
& rSet
)
315 return std::make_shared
<SfxDocumentInfoDialog
>(pParent
, rSet
);
318 std::set
<Color
> SfxObjectShell::GetDocColors()
320 std::set
<Color
> empty
;
324 std::vector
<Color
> SfxObjectShell::GetThemeColors() { return std::vector
<Color
>(); }
326 sfx::AccessibilityIssueCollection
SfxObjectShell::runAccessibilityCheck()
328 sfx::AccessibilityIssueCollection aCollection
;
332 SfxStyleSheetBasePool
* SfxObjectShell::GetStyleSheetPool()
341 SfxStyleSheetBase
*pSource
;
342 SfxStyleSheetBase
*pDest
;
347 void SfxObjectShell::LoadStyles
349 SfxObjectShell
&rSource
/* the document template from which
350 the styles are to be loaded */
355 This method is called by the SFx if styles are to be loaded from a template.
356 Existing styles are in this case overwritten. The document must then be
357 re-formatted. Therefore, applications usually override this method
358 and call the implementation in the base class.
362 SfxStyleSheetBasePool
*pSourcePool
= rSource
.GetStyleSheetPool();
363 DBG_ASSERT(pSourcePool
, "Source-DocumentShell without StyleSheetPool");
364 SfxStyleSheetBasePool
*pMyPool
= GetStyleSheetPool();
365 DBG_ASSERT(pMyPool
, "Dest-DocumentShell without StyleSheetPool");
366 auto xIter
= pSourcePool
->CreateIterator(SfxStyleFamily::All
);
367 std::unique_ptr
<Styles_Impl
[]> pFound(new Styles_Impl
[xIter
->Count()]);
368 sal_uInt16 nFound
= 0;
370 SfxStyleSheetBase
*pSource
= xIter
->First();
373 SfxStyleSheetBase
*pDest
=
374 pMyPool
->Find( pSource
->GetName(), pSource
->GetFamily() );
377 pDest
= &pMyPool
->Make( pSource
->GetName(),
378 pSource
->GetFamily(), pSource
->GetMask());
379 // Setting of parents, the next style
381 pFound
[nFound
].pSource
= pSource
;
382 pFound
[nFound
].pDest
= pDest
;
384 pSource
= xIter
->Next();
387 for ( sal_uInt16 i
= 0; i
< nFound
; ++i
)
389 pFound
[i
].pDest
->GetItemSet().PutExtended(pFound
[i
].pSource
->GetItemSet(), SfxItemState::DONTCARE
, SfxItemState::DEFAULT
);
390 if(pFound
[i
].pSource
->HasParentSupport())
391 pFound
[i
].pDest
->SetParent(pFound
[i
].pSource
->GetParent());
392 if(pFound
[i
].pSource
->HasFollowSupport())
393 pFound
[i
].pDest
->SetFollow(pFound
[i
].pSource
->GetParent());
397 sfx2::StyleManager
* SfxObjectShell::GetStyleManager()
404 class QueryTemplateBox
407 std::unique_ptr
<weld::MessageDialog
> m_xQueryBox
;
409 QueryTemplateBox(weld::Window
* pParent
, const OUString
& rMessage
)
410 : m_xQueryBox(Application::CreateMessageDialog(pParent
, VclMessageType::Question
, VclButtonsType::NONE
, rMessage
))
412 m_xQueryBox
->add_button(SfxResId(STR_QRYTEMPL_UPDATE_BTN
), RET_YES
);
413 m_xQueryBox
->add_button(SfxResId(STR_QRYTEMPL_KEEP_BTN
), RET_NO
);
414 m_xQueryBox
->set_default_response(RET_YES
);
415 m_xQueryBox
->set_help_id(HID_QUERY_LOAD_TEMPLATE
);
417 short run() { return m_xQueryBox
->run(); }
421 void SfxObjectShell::UpdateFromTemplate_Impl( )
425 This internal method checks whether the document was created from a
426 template, and if this is newer than the document. If this is the case,
427 the user is asked if the Templates (StyleSheets) should be updated.
428 If this is answered positively, the StyleSheets are updated.
433 SfxMedium
*pFile
= GetMedium();
434 DBG_ASSERT( pFile
, "cannot UpdateFromTemplate without medium" );
438 if ( !comphelper::isFileUrl( pFile
->GetName() ) )
439 // update only for documents loaded from the local file system
442 // tdf#113935 - do not remove this line - somehow, it makes the process
443 // of switching from viewing a read-only document to opening it in writable
445 uno::Reference
< embed::XStorage
> xDocStor
= pFile
->GetStorage(false);
447 // only for own storage formats
448 if ( !pFile
->GetFilter() || !pFile
->GetFilter()->IsOwnFormat() )
451 const SfxUInt16Item
* pUpdateDocItem
= SfxItemSet::GetItem
<SfxUInt16Item
>(pFile
->GetItemSet(), SID_UPDATEDOCMODE
, false);
452 sal_Int16 bCanUpdateFromTemplate
= pUpdateDocItem
? pUpdateDocItem
->GetValue() : document::UpdateDocMode::NO_UPDATE
;
454 // created from template?
455 uno::Reference
<document::XDocumentProperties
> xDocProps(getDocProperties());
456 const OUString
aTemplName( xDocProps
->getTemplateName() );
457 OUString
aTemplURL( xDocProps
->getTemplateURL() );
460 if ( !aTemplName
.isEmpty() || (!aTemplURL
.isEmpty() && !IsReadOnly()) )
462 // try to locate template, first using filename this must be done
463 // because writer global document uses this "great" idea to manage
464 // the templates of all parts in the master document but it is NOT
465 // an error if the template filename points not to a valid file
466 SfxDocumentTemplates aTempl
;
467 if (!aTemplURL
.isEmpty())
470 aFoundName
= ::rtl::Uri::convertRelToAbs(GetMedium()->GetName(),
472 } catch (::rtl::MalformedUriException
const&) {
473 assert(false); // don't think that's supposed to happen?
477 if( aFoundName
.isEmpty() && !aTemplName
.isEmpty() )
478 // if the template filename did not lead to success,
479 // try to get a file name for the logical template name
480 aTempl
.GetFull( u
"", aTemplName
, aFoundName
);
483 if ( aFoundName
.isEmpty() )
486 // check existence of template storage
487 aTemplURL
= aFoundName
;
489 // should the document checked against changes in the template ?
490 if ( !IsQueryLoadTemplate() )
495 // load document properties of template
497 util::DateTime aTemplDate
;
500 Reference
<document::XDocumentProperties
> const
501 xTemplateDocProps( document::DocumentProperties::create(
502 ::comphelper::getProcessComponentContext()));
503 xTemplateDocProps
->loadFromMedium(aTemplURL
,
504 Sequence
<beans::PropertyValue
>());
505 aTemplDate
= xTemplateDocProps
->getModificationDate();
508 catch (const Exception
&)
510 TOOLS_INFO_EXCEPTION("sfx.doc", "");
513 // if modify date was read successfully
516 // compare modify data of template with the last check date of the document
517 const util::DateTime
aInfoDate( xDocProps
->getTemplateDate() );
518 if ( aTemplDate
> aInfoDate
)
521 if( bCanUpdateFromTemplate
== document::UpdateDocMode::QUIET_UPDATE
522 || bCanUpdateFromTemplate
== document::UpdateDocMode::FULL_UPDATE
)
524 else if ( bCanUpdateFromTemplate
== document::UpdateDocMode::ACCORDING_TO_CONFIG
)
526 const OUString
sMessage( SfxResId(STR_QRYTEMPL_MESSAGE
).replaceAll( "$(ARG1)", aTemplName
) );
527 QueryTemplateBox
aBox(Application::GetFrameWeld(GetDialogParent()), sMessage
);
528 if (RET_YES
== aBox
.run())
534 // user refuses, so don't ask again for this document
535 SetQueryLoadTemplate(false);
544 // styles should be updated, create document in organizer mode to read in the styles
546 SfxObjectShellLock xTemplDoc
= CreateObjectByFactoryName( GetFactory().GetFactoryName(), SfxObjectCreateMode::ORGANIZER
);
547 xTemplDoc
->DoInitNew();
549 // TODO/MBA: do we need a BaseURL? Then LoadFrom must be extended!
550 //xTemplDoc->SetBaseURL( aFoundName );
552 // TODO/LATER: make sure that we don't use binary templates!
553 SfxMedium
aMedium( aFoundName
, StreamMode::STD_READ
);
554 if ( xTemplDoc
->LoadFrom( aMedium
) )
556 // transfer styles from xTemplDoc to this document
557 // TODO/MBA: make sure that no BaseURL is needed in *this* document
558 LoadStyles(*xTemplDoc
);
560 // remember date/time of check
561 xDocProps
->setTemplateDate(aTemplDate
);
562 // TODO/LATER: new functionality to store document info is required ( didn't work for SO7 XML format )
566 bool SfxObjectShell::IsHelpDocument() const
568 std::shared_ptr
<const SfxFilter
> pFilter
= GetMedium()->GetFilter();
569 return (pFilter
&& pFilter
->GetFilterName() == "writer_web_HTML_help");
572 void SfxObjectShell::ResetFromTemplate( const OUString
& rTemplateName
, const OUString
& rFileName
)
574 // only care about resetting this data for LibreOffice formats otherwise
575 if ( !IsOwnStorageFormat( *GetMedium()) )
578 uno::Reference
<document::XDocumentProperties
> xDocProps(getDocProperties());
579 xDocProps
->setTemplateURL( OUString() );
580 xDocProps
->setTemplateName( OUString() );
581 xDocProps
->setTemplateDate( util::DateTime() );
582 xDocProps
->resetUserData( OUString() );
587 if( !comphelper::isFileUrl( rFileName
) )
591 if( SfxGetpApp()->Get_Impl()->GetDocumentTemplates()->GetFull( u
"", rTemplateName
, aFoundName
) )
593 INetURLObject
aObj( rFileName
);
594 xDocProps
->setTemplateURL( aObj
.GetMainURL(INetURLObject::DecodeMechanism::ToIUri
) );
595 xDocProps
->setTemplateName( rTemplateName
);
597 ::DateTime
now( ::DateTime::SYSTEM
);
598 xDocProps
->setTemplateDate( now
.GetUNODateTime() );
600 SetQueryLoadTemplate( true );
604 bool SfxObjectShell::IsQueryLoadTemplate() const
606 return pImpl
->bQueryLoadTemplate
;
609 bool SfxObjectShell::IsUseUserData() const
611 return pImpl
->bUseUserData
;
614 bool SfxObjectShell::IsUseThumbnailSave() const
616 return pImpl
->bUseThumbnailSave
;
619 void SfxObjectShell::SetQueryLoadTemplate( bool bNew
)
621 if ( pImpl
->bQueryLoadTemplate
!= bNew
)
623 pImpl
->bQueryLoadTemplate
= bNew
;
626 void SfxObjectShell::SetUseUserData( bool bNew
)
628 if ( pImpl
->bUseUserData
!= bNew
)
630 pImpl
->bUseUserData
= bNew
;
633 void SfxObjectShell::SetUseThumbnailSave( bool _bNew
)
635 if ( pImpl
->bUseThumbnailSave
!= _bNew
)
637 pImpl
->bUseThumbnailSave
= _bNew
;
640 bool SfxObjectShell::IsLoadReadonly() const
642 return pImpl
->bLoadReadonly
;
645 bool SfxObjectShell::IsSaveVersionOnClose() const
647 return pImpl
->bSaveVersionOnClose
;
650 void SfxObjectShell::SetLoadReadonly( bool bNew
)
652 if ( pImpl
->bLoadReadonly
!= bNew
)
654 pImpl
->bLoadReadonly
= bNew
;
657 void SfxObjectShell::SetSaveVersionOnClose( bool bNew
)
659 if ( pImpl
->bSaveVersionOnClose
!= bNew
)
661 pImpl
->bSaveVersionOnClose
= bNew
;
664 sal_uInt32
SfxObjectShell::GetModifyPasswordHash() const
666 return pImpl
->m_nModifyPasswordHash
;
669 bool SfxObjectShell::SetModifyPasswordHash( sal_uInt32 nHash
)
671 if ( ( !IsReadOnly() && !IsReadOnlyUI() )
672 || !(pImpl
->nFlagsInProgress
& SfxLoadedFlags::MAINDOCUMENT
) )
674 // the hash can be changed only in editable documents,
675 // or during loading of document
676 pImpl
->m_nModifyPasswordHash
= nHash
;
683 const uno::Sequence
< beans::PropertyValue
>& SfxObjectShell::GetModifyPasswordInfo() const
685 return pImpl
->m_aModifyPasswordInfo
;
688 bool SfxObjectShell::SetModifyPasswordInfo( const uno::Sequence
< beans::PropertyValue
>& aInfo
)
690 if ( ( !IsReadOnly() && !IsReadOnlyUI() )
691 || !(pImpl
->nFlagsInProgress
& SfxLoadedFlags::MAINDOCUMENT
) )
693 // the hash can be changed only in editable documents,
694 // or during loading of document
695 pImpl
->m_aModifyPasswordInfo
= aInfo
;
702 void SfxObjectShell::SetModifyPasswordEntered( bool bEntered
)
704 pImpl
->m_bModifyPasswordEntered
= bEntered
;
707 bool SfxObjectShell::IsModifyPasswordEntered() const
709 return pImpl
->m_bModifyPasswordEntered
;
712 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */