File indexing completed on 2024-04-28 05:08:18

0001 /***************************************************************************
0002     Copyright (C) 2001-2009 Robby Stephenson <robby@periapsis.org>
0003  ***************************************************************************/
0004 
0005 /***************************************************************************
0006  *                                                                         *
0007  *   This program is free software; you can redistribute it and/or         *
0008  *   modify it under the terms of the GNU General Public License as        *
0009  *   published by the Free Software Foundation; either version 2 of        *
0010  *   the License or (at your option) version 3 or any later version        *
0011  *   accepted by the membership of KDE e.V. (or its successor approved     *
0012  *   by the membership of KDE e.V.), which shall act as a proxy            *
0013  *   defined in Section 14 of version 3 of the license.                    *
0014  *                                                                         *
0015  *   This program is distributed in the hope that it will be useful,       *
0016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0018  *   GNU General Public License for more details.                          *
0019  *                                                                         *
0020  *   You should have received a copy of the GNU General Public License     *
0021  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
0022  *                                                                         *
0023  ***************************************************************************/
0024 
0025 #ifndef TELLICO_DOCUMENT_H
0026 #define TELLICO_DOCUMENT_H
0027 
0028 #include "datavectors.h"
0029 #include "filter.h"
0030 
0031 #include <QObject>
0032 #include <QPointer>
0033 #include <QUrl>
0034 #include <QTimer>
0035 
0036 namespace Tellico {
0037   namespace Import {
0038     class TellicoImporter;
0039     class TellicoSaxImporter;
0040   }
0041 
0042   namespace Data {
0043 
0044 /**
0045  * The Document contains everything needed to deal with the contents, thus separated from
0046  * the viewer, the Tellico object. It can take of opening and saving documents, and contains
0047  * a list of the collections in the document.
0048  *
0049  * @author Robby Stephenson
0050  */
0051 class Document : public QObject {
0052 Q_OBJECT
0053 
0054 public:
0055   static Document* self() { if(!s_self) s_self = new Document(); return s_self; }
0056 
0057   /**
0058    * Sets the URL associated with the document.
0059    *
0060    * @param url The URL
0061    */
0062   void setURL(const QUrl& url);
0063   /**
0064    * Checks the modified flag, which indicates if the document has changed since the
0065    * last save.
0066    *
0067    * @return A boolean indicating the modified status
0068    */
0069   bool isModified() const { return m_isModified; }
0070   void setModified(bool modified);
0071   /**
0072    * Sets whether all images are loaded from file or not
0073    */
0074   void setLoadAllImages(bool loadAll) { m_loadAllImages = loadAll; }
0075   /**
0076    * Returns the current url associated with the document
0077    *
0078    * @return The url
0079    */
0080   const QUrl& URL() const { return m_url; }
0081   /**
0082    * Initializes a new document. The signalNewDoc() signal is emitted. The return
0083    * value is currently always true, but should indicate whether or not a new document
0084    * was correctly initialized.
0085    *
0086    * @param type The type of collection to add
0087    * @return A boolean indicating success
0088    */
0089   bool newDocument(int type);
0090   /**
0091    * Open a document given a specified location. If, for whatever reason, the file
0092    * cannot be opened, a proper message box is shown, indicating the problem. The
0093    * signalNewDoc() signal is made once the file contents have been confirmed.
0094    *
0095    * @param url The location to open
0096    * @return A boolean indicating success
0097    */
0098   bool openDocument(const QUrl& url);
0099   /**
0100    * Saves the document contents to a file.
0101    *
0102    * @param url The location to save the file
0103    * @param force Boolean indicating the file should be overwritten if necessary
0104    * @return A boolean indicating success
0105    */
0106   bool saveDocument(const QUrl& url, bool force = false);
0107   bool saveDocumentTemplate(const QUrl& url, const QString& collTitle);
0108   /**
0109    * Closes the document, deleting the contents. The return value is presently always true.
0110    *
0111    * @return A boolean indicating success
0112    */
0113   bool closeDocument();
0114   /**
0115    * Deletes the contents of the document. A signalCollectionDeleted() will be sent for every
0116    * collection in the document.
0117    */
0118   void deleteContents();
0119   /**
0120    * Returns a pointer to the document collection
0121    *
0122    * @return The collection
0123    */
0124   CollPtr collection() const;
0125   /**
0126    * Returns true if there are no entries. A doc with an empty collection is still empty.
0127    */
0128   bool isEmpty() const;
0129   /**
0130    * Appends the contents of another collection to the current one. The collections must be the
0131    * same type. Fields which are in the current collection are left alone. Fields
0132    * in the appended collection not in the current one are added. Entries in the appended collection
0133    * are added to the current one.
0134    *
0135    * @param coll A pointer to the appended collection.
0136    * @param structuralChange A flag indicating a structural change was made to the database
0137    */
0138   void appendCollection(CollPtr coll);
0139   static void appendCollection(CollPtr targetColl, CollPtr sourceColl, bool* structuralChange);
0140   /**
0141    * Merges another collection into this one. The collections must be the same type. Fields in the
0142    * current collection are left alone. Fields not in the current are added. The merging is slow
0143    * since each entry in @p coll must be compared to every entry in the current collection.
0144    *
0145    * @param coll A pointer to the collection to be merged.
0146    * @param structuralChange A flag indicating a structural change was made to the database
0147    * @return A QPair of the merged entries, see note in datavectors.h
0148    */
0149   MergePair mergeCollection(CollPtr coll);
0150   static MergePair mergeCollection(CollPtr targetColl, CollPtr sourceColl, bool* structuralChange);
0151   /**
0152    * Replace the current collection with a new one. Effectively, this is equivalent to opening
0153    * a new file containing this collection.
0154    *
0155    * @param coll A Pointer to the new collection, the document takes ownership.
0156    */
0157   void replaceCollection(CollPtr coll);
0158   void unAppendCollection(FieldList origFields, QList<int> addedEntries);
0159   void unMergeCollection(FieldList origFields_, MergePair entryPair);
0160   bool loadAllImagesNow() const;
0161   bool allImagesOnDisk() const { return m_allImagesOnDisk; }
0162   int imageCount() const;
0163   EntryList filteredEntries(FilterPtr filter) const;
0164 
0165   void renameCollection(const QString& newTitle);
0166 
0167   void checkInEntry(EntryPtr entry);
0168   void checkOutEntry(EntryPtr entry);
0169 
0170   /**
0171    * The second entry vector contains entries with images which should not be removed
0172    * in addition to those already in the collection
0173    */
0174   void removeImagesNotInCollection(EntryList entries, EntryList entriesToKeep);
0175   void cancelImageWriting() { m_cancelImageWriting = true; }
0176 
0177 public Q_SLOTS:
0178   /**
0179    * Sets the modified flag to true, emitting signalModified.
0180    *
0181    */
0182   void slotSetModified();
0183   void slotSetClean(bool clean);
0184 
0185 Q_SIGNALS:
0186   /**
0187    * Signals that the document has been modified.
0188    */
0189   void signalModified(bool modified);
0190   /**
0191    * Signals that a status message should be shown.
0192    *
0193    * @param str The message
0194    */
0195   void signalStatusMsg(const QString& str);
0196   /**
0197    * Signals that all images in the loaded file have been loaded
0198    * into memory or onto the disk
0199    */
0200   void signalCollectionImagesLoaded(Tellico::Data::CollPtr coll);
0201   void signalCollectionAdded(Tellico::Data::CollPtr coll);
0202   void signalCollectionDeleted(Tellico::Data::CollPtr coll);
0203   void signalCollectionModified(Tellico::Data::CollPtr coll, bool structuralChange);
0204 
0205 private Q_SLOTS:
0206   /**
0207    * Does an initial loading of all images, used for writing
0208    * images to temp dir initially
0209    */
0210   void slotLoadAllImages();
0211 
0212 private:
0213   static Document* s_self;
0214 
0215   /**
0216    * Writes all images in the current collection to the cache directory
0217    * if cacheDir = LocalDir, then url will be used and must not be empty
0218    */
0219   void writeAllImages(int cacheDir, const QUrl& url=QUrl());
0220   bool pruneImages();
0221 
0222   // make all constructors private
0223   Document();
0224   Document(const Document& doc);
0225   Document& operator=(const Document&);
0226   ~Document();
0227 
0228   CollPtr m_coll;
0229   bool m_isModified;
0230   bool m_loadAllImages;
0231   QUrl m_url;
0232   bool m_validFile;
0233   QPointer<Import::TellicoImporter> m_importer;
0234   bool m_cancelImageWriting;
0235   int m_fileFormat;
0236   bool m_allImagesOnDisk;
0237   QTimer m_loadImagesTimer;
0238 };
0239 
0240   } // end namespace
0241 } // end namespace
0242 #endif