1
// -*- c-basic-offset:4; indent-tabs-mode:nil -*-
2
// vim: set ts=4 sts=4 sw=4 et:
3
/* This file is part of the KDE project
4
Copyright (C) 1999 Kurt Granroth <granroth@kde.org>
5
Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
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.
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.
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.
23
#include "konqbookmarkbar.h"
25
#include <QApplication>
33
#include <kactionmenu.h>
38
#include <kconfiggroup.h>
40
#include "konqbookmarkmenu.h"
41
#include "kbookmarkimporter.h"
42
#include "kbookmarkdombuilder.h"
46
class KBookmarkBarPrivate
49
QList<KAction *> m_actions;
51
QList<int> widgetPositions; //right edge, bottom edge
53
bool m_filteredToolbar;
56
KBookmarkBarPrivate() :
59
// see KBookmarkSettings::readSettings in kio
60
KConfig config("kbookmarkrc", KConfig::NoGlobals);
61
KConfigGroup cg(&config, "Bookmarks");
62
m_filteredToolbar = cg.readEntry( "FilteredToolbar", false );
63
m_contextMenu = cg.readEntry( "ContextMenuActions", true );
68
KBookmarkBar::KBookmarkBar( KBookmarkManager* mgr,
69
KonqBookmarkOwner *_owner, KToolBar *_toolBar,
71
: QObject( parent ), m_pOwner(_owner), m_toolBar(_toolBar),
72
m_pManager( mgr ), d( new KBookmarkBarPrivate )
74
m_toolBar->setAcceptDrops( true );
75
m_toolBar->installEventFilter( this ); // for drops
79
m_toolBar->setContextMenuPolicy(Qt::CustomContextMenu);
80
connect(m_toolBar, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(contextMenu(const QPoint &)));
83
connect( mgr, SIGNAL( changed(const QString &, const QString &) ),
84
SLOT( slotBookmarksChanged(const QString &) ) );
85
connect( mgr, SIGNAL( configChanged() ),
86
SLOT( slotConfigChanged() ) );
88
KBookmarkGroup toolbar = getToolbar();
89
fillBookmarkBar( toolbar );
90
m_toolBarSeparator = new QAction(this);
93
QString KBookmarkBar::parentAddress()
95
if(d->m_filteredToolbar)
98
return m_pManager->toolbar().address();
102
KBookmarkGroup KBookmarkBar::getToolbar()
104
if(d->m_filteredToolbar)
105
return m_pManager->root();
107
return m_pManager->toolbar();
110
KBookmarkBar::~KBookmarkBar()
113
qDeleteAll( d->m_actions );
114
qDeleteAll( m_lstSubMenus );
118
void KBookmarkBar::clear()
122
qDeleteAll(d->m_actions);
123
d->m_actions.clear();
124
qDeleteAll( m_lstSubMenus );
125
m_lstSubMenus.clear();
128
void KBookmarkBar::slotBookmarksChanged( const QString & group )
130
KBookmarkGroup tb = getToolbar(); // heavy for non cached toolbar version
131
kDebug(7043) << "KBookmarkBar::slotBookmarksChanged( " << group << " )";
136
if( d->m_filteredToolbar )
139
fillBookmarkBar( tb );
141
else if ( KBookmark::commonParent(group, tb.address()) == group) // Is group a parent of tb.address?
144
fillBookmarkBar( tb );
148
// Iterate recursively into child menus
149
for ( QList<KBookmarkMenu *>::ConstIterator smit = m_lstSubMenus.constBegin(), smend = m_lstSubMenus.constEnd();
150
smit != smend; ++smit )
152
(*smit)->slotBookmarksChanged( group );
157
void KBookmarkBar::slotConfigChanged()
159
KConfig config("kbookmarkrc", KConfig::NoGlobals);
160
KConfigGroup cg(&config, "Bookmarks");
161
d->m_filteredToolbar = cg.readEntry( "FilteredToolbar", false );
162
d->m_contextMenu = cg.readEntry( "ContextMenuActions", true );
164
fillBookmarkBar(getToolbar());
167
void KBookmarkBar::fillBookmarkBar(const KBookmarkGroup & parent)
172
for (KBookmark bm = parent.first(); !bm.isNull(); bm = parent.next(bm))
174
// Filtered special cases
175
if(d->m_filteredToolbar)
177
if(bm.isGroup() && !bm.showInToolbar() )
178
fillBookmarkBar(bm.toGroup());
180
if(!bm.showInToolbar())
187
if ( bm.isSeparator() )
188
m_toolBar->addSeparator();
191
KAction *action = new KBookmarkAction( bm, m_pOwner, 0 );
192
m_toolBar->addAction(action);
193
d->m_actions.append( action );
198
KBookmarkActionMenu *action = new KBookmarkActionMenu(bm, 0);
199
action->setDelayed( false );
200
m_toolBar->addAction(action);
201
d->m_actions.append( action );
202
KBookmarkMenu *menu = new KonqBookmarkMenu(m_pManager, m_pOwner, action, bm.address());
203
m_lstSubMenus.append( menu );
208
void KBookmarkBar::removeTempSep()
210
if (m_toolBarSeparator)
211
m_toolBar->removeAction(m_toolBarSeparator);
216
* Handle a QDragMoveEvent event on a toolbar drop
217
* @return true if the event should be accepted, false if the event should be ignored
218
* @param pos the current QDragMoveEvent position
220
* @param actions the list of actions plugged into the bar
221
* returned action was dropped on
223
bool KBookmarkBar::handleToolbarDragMoveEvent(const QPoint& p, const QList<KAction *>& actions, const QString &text)
225
if(d->m_filteredToolbar)
227
int pos = m_toolBar->orientation() == Qt::Horizontal ? p.x() : p.y();
228
Q_ASSERT( actions.isEmpty() || (m_toolBar == qobject_cast<KToolBar*>(actions.first()->associatedWidgets().value(0))) );
229
m_toolBar->setUpdatesEnabled(false);
232
bool foundWidget = false;
234
// only relevant if the toolbar is Horizontal!
235
bool rtl = QApplication::isRightToLeft() && m_toolBar->orientation() == Qt::Horizontal;
236
m_toolBarSeparator->setText(text);
239
if(actions.isEmpty())
242
m_toolBar->addAction(m_toolBarSeparator);
243
m_toolBar->setUpdatesEnabled(true);
247
// else find the toolbar button
248
for(int i = 0; i < d->widgetPositions.count(); ++i)
250
if( rtl ^ (pos <= d->widgetPositions[i]) )
260
if (foundWidget) // found the containing button
262
int leftOrTop = d->m_sepIndex == 0 ? 0 : d->widgetPositions[d->m_sepIndex-1];
263
int rightOrBottom = d->widgetPositions[d->m_sepIndex];
264
if ( rtl ^ (pos >= (leftOrTop + rightOrBottom)/2) )
266
// if in second half of button then
267
// we jump to next index
270
if(d->m_sepIndex != actions.count())
272
QAction *before = m_toolBar->actions()[d->m_sepIndex];
273
m_toolBar->insertAction(before, m_toolBarSeparator);
277
m_toolBar->addAction(m_toolBarSeparator);
279
m_toolBar->setUpdatesEnabled(true);
282
else // (!foundWidget)
284
// if !b and not past last button, we didn't find button
285
if (rtl ^ (pos <= d->widgetPositions[d->widgetPositions.count()-1]) )
287
m_toolBar->setUpdatesEnabled(true);
290
else // location is beyond last action, assuming we want to add in the end
292
d->m_sepIndex = actions.count();
293
m_toolBar->addAction(m_toolBarSeparator);
294
m_toolBar->setUpdatesEnabled(true);
300
void KBookmarkBar::contextMenu(const QPoint & pos)
302
KBookmarkActionInterface * action = dynamic_cast<KBookmarkActionInterface *>( m_toolBar->actionAt(pos) );
305
//Show default (ktoolbar) menu
306
m_toolBar->setContextMenuPolicy( Qt::DefaultContextMenu );
307
//Recreate event with the same position
308
QContextMenuEvent evt( QContextMenuEvent::Other, pos );
309
QCoreApplication::sendEvent( m_toolBar, &evt );
310
//Reassign custom context menu
311
m_toolBar->setContextMenuPolicy( Qt::CustomContextMenu );
315
KMenu * menu = new KonqBookmarkContextMenu(action->bookmark(), m_pManager, m_pOwner);
316
menu->setAttribute(Qt::WA_DeleteOnClose);
317
menu->popup(m_toolBar->mapToGlobal(pos));
321
// TODO *** drop improvements ***
322
// open submenus on drop interactions
323
bool KBookmarkBar::eventFilter( QObject *, QEvent *e )
325
if (d->m_filteredToolbar)
326
return false; // todo: make this limit the actions
328
if ( e->type() == QEvent::DragLeave )
332
else if ( e->type() == QEvent::Drop )
336
QDropEvent *dev = static_cast<QDropEvent*>( e );
337
QList<KBookmark> list = KBookmark::List::fromMimeData( dev->mimeData() );
338
if ( list.isEmpty() )
340
if (list.count() > 1)
341
kWarning(7043) << "Sorry, currently you can only drop one address "
342
"onto the bookmark bar!";
343
KBookmark toInsert = list.first();
345
KBookmarkGroup parentBookmark = getToolbar();
347
if(d->m_sepIndex == 0)
349
KBookmark newBookmark = parentBookmark.addBookmark(toInsert.fullText(), toInsert.url() );
351
parentBookmark.moveBookmark( newBookmark, KBookmark() );
352
m_pManager->emitChanged( parentBookmark );
357
KBookmark after = parentBookmark.first();
359
for(int i=0; i < d->m_sepIndex - 1 ; ++i)
360
after = parentBookmark.next(after);
361
KBookmark newBookmark = parentBookmark.addBookmark(toInsert.fullText(), toInsert.url() );
363
parentBookmark.moveBookmark( newBookmark, after );
364
m_pManager->emitChanged( parentBookmark );
368
else if ( e->type() == QEvent::DragMove || e->type() == QEvent::DragEnter )
370
QDragMoveEvent *dme = static_cast<QDragMoveEvent*>( e );
371
if (!KBookmark::List::canDecode( dme->mimeData() ))
374
//cache text, save positions (inserting the temporary widget changes the positions)
375
if(e->type() == QEvent::DragEnter)
377
QList<KBookmark> list = KBookmark::List::fromMimeData( dme->mimeData() );
378
if ( list.isEmpty() )
380
d->tempLabel = list.first().url().pathOrUrl();
382
d->widgetPositions.clear();
384
for (int i = 0; i < m_toolBar->actions().count(); ++i)
385
if (QWidget* button = m_toolBar->widgetForAction(m_toolBar->actions()[i])) {
386
if(m_toolBar->orientation() == Qt::Horizontal) {
387
if(QApplication::isLeftToRight()) {
388
d->widgetPositions.push_back(button->geometry().right());
390
d->widgetPositions.push_back(button->geometry().left());
393
d->widgetPositions.push_back(button->geometry().bottom());
398
bool accept = handleToolbarDragMoveEvent(dme->pos(), d->m_actions, d->tempLabel);
402
return true; //Really?
408
#include "konqbookmarkbar.moc"