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"
25 #include <kbookmarkmanager.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
38 Private(const KBookmark
& root
)
41 mRootItem
= new TreeItem(root
, 0);
54 KBookmarkModel::KBookmarkModel(const KBookmark
& root
)
55 : QAbstractItemModel(), d(new Private(root
))
59 void KBookmarkModel::setRoot(const KBookmark
& root
)
64 KBookmarkModel::~KBookmarkModel()
69 void KBookmarkModel::resetModel()
72 d
->mRootItem
= new TreeItem(d
->mRoot
, 0);
76 QVariant
KBookmarkModel::data(const QModelIndex
&index
, int role
) const
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") );
90 switch( index
.column() )
93 return QVariant( bk
.fullText() );
95 return QVariant( bk
.url().pathOrUrl() );
97 QDomNode subnode
= bk
.internalElement().namedItem("desc");
98 return (subnode
.firstChild().isNull())
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
);
108 return QVariant( text1
+ " -- " + text2
);
111 return QVariant( QString() ); //can't happen
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());
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
140 if(index
.column() == 0 || index
.column() == 2)
141 return Qt::ItemIsEnabled
| Qt::ItemIsSelectable
| Qt::ItemIsEditable
| Qt::ItemIsDragEnabled
| Qt::ItemIsDropEnabled
;
144 if(index
.column() < 3)
145 return Qt::ItemIsEnabled
| Qt::ItemIsSelectable
| Qt::ItemIsEditable
| Qt::ItemIsDragEnabled
| Qt::ItemIsDropEnabled
;
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()));
162 QVariant
KBookmarkModel::headerData(int section
, Qt::Orientation orientation
, int role
) const
164 if(role
== Qt::DisplayRole
&& orientation
== Qt::Horizontal
)
169 return i18n("Bookmark");
173 return i18n("Comment");
175 return i18n("Status");
177 return QString(); // Can't happpen
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
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
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
228 return static_cast<TreeItem
*>(parent
.internalPointer())->childCount();
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
);
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
)
289 //FIXME this only works for internal drag and drops
290 //FIXME Moving is *very* buggy
296 idx
= index(row
, column
, parent
);
298 KBookmark bk
= bookmarkForIndex(idx
);
299 QString addr
= bk
.address();
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
);
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
340 KBookmark
KBookmarkModel::bookmarkForIndex(const QModelIndex
& index
) const
342 return static_cast<TreeItem
*>(index
.internalPointer())->bookmark();
345 #include "bookmarkmodel.moc"