Version 7.1.7.1, tag libreoffice-7.1.7.1
[LibreOffice.git] / sfx2 / source / appl / sfxpicklist.cxx
blob82775fd9a328745fe96d225c8e6762914ae19b36
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 .
20 #include <comphelper/lok.hxx>
21 #include <comphelper/base64.hxx>
22 #include <com/sun/star/document/XDocumentProperties.hpp>
23 #include <unotools/historyoptions.hxx>
24 #include <unotools/useroptions.hxx>
25 #include <tools/datetime.hxx>
26 #include <tools/urlobj.hxx>
27 #include <svl/inethist.hxx>
28 #include <vcl/gdimtf.hxx>
29 #include <vcl/pngwrite.hxx>
30 #include <vcl/svapp.hxx>
31 #include <officecfg/Office/Common.hxx>
34 #include <sfx2/app.hxx>
35 #include <sfxpicklist.hxx>
36 #include <sfx2/sfxsids.hrc>
37 #include <sfx2/event.hxx>
38 #include <sfx2/objsh.hxx>
39 #include <sfx2/docfile.hxx>
40 #include <openurlhint.hxx>
41 #include <sfx2/docfilt.hxx>
42 #include <sfx2/viewfrm.hxx>
44 #include <rtl/instance.hxx>
47 using namespace ::com::sun::star::uno;
48 using namespace ::com::sun::star::beans;
49 using namespace ::com::sun::star::util;
52 namespace
54 class thePickListMutex
55 : public rtl::Static<osl::Mutex, thePickListMutex> {};
58 class SfxPickListImpl : public SfxListener
60 /**
61 * Adds the given document to the pick list (recent documents) if it satisfies
62 certain requirements, e.g. being writable. Check implementation for requirement
63 details.
65 static void AddDocumentToPickList( const SfxObjectShell* pDocShell );
67 public:
68 SfxPickListImpl(SfxApplication& rApp);
69 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
72 void SfxPickListImpl::AddDocumentToPickList( const SfxObjectShell* pDocSh )
74 if (pDocSh->IsAvoidRecentDocs() || comphelper::LibreOfficeKit::isActive())
75 return;
77 SfxMedium *pMed = pDocSh->GetMedium();
78 if( !pMed )
79 return;
81 // Unnamed Documents and embedded-Documents not in Picklist
82 if ( !pDocSh->HasName() ||
83 SfxObjectCreateMode::STANDARD != pDocSh->GetCreateMode() )
84 return;
86 // Help not in History
87 INetURLObject aURL( pDocSh->IsDocShared() ? pDocSh->GetSharedFileURL() : pMed->GetOrigURL() );
88 if ( aURL.GetProtocol() == INetProtocol::VndSunStarHelp )
89 return;
91 // add no document that forbids this
92 if ( !pMed->IsUpdatePickList() )
93 return;
95 // ignore hidden documents
96 if ( !SfxViewFrame::GetFirst( pDocSh ) )
97 return;
99 OUString aTitle = pDocSh->GetTitle(SFX_TITLE_PICKLIST);
100 OUString aFilter;
101 std::shared_ptr<const SfxFilter> pFilter = pMed->GetFilter();
102 if ( pFilter )
103 aFilter = pFilter->GetFilterName();
105 std::optional<OUString> aThumbnail;
107 // generate the thumbnail
108 //fdo#74834: only generate thumbnail for history if the corresponding option is not disabled in the configuration
109 if (!pDocSh->IsModified() && !Application::IsHeadlessModeEnabled() &&
110 officecfg::Office::Common::History::RecentDocsThumbnail::get())
112 // not modified => the document matches what is in the shell
113 const SfxUnoAnyItem* pEncryptionDataItem = SfxItemSet::GetItem<SfxUnoAnyItem>(pMed->GetItemSet(), SID_ENCRYPTIONDATA, false);
114 if ( pEncryptionDataItem )
116 // encrypted document, will show a generic document icon instead
117 aThumbnail = OUString();
119 else
121 BitmapEx aResultBitmap = pDocSh->GetPreviewBitmap();
122 if (!aResultBitmap.IsEmpty())
124 SvMemoryStream aStream(65535, 65535);
125 vcl::PNGWriter aWriter(aResultBitmap);
126 if (aWriter.Write(aStream))
128 Sequence<sal_Int8> aSequence(static_cast<const sal_Int8*>(aStream.GetData()), aStream.Tell());
129 OUStringBuffer aBuffer;
130 ::comphelper::Base64::encode(aBuffer, aSequence);
131 aThumbnail = aBuffer.makeStringAndClear();
137 // add to svtool history options
138 SvtHistoryOptions().AppendItem( ePICKLIST,
139 aURL.GetURLNoPass( INetURLObject::DecodeMechanism::NONE ),
140 aFilter,
141 aTitle,
142 aThumbnail);
144 if ( aURL.GetProtocol() == INetProtocol::File )
145 Application::AddToRecentDocumentList( aURL.GetURLNoPass( INetURLObject::DecodeMechanism::NONE ),
146 pFilter ? pFilter->GetMimeType() : OUString(),
147 pFilter ? pFilter->GetServiceName() : OUString() );
150 SfxPickList::SfxPickList(SfxApplication& rApp)
151 : mxImpl(new SfxPickListImpl(rApp))
155 SfxPickList::~SfxPickList()
159 SfxPickListImpl::SfxPickListImpl(SfxApplication& rApp)
161 StartListening(rApp);
164 void SfxPickListImpl::Notify( SfxBroadcaster&, const SfxHint& rHint )
166 const SfxOpenUrlHint* pOpenUrlHint = dynamic_cast<const SfxOpenUrlHint*>(&rHint);
167 if ( pOpenUrlHint )
169 INetURLHistory::GetOrCreate()->PutUrl( INetURLObject( pOpenUrlHint->GetDocumentURL() ));
172 const SfxEventHint* pEventHint = dynamic_cast<const SfxEventHint*>(&rHint);
173 if ( !pEventHint )
174 return;
176 // only ObjectShell-related events with media interest
177 SfxObjectShell* pDocSh = pEventHint->GetObjShell();
178 if( !pDocSh )
179 return;
181 switch ( pEventHint->GetEventId() )
183 case SfxEventHintId::CreateDoc:
185 bool bAllowModif = pDocSh->IsEnableSetModified();
186 if ( bAllowModif )
187 pDocSh->EnableSetModified( false );
189 using namespace ::com::sun::star;
190 uno::Reference<document::XDocumentProperties> xDocProps(
191 pDocSh->getDocProperties());
192 if (xDocProps.is()) {
193 xDocProps->setAuthor( SvtUserOptions().GetFullName() );
194 ::DateTime now( ::DateTime::SYSTEM );
195 xDocProps->setCreationDate( now.GetUNODateTime() );
198 if ( bAllowModif )
199 pDocSh->EnableSetModified( bAllowModif );
201 break;
203 case SfxEventHintId::OpenDoc:
204 case SfxEventHintId::SaveDocDone:
205 case SfxEventHintId::SaveAsDocDone:
206 case SfxEventHintId::SaveToDocDone:
207 case SfxEventHintId::CloseDoc:
209 AddDocumentToPickList(pDocSh);
211 break;
213 case SfxEventHintId::SaveAsDoc:
215 SfxMedium *pMedium = pDocSh->GetMedium();
216 if (!pMedium)
217 return;
219 // We're starting a "Save As". Add the current document (if it's
220 // not a "new" document) to the "Recent Documents" list before we
221 // switch to the new path.
222 // If the current document is new, path will be empty.
223 OUString path = pMedium->GetOrigURL();
224 if (!path.isEmpty())
226 AddDocumentToPickList(pDocSh);
229 break;
230 default: break;
234 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */