You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tellico/src/collection.h

396 lines
12 KiB

/***************************************************************************
copyright : (C) 2001-2006 by Robby Stephenson
email : robby@periapsis.org
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of version 2 of the GNU General Public License as *
* published by the Free Software Foundation; *
* *
***************************************************************************/
#ifndef COLLECTION_H
#define COLLECTION_H
#include "field.h"
#include "entry.h"
#include "filter.h"
#include "borrower.h"
#include "datavectors.h"
#include <ksharedptr.h>
#include <tqstringlist.h>
#include <tqptrlist.h>
#include <tqstring.h>
#include <tqdict.h>
#include <tqintdict.h>
#include <tqobject.h>
namespace Tellico {
namespace Data {
class EntryGroup;
typedef TQDict<EntryGroup> EntryGroupDict;
/**
* The Collection class is the primary data object, holding a
* list of fields and entries.
*
* A collection holds entries of a single type, whether it be books, CDs, or whatever.
* It has a list of attributes which apply for the whole collection. A unique id value
* identifies each collection object.
*
* @see Entry
* @see Field
*
* @author Robby Stephenson
*/
class Collection : public TQObject, public TDEShared {
TQ_OBJECT
public:
enum Type {
Base = 1,
Book = 2,
Video = 3,
Album = 4,
Bibtex = 5,
ComicBook = 6,
Wine = 7,
Coin = 8,
Stamp = 9,
Card = 10,
Game = 11,
File = 12,
BoardGame = 13
// if you want to add custom collection types, use a number sure to be unique like 101
};
/**
* The constructor is only used to create custom collections. It adds a title field,
* in the "General" group. The iconName is set to be the typeName;
*
* @param title The title of the collection itself
* @param entryTitle The title of the entries, which can be translated
*/
explicit Collection(const TQString& title);
/**
*/
virtual ~Collection();
/**
* Returns the type of the collection.
*
* @return The type
*/
virtual Type type() const { return Base; }
/**
* Returns the id of the collection.
*
* @return The id
*/
long id() const { return m_id; }
/**
* Returns the name of the collection.
*
* @return The name
*/
const TQString& title() const { return m_title; }
/**
* Sets the title of the collection.
*
* @param title The new collection title
*/
void setTitle(const TQString& title) { m_title = title; }
/**
* Returns the name of the entries in the collection, e.g. "book".
* Not translated.
*
* @return The type name
*/
TQString typeName() const;
/**
* Returns a reference to the list of all the entries in the collection.
*
* @return The list of entries
*/
const EntryVec& entries() const { return m_entries; }
/**
* Returns a reference to the list of the collection attributes.
*
* @return The list of fields
*/
const FieldVec& fields() const { return m_fields; }
EntryPtr entryById(long id);
/**
* Returns a reference to the list of the collection's people fields.
*
* @return The list of fields
*/
const FieldVec& peopleFields() const { return m_peopleFields; }
/**
* Returns a reference to the list of the collection's image fields.
*
* @return The list of fields
*/
const FieldVec& imageFields() const { return m_imageFields; }
/**
* Returns a reference to the list of field groups. This value is cached rather
* than generated with each call, so the method should be fairly fast.
*
* @return The list of group names
*/
const TQStringList& fieldCategories() const { return m_fieldCategories; }
/**
* Returns the name of the field used to group the entries by default.
*
* @return The field name
*/
const TQString& defaultGroupField() const { return m_defaultGroupField; }
/**
* Sets the name of the default field used to group the entries.
*
* @param name The name of the field
*/
void setDefaultGroupField(const TQString& name) { m_defaultGroupField = name; }
/**
* Returns the number of entries in the collection.
*
* @return The number of entries
*/
size_t entryCount() const { return m_entries.count(); }
/**
* Adds a entry to the collection. The collection takes ownership of the entry object.
*
* @param entry A pointer to the entry
*/
void addEntries(EntryVec entries);
/**
* Updates the dicts that include the entry.
*
* @param entry A pointer to the entry
*/
void updateDicts(EntryVec entries);
/**
* Deletes a entry from the collection.
*
* @param entry The pointer to the entry
* @return A boolean indicating if the entry was in the collection and was deleted
*/
bool removeEntries(EntryVec entries);
/**
* Adds a whole list of attributes. It's gotta be virtual since it calls
* @ref addField, which is virtual.
*
* @param list List of attributes to add
* @return A boolean indicating if the field was added or not
*/
virtual bool addFields(FieldVec list);
/**
* Adds an field to the collection, unless an field with that name
* already exists. The collection takes ownership of the field object.
*
* @param field A pointer to the field
* @return A boolean indicating if the field was added or not
*/
virtual bool addField(FieldPtr field);
virtual bool mergeField(FieldPtr field);
virtual bool modifyField(FieldPtr field);
virtual bool removeField(FieldPtr field, bool force=false);
virtual bool removeField(const TQString& name, bool force=false);
void reorderFields(const FieldVec& list);
// the reason this is not static is so I can call it from a collection pointer
// it also gets virtualized for different collection types
// the return values should be compared against the GOOD and PERFECT
// static match constants in this class
virtual int sameEntry(Data::EntryPtr, Data::EntryPtr) const;
/**
* Determines whether or not a certain value is allowed for an field.
*
* @param key The name of the field
* @param value The desired value
* @return A boolean indicating if the value is an allowed value for that field
*/
bool isAllowed(const TQString& key, const TQString& value) const;
/**
* Returns a list of all the field names.
*
* @return The list of names
*/
const TQStringList& fieldNames() const { return m_fieldNames; }
/**
* Returns a list of all the field titles.
*
* @return The list of titles
*/
const TQStringList& fieldTitles() const { return m_fieldTitles; }
/**
* Returns the title of an field, given its name.
*
* @param name The field name
* @return The field title
*/
const TQString& fieldTitleByName(const TQString& name) const;
/**
* Returns the name of an field, given its title.
*
* @param title The field title
* @return The field name
*/
const TQString& fieldNameByTitle(const TQString& title) const;
/**
* Returns a list of the values of a given field for every entry
* in the collection. The values in the list are not repeated. Attribute
* values which contain ";" are split into separate values. Since this method
* iterates over all the entries, for large collections, it is expensive.
*
* @param name The name of the field
* @return The list of values
*/
TQStringList valuesByFieldName(const TQString& name) const;
/**
* Returns a list of all the fields in a given category.
*
* @param category The name of the category
* @return The field list
*/
FieldVec fieldsByCategory(const TQString& category);
/**
* Returns a pointer to an field given its name. If none is found, a NULL pointer
* is returned.
*
* @param name The field name
* @return The field pointer
*/
FieldPtr fieldByName(const TQString& name) const;
/**
* Returns a pointer to an field given its title. If none is found, a NULL pointer
* is returned. This lookup is slower than by name.
*
* @param title The field title
* @return The field pointer
*/
FieldPtr fieldByTitle(const TQString& title) const;
/**
* Returns @p true if the collection contains a field named @ref name;
*/
bool hasField(const TQString& name) const;
/**
* Returns a list of all the possible entry groups. This value is cached rather
* than generated with each call, so the method should be fairly fast.
*
* @return The list of groups
*/
const TQStringList& entryGroups() const { return m_entryGroups; }
/**
* Returns a pointer to a dict of all the entries grouped by
* a certain field
*
* @param name The name of the field by which the entries are grouped
* @return The list of group names
*/
EntryGroupDict* entryGroupDictByName(const TQString& name);
/**
* Invalidates all group names in the collection.
*/
void invalidateGroups();
/**
* Returns true if the collection contains at least one Image field.
*
* @return Returns true if the collection contains at least one Image field;
*/
bool hasImages() const { return !m_imageFields.isEmpty(); }
void setTrackGroups(bool b) { m_trackGroups = b; }
void addBorrower(Data::BorrowerPtr borrower);
const BorrowerVec& borrowers() const { return m_borrowers; }
/**
* Clears all vectors which contain shared ptrs
*/
void clear();
void addFilter(FilterPtr filter);
bool removeFilter(FilterPtr filter);
const FilterVec& filters() const { return m_filters; }
static bool mergeEntry(EntryPtr entry1, EntryPtr entry2, bool overwrite, bool askUser=false);
/**
* The string used for empty values. This forces consistency.
*/
static const char* s_emptyGroupTitle;
/**
* The string used for the people pseudo-group. This forces consistency.
*/
static const TQString s_peopleGroupName;
// these are the values that should be compared against
// the result from sameEntry()
static const int ENTRY_GOOD_MATCH = 10;
static const int ENTRY_PERFECT_MATCH = 20;
signals:
void signalGroupsModified(Tellico::Data::CollPtr coll, PtrVector<Tellico::Data::EntryGroup> groups);
void signalRefreshField(Tellico::Data::FieldPtr field);
private:
TQStringList entryGroupNamesByField(EntryPtr entry, const TQString& fieldName);
void removeEntriesFromDicts(EntryVec entries);
void populateDict(EntryGroupDict* dict, const TQString& fieldName, EntryVec entries);
void populateCurrentDicts(EntryVec entries);
void cleanGroups();
bool dependentFieldHasRecursion(FieldPtr field);
/*
* Gets the preferred ID of the collection. Currently, it just gets incremented as
* new collections are created.
*/
static long getID();
/**
* The copy constructor is private, to ensure that it's never used.
*/
Collection(const Collection& coll);
/**
* The assignment operator is private, to ensure that it's never used.
*/
Collection operator=(const Collection& coll);
long m_id;
long m_nextEntryId;
TQString m_title;
TQString m_typeName;
TQString m_iconName;
TQString m_defaultGroupField;
FieldVec m_fields;
FieldVec m_peopleFields; // keep separate list of people fields
FieldVec m_imageFields; // keep track of image fields
TQDict<Field> m_fieldNameDict;
TQDict<Field> m_fieldTitleDict;
TQStringList m_fieldCategories;
TQStringList m_fieldNames;
TQStringList m_fieldTitles;
EntryVec m_entries;
TQIntDict<Entry> m_entryIdDict;
TQDict<EntryGroupDict> m_entryGroupDicts;
TQStringList m_entryGroups;
PtrVector<EntryGroup> m_groupsToDelete;
FilterVec m_filters;
BorrowerVec m_borrowers;
bool m_trackGroups : 1;
};
} // end namespace
} //end namespace
#endif