diff options
author | Kurt Zenker <kz@openoffice.org> | 2006-04-26 19:45:19 +0000 |
---|---|---|
committer | Kurt Zenker <kz@openoffice.org> | 2006-04-26 19:45:19 +0000 |
commit | f614d3f678fcb0a41a7796308c388eebf5f850ce (patch) | |
tree | 3a1dd1dbe7fbafad649fc00e5a1e883a5b23e869 /sd/source/ui/dlg/TemplateScanner.cxx | |
parent | 4f669bb75710f17a57e19f4af314090556e066a3 (diff) |
INTEGRATION: CWS taskpane (1.8.116); FILE MERGED
2006/04/18 15:21:20 af 1.8.116.4: #i61115# Removed OSL_TRACE.
2006/04/11 15:00:19 af 1.8.116.3: #i61359# Using multiset so that all folders are correctly scanned. Moved the finalization code so that it is executed.
2006/03/24 10:56:34 af 1.8.116.2: #i61115# Ordering template folders so that user supplied templates come first.
2006/02/17 12:52:51 af 1.8.116.1: #i61359# Added support for the AsynchronousTask interface.
Diffstat (limited to 'sd/source/ui/dlg/TemplateScanner.cxx')
-rw-r--r-- | sd/source/ui/dlg/TemplateScanner.cxx | 475 |
1 files changed, 364 insertions, 111 deletions
diff --git a/sd/source/ui/dlg/TemplateScanner.cxx b/sd/source/ui/dlg/TemplateScanner.cxx index 60a54914c..1aa44c194 100644 --- a/sd/source/ui/dlg/TemplateScanner.cxx +++ b/sd/source/ui/dlg/TemplateScanner.cxx @@ -4,9 +4,9 @@ * * $RCSfile: TemplateScanner.cxx,v $ * - * $Revision: 1.8 $ + * $Revision: 1.9 $ * - * last change: $Author: rt $ $Date: 2005-09-09 03:50:32 $ + * last change: $Author: kz $ $Date: 2006-04-26 20:45:19 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -35,49 +35,121 @@ #include "TemplateScanner.hxx" -#ifndef _OSL_TIME_H_ -#include <osl/time.h> +#ifndef _COMPHELPER_SERVICEFACTORY_HXX +#include <comphelper/processfactory.hxx> +#endif +#ifndef _COMPHELPER_DOCUMENTCONSTANTS_HXX +#include <comphelper/documentconstants.hxx> #endif -#ifndef _VOS_MUTEX_HXX +#include <tools/debug.hxx> #include <vos/mutex.hxx> -#endif +#include <vcl/svapp.hxx> -#ifndef _SFXAPP_HXX -#include <sfx2/app.hxx> +#ifndef _COM_SUN_STAR_FRAME_XDOCUMENTTEMPLATES_HPP_ +#include <com/sun/star/frame/XDocumentTemplates.hpp> #endif - #ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_ #include <com/sun/star/lang/XMultiServiceFactory.hpp> #endif - -#ifndef _COMPHELPER_DOCUMENTCONSTANTS_HXX -#include <comphelper/documentconstants.hxx> +#ifndef _COM_SUN_STAR_UCB_XCOMMANDENVIRONMENT_HPP_ +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#endif +#ifndef _COM_SUN_STAR_UCB_XCONTENTACCESS_HPP_ +#include <com/sun/star/ucb/XContentAccess.hpp> +#endif +#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_ +#include <com/sun/star/sdbc/XResultSet.hpp> +#endif +#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_ +#include <com/sun/star/sdbc/XRow.hpp> #endif -using namespace ::rtl; -using namespace ::ucb; +#include <set> + using namespace ::com::sun::star; using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::sdbc; -using namespace ::com::sun::star::ucb; namespace { -const OUString TITLE = OUString::createFromAscii ("Title"); -const OUString TARGET_DIR_URL = OUString::createFromAscii ("TargetDirURL"); -const OUString DESCRIPTION = OUString::createFromAscii ("TypeDescription"); -const OUString TARGET_URL = OUString::createFromAscii ("TargetURL"); +const ::rtl::OUString TITLE = ::rtl::OUString::createFromAscii ("Title"); +const ::rtl::OUString TARGET_DIR_URL = ::rtl::OUString::createFromAscii ("TargetDirURL"); +const ::rtl::OUString DESCRIPTION = ::rtl::OUString::createFromAscii ("TypeDescription"); +const ::rtl::OUString TARGET_URL = ::rtl::OUString::createFromAscii ("TargetURL"); -const OUString DOCTEMPLATES = OUString::createFromAscii ("com.sun.star.frame.DocumentTemplates"); +const ::rtl::OUString DOCTEMPLATES = ::rtl::OUString::createFromAscii ("com.sun.star.frame.DocumentTemplates"); // These strings are used to find impress templates in the tree of // template files. Should probably be determined dynamically. -const OUString IMPRESS_BIN_TEMPLATE = OUString::createFromAscii ("application/vnd.stardivision.impress"); -const OUString IMPRESS_XML_TEMPLATE = MIMETYPE_VND_SUN_XML_IMPRESS; +const ::rtl::OUString IMPRESS_BIN_TEMPLATE = ::rtl::OUString::createFromAscii ("application/vnd.stardivision.impress"); +const ::rtl::OUString IMPRESS_XML_TEMPLATE = MIMETYPE_VND_SUN_XML_IMPRESS; // The following id comes from the bugdoc in #i2764#. -const OUString IMPRESS_XML_TEMPLATE_B = OUString::createFromAscii ("Impress 2.0"); -const OUString IMPRESS_XML_TEMPLATE_OASIS = MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION; +const ::rtl::OUString IMPRESS_XML_TEMPLATE_B = ::rtl::OUString::createFromAscii ("Impress 2.0"); +const ::rtl::OUString IMPRESS_XML_TEMPLATE_OASIS = MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION; + + +class FolderDescriptor +{ +public: + FolderDescriptor ( + int nPriority, + const ::rtl::OUString& rsTitle, + const ::rtl::OUString& rsTargetDir, + const ::rtl::OUString& rsContentIdentifier, + const Reference<com::sun::star::ucb::XCommandEnvironment>& rxFolderEnvironment) + : mnPriority(nPriority), + msTitle(rsTitle), + msTargetDir(rsTargetDir), + msContentIdentifier(rsContentIdentifier), + mxFolderEnvironment(rxFolderEnvironment) + { } + int mnPriority; + ::rtl::OUString msTitle; + ::rtl::OUString msTargetDir; + ::rtl::OUString msContentIdentifier; + // Reference<sdbc::XResultSet> mxFolderResultSet; + Reference<com::sun::star::ucb::XCommandEnvironment> mxFolderEnvironment; + + class Comparator { public: + bool operator() (const FolderDescriptor& r1, const FolderDescriptor& r2) + { return r1.mnPriority < r2.mnPriority; } + }; +}; + +/** Use a heuristic based on the URL of a top-level template folder to + assign a priority that is used to sort the folders. +*/ +int Classify (const ::rtl::OUString& rsTitle, const ::rtl::OUString& rsURL) +{ + int nPriority (0); + + if (rsURL.getLength() == 0) + nPriority = 100; + else if (rsURL.indexOf(::rtl::OUString::createFromAscii("presnt"))>=0) + { + nPriority = 30; + } + else if (rsURL.indexOf(::rtl::OUString::createFromAscii("layout"))>=0) + { + nPriority = 20; + } + else if (rsURL.indexOf(::rtl::OUString::createFromAscii("educate"))>=0) + { + nPriority = 40; + } + else if (rsURL.indexOf(::rtl::OUString::createFromAscii("finance"))>=0) + { + nPriority = 40; + } + else + { + // All other folders are taken for user supplied and have the + // highest priority. + nPriority = 10; + } + + return nPriority; +} } // end of anonymous namespace @@ -87,7 +159,23 @@ const OUString IMPRESS_XML_TEMPLATE_OASIS = MIMETYPE_OASIS_OPENDOCUMENT_PRESENTA namespace sd { +class TemplateScanner::FolderDescriptorList + : public ::std::multiset<FolderDescriptor,FolderDescriptor::Comparator> +{ +}; + TemplateScanner::TemplateScanner (void) + : meState(INITIALIZE_SCANNING), + maFolderContent(), + mpTemplateDirectory(NULL), + maFolderList(), + mpLastAddedEntry(NULL), + mxTemplateRoot(), + mxFolderEnvironment(), + mxEntryEnvironment(), + mxFolderResultSet(), + mxEntryResultSet(), + mpFolderDescriptors(new FolderDescriptorList()) { // empty; } @@ -97,6 +185,8 @@ TemplateScanner::TemplateScanner (void) TemplateScanner::~TemplateScanner (void) { + mpFolderDescriptors.reset(); + // Delete all entries of the template list that have not been // transferred to another object. std::vector<TemplateDir*>::iterator I; @@ -108,132 +198,224 @@ TemplateScanner::~TemplateScanner (void) -void TemplateScanner::GetTemplateRoot (void) +TemplateScanner::State TemplateScanner::GetTemplateRoot (void) { - Reference<lang::XMultiServiceFactory> xFactory = - ::comphelper::getProcessServiceFactory (); - DBG_ASSERT (xFactory.is(), - "TemplateScanner::GetTemplateRoot: xFactory is NULL"); + State eNextState (INITIALIZE_FOLDER_SCANNING); + + Reference<lang::XMultiServiceFactory> xFactory = ::comphelper::getProcessServiceFactory (); + DBG_ASSERT (xFactory.is(), "TemplateScanner::GetTemplateRoot: xFactory is NULL"); - Reference<frame::XDocumentTemplates> xTemplates ( - xFactory->createInstance (DOCTEMPLATES), UNO_QUERY); - DBG_ASSERT (xTemplates.is(), - "TemplateScanner::GetTemplateRoot: xTemplates is NULL"); - - if (xTemplates.is()) - mxTemplateRoot = xTemplates->getContent(); + if (xFactory.is()) + { + Reference<frame::XDocumentTemplates> xTemplates ( + xFactory->createInstance (DOCTEMPLATES), UNO_QUERY); + DBG_ASSERT (xTemplates.is(), "TemplateScanner::GetTemplateRoot: xTemplates is NULL"); + + if (xTemplates.is()) + mxTemplateRoot = xTemplates->getContent(); + else + eNextState = ERROR; + } + else + eNextState = ERROR; + return eNextState; } -void TemplateScanner::ScanEntries (Content& rRoot, TemplateDir* pDir) +TemplateScanner::State TemplateScanner::InitializeEntryScanning (void) { - Reference<XCommandEnvironment> aCmdEnv; + State eNextState (SCAN_ENTRY); + + if (maFolderContent.isFolder()) + { + mxEntryEnvironment = Reference<com::sun::star::ucb::XCommandEnvironment>(); - // We are interested only in three properties: the entry's name, - // its URL, and its content type. - Sequence<OUString> aProps (3); - aProps[0] = TITLE; - aProps[1] = TARGET_URL; - aProps[2] = DESCRIPTION; + // We are interested only in three properties: the entry's name, + // its URL, and its content type. + Sequence<rtl::OUString> aProps (3); + aProps[0] = TITLE; + aProps[1] = TARGET_URL; + aProps[2] = DESCRIPTION; + + // Create a cursor to iterate over the templates in this folders. + ::ucb::ResultSetInclude eInclude = ::ucb::INCLUDE_DOCUMENTS_ONLY; + mxEntryResultSet = Reference<com::sun::star::sdbc::XResultSet>( + maFolderContent.createCursor(aProps, eInclude)); + } + else + eNextState = ERROR; + + return eNextState; +} - // Create a cursor to iterate over the templates in this folders. - ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY; - Reference<XResultSet> xResultSet (rRoot.createCursor (aProps, eInclude)); - if (xResultSet.is()) + + +TemplateScanner::State TemplateScanner::ScanEntry (void) +{ + State eNextState (ERROR); + + Reference<com::sun::star::ucb::XContentAccess> xContentAccess (mxEntryResultSet, UNO_QUERY); + Reference<com::sun::star::sdbc::XRow> xRow (mxEntryResultSet, UNO_QUERY); + + if (xContentAccess.is() && xRow.is() && mxEntryResultSet.is()) { - Reference<XContentAccess> xContentAccess (xResultSet, UNO_QUERY); - Reference<XRow> xRow (xResultSet, UNO_QUERY); + if (mxEntryResultSet->next()) + { + ::rtl::OUString sTitle (xRow->getString (1)); + ::rtl::OUString sTargetURL (xRow->getString (2)); + ::rtl::OUString sContentType (xRow->getString (3)); - // Iterate over the template folder. - while (xResultSet->next()) + ::rtl::OUString aId = xContentAccess->queryContentIdentifierString(); + ::ucb::Content aContent = ::ucb::Content (aId, mxEntryEnvironment); + if (aContent.isDocument ()) + { + // Check wether the entry is an impress template. If so + // add a new entry to the resulting list (which is created + // first if necessary). + if ( (sContentType == MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE) + || (sContentType == IMPRESS_XML_TEMPLATE_OASIS) + || (sContentType == IMPRESS_BIN_TEMPLATE) + || (sContentType == IMPRESS_XML_TEMPLATE) + || (sContentType == IMPRESS_XML_TEMPLATE_B)) + { + mpLastAddedEntry = new TemplateEntry(sTitle, sTargetURL); + mpTemplateDirectory->maEntries.push_back(mpLastAddedEntry); + } + } + + // Continue scanning entries. + eNextState = SCAN_ENTRY; + } + else { - OUString aTitle (xRow->getString (1)); - OUString aTargetURL (xRow->getString (2)); - OUString aContentType (xRow->getString (3)); - - OUString aId = xContentAccess->queryContentIdentifierString(); - Content aContent = Content (aId, aCmdEnv); - if ( ! aContent.isDocument ()) - continue; - - // Check wether the entry is an impress template. If so add a - // new entry to the resulting list (which is created first if - // necessary). - if ( (aContentType == MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE) - || (aContentType == IMPRESS_XML_TEMPLATE_OASIS) - || (aContentType == IMPRESS_BIN_TEMPLATE) - || (aContentType == IMPRESS_XML_TEMPLATE) - || (aContentType == IMPRESS_XML_TEMPLATE_B)) - pDir->m_aEntries.push_back ( - new TemplateEntry (aTitle, aTargetURL)); + if (mpTemplateDirectory->maEntries.empty()) + { + delete mpTemplateDirectory; + mpTemplateDirectory = NULL; + } + else + { + ::vos::OGuard aGuard(Application::GetSolarMutex()); + maFolderList.push_back(mpTemplateDirectory); + } + + // Continue with scanning the next folder. + eNextState = SCAN_FOLDER; } } + + return eNextState; } -void TemplateScanner::ScanFolders (void) +TemplateScanner::State TemplateScanner::InitializeFolderScanning (void) { + State eNextState (ERROR); + + mxFolderResultSet = Reference<sdbc::XResultSet>(); + try { // Create content for template folders. - Reference<XCommandEnvironment> aCmdEnv; - Content aTemplateDir (mxTemplateRoot, aCmdEnv); + mxFolderEnvironment = Reference<com::sun::star::ucb::XCommandEnvironment>(); + ::ucb::Content aTemplateDir (mxTemplateRoot, mxFolderEnvironment); // Define the list of properties we are interested in. - Sequence<OUString> aProps (2); + Sequence<rtl::OUString> aProps (2); aProps[0] = TITLE; aProps[1] = TARGET_DIR_URL; // Create an cursor to iterate over the template folders. - ResultSetInclude eInclude = INCLUDE_FOLDERS_ONLY; - Reference<XResultSet> xResultSet (aTemplateDir.createCursor ( - aProps, eInclude)); + ::ucb::ResultSetInclude eInclude = ::ucb::INCLUDE_FOLDERS_ONLY; + mxFolderResultSet = Reference<sdbc::XResultSet>( + aTemplateDir.createCursor(aProps, eInclude)); + if (mxFolderResultSet.is()) + eNextState = GATHER_FOLDER_LIST; + } + catch (::com::sun::star::uno::Exception&) + { + eNextState = ERROR; + } + + return eNextState; +} + + - if (xResultSet.is()) - { - Reference<XContentAccess> xContentAccess (xResultSet, UNO_QUERY); - while (xResultSet->next()) +TemplateScanner::State TemplateScanner::GatherFolderList (void) +{ + State eNextState (ERROR); + + Reference<com::sun::star::ucb::XContentAccess> xContentAccess (mxFolderResultSet, UNO_QUERY); + if (xContentAccess.is() && mxFolderResultSet.is()) + { + while (mxFolderResultSet->next()) + { + Reference<sdbc::XRow> xRow (mxFolderResultSet, UNO_QUERY); + if (xRow.is()) { - Reference<XRow> xRow (xResultSet, UNO_QUERY); - if ( ! xRow.is()) - continue; + ::rtl::OUString sTitle (xRow->getString (1)); + ::rtl::OUString sTargetDir (xRow->getString (2)); + ::rtl::OUString aId = xContentAccess->queryContentIdentifierString(); + + mpFolderDescriptors->insert( + FolderDescriptor( + Classify(sTitle,sTargetDir), + sTitle, + sTargetDir, + aId, + mxFolderEnvironment)); + } + } - OUString aTitle (xRow->getString (1)); - OUString aTargetDir (xRow->getString (2)); + eNextState = SCAN_FOLDER; + } + + return eNextState; +} - OUString aId = xContentAccess->queryContentIdentifierString(); - Content aContent = Content (aId, aCmdEnv); - if (aContent.isFolder()) - { - // Scan the folder and insert it into the list of - // template folders. - TemplateDir* pDir = new TemplateDir (aTitle, aTargetDir); - if (pDir != NULL) - { - ScanEntries (aContent, pDir); - if (pDir->m_aEntries.empty()) - delete pDir; - else - { - ::vos::OGuard aGuard(Application::GetSolarMutex()); - maFolderList.push_back(pDir); - } - } - } + + + +TemplateScanner::State TemplateScanner::ScanFolder (void) +{ + State eNextState (ERROR); + + if (mpFolderDescriptors->size() > 0) + { + FolderDescriptor aDescriptor (*mpFolderDescriptors->begin()); + mpFolderDescriptors->erase(mpFolderDescriptors->begin()); + + ::rtl::OUString sTitle (aDescriptor.msTitle); + ::rtl::OUString sTargetDir (aDescriptor.msTargetDir); + ::rtl::OUString aId (aDescriptor.msContentIdentifier); + + maFolderContent = ::ucb::Content (aId, aDescriptor.mxFolderEnvironment); + if (maFolderContent.isFolder()) + { + // Scan the folder and insert it into the list of template + // folders. + mpTemplateDirectory = new TemplateDir (sTitle, sTargetDir); + if (mpTemplateDirectory != NULL) + { + // Continue with scanning all entries in the folder. + eNextState = INITIALIZE_ENTRY_SCAN; } } } - catch(::com::sun::star::uno::Exception&) + else { - // Ignore all exceptions. + eNextState = DONE; } + + return eNextState; } @@ -241,8 +423,8 @@ void TemplateScanner::ScanFolders (void) void TemplateScanner::Scan (void) { - GetTemplateRoot (); - ScanFolders (); + while (HasNextStep()) + RunNextStep(); } @@ -253,4 +435,75 @@ std::vector<TemplateDir*>& TemplateScanner::GetFolderList (void) return maFolderList; } + + + +void TemplateScanner::RunNextStep (void) +{ + switch (meState) + { + case INITIALIZE_SCANNING: + meState = GetTemplateRoot(); + break; + + case INITIALIZE_FOLDER_SCANNING: + meState = InitializeFolderScanning(); + break; + + case SCAN_FOLDER: + meState = ScanFolder(); + break; + + case GATHER_FOLDER_LIST: + meState = GatherFolderList(); + break; + + case INITIALIZE_ENTRY_SCAN: + meState = InitializeEntryScanning(); + break; + + case SCAN_ENTRY: + meState = ScanEntry(); + break; + } + + switch (meState) + { + case DONE: + case ERROR: + mxTemplateRoot.clear(); + mxTemplateRoot.clear(); + mxFolderEnvironment.clear(); + mxEntryEnvironment.clear(); + mxFolderResultSet.clear(); + mxEntryResultSet.clear(); + mpLastAddedEntry = NULL; + break; + } +} + + + + +bool TemplateScanner::HasNextStep (void) +{ + switch (meState) + { + case DONE: + case ERROR: + return false; + + default: + return true; + } +} + + + + +const TemplateEntry* TemplateScanner::GetLastAddedEntry (void) const +{ + return mpLastAddedEntry; +} + } |