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_COLLECTION_H 26 #define TELLICO_COLLECTION_H 27 28 #include "field.h" 29 #include "entry.h" 30 #include "filter.h" 31 #include "borrower.h" 32 #include "datavectors.h" 33 34 #include <QStringList> 35 #include <QHash> 36 #include <QObject> 37 38 namespace Tellico { 39 namespace Data { 40 class EntryGroup; 41 typedef QHash<QString, EntryGroup*> EntryGroupDict; 42 43 /** 44 * The Collection class is the primary data object, holding a 45 * list of fields and entries. 46 * 47 * A collection holds entries of a single type, whether it be books, CDs, or whatever. 48 * It has a list of attributes which apply for the whole collection. A unique id value 49 * identifies each collection object. 50 * 51 * @see Entry 52 * @see Field 53 * 54 * @author Robby Stephenson 55 */ 56 class Collection : public QObject, public QSharedData { 57 Q_OBJECT 58 59 public: 60 enum Type { 61 Base = 1, 62 Book = 2, 63 Video = 3, 64 Album = 4, 65 Bibtex = 5, 66 ComicBook = 6, 67 Wine = 7, 68 Coin = 8, 69 Stamp = 9, 70 Card = 10, 71 Game = 11, 72 File = 12, 73 BoardGame = 13 74 // if you want to add custom collection types, use a number sure to be unique like 101 75 // don't forget to update macros in core/tellico_config_addons.cpp 76 }; 77 78 /** 79 * The constructor is only used to create custom collections. 80 * 81 * @param addDefaultFields whether to add default fields or not 82 * @param title The title of the collection itself 83 */ 84 explicit Collection(bool addDefaultFields, const QString& title=QString()); 85 /** 86 */ 87 virtual ~Collection(); 88 89 /** 90 * Returns the type of the collection. 91 * 92 * @return The type 93 */ type()94 virtual Type type() const { return Base; } 95 /** 96 * Returns the id of the collection. 97 * 98 * @return The id 99 */ id()100 ID id() const { return m_id; } 101 /** 102 * Returns the name of the collection. 103 * 104 * @return The name 105 */ title()106 const QString& title() const { return m_title; } 107 /** 108 * Sets the title of the collection. 109 * 110 * @param title The new collection title 111 */ setTitle(const QString & title)112 void setTitle(const QString& title) { m_title = title; } 113 /** 114 * Returns a reference to the list of all the entries in the collection. 115 * 116 * @return The list of entries 117 */ entries()118 const EntryList& entries() const { return m_entries; } 119 /** 120 * Returns a reference to the list of the collection attributes. 121 * 122 * @return The list of fields 123 */ fields()124 const FieldList& fields() const { return m_fields; } 125 EntryPtr entryById(ID id); 126 /** 127 * Returns a reference to the list of the collection's people fields. 128 * 129 * @return The list of fields 130 */ peopleFields()131 const FieldList& peopleFields() const { return m_peopleFields; } 132 /** 133 * Returns a reference to the list of the collection's image fields. 134 * 135 * @return The list of fields 136 */ imageFields()137 const FieldList& imageFields() const { return m_imageFields; } 138 /** 139 * Return the primary image field, which is used for icons for the entry. 140 * By default, the first image field is returned. 141 * 142 * @return The primary image field 143 */ 144 FieldPtr primaryImageField() const; 145 /** 146 * Returns a reference to the list of field groups. This value is cached rather 147 * than generated with each call, so the method should be fairly fast. 148 * 149 * @return The list of group names 150 */ fieldCategories()151 const QStringList& fieldCategories() const { return m_fieldCategories; } 152 /** 153 * Returns the name of the field used to group the entries by default. 154 * 155 * @return The field name 156 */ defaultGroupField()157 const QString& defaultGroupField() const { return m_defaultGroupField; } 158 /** 159 * Sets the name of the default field used to group the entries. 160 * 161 * @param name The name of the field 162 */ setDefaultGroupField(const QString & name)163 void setDefaultGroupField(const QString& name) { m_defaultGroupField = name; } 164 /** 165 * Returns the number of entries in the collection. 166 * 167 * @return The number of entries 168 */ entryCount()169 int entryCount() const { return m_entries.count(); } 170 /** 171 * Adds a entry to the collection. The collection takes ownership of the entry object. 172 * 173 * @param entry A pointer to the entry 174 */ 175 void addEntries(const EntryList& entries); addEntries(EntryPtr entry)176 void addEntries(EntryPtr entry) { addEntries(EntryList() << entry); } 177 /** 178 * Updates the dicts that include the entry. 179 * 180 * @param entry A pointer to the entry 181 */ 182 void updateDicts(const EntryList& entries, const QStringList& fields); 183 /** 184 * Deletes a entry from the collection. 185 * 186 * @param entry The pointer to the entry 187 * @return A boolean indicating if the entry was in the collection and was deleted 188 */ 189 bool removeEntries(const EntryList& entries); entryIdList()190 QList<int> entryIdList() const { return m_entryById.keys(); } 191 /** 192 * Adds a whole list of fields. It calls 193 * @ref addField, which is virtual. 194 * 195 * @param list List of fields to add 196 * @return A boolean indicating if the fields were successfully added or not 197 */ 198 bool addFields(FieldList list); 199 /** 200 * Adds an field to the collection, unless an field with that name 201 * already exists. The collection takes ownership of the field object. 202 * 203 * @param field A pointer to the field 204 * @return A boolean indicating if the field was added or not 205 */ 206 virtual bool addField(FieldPtr field); 207 virtual bool mergeField(FieldPtr field); 208 virtual bool modifyField(FieldPtr field); 209 virtual bool removeField(FieldPtr field, bool force=false); 210 virtual bool removeField(const QString& name, bool force=false); 211 void reorderFields(const FieldList& list); 212 213 // the reason this is not static is so I can call it from a collection pointer 214 // it also gets overridden for different collection types 215 // the return values should be compared against the GOOD and PERFECT 216 // static match constants 217 virtual int sameEntry(Data::EntryPtr, Data::EntryPtr) const; 218 219 /** 220 * Determines whether or not a certain value is allowed for an field. 221 * 222 * @param field The name of the field 223 * @param value The desired value 224 * @return A boolean indicating if the value is an allowed value for that field 225 */ 226 bool isAllowed(const QString& field, const QString& value) const; 227 /** 228 * Returns a list of all the field names. 229 * 230 * @return The list of names 231 */ 232 QStringList fieldNames() const; 233 /** 234 * Returns a list of all the field titles. 235 * 236 * @return The list of titles 237 */ 238 QStringList fieldTitles() const; 239 /** 240 * Returns the title of an field, given its name. 241 * 242 * @param name The field name 243 * @return The field title 244 */ 245 QString fieldTitleByName(const QString& name) const; 246 /** 247 * Returns the name of an field, given its title. 248 * 249 * @param title The field title 250 * @return The field name 251 */ 252 QString fieldNameByTitle(const QString& title) const; 253 /** 254 * Returns a list of the values of a given field for every entry 255 * in the collection. The values in the list are not repeated. Attribute 256 * values which contain ";" are split into separate values. Since this method 257 * iterates over all the entries, for large collections, it is expensive. 258 * 259 * @param name The name of the field 260 * @return The list of values 261 */ 262 QStringList valuesByFieldName(const QString& name) const; 263 /** 264 * Returns a list of all the fields in a given category. 265 * 266 * @param category The name of the category 267 * @return The field list 268 */ 269 FieldList fieldsByCategory(const QString& category); 270 /** 271 * Returns a pointer to an field given its name. If none is found, a NULL pointer 272 * is returned. 273 * 274 * @param name The field name 275 * @return The field pointer 276 */ 277 FieldPtr fieldByName(const QString& name) const; 278 /** 279 * Returns a pointer to an field given its title. If none is found, a NULL pointer 280 * is returned. This lookup is slower than by name. 281 * 282 * @param title The field title 283 * @return The field pointer 284 */ 285 FieldPtr fieldByTitle(const QString& title) const; 286 /** 287 * Returns @p true if the collection contains a field named @ref name; 288 */ 289 bool hasField(const QString& name) const; 290 /** 291 * Returns a list of all the possible entry groups. This value is cached rather 292 * than generated with each call, so the method should be fairly fast. 293 * 294 * @return The list of groups 295 */ entryGroups()296 const QStringList& entryGroups() const { return m_entryGroups; } 297 /** 298 * Returns a pointer to a dict of all the entries grouped by 299 * a certain field 300 * 301 * @param name The name of the field by which the entries are grouped 302 * @return The list of group names 303 */ 304 EntryGroupDict* entryGroupDictByName(const QString& name); 305 /** 306 * Invalidates all group names in the collection. 307 */ 308 void invalidateGroups(); 309 /** 310 * Returns true if the collection contains at least one Image field. 311 * 312 * @return Returns true if the collection contains at least one Image field; 313 */ hasImages()314 bool hasImages() const { return !m_imageFields.isEmpty(); } 315 setTrackGroups(bool b)316 void setTrackGroups(bool b) { m_trackGroups = b; } 317 318 void addBorrower(Data::BorrowerPtr borrower); borrowers()319 const BorrowerList& borrowers() const { return m_borrowers; } 320 /** 321 * Clears all vectors which contain shared ptrs 322 */ 323 void clear(); 324 325 void addFilter(FilterPtr filter); 326 bool removeFilter(FilterPtr filter); filters()327 const FilterList& filters() const { return m_filters; } 328 329 /** 330 * Prepare text for formatting 331 * 332 * Useful only for BibtexCollection to strip bibtex strings 333 */ 334 virtual QString prepareText(const QString& text) const; 335 336 /** 337 * The string used for the people pseudo-group. This forces consistency. 338 */ 339 static const QString s_peopleGroupName; 340 341 Q_SIGNALS: 342 void signalGroupsModified(Tellico::Data::CollPtr coll, QList<Tellico::Data::EntryGroup*> groups); 343 void signalRefreshField(Tellico::Data::FieldPtr field); 344 void mergeAddedField(Tellico::Data::CollPtr coll, Tellico::Data::FieldPtr field); 345 346 protected: 347 Collection(const QString& title); 348 349 private: 350 QStringList entryGroupNamesByField(EntryPtr entry, const QString& fieldName); 351 void removeEntriesFromDicts(const EntryList& entries, const QStringList& fields); 352 void populateDict(EntryGroupDict* dict, const QString& fieldName, const EntryList& entries); 353 void populateCurrentDicts(const EntryList& entries, const QStringList& fields); 354 void cleanGroups(); 355 356 /* 357 * Gets the preferred ID of the collection. Currently, it just gets incremented as 358 * new collections are created. 359 */ 360 static int getID(); 361 362 Q_DISABLE_COPY(Collection) 363 364 ID m_id; 365 ID m_nextEntryId; 366 QString m_title; 367 QString m_defaultGroupField; 368 QString m_lastGroupField; 369 370 FieldList m_fields; 371 FieldList m_peopleFields; // keep separate list of people fields 372 FieldList m_imageFields; // keep track of image fields 373 QHash<QString, Field*> m_fieldByName; 374 QHash<QString, Field*> m_fieldByTitle; 375 QStringList m_fieldCategories; 376 377 EntryList m_entries; 378 QHash<int, Entry*> m_entryById; 379 380 QHash<QString, EntryGroupDict*> m_entryGroupDicts; 381 QStringList m_entryGroups; 382 QList<EntryGroup*> m_groupsToDelete; 383 384 FilterList m_filters; 385 BorrowerList m_borrowers; 386 387 bool m_trackGroups; 388 }; 389 390 } // end namespace 391 } //end namespace 392 #endif 393