bump product version to 6.3.0.0.beta1
[LibreOffice.git] / sd / source / ui / dlg / TemplateScanner.cxx
blob14e53a6b6fa242b0f90e459f1fcdb9acb6a75f88
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 <TemplateScanner.hxx>
22 #include <comphelper/processfactory.hxx>
23 #include <comphelper/documentconstants.hxx>
25 #include <sfx2/doctempl.hxx>
26 #include <com/sun/star/frame/DocumentTemplates.hpp>
27 #include <com/sun/star/frame/XDocumentTemplates.hpp>
28 #include <com/sun/star/ucb/XContentAccess.hpp>
29 #include <com/sun/star/sdbc/XResultSet.hpp>
30 #include <com/sun/star/sdbc/XRow.hpp>
32 #include <set>
34 using namespace ::com::sun::star;
35 using namespace ::com::sun::star::uno;
37 namespace {
39 const char TITLE[] = "Title";
41 class FolderDescriptor
43 public:
44 FolderDescriptor (
45 int nPriority,
46 const OUString& rsContentIdentifier,
47 const Reference<css::ucb::XCommandEnvironment>& rxFolderEnvironment)
48 : mnPriority(nPriority),
49 msContentIdentifier(rsContentIdentifier),
50 mxFolderEnvironment(rxFolderEnvironment)
51 { }
52 int const mnPriority;
53 OUString const msContentIdentifier;
54 // Reference<sdbc::XResultSet> mxFolderResultSet;
55 Reference<css::ucb::XCommandEnvironment> mxFolderEnvironment;
57 class Comparator
59 public:
60 bool operator() (const FolderDescriptor& r1, const FolderDescriptor& r2) const
61 { return r1.mnPriority < r2.mnPriority; }
65 /** Use a heuristic based on the URL of a top-level template folder to
66 assign a priority that is used to sort the folders.
68 int Classify (const OUString&, const OUString& rsURL)
70 int nPriority (0);
72 if (rsURL.isEmpty())
73 nPriority = 100;
74 else if (rsURL.indexOf("presnt")>=0)
76 nPriority = 30;
78 else if (rsURL.indexOf("layout")>=0)
80 nPriority = 20;
82 else if (rsURL.indexOf("educate")>=0)
84 nPriority = 40;
86 else if (rsURL.indexOf("finance")>=0)
88 nPriority = 40;
90 else
92 // All other folders are taken for user supplied and have the
93 // highest priority.
94 nPriority = 10;
97 return nPriority;
100 } // end of anonymous namespace
102 namespace sd
105 class TemplateScanner::FolderDescriptorList
106 : public ::std::multiset<FolderDescriptor,FolderDescriptor::Comparator>
110 TemplateScanner::TemplateScanner()
111 : meState(INITIALIZE_SCANNING),
112 maFolderContent(),
113 mpFolderDescriptors(new FolderDescriptorList),
114 mxTemplateRoot(),
115 mxFolderEnvironment(),
116 mxEntryEnvironment(),
117 mxFolderResultSet(),
118 mxEntryResultSet()
120 // empty;
123 TemplateScanner::~TemplateScanner()
127 TemplateScanner::State TemplateScanner::GetTemplateRoot()
129 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
130 Reference<frame::XDocumentTemplates> xTemplates = frame::DocumentTemplates::create(xContext);
131 mxTemplateRoot = xTemplates->getContent();
133 return INITIALIZE_FOLDER_SCANNING;
136 TemplateScanner::State TemplateScanner::InitializeEntryScanning()
138 State eNextState (SCAN_ENTRY);
140 if (maFolderContent.isFolder())
142 mxEntryEnvironment.clear();
144 // We are interested only in three properties: the entry's name,
145 // its URL, and its content type.
146 Sequence<OUString> aProps (3);
147 aProps[0] = TITLE;
148 aProps[1] = "TargetURL";
149 aProps[2] = "TypeDescription";
151 // Create a cursor to iterate over the templates in this folders.
152 mxEntryResultSet.set( maFolderContent.createCursor(aProps, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY));
154 else
155 eNextState = ERROR;
157 return eNextState;
160 TemplateScanner::State TemplateScanner::ScanEntry()
162 State eNextState (ERROR);
164 Reference<css::ucb::XContentAccess> xContentAccess (mxEntryResultSet, UNO_QUERY);
165 Reference<css::sdbc::XRow> xRow (mxEntryResultSet, UNO_QUERY);
167 if (xContentAccess.is() && xRow.is() && mxEntryResultSet.is())
169 if (mxEntryResultSet->next())
171 OUString sTitle (xRow->getString (1));
172 OUString sTargetURL (xRow->getString (2));
173 OUString sContentType (xRow->getString (3));
175 OUString aId = xContentAccess->queryContentIdentifierString();
176 ::ucbhelper::Content aContent = ::ucbhelper::Content (aId, mxEntryEnvironment, comphelper::getProcessComponentContext());
177 if (aContent.isDocument ())
179 // Check whether the entry is an impress template. If so
180 // add a new entry to the resulting list (which is created
181 // first if necessary).
182 // These strings are used to find impress templates in the tree of
183 // template files. Should probably be determined dynamically.
184 if ( (sContentType == MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII)
185 || (sContentType == MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII)
186 || (sContentType == "application/vnd.stardivision.impress")
187 || (sContentType == MIMETYPE_VND_SUN_XML_IMPRESS_ASCII)
188 // The following id comes from the bugdoc in #i2764#.
189 || (sContentType == "Impress 2.0"))
191 OUString sLocalisedTitle = SfxDocumentTemplates::ConvertResourceString(sTitle);
192 mpTemplateEntries.push_back(std::make_unique<TemplateEntry>(sLocalisedTitle, sTargetURL));
196 // Continue scanning entries.
197 eNextState = SCAN_ENTRY;
199 else
201 // Continue with scanning the next folder.
202 eNextState = SCAN_FOLDER;
206 return eNextState;
209 TemplateScanner::State TemplateScanner::InitializeFolderScanning()
211 State eNextState (ERROR);
213 mxFolderResultSet.clear();
217 // Create content for template folders.
218 mxFolderEnvironment.clear();
219 ::ucbhelper::Content aTemplateDir (mxTemplateRoot, mxFolderEnvironment, comphelper::getProcessComponentContext());
221 // Define the list of properties we are interested in.
222 Sequence<OUString> aProps (2);
223 aProps[0] = TITLE;
224 aProps[1] = "TargetDirURL";
226 // Create an cursor to iterate over the template folders.
227 mxFolderResultSet.set( aTemplateDir.createCursor(aProps, ::ucbhelper::INCLUDE_FOLDERS_ONLY));
228 if (mxFolderResultSet.is())
229 eNextState = GATHER_FOLDER_LIST;
231 catch (css::uno::Exception&)
233 eNextState = ERROR;
236 return eNextState;
239 TemplateScanner::State TemplateScanner::GatherFolderList()
241 State eNextState (ERROR);
243 Reference<css::ucb::XContentAccess> xContentAccess (mxFolderResultSet, UNO_QUERY);
244 if (xContentAccess.is() && mxFolderResultSet.is())
246 while (mxFolderResultSet->next())
248 Reference<sdbc::XRow> xRow (mxFolderResultSet, UNO_QUERY);
249 if (xRow.is())
251 OUString sTitle (xRow->getString (1));
252 OUString sTargetDir (xRow->getString (2));
253 OUString aId = xContentAccess->queryContentIdentifierString();
255 mpFolderDescriptors->insert(
256 FolderDescriptor(
257 Classify(sTitle,sTargetDir),
258 aId,
259 mxFolderEnvironment));
263 eNextState = SCAN_FOLDER;
266 return eNextState;
269 TemplateScanner::State TemplateScanner::ScanFolder()
271 State eNextState (ERROR);
273 if (!mpFolderDescriptors->empty())
275 FolderDescriptor aDescriptor (*mpFolderDescriptors->begin());
276 mpFolderDescriptors->erase(mpFolderDescriptors->begin());
278 OUString aId (aDescriptor.msContentIdentifier);
280 maFolderContent = ::ucbhelper::Content (aId, aDescriptor.mxFolderEnvironment, comphelper::getProcessComponentContext());
281 if (maFolderContent.isFolder())
283 // Scan the folder and insert it into the list of template
284 // folders.
285 // Continue with scanning all entries in the folder.
286 mpTemplateEntries.clear();
287 eNextState = INITIALIZE_ENTRY_SCAN;
290 else
292 eNextState = DONE;
295 return eNextState;
298 void TemplateScanner::RunNextStep()
300 switch (meState)
302 case INITIALIZE_SCANNING:
303 meState = GetTemplateRoot();
304 break;
306 case INITIALIZE_FOLDER_SCANNING:
307 meState = InitializeFolderScanning();
308 break;
310 case SCAN_FOLDER:
311 meState = ScanFolder();
312 break;
314 case GATHER_FOLDER_LIST:
315 meState = GatherFolderList();
316 break;
318 case INITIALIZE_ENTRY_SCAN:
319 meState = InitializeEntryScanning();
320 break;
322 case SCAN_ENTRY:
323 meState = ScanEntry();
324 break;
325 default:
326 break;
329 switch (meState)
331 case DONE:
332 case ERROR:
333 mxTemplateRoot.clear();
334 mxFolderEnvironment.clear();
335 mxEntryEnvironment.clear();
336 mxFolderResultSet.clear();
337 mxEntryResultSet.clear();
338 break;
339 default:
340 break;
344 bool TemplateScanner::HasNextStep()
346 switch (meState)
348 case DONE:
349 case ERROR:
350 return false;
352 default:
353 return true;
359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */