Fix crash if key bindings specified in profile cannot be found. Improve
[personal-kdebase.git] / apps / keditbookmarks / bookmarkmodel.cpp
blob103df1b30c630f0a483b7591a81c1ec27379e14a
1 /* This file is part of the KDE project
2 Copyright (C) 2005 Daniel Teske <teske@squorn.de>
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public
6 License version 2 or at your option version 3 as published by
7 the Free Software Foundation.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; see the file COPYING. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
20 #include "bookmarkmodel.h"
21 #include "treeitem_p.h"
22 #include "toplevel.h"
23 #include "commands.h"
25 #include <kbookmarkmanager.h>
26 #include <KIcon>
27 #include <kdebug.h>
28 #include <klocale.h>
29 #include <QtGui/QIcon>
30 #include <QtCore/QVector>
31 #include <QtGui/QPixmap>
32 #include <QtCore/QStringList>
33 #include <QtCore/QMimeData>
35 class KBookmarkModel::Private
37 public:
38 Private(const KBookmark& root)
39 : mRoot(root)
41 mRootItem = new TreeItem(root, 0);
43 ~Private()
45 delete mRootItem;
47 //TESTING
48 mRootItem = 0;
50 TreeItem * mRootItem;
51 KBookmark mRoot;
54 KBookmarkModel::KBookmarkModel(const KBookmark& root)
55 : QAbstractItemModel(), d(new Private(root))
59 void KBookmarkModel::setRoot(const KBookmark& root)
61 d->mRoot = root;
62 resetModel();
64 KBookmarkModel::~KBookmarkModel()
66 delete d;
69 void KBookmarkModel::resetModel()
71 delete d->mRootItem;
72 d->mRootItem = new TreeItem(d->mRoot, 0);
73 reset();
76 QVariant KBookmarkModel::data(const QModelIndex &index, int role) const
78 //Text
79 if(index.isValid() && (role == Qt::DisplayRole || role == Qt::EditRole))
81 KBookmark bk = bookmarkForIndex(index);
82 if(bk.address().isEmpty())
84 if(index.column() == 0)
85 return QVariant( i18n("Bookmarks") );
86 else
87 return QVariant();
90 switch( index.column() )
92 case 0:
93 return QVariant( bk.fullText() );
94 case 1:
95 return QVariant( bk.url().pathOrUrl() );
96 case 2: {
97 QDomNode subnode = bk.internalElement().namedItem("desc");
98 return (subnode.firstChild().isNull())
99 ? QString()
100 : subnode.firstChild().toText().data();
102 case 3: { //Status column
103 QString text1 = ""; //FIXME favicon state
104 QString text2 = ""; //FIXME link state
105 if(text1.isNull() || text2.isNull())
106 return QVariant( text1 + text2);
107 else
108 return QVariant( text1 + " -- " + text2);
110 default:
111 return QVariant( QString() ); //can't happen
115 //Icon
116 if(index.isValid() && role == Qt::DecorationRole && index.column() == 0)
118 KBookmark bk = bookmarkForIndex(index);
119 if(bk.address().isEmpty())
120 return KIcon("bookmarks");
121 return KIcon(bk.icon());
123 return QVariant();
126 //FIXME QModelIndex KBookmarkModel::buddy(const QModelIndex & index) //return parent for empty folder padders
127 // no empty folder padders atm
130 Qt::ItemFlags KBookmarkModel::flags(const QModelIndex &index) const
132 if (!index.isValid())
133 return Qt::ItemIsDropEnabled;
135 KBookmark bk = bookmarkForIndex(index);
136 if( !bk.address().isEmpty() ) // non root
138 if( bk.isGroup())
140 if(index.column() == 0 || index.column() == 2)
141 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
143 else
144 if(index.column() < 3)
145 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
148 // root
149 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
152 bool KBookmarkModel::setData(const QModelIndex &index, const QVariant &value, int role)
154 if(index.isValid() && role == Qt::EditRole)
156 CmdHistory::self()->addCommand(new EditCommand(bookmarkForIndex(index).address(), index.column(), value.toString()));
157 return true;
159 return false;
162 QVariant KBookmarkModel::headerData(int section, Qt::Orientation orientation, int role) const
164 if(role == Qt::DisplayRole && orientation == Qt::Horizontal)
166 switch(section)
168 case 0:
169 return i18n("Bookmark");
170 case 1:
171 return i18n("URL");
172 case 2:
173 return i18n("Comment");
174 case 3:
175 return i18n("Status");
176 default:
177 return QString(); // Can't happpen
180 else
181 return QVariant();
184 QModelIndex KBookmarkModel::index(int row, int column, const QModelIndex &parent) const
186 if( ! parent.isValid())
187 return createIndex(row, column, d->mRootItem);
189 TreeItem * item = static_cast<TreeItem *>(parent.internalPointer());
190 if(row == item->childCount()) {// Received drop below last row, simulate drop on last row
191 return createIndex(row-1, column, item->child(row-1));
194 return createIndex(row, column, item->child(row));
199 QModelIndex KBookmarkModel::parent(const QModelIndex &index) const
201 if(!index.isValid())
203 // qt asks for the parent of an invalid parent
204 // either we are in a inconsistent case or more likely
205 // we are dragging and dropping and qt didn't check
206 // what itemAt() returned
207 return index;
210 KBookmark bk = bookmarkForIndex(index);;
211 const QString rootAddress = d->mRoot.address();
213 if(bk.address() == rootAddress)
214 return QModelIndex();
216 KBookmarkGroup parent = bk.parentGroup();
217 TreeItem * item = static_cast<TreeItem *>(index.internalPointer());
218 if(parent.address() != rootAddress)
219 // TODO replace first argument with parent.positionInParent()
220 return createIndex( KBookmark::positionInParent(parent.address()) , 0, item->parent());
221 else //parent is root
222 return createIndex( 0, 0, item->parent());
225 int KBookmarkModel::rowCount(const QModelIndex &parent) const
227 if(parent.isValid())
228 return static_cast<TreeItem *>(parent.internalPointer())->childCount();
229 else //root case
231 return 1; // Only one child: "Bookmarks"
235 int KBookmarkModel::columnCount(const QModelIndex &) const
237 return 4; // Name, URL, Comment and Status
240 QModelIndex KBookmarkModel::indexForBookmark(const KBookmark& bk) const
242 return createIndex(KBookmark::positionInParent(bk.address()) , 0, d->mRootItem->treeItemForBookmark(bk));
245 void KBookmarkModel::emitDataChanged(const KBookmark& bk)
247 QModelIndex idx = indexForBookmark(bk);
248 emit dataChanged(idx, idx.sibling(idx.row(), columnCount(QModelIndex())-1) );
251 QMimeData * KBookmarkModel::mimeData( const QModelIndexList & indexes ) const
253 QMimeData *mimeData = new QMimeData;
254 KBookmark::List bookmarks;
255 QByteArray addresses;
257 QModelIndexList::const_iterator it, end;
258 end = indexes.constEnd();
259 for( it = indexes.constBegin(); it!= end; ++it)
260 if( it->column() == 0)
262 bookmarks.push_back( bookmarkForIndex(*it) );
263 if(!addresses.isEmpty())
264 addresses.append(";");
265 addresses.append( bookmarkForIndex(*it).address().toLatin1() );
266 kDebug()<<"appended"<<bookmarkForIndex(*it).address().toLatin1();
269 bookmarks.populateMimeData(mimeData);
270 mimeData->setData( "application/x-keditbookmarks", addresses);
271 return mimeData;
274 Qt::DropActions KBookmarkModel::supportedDropActions () const
276 //FIXME check if that actually works
277 return Qt::CopyAction | Qt::MoveAction;
280 QStringList KBookmarkModel::mimeTypes () const
282 return KBookmark::List::mimeDataTypes();
285 bool KBookmarkModel::dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent)
287 Q_UNUSED(action)
289 //FIXME this only works for internal drag and drops
290 //FIXME Moving is *very* buggy
292 QModelIndex idx;
293 if(row == -1)
294 idx = parent;
295 else
296 idx = index(row, column, parent);
298 KBookmark bk = bookmarkForIndex(idx);
299 QString addr = bk.address();
300 if(bk.isGroup())
301 addr += "/0";
303 if(action == Qt::CopyAction)
305 KEBMacroCommand * cmd = CmdGen::insertMimeSource("Copy", data, addr);
306 CmdHistory::self()->didCommand(cmd);
308 else if(action == Qt::MoveAction)
310 KBookmark::List bookmarks;
311 if(data->hasFormat("application/x-keditbookmarks"))
313 QList<QByteArray> addresses = data->data("application/x-keditbookmarks").split(';');
314 QList<QByteArray>::const_iterator it, end;
315 end = addresses.constEnd();
316 for(it = addresses.constBegin(); it != end; ++it)
318 KBookmark bk = CurrentMgr::self()->mgr()->findByAddress(QString::fromLatin1(*it));
319 kDebug()<<"Extracted bookmark xxx to list: "<<bk.address();
320 bookmarks.push_back(bk);
323 KEBMacroCommand * cmd = CmdGen::itemsMoved(bookmarks, addr, false);
324 CmdHistory::self()->didCommand(cmd);
326 else
328 kDebug()<<"NO FORMAT";
329 bookmarks = KBookmark::List::fromMimeData(data);
330 KEBMacroCommand * cmd = CmdGen::insertMimeSource("Copy", data, addr);
331 CmdHistory::self()->didCommand(cmd);
335 //FIXME drag and drop implementation
337 return true;
340 KBookmark KBookmarkModel::bookmarkForIndex(const QModelIndex& index) const
342 return static_cast<TreeItem *>(index.internalPointer())->bookmark();
345 #include "bookmarkmodel.moc"