summaryrefslogtreecommitdiffstats
path: root/src/entry.h
blob: de1ba661accc9efd391406823438445a3b6c7851 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
/***************************************************************************
    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 TELLICO_ENTRY_H
#define TELLICO_ENTRY_H

#include "datavectors.h"

#include <tqstringlist.h>
#include <tqstring.h>
#include <tqobject.h>

#include <functional>

namespace Tellico {
  namespace Data {
    class Collection;

/**
 * The EntryGroup is simply a vector of entries which knows the name of its group,
 * and the name of the field to which that group belongs.
 *
 * An example for a book collection would be a group of books, all written by
 * David Weber. The @ref groupName() would be "Weber, David" and the
 * @ref fieldName() would be "author".
 *
 * It's a TQObject because EntryGroupItem holds a TQGuardedPtr
 *
 * @author Robby Stephenson
 */
class EntryGroup : public TQObject, public EntryVec {
Q_OBJECT
  

public:
  EntryGroup(const TQString& group, const TQString& field);
  ~EntryGroup();

  const TQString& groupName() const { return m_group; }
  const TQString& fieldName() const { return m_field; }

private:
  TQString m_group;
  TQString m_field;
};

/**
 * The Entry class represents a book, a CD, or whatever is the basic entity
 * in the collection.
 *
 * Each Entry object has a set of field values, such as title, artist, or format,
 * and must belong to a collection. A unique id number identifies each entry.
 *
 * @see Field
 *
 * @author Robby Stephenson
 */
class Entry : public TDEShared {

public:
  /**
   * The constructor, which automatically sets the id to the current number
   * of entries in the collection.
   *
   * @param coll A pointer to the parent collection object
   */
  Entry(CollPtr coll);
  Entry(CollPtr coll, int id);
  /**
   * The copy constructor, needed since the id must be different.
   */
  Entry(const Entry& entry);
  /**
   * The assignment operator is overloaded, since the id must be different.
   */
  Entry& operator=(const Entry& other);

  ~Entry();

  /**
   * Every entry has a title.
   *
   * @return The entry title
   */
  TQString title() const;
  /**
   * Returns the value of the field with a given key name. If the key doesn't
   * exist, the method returns @ref TQString().
   *
   * @param fieldName The field name
   * @param formatted Whether to format the field or not.
   * @return The value of the field
   */
  TQString field(const TQString& fieldName, bool formatted=false) const;
  TQString field(Data::FieldPtr field, bool formatted=false) const;
  /**
   * Returns the formatted value of the field with a given key name. If the
   * key doesn't exist, the method returns @ref TQString(). The value is cached,
   * so the first time the value is requested, @ref Field::format is called.
   * The second time, that lookup isn't necessary.
   *
   * @param fieldName The field name
   * @return The formatted value of the field
   */
  TQString formattedField(const TQString& fieldName) const;
  TQString formattedField(Data::FieldPtr field) const;
  /**
   * Splits a field value. This is faster than calling Data::Field::split() since
   * a regexp is not used, only a string.
   *
   * @param field The field name
   * @param format Whether to format the values or not
   * @return The list of field values
   */
  TQStringList fields(const TQString& fieldName, bool formatted) const;
  TQStringList fields(Data::FieldPtr field, bool formatted) const;
  /**
   * Sets the value of an field for the entry. The method first verifies that
   * the value is allowed for that particular key.
   *
   * @param fieldName The name of the field
   * @param value The value of the field
   * @return A boolean indicating whether or not the field was successfully set
   */
  bool setField(const TQString& fieldName, const TQString& value);
  bool setField(Data::FieldPtr field, const TQString& value);
  /**
   * Returns a pointer to the parent collection of the entry.
   *
   * @return The collection pointer
   */
  CollPtr collection() const;
  /**
   * Changes the collection owner of the entry
   */
  void setCollection(CollPtr coll);
  /**
   * Returns the id of the entry
   *
   * @return The id
   */
  long id() const { return m_id; }
  void setId(long id) { m_id = id; }
  /**
   * Adds the entry to a group. The group list within the entry is updated
   * and the entry is added to the group.
   *
   * @param group The group
   * @return a bool indicating if it was successfully added. If the entry was already
   * in the group, the return value is false
   */
  bool addToGroup(EntryGroup* group);
  /**
   * Removes the entry from a group. The group list within the entry is updated
   * and the entry is removed from the group.
   *
   * @param group The group
   * @return a bool indicating if the group was successfully removed
   */
  bool removeFromGroup(EntryGroup* group);
  void clearGroups();
  /**
   * Returns a list of the groups to which the entry belongs
   *
   * @return The list of groups
   */
  const PtrVector<EntryGroup>& groups() const { return m_groups; }
  /**
   * Returns a list containing the names of the groups for
   * a certain field to which the entry belongs
   *
   * @param fieldName The name of the field
   * @return The list of names
   */
  TQStringList groupNamesByFieldName(const TQString& fieldName) const;
  /**
   * Returns a list of all the field values contained in the entry.
   *
   * @return The list of field values
   */
  TQStringList fieldValues() const { return m_fields.values(); }
  /**
   * Returns a list of all the formatted field values contained in the entry.
   *
   * @return The list of field values
   */
  TQStringList formattedFieldValues() const { return m_formattedFields.values(); }
  /**
   * Returns a boolean indicating if the entry's parent collection recognizes
   * it existence, that is, the parent collection has this entry in its list.
   *
   * @return Whether the entry is owned or not
   */
  bool isOwned();
  /**
   * Removes the formatted value of the field from the map. This should be used when
   * the field's format flag has changed.
   *
   * @param name The name of the field that changed. TQString() means invalidate all fields.
   */
  void invalidateFormattedFieldValue(const TQString& name=TQString());

  static int compareValues(EntryPtr entry1, EntryPtr entry2, FieldPtr field);
  static int compareValues(EntryPtr entry1, EntryPtr entry2, const TQString& field, ConstCollPtr coll);

  /**
   * Construct the derived valued for an field. The format string should be
   * of the form "%{name1} %{name2}" where the names are replaced by the value
   * of that field for the entry. Whether or not formatting is done on the
   * strings themselves should be taken into account.
   *
   * @param formatString The format string
   * @param formatted Whether the inserted values should be formatted.
   * @return The constructed field value
   */
  static TQString dependentValue(ConstEntryPtr e, const TQString& formatString, bool formatted);

private:
  /**
   * two entries are equal if all their field values are equal, except for
   * file catalogs which match on the url only
   */
  bool operator==(const Entry& other);

  CollPtr m_coll;
  long m_id;
  StringMap m_fields;
  mutable StringMap m_formattedFields;
  PtrVector<EntryGroup> m_groups;
};

class EntryCmp : public std::binary_function<EntryPtr, EntryPtr, bool> {

public:
  EntryCmp(const TQString& field) : m_field(field) {}

  bool operator()(EntryPtr e1, EntryPtr e2) const {
    return e1->field(m_field) < e2->field(m_field);
  }

private:
  TQString m_field;
};

  } // end namespace
} // end namespace

#endif