Version 7.1.7.1, tag libreoffice-7.1.7.1
[LibreOffice.git] / sfx2 / source / doc / objcont.cxx
blob8d3faa98a8a0209a3ef487d400b063be670f87dd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <vcl/window.hxx>
30 #include <svl/style.hxx>
32 #include <svl/intitem.hxx>
33 #include <svl/ctloptions.hxx>
34 #include <comphelper/processfactory.hxx>
35 #include <unotools/securityoptions.hxx>
36 #include <tools/datetime.hxx>
37 #include <tools/diagnose_ex.h>
38 #include <tools/helpers.hxx>
39 #include <rtl/uri.hxx>
41 #include <unotools/useroptions.hxx>
42 #include <vcl/virdev.hxx>
43 #include <vcl/settings.hxx>
44 #include <vcl/gdimtf.hxx>
46 #include <sfx2/app.hxx>
47 #include <sfx2/dinfdlg.hxx>
48 #include <sfx2/sfxresid.hxx>
49 #include <appdata.hxx>
50 #include <sfx2/docfac.hxx>
51 #include <sfx2/viewsh.hxx>
52 #include <sfx2/objsh.hxx>
53 #include <objshimp.hxx>
54 #include <sfx2/printer.hxx>
55 #include <sfx2/viewfrm.hxx>
56 #include <sfx2/doctempl.hxx>
57 #include <sfx2/sfxsids.hrc>
58 #include <sfx2/strings.hrc>
59 #include <sfx2/docfile.hxx>
60 #include <sfx2/docfilt.hxx>
61 #include <memory>
62 #include <helpids.h>
64 using namespace ::com::sun::star;
65 using namespace ::com::sun::star::uno;
68 static
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;
92 return false;
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>();
103 return xFile;
106 BitmapEx SfxObjectShell::GetPreviewBitmap() const
108 ScopedVclPtrInstance< VirtualDevice > pDevice;
109 pDevice->SetAntialiasing(AntialiasingFlags::Enable | pDevice->GetAntialiasing());
110 if(!CreatePreview_Impl(/*bFullContent*/false, pDevice, nullptr))
111 return BitmapEx();
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);
119 return aBitmap;
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() )
130 return false;
132 MapMode aMode( GetMapUnit() );
133 Size aTmpSize;
134 sal_Int8 nAspect;
135 if ( bFullContent )
137 nAspect = ASPECT_CONTENT;
138 aTmpSize = GetVisArea( nAspect ).GetSize();
140 else
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!" );
149 if(pFile)
151 pDevice->SetMapMode( aMode );
152 pFile->SetPrefMapMode( aMode );
153 pFile->SetPrefSize( aTmpSize );
154 pFile->Record( pDevice );
156 else
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 = 256;
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()) >
167 nMaximumExtent ||
168 sal::static_int_cast< tools::ULong >(aSizePix.Height()) >
169 nMaximumExtent ) )
171 double fWH = static_cast< double >( aSizePix.Width() ) / aSizePix.Height();
172 if ( fWH <= 1.0 )
174 aSizePix.setWidth( FRound( nMaximumExtent * fWH ) );
175 aSizePix.setHeight( nMaximumExtent );
177 else
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 );
188 LanguageType eLang;
189 SvtCTLOptions aCTLOptions;
190 if ( SvtCTLOptions::NUMERALS_HINDI == aCTLOptions.GetCTLTextNumerals() )
191 eLang = LANGUAGE_ARABIC_SAUDI_ARABIA;
192 else if ( SvtCTLOptions::NUMERALS_ARABIC == aCTLOptions.GetCTLTextNumerals() )
193 eLang = LANGUAGE_ENGLISH;
194 else
195 eLang = Application::GetSettings().GetLanguageTag().getLanguageType();
197 pDevice->SetDigitLanguage( eLang );
199 const_cast<SfxObjectShell*>(this)->DoDraw( pDevice, Point(0,0), aTmpSize, JobSetup(), nAspect );
201 if(pFile)
202 pFile->Stop();
204 return true;
208 void SfxObjectShell::UpdateDocInfoForSave()
210 uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
212 // clear user data if recommend (see 'Tools - Options - LibreOffice - Security')
213 if ( SvtSecurityOptions().IsOptionSet(
214 SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo ) )
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() );
232 else
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 );
244 static void
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 ;
279 if (nDays==0)
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);
284 else if (nDays<=31)
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
291 --nDays;
292 nAddTime = tools::Time( nDays * n24Time.GetTime());
293 nAddTime += n24Time-static_cast<const tools::Time&>(pImpl->nTime);
294 nAddTime += aNow ;
297 lcl_add(editDuration, nAddTime);
300 pImpl->nTime = aNow;
301 try {
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 &)
309 // ignore overflow
313 std::shared_ptr<SfxDocumentInfoDialog> SfxObjectShell::CreateDocumentInfoDialog(weld::Window* pParent,
314 const SfxItemSet& rSet)
316 return std::make_shared<SfxDocumentInfoDialog>(pParent, rSet);
319 std::set<Color> SfxObjectShell::GetDocColors()
321 std::set<Color> empty;
322 return empty;
325 sfx::AccessibilityIssueCollection SfxObjectShell::runAccessibilityCheck()
327 sfx::AccessibilityIssueCollection aCollection;
328 return aCollection;
331 SfxStyleSheetBasePool* SfxObjectShell::GetStyleSheetPool()
333 return nullptr;
336 namespace {
338 struct Styles_Impl
340 SfxStyleSheetBase *pSource;
341 SfxStyleSheetBase *pDest;
346 void SfxObjectShell::LoadStyles
348 SfxObjectShell &rSource /* the document template from which
349 the styles are to be loaded */
352 /* [Description]
354 This method is called by the SFx if styles are to be loaded from a template.
355 Existing styles are in this case overwritten. The document must then be
356 re-formatted. Therefore, applications usually override this method
357 and call the implementation in the base class.
361 SfxStyleSheetBasePool *pSourcePool = rSource.GetStyleSheetPool();
362 DBG_ASSERT(pSourcePool, "Source-DocumentShell without StyleSheetPool");
363 SfxStyleSheetBasePool *pMyPool = GetStyleSheetPool();
364 DBG_ASSERT(pMyPool, "Dest-DocumentShell without StyleSheetPool");
365 auto xIter = pSourcePool->CreateIterator(SfxStyleFamily::All);
366 std::unique_ptr<Styles_Impl[]> pFound(new Styles_Impl[xIter->Count()]);
367 sal_uInt16 nFound = 0;
369 SfxStyleSheetBase *pSource = xIter->First();
370 while ( pSource )
372 SfxStyleSheetBase *pDest =
373 pMyPool->Find( pSource->GetName(), pSource->GetFamily() );
374 if ( !pDest )
376 pDest = &pMyPool->Make( pSource->GetName(),
377 pSource->GetFamily(), pSource->GetMask());
378 // Setting of parents, the next style
380 pFound[nFound].pSource = pSource;
381 pFound[nFound].pDest = pDest;
382 ++nFound;
383 pSource = xIter->Next();
386 for ( sal_uInt16 i = 0; i < nFound; ++i )
388 pFound[i].pDest->GetItemSet().PutExtended(pFound[i].pSource->GetItemSet(), SfxItemState::DONTCARE, SfxItemState::DEFAULT);
389 if(pFound[i].pSource->HasParentSupport())
390 pFound[i].pDest->SetParent(pFound[i].pSource->GetParent());
391 if(pFound[i].pSource->HasFollowSupport())
392 pFound[i].pDest->SetFollow(pFound[i].pSource->GetParent());
396 sfx2::StyleManager* SfxObjectShell::GetStyleManager()
398 return nullptr;
401 namespace
403 class QueryTemplateBox
405 private:
406 std::unique_ptr<weld::MessageDialog> m_xQueryBox;
407 public:
408 QueryTemplateBox(weld::Window* pParent, const OUString& rMessage)
409 : m_xQueryBox(Application::CreateMessageDialog(pParent, VclMessageType::Question, VclButtonsType::NONE, rMessage))
411 m_xQueryBox->add_button(SfxResId(STR_QRYTEMPL_UPDATE_BTN), RET_YES);
412 m_xQueryBox->add_button(SfxResId(STR_QRYTEMPL_KEEP_BTN), RET_NO);
413 m_xQueryBox->set_default_response(RET_YES);
414 m_xQueryBox->set_help_id(HID_QUERY_LOAD_TEMPLATE);
416 short run() { return m_xQueryBox->run(); }
420 void SfxObjectShell::UpdateFromTemplate_Impl( )
422 /* [Description]
424 This internal method checks whether the document was created from a
425 template, and if this is newer than the document. If this is the case,
426 the user is asked if the Templates (StyleSheets) should be updated.
427 If this is answered positively, the StyleSheets are updated.
431 // Storage-medium?
432 SfxMedium *pFile = GetMedium();
433 DBG_ASSERT( pFile, "cannot UpdateFromTemplate without medium" );
434 if ( !pFile )
435 return;
437 if ( !comphelper::isFileUrl( pFile->GetName() ) )
438 // update only for documents loaded from the local file system
439 return;
441 // tdf#113935 - do not remove this line - somehow, it makes the process
442 // of switching from viewing a read-only document to opening it in writable
443 // mode much faster.
444 uno::Reference< embed::XStorage > xDocStor = pFile->GetStorage(false);
446 // only for own storage formats
447 if ( !pFile->GetFilter() || !pFile->GetFilter()->IsOwnFormat() )
448 return;
450 const SfxUInt16Item* pUpdateDocItem = SfxItemSet::GetItem<SfxUInt16Item>(pFile->GetItemSet(), SID_UPDATEDOCMODE, false);
451 sal_Int16 bCanUpdateFromTemplate = pUpdateDocItem ? pUpdateDocItem->GetValue() : document::UpdateDocMode::NO_UPDATE;
453 // created from template?
454 uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
455 const OUString aTemplName( xDocProps->getTemplateName() );
456 OUString aTemplURL( xDocProps->getTemplateURL() );
457 OUString aFoundName;
459 if ( !aTemplName.isEmpty() || (!aTemplURL.isEmpty() && !IsReadOnly()) )
461 // try to locate template, first using filename this must be done
462 // because writer global document uses this "great" idea to manage
463 // the templates of all parts in the master document but it is NOT
464 // an error if the template filename points not to a valid file
465 SfxDocumentTemplates aTempl;
466 if (!aTemplURL.isEmpty())
468 try {
469 aFoundName = ::rtl::Uri::convertRelToAbs(GetMedium()->GetName(),
470 aTemplURL);
471 } catch (::rtl::MalformedUriException const&) {
472 assert(false); // don't think that's supposed to happen?
476 if( aFoundName.isEmpty() && !aTemplName.isEmpty() )
477 // if the template filename did not lead to success,
478 // try to get a file name for the logical template name
479 aTempl.GetFull( OUString(), aTemplName, aFoundName );
482 if ( aFoundName.isEmpty() )
483 return;
485 // check existence of template storage
486 aTemplURL = aFoundName;
488 // should the document checked against changes in the template ?
489 if ( !IsQueryLoadTemplate() )
490 return;
492 bool bLoad = false;
494 // load document properties of template
495 bool bOK = false;
496 util::DateTime aTemplDate;
499 Reference<document::XDocumentProperties> const
500 xTemplateDocProps( document::DocumentProperties::create(
501 ::comphelper::getProcessComponentContext()));
502 xTemplateDocProps->loadFromMedium(aTemplURL,
503 Sequence<beans::PropertyValue>());
504 aTemplDate = xTemplateDocProps->getModificationDate();
505 bOK = true;
507 catch (const Exception&)
509 TOOLS_INFO_EXCEPTION("sfx.doc", "");
512 // if modify date was read successfully
513 if ( bOK )
515 // compare modify data of template with the last check date of the document
516 const util::DateTime aInfoDate( xDocProps->getTemplateDate() );
517 if ( aTemplDate > aInfoDate )
519 // ask user
520 if( bCanUpdateFromTemplate == document::UpdateDocMode::QUIET_UPDATE
521 || bCanUpdateFromTemplate == document::UpdateDocMode::FULL_UPDATE )
522 bLoad = true;
523 else if ( bCanUpdateFromTemplate == document::UpdateDocMode::ACCORDING_TO_CONFIG )
525 const OUString sMessage( SfxResId(STR_QRYTEMPL_MESSAGE).replaceAll( "$(ARG1)", aTemplName ) );
526 vcl::Window *pWin = GetDialogParent();
527 QueryTemplateBox aBox(pWin ? pWin->GetFrameWeld() : nullptr, sMessage);
528 if (RET_YES == aBox.run())
529 bLoad = true;
532 if( !bLoad )
534 // user refuses, so don't ask again for this document
535 SetQueryLoadTemplate(false);
536 SetModified();
541 if ( !bLoad )
542 return;
544 // styles should be updated, create document in organizer mode to read in the styles
545 //TODO: testen!
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()) )
576 return;
578 uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
579 xDocProps->setTemplateURL( OUString() );
580 xDocProps->setTemplateName( OUString() );
581 xDocProps->setTemplateDate( util::DateTime() );
582 xDocProps->resetUserData( OUString() );
584 // TODO/REFACTOR:
585 // Title?
587 if( !comphelper::isFileUrl( rFileName ) )
588 return;
590 OUString aFoundName;
591 if( SfxGetpApp()->Get_Impl()->GetDocumentTemplates()->GetFull( OUString(), 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 )
622 SetModified();
623 pImpl->bQueryLoadTemplate = bNew;
626 void SfxObjectShell::SetUseUserData( bool bNew )
628 if ( pImpl->bUseUserData != bNew )
629 SetModified();
630 pImpl->bUseUserData = bNew;
633 void SfxObjectShell::SetUseThumbnailSave( bool _bNew )
635 if ( pImpl->bUseThumbnailSave != _bNew )
636 SetModified();
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 )
653 SetModified();
654 pImpl->bLoadReadonly = bNew;
657 void SfxObjectShell::SetSaveVersionOnClose( bool bNew )
659 if ( pImpl->bSaveVersionOnClose != bNew )
660 SetModified();
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;
677 return true;
680 return false;
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;
696 return true;
699 return false;
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: */