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

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_COLLECTION_H
0026 #define TELLICO_COLLECTION_H
0027 
0028 #include "field.h"
0029 #include "entry.h"
0030 #include "filter.h"
0031 #include "borrower.h"
0032 #include "datavectors.h"
0033 
0034 #include <QStringList>
0035 #include <QHash>
0036 #include <QObject>
0037 
0038 namespace Tellico {
0039   namespace Data {
0040     class EntryGroup;
0041     typedef QHash<QString, EntryGroup*> EntryGroupDict;
0042 
0043 /**
0044  * The Collection class is the primary data object, holding a
0045  * list of fields and entries.
0046  *
0047  * A collection holds entries of a single type, whether it be books, CDs, or whatever.
0048  * It has a list of attributes which apply for the whole collection. A unique id value
0049  * identifies each collection object.
0050  *
0051  * @see Entry
0052  * @see Field
0053  *
0054  * @author Robby Stephenson
0055  */
0056 class Collection : public QObject, public QSharedData {
0057 Q_OBJECT
0058 
0059 public:
0060   enum Type {
0061     Base = 1,
0062     Book = 2,
0063     Video = 3,
0064     Album = 4,
0065     Bibtex = 5,
0066     ComicBook = 6,
0067     Wine = 7,
0068     Coin = 8,
0069     Stamp = 9,
0070     Card = 10,
0071     Game = 11,
0072     File = 12,
0073     BoardGame = 13
0074     // if you want to add custom collection types, use a number sure to be unique like 101
0075     // don't forget to update macros in core/tellico_config_addons.cpp tests/fetchertest.cpp
0076   };
0077 
0078   /**
0079    * The constructor is only used to create custom collections.
0080    *
0081    * @param addDefaultFields whether to add default fields or not
0082    * @param title The title of the collection itself
0083    */
0084   explicit Collection(bool addDefaultFields, const QString& title=QString());
0085   /**
0086    */
0087   virtual ~Collection();
0088 
0089   /**
0090    * Returns the type of the collection.
0091    *
0092    * @return The type
0093    */
0094   virtual Type type() const { return Base; }
0095   /**
0096    * Returns the id of the collection.
0097    *
0098    * @return The id
0099    */
0100   ID id() const { return m_id; }
0101   /**
0102    * Returns the name of the collection.
0103    *
0104    * @return The name
0105    */
0106   const QString& title() const { return m_title; }
0107   /**
0108    * Sets the title of the collection.
0109    *
0110    * @param title The new collection title
0111    */
0112   void setTitle(const QString& title) { m_title = title; }
0113   /**
0114    * Returns a reference to the list of all the entries in the collection.
0115    *
0116    * @return The list of entries
0117    */
0118   const EntryList& entries() const { return m_entries; }
0119   /**
0120    * Returns a reference to the list of the collection attributes.
0121    *
0122    * @return The list of fields
0123    */
0124   const FieldList& fields() const { return m_fields; }
0125   EntryPtr entryById(ID id);
0126   /**
0127    * Returns a reference to the list of the collection's people fields.
0128    *
0129    * @return The list of fields
0130    */
0131   const FieldList& peopleFields() const { return m_peopleFields; }
0132   /**
0133    * Returns a reference to the list of the collection's image fields.
0134    *
0135    * @return The list of fields
0136    */
0137   const FieldList& imageFields() const { return m_imageFields; }
0138   /**
0139    * Return the primary image field, which is used for icons for the entry.
0140    * By default, the first image field is returned.
0141    *
0142    * @return The primary image field
0143    */
0144   FieldPtr primaryImageField() const;
0145   QString titleField() const;
0146   /**
0147    * Returns a reference to the list of field groups. This value is cached rather
0148    * than generated with each call, so the method should be fairly fast.
0149    *
0150    * @return The list of group names
0151    */
0152   const QStringList& fieldCategories() const { return m_fieldCategories; }
0153   /**
0154    * Returns the name of the field used to group the entries by default.
0155    *
0156    * @return The field name
0157    */
0158   const QString& defaultGroupField() const { return m_defaultGroupField; }
0159   /**
0160    * Sets the name of the default field used to group the entries.
0161    *
0162    * @param name The name of the field
0163    */
0164   void setDefaultGroupField(const QString& name) { m_defaultGroupField = name; }
0165   /**
0166    * Returns the number of entries in the collection.
0167    *
0168    * @return The number of entries
0169    */
0170   int entryCount() const { return m_entries.count(); }
0171   /**
0172    * Adds a entry to the collection. The collection takes ownership of the entry object.
0173    *
0174    * @param entry A pointer to the entry
0175    */
0176   void addEntries(const EntryList& entries);
0177   void addEntries(EntryPtr entry) { addEntries(EntryList() << entry); }
0178   /**
0179    * Updates the dicts that include the entry.
0180    *
0181    * @param entry A pointer to the entry
0182    */
0183   void updateDicts(const EntryList& entries, const QStringList& fields);
0184   /**
0185    * Deletes a entry from the collection.
0186    *
0187    * @param entry The pointer to the entry
0188    * @return A boolean indicating if the entry was in the collection and was deleted
0189    */
0190   bool removeEntries(const EntryList& entries);
0191   QList<int> entryIdList() const { return m_entryById.keys(); }
0192   /**
0193    * Adds a whole list of fields. It calls
0194    * @ref addField, which is virtual.
0195    *
0196    * @param list List of fields to add
0197    * @return A boolean indicating if the fields were successfully added or not
0198    */
0199   bool addFields(FieldList list);
0200   /**
0201    * Adds an field to the collection, unless an field with that name
0202    * already exists. The collection takes ownership of the field object.
0203    *
0204    * @param field A pointer to the field
0205    * @return A boolean indicating if the field was added or not
0206    */
0207   virtual bool addField(FieldPtr field);
0208   virtual bool modifyField(FieldPtr field);
0209   virtual bool removeField(FieldPtr field, bool force=false);
0210   virtual bool removeField(const QString& name, bool force=false);
0211   void reorderFields(const FieldList& list);
0212   /**
0213    * Merges a field into a collection
0214    *
0215    * @param field A pointer to the field
0216    * @return A boolean indicating if structural changes were made to the collection
0217    */
0218   bool mergeField(FieldPtr field);
0219 
0220   // the reason this is not static is so I can call it from a collection pointer
0221   // it also gets overridden for different collection types
0222   // the return values should be compared against the GOOD and PERFECT
0223   // static match constants
0224   virtual int sameEntry(Data::EntryPtr, Data::EntryPtr) const;
0225 
0226   /**
0227    * Determines whether or not a certain value is allowed for an field.
0228    *
0229    * @param field The name of the field
0230    * @param value The desired value
0231    * @return A boolean indicating if the value is an allowed value for that field
0232    */
0233   bool isAllowed(const QString& field, const QString& value) const;
0234   /**
0235    * Returns a list of all the field names.
0236    *
0237    * @return The list of names
0238    */
0239   QStringList fieldNames() const;
0240   /**
0241    * Returns a list of all the field titles.
0242    *
0243    * @return The list of titles
0244    */
0245   QStringList fieldTitles() const;
0246   /**
0247    * Returns the title of an field, given its name.
0248    *
0249    * @param name The field name
0250    * @return The field title
0251    */
0252   QString fieldTitleByName(const QString& name) const;
0253   /**
0254    * Returns the name of an field, given its title.
0255    *
0256    * @param title The field title
0257    * @return The field name
0258    */
0259   QString fieldNameByTitle(const QString& title) const;
0260   /**
0261    * Returns a list of the values of a given field for every entry
0262    * in the collection. The values in the list are not repeated. Attribute
0263    * values which contain ";" are split into separate values. Since this method
0264    * iterates over all the entries, for large collections, it is expensive.
0265    *
0266    * @param name The name of the field
0267    * @return The list of values
0268    */
0269   QStringList valuesByFieldName(const QString& name) const;
0270   /**
0271    * Returns a list of all the fields in a given category.
0272    *
0273    * @param category The name of the category
0274    * @return The field list
0275    */
0276   FieldList fieldsByCategory(const QString& category);
0277   /**
0278    * Returns a pointer to an field given its name. If none is found, a NULL pointer
0279    * is returned.
0280    *
0281    * @param name The field name
0282    * @return The field pointer
0283    */
0284   FieldPtr fieldByName(const QString& name) const;
0285   /**
0286    * Returns a pointer to an field given its title. If none is found, a NULL pointer
0287    * is returned. This lookup is slower than by name.
0288    *
0289    * @param title The field title
0290    * @return The field pointer
0291    */
0292   FieldPtr fieldByTitle(const QString& title) const;
0293   /**
0294    * Returns @p true if the collection contains a field named @ref name;
0295    */
0296   bool hasField(const QString& name) const;
0297   /**
0298    * Returns a list of all the possible entry groups. This value is cached rather
0299    * than generated with each call, so the method should be fairly fast.
0300    *
0301    * @return The list of groups
0302    */
0303   const QStringList& entryGroups() const { return m_entryGroups; }
0304   /**
0305    * Returns a pointer to a dict of all the entries grouped by
0306    * a certain field
0307    *
0308    * @param name The name of the field by which the entries are grouped
0309    * @return The list of group names
0310    */
0311   EntryGroupDict* entryGroupDictByName(const QString& name);
0312   /**
0313    * Invalidates all group names in the collection.
0314    */
0315   void invalidateGroups();
0316   /**
0317    * Returns true if the collection contains at least one Image field.
0318    *
0319    * @return Returns true if the collection contains at least one Image field;
0320    */
0321   bool hasImages() const { return !m_imageFields.isEmpty(); }
0322 
0323   void setTrackGroups(bool b) { m_trackGroups = b; }
0324 
0325   void addBorrower(Data::BorrowerPtr borrower);
0326   const BorrowerList& borrowers() const { return m_borrowers; }
0327   /**
0328    * Clears all vectors which contain shared ptrs
0329    */
0330   void clear();
0331 
0332   void addFilter(FilterPtr filter);
0333   bool removeFilter(FilterPtr filter);
0334   const FilterList& filters() const { return m_filters; }
0335 
0336   /**
0337    * Prepare text for formatting
0338    *
0339    * Useful only for BibtexCollection to strip bibtex strings
0340    */
0341   virtual QString prepareText(const QString& text) const;
0342 
0343   /**
0344    * The string used for the people pseudo-group. This forces consistency.
0345    */
0346   static const QString s_peopleGroupName;
0347 
0348 Q_SIGNALS:
0349   void signalGroupsModified(Tellico::Data::CollPtr coll, QList<Tellico::Data::EntryGroup*> groups);
0350   void signalRefreshField(Tellico::Data::FieldPtr field);
0351   void mergeAddedField(Tellico::Data::CollPtr coll, Tellico::Data::FieldPtr field);
0352 
0353 protected:
0354   Collection(const QString& title);
0355 
0356 private:
0357   QStringList entryGroupNamesByField(EntryPtr entry, const QString& fieldName);
0358   void removeEntriesFromDicts(const EntryList& entries, const QStringList& fields);
0359   void populateDict(EntryGroupDict* dict, const QString& fieldName, const EntryList& entries);
0360   void populateCurrentDicts(const EntryList& entries, const QStringList& fields);
0361   void cleanGroups();
0362 
0363   /*
0364    * Gets the preferred ID of the collection. Currently, it just gets incremented as
0365    * new collections are created.
0366    */
0367   static int getID();
0368 
0369   Q_DISABLE_COPY(Collection)
0370 
0371   ID m_id;
0372   ID m_nextEntryId;
0373   QString m_title;
0374   QString m_defaultGroupField;
0375   QString m_lastGroupField;
0376   QString m_titleField;
0377 
0378   FieldList m_fields;
0379   FieldList m_peopleFields; // keep separate list of people fields
0380   FieldList m_imageFields; // keep track of image fields
0381   QHash<QString, Field*> m_fieldByName;
0382   QHash<QString, Field*> m_fieldByTitle;
0383   QStringList m_fieldCategories;
0384 
0385   EntryList m_entries;
0386   QHash<int, Entry*> m_entryById;
0387 
0388   QHash<QString, EntryGroupDict*> m_entryGroupDicts;
0389   QStringList m_entryGroups;
0390   QList<EntryGroup*> m_groupsToDelete;
0391 
0392   FilterList m_filters;
0393   BorrowerList m_borrowers;
0394 
0395   bool m_trackGroups;
0396 };
0397 
0398   } // end namespace
0399 } //end namespace
0400 #endif