BitmapEx SfxObjectShell::GetPreviewBitmap() const
{
SfxCloseVetoLock lock(this);
ScopedVclPtrInstance< VirtualDevice > pDevice;
pDevice->SetAntialiasing(AntialiasingFlags::Enable | pDevice->GetAntialiasing()); if(!CreatePreview_Impl(/*bFullContent*/false, pDevice, nullptr)) return BitmapEx();
Size size = pDevice->GetOutputSizePixel();
BitmapEx aBitmap = pDevice->GetBitmapEx( Point(), size); // Scale down the image to the desired size from the 4*size from CreatePreview_Impl().
size = Size( size.Width() / 4, size.Height() / 4 );
aBitmap.Scale(size, BmpScaleFlag::BestQuality); if (!aBitmap.IsEmpty())
aBitmap.Convert(BmpConversion::N24Bit); return aBitmap;
}
bool SfxObjectShell::CreatePreview_Impl( bool bFullContent, VirtualDevice* pDevice, GDIMetaFile* pFile) const
{ // DoDraw can only be called when no printing is done, otherwise // the printer may be turned off
SfxViewFrame *pFrame = SfxViewFrame::GetFirst( this ); if ( pFrame && pFrame->GetViewShell() &&
pFrame->GetViewShell()->GetPrinter() &&
pFrame->GetViewShell()->GetPrinter()->IsPrinting() ) returnfalse;
// clear user data if recommend (see 'Tools - Options - LibreOffice - Security') if ( SvtSecurityOptions::IsOptionSet(
SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo ) && !SvtSecurityOptions::IsOptionSet(
SvtSecurityOptions::EOption::DocWarnKeepDocUserInfo))
{
xDocProps->resetUserData( OUString() );
} elseif ( IsModified() )
{ const OUString aUserName = SvtUserOptions().GetFullName(); if ( !IsUseUserData() )
{ // remove all data pointing to the current user if (xDocProps->getAuthor() == aUserName) {
xDocProps->setAuthor( OUString() );
}
xDocProps->setModifiedBy( OUString() ); if (xDocProps->getPrintedBy() == aUserName) {
xDocProps->setPrintedBy( OUString() );
}
} else
{ // update ModificationAuthor, revision and editing time
::DateTime now( ::DateTime::SYSTEM );
xDocProps->setModificationDate( now.GetUNODateTime() );
xDocProps->setModifiedBy( aUserName ); if (!SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::DocWarnRemoveEditingTimeInfo))
UpdateTime_Impl( xDocProps );
} // reset only editing time to zero if RemoveEditingTimeOnSaving is true if (SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::DocWarnRemoveEditingTimeInfo))
xDocProps->setEditingDuration(0);
} else
{ // reset only editing time to zero if RemoveEditingTimeOnSaving is true if (SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::DocWarnRemoveEditingTimeInfo))
xDocProps->setEditingDuration(0);
}
}
staticvoid
lcl_add(util::Duration & rDur, tools::Time const& rTime)
{ // here we don't care about overflow: rDur is converted back to seconds // anyway, and tools::Time cannot store more than ~4000 hours
rDur.Hours += rTime.GetHour();
rDur.Minutes += rTime.GetMin();
rDur.Seconds += rTime.GetSec();
}
// Update the processing time void SfxObjectShell::UpdateTime_Impl( const uno::Reference<document::XDocumentProperties> & i_xDocProps)
{ // Get old time from documentinfo const sal_Int32 secs = i_xDocProps->getEditingDuration();
util::Duration editDuration(false, 0, 0, 0,
secs/3600, (secs%3600)/60, secs%60, 0);
// Initialize some local member! It's necessary for follow operations!
DateTime aNow( DateTime::SYSTEM ); // Date and time at current moment
// Save impossible cases! // User has changed time to the past between last editing and now... it's not possible!!!
DBG_ASSERT( !(aNow.GetDate()<pImpl->nTime.GetDate()), "Timestamp of last change is in the past!?..." );
// Do the follow only, if user has NOT changed time to the past. // Else add a time of 0 to aOldTime... !!! if (aNow.GetDate()>=pImpl->nTime.GetDate())
{ // Count of days between now and last editing
sal_Int32 nDays = aNow.GetSecFromDateTime(Date(pImpl->nTime.GetDate()))/86400 ;
tools::Time nAddTime(tools::Time::EMPTY); // Value to add on aOldTime
if (nDays==0)
{ // If no day between now and last editing - calculate time directly.
nAddTime = static_cast<const tools::Time&>(aNow) - static_cast<const tools::Time&>(pImpl->nTime);
} elseif (nDays<=31)
{ // If time of working without save greater than 1 month (!)... // we add 0 to aOldTime!
// If 1 or up to 31 days between now and last editing - calculate time indirectly. // nAddTime = (24h - nTime) + (nDays * 24h) + aNow
tools::Time n24Time (24,0,0,0); // Time-value for 24 hours
--nDays;
nAddTime.MakeTimeFromNS(nDays * n24Time.GetNSFromTime());
nAddTime += n24Time-static_cast<const tools::Time&>(pImpl->nTime);
nAddTime += aNow ;
}
std::optional<NamedColor> SfxObjectShell::GetRecentColor(sal_uInt16 nSlotId)
{ auto it = pImpl->m_aRecentColors.find(nSlotId); if (it != pImpl->m_aRecentColors.end()) return it->second;
{ // Storage-medium?
SfxMedium *pFile = GetMedium();
DBG_ASSERT( pFile, "cannot UpdateFromTemplate without medium" ); if ( !pFile ) return;
if ( !comphelper::isFileUrl( pFile->GetName() ) ) // update only for documents loaded from the local file system return;
// tdf#113935 - do not remove this line - somehow, it makes the process // of switching from viewing a read-only document to opening it in writable // mode much faster.
uno::Reference< embed::XStorage > xDocStor = pFile->GetStorage(false);
// only for own storage formats if ( !pFile->GetFilter() || !pFile->GetFilter()->IsOwnFormat() ) return;
// created from template?
uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties()); const OUString aTemplName( xDocProps->getTemplateName() );
OUString aTemplURL( xDocProps->getTemplateURL() );
OUString aFoundName;
if ( !aTemplName.isEmpty() || (!aTemplURL.isEmpty() && !IsReadOnly()) )
{ // try to locate template, first using filename this must be done // because writer global document uses this "great" idea to manage // the templates of all parts in the master document but it is NOT // an error if the template filename points not to a valid file
SfxDocumentTemplates aTempl; if (!aTemplURL.isEmpty())
{ try {
aFoundName = ::rtl::Uri::convertRelToAbs(GetMedium()->GetName(),
aTemplURL);
} catch (::rtl::MalformedUriException const&) {
assert(false); // don't think that's supposed to happen?
}
}
if( aFoundName.isEmpty() && !aTemplName.isEmpty() ) // if the template filename did not lead to success, // try to get a file name for the logical template name
aTempl.GetFull( u"", aTemplName, aFoundName );
}
if ( aFoundName.isEmpty() ) return;
// check existence of template storage
aTemplURL = aFoundName;
// should the document checked against changes in the template ? if ( !IsQueryLoadTemplate() ) return;
// if modify date was read successfully if ( bOK )
{ // compare modify data of template with the last check date of the document const util::DateTime aInfoDate( xDocProps->getTemplateDate() ); if ( aTemplDate > aInfoDate )
{ // ask user if( bCanUpdateFromTemplate == document::UpdateDocMode::QUIET_UPDATE
|| bCanUpdateFromTemplate == document::UpdateDocMode::FULL_UPDATE )
bLoad = true; elseif ( bCanUpdateFromTemplate == document::UpdateDocMode::ACCORDING_TO_CONFIG )
{ const OUString sMessage( SfxResId(STR_QRYTEMPL_MESSAGE).replaceAll( "$(ARG1)", aTemplName ) );
QueryTemplateBox aBox(Application::GetFrameWeld(GetDialogParent()), sMessage); if (RET_YES == aBox.run())
bLoad = true;
}
if( !bLoad )
{ // user refuses, so don't ask again for this document
SetQueryLoadTemplate(false);
SetModified();
}
}
}
if ( !bLoad ) return;
// styles should be updated, create document in organizer mode to read in the styles //TODO: testen!
SfxObjectShellLock xTemplDoc = CreateObjectByFactoryName( GetFactory().GetFactoryName(), SfxObjectCreateMode::ORGANIZER );
xTemplDoc->DoInitNew();
// TODO/MBA: do we need a BaseURL? Then LoadFrom must be extended! //xTemplDoc->SetBaseURL( aFoundName );
// TODO/LATER: make sure that we don't use binary templates!
SfxMedium aMedium( aFoundName, StreamMode::STD_READ ); if ( xTemplDoc->LoadFrom( aMedium ) )
{ // transfer styles from xTemplDoc to this document // TODO/MBA: make sure that no BaseURL is needed in *this* document
LoadStyles(*xTemplDoc);
// remember date/time of check
xDocProps->setTemplateDate(aTemplDate); // TODO/LATER: new functionality to store document info is required ( didn't work for SO7 XML format )
}
}
bool SfxObjectShell::IsHelpDocument() const
{ if (!pMedium)
{ returnfalse;
}
void SfxObjectShell::ResetFromTemplate( const OUString& rTemplateName, std::u16string_view rFileName )
{ // only care about resetting this data for LibreOffice formats otherwise if ( !IsOwnStorageFormat( *GetMedium()) ) return;
bool SfxObjectShell::SetModifyPasswordHash( sal_uInt32 nHash )
{ if ( ( !IsReadOnly() && !IsReadOnlyUI() )
|| !(pImpl->nFlagsInProgress & SfxLoadedFlags::MAINDOCUMENT ) )
{ // the hash can be changed only in editable documents, // or during loading of document
pImpl->m_nModifyPasswordHash = nHash; returntrue;
}
bool SfxObjectShell::SetModifyPasswordInfo( const uno::Sequence< beans::PropertyValue >& aInfo )
{ if ( ( !IsReadOnly() && !IsReadOnlyUI() )
|| !(pImpl->nFlagsInProgress & SfxLoadedFlags::MAINDOCUMENT ) )
{ // the hash can be changed only in editable documents, // or during loading of document
pImpl->m_aModifyPasswordInfo = aInfo; returntrue;
}