1 /***************************************************************************
2     Copyright (C) 2001-2009 Robby Stephenson <robby@periapsis.org>
3  ***************************************************************************/
4 
5 /***************************************************************************
6  *                                                                         *
7  *   This program is free software; you can redistribute it and/or         *
8  *   modify it under the terms of the GNU General Public License as        *
9  *   published by the Free Software Foundation; either version 2 of        *
10  *   the License or (at your option) version 3 or any later version        *
11  *   accepted by the membership of KDE e.V. (or its successor approved     *
12  *   by the membership of KDE e.V.), which shall act as a proxy            *
13  *   defined in Section 14 of version 3 of the license.                    *
14  *                                                                         *
15  *   This program is distributed in the hope that it will be useful,       *
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  *   GNU General Public License for more details.                          *
19  *                                                                         *
20  *   You should have received a copy of the GNU General Public License     *
21  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
22  *                                                                         *
23  ***************************************************************************/
24 
25 #ifndef TELLICO_DOCUMENT_H
26 #define TELLICO_DOCUMENT_H
27 
28 #include "datavectors.h"
29 #include "filter.h"
30 
31 #include <QObject>
32 #include <QPointer>
33 #include <QUrl>
34 #include <QTimer>
35 
36 namespace Tellico {
37   namespace Import {
38     class TellicoImporter;
39     class TellicoSaxImporter;
40   }
41 
42   namespace Data {
43 
44 /**
45  * The Document contains everything needed to deal with the contents, thus separated from
46  * the viewer, the Tellico object. It can take of opening and saving documents, and contains
47  * a list of the collections in the document.
48  *
49  * @author Robby Stephenson
50  */
51 class Document : public QObject {
52 Q_OBJECT
53 
54 public:
self()55   static Document* self() { if(!s_self) s_self = new Document(); return s_self; }
56 
57   /**
58    * Sets the URL associated with the document.
59    *
60    * @param url The URL
61    */
62   void setURL(const QUrl& url);
63   /**
64    * Checks the modified flag, which indicates if the document has changed since the
65    * last save.
66    *
67    * @return A boolean indicating the modified status
68    */
isModified()69   bool isModified() const { return m_isModified; }
70   void setModified(bool modified);
71   /**
72    * Sets whether all images are loaded from file or not
73    */
setLoadAllImages(bool loadAll)74   void setLoadAllImages(bool loadAll) { m_loadAllImages = loadAll; }
75   /**
76    * Returns the current url associated with the document
77    *
78    * @return The url
79    */
URL()80   const QUrl& URL() const { return m_url; }
81   /**
82    * Initializes a new document. The signalNewDoc() signal is emitted. The return
83    * value is currently always true, but should indicate whether or not a new document
84    * was correctly initialized.
85    *
86    * @param type The type of collection to add
87    * @return A boolean indicating success
88    */
89   bool newDocument(int type);
90   /**
91    * Open a document given a specified location. If, for whatever reason, the file
92    * cannot be opened, a proper message box is shown, indicating the problem. The
93    * signalNewDoc() signal is made once the file contents have been confirmed.
94    *
95    * @param url The location to open
96    * @return A boolean indicating success
97    */
98   bool openDocument(const QUrl& url);
99   /**
100    * Saves the document contents to a file.
101    *
102    * @param url The location to save the file
103    * @param force Boolean indicating the file should be overwritten if necessary
104    * @return A boolean indicating success
105    */
106   bool saveDocument(const QUrl& url, bool force = false);
107   /**
108    * Closes the document, deleting the contents. The return value is presently always true.
109    *
110    * @return A boolean indicating success
111    */
112   bool closeDocument();
113   /**
114    * Deletes the contents of the document. A signalCollectionDeleted() will be sent for every
115    * collection in the document.
116    */
117   void deleteContents();
118   /**
119    * Returns a pointer to the document collection
120    *
121    * @return The collection
122    */
123   CollPtr collection() const;
124   /**
125    * Returns true if there are no entries. A doc with an empty collection is still empty.
126    */
127   bool isEmpty() const;
128   /**
129    * Appends the contents of another collection to the current one. The collections must be the
130    * same type. Fields which are in the current collection are left alone. Fields
131    * in the appended collection not in the current one are added. Entries in the appended collection
132    * are added to the current one.
133    *
134    * @param coll A pointer to the appended collection.
135    */
136   void appendCollection(CollPtr coll);
137   static void appendCollection(CollPtr targetColl, CollPtr sourceColl);
138   /**
139    * Merges another collection into this one. The collections must be the same type. Fields in the
140    * current collection are left alone. Fields not in the current are added. The merging is slow
141    * since each entry in @p coll must be compared to every entry in the current collection.
142    *
143    * @param coll A pointer to the collection to be merged.
144    * @return A QPair of the merged entries, see note in datavectors.h
145    */
146   MergePair mergeCollection(CollPtr coll);
147   static MergePair mergeCollection(CollPtr targetColl, CollPtr sourceColl);
148   /**
149    * Replace the current collection with a new one. Effectively, this is equivalent to opening
150    * a new file containing this collection.
151    *
152    * @param coll A Pointer to the new collection, the document takes ownership.
153    */
154   void replaceCollection(CollPtr coll);
155   void unAppendCollection(FieldList origFields, QList<int> addedEntries);
156   void unMergeCollection(FieldList origFields_, MergePair entryPair);
157   bool loadAllImagesNow() const;
allImagesOnDisk()158   bool allImagesOnDisk() const { return m_allImagesOnDisk; }
159   int imageCount() const;
160   EntryList filteredEntries(FilterPtr filter) const;
161 
162   void renameCollection(const QString& newTitle);
163 
164   void checkInEntry(EntryPtr entry);
165   void checkOutEntry(EntryPtr entry);
166 
167   /**
168    * The second entry vector contains entries with images which should not be removed
169    * in addition to those already in the collection
170    */
171   void removeImagesNotInCollection(EntryList entries, EntryList entriesToKeep);
cancelImageWriting()172   void cancelImageWriting() { m_cancelImageWriting = true; }
173 
174 public Q_SLOTS:
175   /**
176    * Sets the modified flag to true, emitting signalModified.
177    *
178    */
179   void slotSetModified();
180   void slotSetClean(bool clean);
181 
182 Q_SIGNALS:
183   /**
184    * Signals that the document has been modified.
185    */
186   void signalModified(bool modified);
187   /**
188    * Signals that a status message should be shown.
189    *
190    * @param str The message
191    */
192   void signalStatusMsg(const QString& str);
193   /**
194    * Signals that all images in the loaded file have been loaded
195    * into memory or onto the disk
196    */
197   void signalCollectionImagesLoaded(Tellico::Data::CollPtr coll);
198   void signalCollectionAdded(Tellico::Data::CollPtr coll);
199   void signalCollectionDeleted(Tellico::Data::CollPtr coll);
200 
201 private Q_SLOTS:
202   /**
203    * Does an initial loading of all images, used for writing
204    * images to temp dir initially
205    */
206   void slotLoadAllImages();
207 
208 private:
209   static Document* s_self;
210 
211   /**
212    * Writes all images in the current collection to the cache directory
213    * if cacheDir = LocalDir, then url will be used and must not be empty
214    */
215   void writeAllImages(int cacheDir, const QUrl& url=QUrl());
216   bool pruneImages();
217 
218   // make all constructors private
219   Document();
220   Document(const Document& doc);
221   Document& operator=(const Document&);
222   ~Document();
223 
224   CollPtr m_coll;
225   bool m_isModified;
226   bool m_loadAllImages;
227   QUrl m_url;
228   bool m_validFile;
229   QPointer<Import::TellicoImporter> m_importer;
230   bool m_cancelImageWriting;
231   int m_fileFormat;
232   bool m_allImagesOnDisk;
233   QTimer m_loadImagesTimer;
234 };
235 
236   } // end namespace
237 } // end namespace
238 #endif
239