Warning, file /graphics/kxstitch/src/SymbolManager.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  * Copyright (C) 2010-2015 by Stephen Allewell
0003  * steve.allewell@gmail.com
0004  *
0005  * This program is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License as published by
0007  * the Free Software Foundation; either version 2 of the License, or
0008  * (at your option) any later version.
0009  */
0010 
0011 /**
0012  * @file
0013  * Implement the SymbolManager class. This loads all symbol libraries from the kxstitch application
0014  * data folders and allows the selection of a library by name. The manager is implemented as a
0015  * singleton class accessible from anywhere in the application. Symbols need to be available to the
0016  * palette manager and from the renderer.
0017  */
0018 
0019 /**
0020  * @page symbol_manager Symbol Manager
0021  * The symbol manager provides an interface between the application and the collection of symbol sets.
0022  * A number of symbol libraries can exist and a particular set can be selected in the palette manager
0023  * symbol selector.
0024  */
0025 
0026 #include "SymbolManager.h"
0027 
0028 #include <QDir>
0029 #include <QDirIterator>
0030 #include <QFile>
0031 #include <QStandardPaths>
0032 #include <QUrl>
0033 
0034 #include <KLocalizedString>
0035 #include <KMessageBox>
0036 
0037 #include "Exceptions.h"
0038 #include "Symbol.h"
0039 #include "SymbolLibrary.h"
0040 
0041 SymbolManager *SymbolManager::symbolManager = nullptr;
0042 
0043 /**
0044  * Accessor for the static object
0045  */
0046 SymbolManager &SymbolManager::self()
0047 {
0048     if (symbolManager == nullptr) {
0049         symbolManager = new SymbolManager();
0050     }
0051 
0052     return *symbolManager;
0053 }
0054 
0055 /**
0056  * Constructor.
0057  */
0058 SymbolManager::SymbolManager()
0059 {
0060     refresh();
0061 }
0062 
0063 /**
0064  *Destructor. Delete all the symbol libraries.
0065  */
0066 SymbolManager::~SymbolManager()
0067 {
0068     qDeleteAll(m_symbolLibraries);
0069 }
0070 
0071 /**
0072  * Get a list of the symbol libraries available.
0073  *
0074  * @return QStringList of symbol library names.
0075  */
0076 QStringList SymbolManager::libraries()
0077 {
0078     QStringList libraryNames;
0079 
0080     QListIterator<SymbolLibrary *> i(self().m_symbolLibraries);
0081 
0082     while (i.hasNext()) {
0083         libraryNames.append(i.next()->name());
0084     }
0085 
0086     return libraryNames;
0087 }
0088 
0089 /**
0090  * Get a pointer to a symbol library by name
0091  *
0092  * @param name of the library required.
0093  *
0094  * @return pointer to the SymbolLibrary instance, returns null if no library found.
0095  */
0096 SymbolLibrary *SymbolManager::library(const QString &name)
0097 {
0098     for (int i = 0; i < self().m_symbolLibraries.count(); ++i) {
0099         SymbolLibrary *symbolLibrary = self().m_symbolLibraries.at(i);
0100 
0101         if (symbolLibrary->name() == name) {
0102             return symbolLibrary;
0103         }
0104     }
0105 
0106     return nullptr;
0107 }
0108 
0109 /**
0110  * Get a list of files stored in the symbols path, iterating each one to create a new SymbolLibrary instance
0111  * and read the library.
0112  * Assumes that local resources are given before global ones and should take priority.
0113  */
0114 void SymbolManager::refresh()
0115 {
0116     const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::DataLocation, QStringLiteral("symbols"), QStandardPaths::LocateDirectory);
0117 
0118     Q_FOREACH (const QString &dir, dirs) {
0119         QDirIterator it(dir, QStringList() << QStringLiteral("*.sym"));
0120 
0121         while (it.hasNext()) {
0122             SymbolLibrary *symbolLibrary = readLibrary(it.next());
0123 
0124             if (symbolLibrary) {
0125                 m_symbolLibraries.append(symbolLibrary);
0126             }
0127         }
0128     }
0129 }
0130 
0131 /**
0132  * Read a symbol library.
0133  *
0134  * @param name path to the symbol file to be read.
0135  *
0136  * @return pointer to the SymbolLibrary instance created.
0137  */
0138 SymbolLibrary *SymbolManager::readLibrary(const QString &name)
0139 {
0140     SymbolLibrary *symbolLibrary = new SymbolLibrary;
0141 
0142     QFile file(name);
0143 
0144     if (file.open(QIODevice::ReadOnly)) {
0145         QDataStream stream(&file);
0146 
0147         try {
0148             stream >> *symbolLibrary;
0149             symbolLibrary->setName(QFileInfo(name).baseName());
0150         } catch (const InvalidFile &e) {
0151             KMessageBox::error(nullptr, i18n("This does not appear to be a valid symbol file"));
0152             delete symbolLibrary;
0153             symbolLibrary = nullptr;
0154         } catch (const InvalidFileVersion &e) {
0155             KMessageBox::error(nullptr, e.version);
0156             delete symbolLibrary;
0157             symbolLibrary = nullptr;
0158         } catch (const FailedReadFile &e) {
0159             KMessageBox::error(nullptr, e.status);
0160             delete symbolLibrary;
0161             symbolLibrary = nullptr;
0162         }
0163 
0164         file.close();
0165     } else {
0166         KMessageBox::error(nullptr, i18n("Failed to open the file %1", name));
0167         delete symbolLibrary;
0168         symbolLibrary = nullptr;
0169     }
0170 
0171     return symbolLibrary;
0172 }