Bump version to 24.04.3.4
[LibreOffice.git] / sfx2 / source / doc / objcont.cxx
blobb762e9d1108460573f20d61ecb431f1ea98eba36
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 <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>
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 = 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()) >
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 if ( SvtCTLOptions::NUMERALS_HINDI == SvtCTLOptions::GetCTLTextNumerals() )
190 eLang = LANGUAGE_ARABIC_SAUDI_ARABIA;
191 else if ( SvtCTLOptions::NUMERALS_ARABIC == SvtCTLOptions::GetCTLTextNumerals() )
192 eLang = LANGUAGE_ENGLISH;
193 else
194 eLang = Application::GetSettings().GetLanguageTag().getLanguageType();
196 pDevice->SetDigitLanguage( eLang );
198 const_cast<SfxObjectShell*>(this)->DoDraw( pDevice, Point(0,0), aTmpSize, JobSetup(), nAspect );
200 if(pFile)
201 pFile->Stop();
203 return true;
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() );
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::optional<NamedColor> SfxObjectShell::GetRecentColor(sal_uInt16 nSlotId)
321 auto it = pImpl->m_aRecentColors.find(nSlotId);
322 if (it != pImpl->m_aRecentColors.end())
323 return it->second;
325 return std::nullopt;
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;
337 return empty;
340 std::shared_ptr<model::ColorSet> SfxObjectShell::GetThemeColors() { return {}; }
342 std::shared_ptr<sfx::IDocumentModelAccessor> SfxObjectShell::GetDocumentModelAccessor() const
344 return {};
347 sfx::AccessibilityIssueCollection SfxObjectShell::runAccessibilityCheck()
349 sfx::AccessibilityIssueCollection aCollection;
350 return aCollection;
353 SfxStyleSheetBasePool* SfxObjectShell::GetStyleSheetPool()
355 return nullptr;
358 namespace {
360 struct Styles_Impl
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 */
374 /* [Description]
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();
392 while ( pSource )
394 SfxStyleSheetBase *pDest =
395 pMyPool->Find( pSource->GetName(), pSource->GetFamily() );
396 if ( !pDest )
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;
404 ++nFound;
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()
420 return nullptr;
423 namespace
425 class QueryTemplateBox
427 private:
428 std::unique_ptr<weld::MessageDialog> m_xQueryBox;
429 public:
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( )
444 /* [Description]
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.
453 // Storage-medium?
454 SfxMedium *pFile = GetMedium();
455 DBG_ASSERT( pFile, "cannot UpdateFromTemplate without medium" );
456 if ( !pFile )
457 return;
459 if ( !comphelper::isFileUrl( pFile->GetName() ) )
460 // update only for documents loaded from the local file system
461 return;
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
465 // mode much faster.
466 uno::Reference< embed::XStorage > xDocStor = pFile->GetStorage(false);
468 // only for own storage formats
469 if ( !pFile->GetFilter() || !pFile->GetFilter()->IsOwnFormat() )
470 return;
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() );
479 OUString aFoundName;
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())
490 try {
491 aFoundName = ::rtl::Uri::convertRelToAbs(GetMedium()->GetName(),
492 aTemplURL);
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() )
505 return;
507 // check existence of template storage
508 aTemplURL = aFoundName;
510 // should the document checked against changes in the template ?
511 if ( !IsQueryLoadTemplate() )
512 return;
514 bool bLoad = false;
516 // load document properties of template
517 bool bOK = false;
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();
527 bOK = true;
529 catch (const Exception&)
531 TOOLS_INFO_EXCEPTION("sfx.doc", "");
534 // if modify date was read successfully
535 if ( bOK )
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 )
541 // ask user
542 if( bCanUpdateFromTemplate == document::UpdateDocMode::QUIET_UPDATE
543 || bCanUpdateFromTemplate == document::UpdateDocMode::FULL_UPDATE )
544 bLoad = true;
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())
550 bLoad = true;
553 if( !bLoad )
555 // user refuses, so don't ask again for this document
556 SetQueryLoadTemplate(false);
557 SetModified();
562 if ( !bLoad )
563 return;
565 // styles should be updated, create document in organizer mode to read in the styles
566 //TODO: testen!
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()) )
597 return;
599 uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
600 xDocProps->setTemplateURL( OUString() );
601 xDocProps->setTemplateName( OUString() );
602 xDocProps->setTemplateDate( util::DateTime() );
603 xDocProps->resetUserData( OUString() );
605 // TODO/REFACTOR:
606 // Title?
608 if( !comphelper::isFileUrl( rFileName ) )
609 return;
611 OUString aFoundName;
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 )
643 SetModified();
644 pImpl->bQueryLoadTemplate = bNew;
647 void SfxObjectShell::SetUseUserData( bool bNew )
649 if ( pImpl->bUseUserData != bNew )
650 SetModified();
651 pImpl->bUseUserData = bNew;
654 void SfxObjectShell::SetUseThumbnailSave( bool _bNew )
656 if ( pImpl->bUseThumbnailSave != _bNew )
657 SetModified();
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 )
674 SetModified();
675 pImpl->bLoadReadonly = bNew;
678 void SfxObjectShell::SetSaveVersionOnClose( bool bNew )
680 if ( pImpl->bSaveVersionOnClose != bNew )
681 SetModified();
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;
698 return true;
701 return false;
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;
717 return true;
720 return false;
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: */