added plugins
[semnotes:semnotes.git] / src / notemodel.cpp
1 /*
2 * This file is part of SemNotes Project.
3 *
4 * Copyright (C) 2009 - 2010 Laura Dragan <laura.dragan@deri.org>
5 *                           Pierre Ludwick <pierre.ludwick@deri.org>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB.  If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23 #include "notemodel.h"
24 #include "note.h"
25 #include <kdebug.h>
26 #include <KGlobal>
27 #include <KLocale>
28 #include <Nepomuk/Tag>
29 #include <QListIterator>
30 #include <QMap>
31 #include <QModelIndex>
32 #include <Nepomuk/Variant>
33
34 namespace SemNotes
35 {
36
37 /**
38  * \brief The NoteModel provides a model to be used with a View.
39  *
40  * \details The model does not contain the actual Note objects. It only contains a list of structures that
41  * store the information about the notes from the RDF Repository to minimize the access to the RDF
42  * Repository which is time consuming. The list is synchronized with the info from the RDF Repository
43  * - at each change of a note, it is updated in the list.
44  *
45  * The class extends the class QAbstractTableModel.
46  */
47
48 /**
49  * Creates a new model from a list of notes.
50  */
51 NoteModel::NoteModel(QList<Note> n, QObject *parent)
52         : QAbstractListModel(parent)
53 {
54     m_notes = n;
55 }
56
57 NoteModel::~NoteModel()
58 {
59 }
60
61
62 /**
63  * Returns the number of notes in the model.
64  */
65 int NoteModel::rowCount(const QModelIndex & parent) const
66 {
67     Q_UNUSED(parent);
68     return m_notes.size();
69 }
70
71 QVariant NoteModel::headerData(int section, Qt::Orientation orientation, int role) const
72 {
73     Q_UNUSED(section);
74     Q_UNUSED(role);
75     Q_UNUSED(orientation);
76     return QVariant();
77 }
78
79 /**
80  * Returns the data at the given index, for the given role.
81  */
82 QVariant NoteModel::data(const QModelIndex & index, int role) const
83 {
84     if (!index.isValid())
85         return QVariant();
86     if (index.row() >= m_notes.size())
87         return QVariant();
88     int row = index.row();
89     Note note = m_notes.at(row);
90     QVariant var;
91     switch (role) {
92     case Qt::EditRole:
93         var = QVariant(note.resourceUri().toString());
94         break;
95     case UriRole:
96         var = QVariant(note.resourceUri().toString());
97         break;
98     case TitleRole:
99         var = QVariant(note.title());
100         break;
101     case CreatedRole: {
102         QDateTime created = note.created();
103         if (created.isValid())
104             var = QVariant(created);
105         else
106             var = QVariant(QDateTime::currentDateTime().toTimeSpec(Qt::LocalTime));
107         break;
108     }
109     case LastModifiedRole: {
110         QDateTime last = note.lastModified();
111         if (last.isValid())
112             var = QVariant(last);
113         else
114             var = QVariant(QDateTime::currentDateTime().toTimeSpec(Qt::LocalTime));
115         break;
116     }
117     case RatingRole:
118         var = QVariant(note.rating());
119         break;
120     case TagRole: {
121         QStringList tagList;
122         QList<Nepomuk::Tag> tags = note.tags();
123         foreach(Nepomuk::Tag tag, tags) {
124             tagList << tag.label();
125         }
126         var = QVariant(tagList);
127         break;
128     }
129     case ContentRole:
130         var = QVariant(note.htmlContent());
131         break;
132     case WidgetRole:
133         break;
134     //testing annos
135     case AcceptedAnnosRole: {
136         QList<Nepomuk::Resource> annos = note.annotations();
137         QStringList uriList;
138         foreach(Nepomuk::Resource uri, annos)
139             uriList << uri.resourceUri().toString();
140         var = QVariant(uriList);
141         break;
142     }
143
144     case AcceptedAnnotationsRole: {
145         QList<Nepomuk::Thing> things = note.isRelated();
146         QStringList uris;
147         foreach(Nepomuk::Thing thing, things) {
148             uris << thing.resourceUri().toString();
149         }
150         var = QVariant(uris);
151         break;
152     }
153     default:
154         break;
155     }
156     return var;
157 }
158
159 Qt::ItemFlags NoteModel::flags(const QModelIndex &index) const
160 {
161     if (!index.isValid())
162         return Qt::ItemIsEnabled;
163     return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled;
164 }
165
166 //QModelIndex NoteModel::index(int row, int column, const QModelIndex &parent) const
167 //{
168 //    return createIndex(row, column);
169 //}
170
171 //QModelIndex NoteModel::parent(const QModelIndex &child) const
172 //{
173 //    return QModelIndex();
174 //}
175
176 /**
177  * Sets the data for the specified index to the given value.
178  *
179  * The value should always be the uri of a note - the data for the note is extracted from the RDF Repository.
180  */
181 bool NoteModel::setData(const QModelIndex &index, const QVariant &value, int role)
182 {
183     if (!index.isValid())
184         return false;
185     if (index.row() >= m_notes.size())
186         return false;
187     int row = index.row();
188     Note note = m_notes.at(row);
189
190     switch (role) {
191     case Qt::EditRole: {
192         QString uri = value.toString();
193         note = Note(QUrl(uri));
194         m_notes.replace(row, note);
195         break;
196     }
197     case UriRole: {
198         QString uri = value.toString();
199         note = Note(QUrl(uri));
200         m_notes.replace(row, note);
201         break;
202     }
203     case TitleRole:
204         note.setTitle(value.toString());
205         break;
206     case CreatedRole:
207         note.setCreated(QDateTime::currentDateTime().toTimeSpec(Qt::LocalTime));
208         break;
209     case LastModifiedRole:
210         note.setLastModified(QDateTime::currentDateTime().toTimeSpec(Qt::LocalTime));
211         break;
212     case RatingRole:
213         note.setRating(value.toUInt());
214         break;
215     case TagRole: {
216         QStringList tagList =  value.toStringList();
217         QList<Nepomuk::Tag> tags;
218         foreach(QString tagText, tagList) {
219             tagText = tagText.trimmed();
220             Nepomuk::Tag tag(tagText);
221             tags.append(tag);
222             tag.setLabel(tagText);
223         }
224         note.setTags(tags);
225         break;
226     }
227     case ContentRole:
228         note.setHtmlContent(value.toString());
229         break;
230
231     case AcceptedAnnoRole: {
232         note.addAnnotation(value.toString());
233         break;
234     }
235     //testing annos
236     case AcceptedAnnosRole: {
237         QStringList uriList = value.toStringList();
238         QList<Nepomuk::Resource> resources;
239         foreach(QString uri, uriList)
240         {
241             Nepomuk::Resource res(uri);
242             resources.append(res);
243         }
244         note.setAnnotations(resources);
245         break;
246     }
247     case AcceptedAnnotationsRole: {
248         QStringList uris =  value.toStringList();
249         QList<Nepomuk::Thing> things;
250         foreach(QString uri, uris) {
251             Nepomuk::Thing thing(uri);
252             things.append(thing);
253         }
254         note.setIsRelated(things);
255         break;
256     }
257     default:
258         break;
259     }
260     return true;
261 }
262
263 /**
264  * Adds \c count rows before the row \c row
265  * The data in the inserted rows is set to a non-valid note.
266  */
267 bool NoteModel::insertRows(int row, int count, const QModelIndex & parent)
268 {
269     beginInsertRows(parent, row, row + count - 1);
270     for (int i = 0; i < count; ++i) {
271         m_notes.insert(row, Note());
272     }
273     endInsertRows();
274     return true;
275 }
276
277 /**
278  * Removes \c count starting from row \c row.
279  */
280 bool NoteModel::removeRows(int row, int count, const QModelIndex & parent)
281 {
282     Q_UNUSED(parent);
283     beginRemoveRows(QModelIndex(), row, row + count - 1);
284     for (int i = 0; i < count; ++i) {
285         kDebug() << "i:" << i << " count:" << count << " row:" << row;
286         kDebug() << "before remove m_notes.size():" << m_notes.size();
287         m_notes.removeAt(row);
288         kDebug() << "after remove m_notes.size():" <<  m_notes.size();
289     }
290     endRemoveRows();
291     return true;
292 }
293
294 Note NoteModel::noteAt(QModelIndex index)
295 {
296     return m_notes.at(index.row());
297 }
298
299 QModelIndex NoteModel::indexOf(Note &note)
300 {
301     return index(m_notes.indexOf(note), 0);
302 }
303
304 }
305 #include "notemodel.moc"