turn SfxPickList singleton a member of SfxApplication
[LibreOffice.git] / sfx2 / source / appl / sfxpicklist.cxx
blob451afe95cf8af03b0485f7802a8b0d6f4329aaba
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 <config_features.h>
22 #include <comphelper/lok.hxx>
23 #include <comphelper/base64.hxx>
24 #include <com/sun/star/document/XDocumentProperties.hpp>
25 #include <unotools/historyoptions.hxx>
26 #include <unotools/useroptions.hxx>
27 #include <tools/urlobj.hxx>
28 #include <framework/menuconfiguration.hxx>
29 #include <sax/tools/converter.hxx>
30 #include <svl/inethist.hxx>
31 #include <svl/stritem.hxx>
32 #include <svl/eitem.hxx>
33 #include <vcl/gdimtf.hxx>
34 #include <vcl/pngwrite.hxx>
35 #include <officecfg/Office/Common.hxx>
36 #include <osl/file.hxx>
37 #include <unotools/localfilehelper.hxx>
38 #include <cppuhelper/implbase.hxx>
41 #include <sfx2/app.hxx>
42 #include <sfxpicklist.hxx>
43 #include <sfx2/sfxuno.hxx>
44 #include <sfxtypes.hxx>
45 #include <sfx2/request.hxx>
46 #include <sfx2/sfxsids.hrc>
47 #include <sfx2/event.hxx>
48 #include <sfx2/objsh.hxx>
49 #include <sfx2/bindings.hxx>
50 #include <sfx2/docfile.hxx>
51 #include <objshimp.hxx>
52 #include <openurlhint.hxx>
53 #include <sfx2/docfilt.hxx>
55 #include <rtl/instance.hxx>
57 #include <algorithm>
60 using namespace ::com::sun::star::uno;
61 using namespace ::com::sun::star::beans;
62 using namespace ::com::sun::star::util;
65 namespace
67 class thePickListMutex
68 : public rtl::Static<osl::Mutex, thePickListMutex> {};
71 class SfxPickListImpl : public SfxListener
73 /**
74 * Adds the given document to the pick list (recent documents) if it satisfies
75 certain requirements, e.g. being writable. Check implementation for requirement
76 details.
78 static void AddDocumentToPickList( SfxObjectShell* pDocShell );
80 public:
81 SfxPickListImpl(SfxApplication& rApp);
82 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
85 void SfxPickListImpl::AddDocumentToPickList( SfxObjectShell* pDocSh )
87 if (pDocSh->IsAvoidRecentDocs() || comphelper::LibreOfficeKit::isActive())
88 return;
90 SfxMedium *pMed = pDocSh->GetMedium();
91 if( !pMed )
92 return;
94 // Unnamed Documents and embedded-Documents not in Picklist
95 if ( !pDocSh->HasName() ||
96 SfxObjectCreateMode::STANDARD != pDocSh->GetCreateMode() )
97 return;
99 // Help not in History
100 INetURLObject aURL( pDocSh->IsDocShared() ? pDocSh->GetSharedFileURL() : pMed->GetOrigURL() );
101 if ( aURL.GetProtocol() == INetProtocol::VndSunStarHelp )
102 return;
104 // add no document that forbids this
105 if ( !pMed->IsUpdatePickList() )
106 return;
108 // ignore hidden documents
109 if ( !SfxViewFrame::GetFirst( pDocSh ) )
110 return;
112 OUString aTitle = pDocSh->GetTitle(SFX_TITLE_PICKLIST);
113 OUString aFilter;
114 std::shared_ptr<const SfxFilter> pFilter = pMed->GetOrigFilter();
115 if ( pFilter )
116 aFilter = pFilter->GetFilterName();
118 boost::optional<OUString> aThumbnail;
120 // generate the thumbnail
121 //fdo#74834: only generate thumbnail for history if the corresponding option is not disabled in the configuration
122 if (!pDocSh->IsModified() && !Application::IsHeadlessModeEnabled() &&
123 officecfg::Office::Common::History::RecentDocsThumbnail::get())
125 // not modified => the document matches what is in the shell
126 const SfxUnoAnyItem* pEncryptionDataItem = SfxItemSet::GetItem<SfxUnoAnyItem>(pMed->GetItemSet(), SID_ENCRYPTIONDATA, false);
127 if ( pEncryptionDataItem )
129 // encrypted document, will show a generic document icon instead
130 aThumbnail = OUString();
132 else
134 std::shared_ptr<GDIMetaFile> xMetaFile = pDocSh->GetPreviewMetaFile();
135 BitmapEx aResultBitmap;
136 if (xMetaFile->CreateThumbnail(aResultBitmap))
138 SvMemoryStream aStream(65535, 65535);
139 vcl::PNGWriter aWriter(aResultBitmap);
140 if (aWriter.Write(aStream))
142 Sequence<sal_Int8> aSequence(static_cast<const sal_Int8*>(aStream.GetData()), aStream.Tell());
143 OUStringBuffer aBuffer;
144 ::comphelper::Base64::encode(aBuffer, aSequence);
145 aThumbnail = aBuffer.makeStringAndClear();
151 // add to svtool history options
152 SvtHistoryOptions().AppendItem( ePICKLIST,
153 aURL.GetURLNoPass( INetURLObject::DecodeMechanism::NONE ),
154 aFilter,
155 aTitle,
156 aThumbnail);
158 if ( aURL.GetProtocol() == INetProtocol::File )
159 Application::AddToRecentDocumentList( aURL.GetURLNoPass( INetURLObject::DecodeMechanism::NONE ),
160 pFilter ? pFilter->GetMimeType() : OUString(),
161 pFilter ? pFilter->GetServiceName() : OUString() );
164 SfxPickList::SfxPickList(SfxApplication& rApp)
165 : mxImpl(new SfxPickListImpl(rApp))
169 SfxPickList::~SfxPickList()
173 SfxPickListImpl::SfxPickListImpl(SfxApplication& rApp)
175 StartListening(rApp);
178 void SfxPickListImpl::Notify( SfxBroadcaster&, const SfxHint& rHint )
180 const SfxOpenUrlHint* pOpenUrlHint = dynamic_cast<const SfxOpenUrlHint*>(&rHint);
181 if ( pOpenUrlHint )
183 INetURLHistory::GetOrCreate()->PutUrl( INetURLObject( pOpenUrlHint->GetDocumentURL() ));
186 const SfxEventHint* pEventHint = dynamic_cast<const SfxEventHint*>(&rHint);
187 if ( pEventHint )
189 // only ObjectShell-related events with media interest
190 SfxObjectShell* pDocSh = pEventHint->GetObjShell();
191 if( !pDocSh )
192 return;
194 switch ( pEventHint->GetEventId() )
196 case SfxEventHintId::CreateDoc:
198 bool bAllowModif = pDocSh->IsEnableSetModified();
199 if ( bAllowModif )
200 pDocSh->EnableSetModified( false );
202 using namespace ::com::sun::star;
203 uno::Reference<document::XDocumentProperties> xDocProps(
204 pDocSh->getDocProperties());
205 if (xDocProps.is()) {
206 xDocProps->setAuthor( SvtUserOptions().GetFullName() );
207 ::DateTime now( ::DateTime::SYSTEM );
208 xDocProps->setCreationDate( now.GetUNODateTime() );
211 if ( bAllowModif )
212 pDocSh->EnableSetModified( bAllowModif );
214 break;
216 case SfxEventHintId::OpenDoc:
217 case SfxEventHintId::SaveDocDone:
218 case SfxEventHintId::SaveAsDocDone:
219 case SfxEventHintId::SaveToDocDone:
220 case SfxEventHintId::CloseDoc:
222 AddDocumentToPickList(pDocSh);
224 break;
226 case SfxEventHintId::SaveAsDoc:
228 SfxMedium *pMedium = pDocSh->GetMedium();
229 if (!pMedium)
230 return;
232 // We're starting a "Save As". Add the current document (if it's
233 // not a "new" document) to the "Recent Documents" list before we
234 // switch to the new path.
235 // If the current document is new, path will be empty.
236 OUString path = pMedium->GetOrigURL();
237 if (!path.isEmpty())
239 AddDocumentToPickList(pDocSh);
242 break;
243 default: break;
248 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */