00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include <qregexp.h>
00023
#include <qfile.h>
00024
00025
#include <kbookmarkbar.h>
00026
#include <kbookmarkdrag.h>
00027
00028
#include <kbookmarkmenu.h>
00029
#include <kdebug.h>
00030
00031
#include <ktoolbar.h>
00032
#include <ktoolbarbutton.h>
00033
00034
#include <kconfig.h>
00035
#include <kpopupmenu.h>
00036
00037
#include "kbookmarkdrag.h"
00038
#include "kbookmarkmenu_p.h"
00039
#include "kbookmarkdombuilder.h"
00040
00041
#include "dptrtemplate.h"
00042
00043
#include <qapplication.h>
00044
00045
class KBookmarkBarPrivate :
public dPtrTemplate<KBookmarkBar, KBookmarkBarPrivate>
00046 {
00047
public:
00048
QPtrList<KAction> m_actions;
00049
bool m_readOnly;
00050
KBookmarkManager* m_filteredMgr;
00051
KToolBar* m_sepToolBar;
00052
int m_sepIndex;
00053
bool m_atFirst;
00054
QString m_dropAddress;
00055
QString m_highlightedAddress;
00056
public:
00057 KBookmarkBarPrivate() {
00058 m_readOnly =
false;
00059 m_filteredMgr = 0;
00060 m_sepToolBar = 0;
00061 m_sepIndex = -1;
00062 m_atFirst =
false;
00063 }
00064 };
00065
template<>
QPtrDict<KBookmarkBarPrivate>* dPtrTemplate<KBookmarkBar, KBookmarkBarPrivate>::d_ptr = 0;
00066
00067 KBookmarkBarPrivate* KBookmarkBar::dptr()
const
00068
{
00069
return KBookmarkBarPrivate::d(
this );
00070 }
00071
00072
00073
class ToolbarFilter :
public KXBELBookmarkImporterImpl
00074 {
00075
public:
00076 ToolbarFilter() : m_visible(false) { ; }
00077
void filter(
const KBookmarkGroup &grp ) { traverse(grp); }
00078
private:
00079
virtual void visit(
const KBookmark & );
00080
virtual void visitEnter(
const KBookmarkGroup & );
00081
virtual void visitLeave(
const KBookmarkGroup & );
00082
private:
00083
bool m_visible;
00084
KBookmarkGroup m_visibleStart;
00085 };
00086
00087 KBookmarkBar::KBookmarkBar(
KBookmarkManager* mgr,
00088
KBookmarkOwner *_owner,
KToolBar *_toolBar,
00089
KActionCollection *coll,
00090
QObject *parent,
const char *name )
00091 :
QObject( parent, name ), m_pOwner(_owner), m_toolBar(_toolBar),
00092 m_actionCollection( coll ), m_pManager(mgr)
00093 {
00094 m_lstSubMenus.
setAutoDelete(
true );
00095
00096 m_toolBar->setAcceptDrops(
true );
00097 m_toolBar->installEventFilter(
this );
00098
00099 dptr()->m_actions.setAutoDelete(
true );
00100
00101 connect( mgr, SIGNAL( changed(
const QString &,
const QString &) ),
00102 SLOT( slotBookmarksChanged(
const QString &) ) );
00103
00104
KBookmarkGroup toolbar = getToolbar();
00105 fillBookmarkBar( toolbar );
00106 }
00107
00108 QString KBookmarkBar::parentAddress()
00109 {
00110
return dptr()->m_filteredMgr ? QString::null : m_pManager->
toolbar().address();
00111 }
00112
00113
#define CURRENT_TOOLBAR() ( \
00114
dptr()->m_filteredMgr ? dptr()->m_filteredMgr->root() \
00115
: m_pManager->toolbar() )
00116
00117
#define CURRENT_MANAGER() ( \
00118
dptr()->m_filteredMgr ? dptr()->m_filteredMgr \
00119
: m_pManager )
00120
00121
KBookmarkGroup KBookmarkBar::getToolbar()
00122 {
00123
if ( KBookmarkSettings::self()->m_filteredtoolbar )
00124 {
00125
if ( !dptr()->m_filteredMgr ) {
00126 dptr()->m_filteredMgr = KBookmarkManager::createTempManager();
00127 }
else {
00128
KBookmarkGroup bkRoot = dptr()->m_filteredMgr->root();
00129
QValueList<KBookmark> bks;
00130
for (KBookmark bm = bkRoot.
first(); !bm.isNull(); bm = bkRoot.
next(bm))
00131 bks << bm;
00132
for (
QValueListConstIterator<KBookmark> it = bks.
begin(); it != bks.
end(); ++it )
00133 bkRoot.
deleteBookmark( (*it) );
00134 }
00135 ToolbarFilter filter;
00136
KBookmarkDomBuilder builder( dptr()->m_filteredMgr->root(),
00137 dptr()->m_filteredMgr );
00138 builder.
connectImporter( &filter );
00139 filter.filter( m_pManager->
root() );
00140 }
00141
00142
return CURRENT_TOOLBAR();
00143 }
00144
00145 KBookmarkBar::~KBookmarkBar()
00146 {
00147
00148 KBookmarkBarPrivate::delete_d(
this);
00149 }
00150
00151
void KBookmarkBar::clear()
00152 {
00153
QPtrListIterator<KAction> it( dptr()->m_actions );
00154 m_toolBar->clear();
00155
for (; it.
current(); ++it ) {
00156 (*it)->unplugAll();
00157 }
00158 dptr()->m_actions.clear();
00159 m_lstSubMenus.
clear();
00160 }
00161
00162
void KBookmarkBar::slotBookmarksChanged(
const QString & group )
00163 {
00164
KBookmarkGroup tb = getToolbar();
00165
kdDebug(7043) <<
"slotBookmarksChanged( " << group <<
" )" <<
endl;
00166
00167
if ( tb.isNull() )
00168
return;
00169
00170
if ( tb.address() == group || KBookmarkSettings::self()->m_filteredtoolbar )
00171 {
00172 clear();
00173 fillBookmarkBar( tb );
00174 }
00175
else
00176 {
00177
00178
QPtrListIterator<KBookmarkMenu> it( m_lstSubMenus );
00179
for (; it.
current(); ++it )
00180 {
00181 it.
current()->slotBookmarksChanged( group );
00182 }
00183 }
00184 }
00185
00186
void KBookmarkBar::fillBookmarkBar(
KBookmarkGroup & parent)
00187 {
00188
if (parent.isNull())
00189
return;
00190
00191
for (KBookmark bm = parent.
first(); !bm.isNull(); bm = parent.
next(bm))
00192 {
00193
QString text = bm.text();
00194 text.
replace(
'&',
"&&" );
00195
if (!bm.isGroup())
00196 {
00197
if ( bm.isSeparator() )
00198 m_toolBar->insertLineSeparator();
00199
else
00200 {
00201
KAction *
action =
new KBookmarkAction( text, bm.icon(), 0, m_actionCollection, 0 );
00202
connect(action, SIGNAL( activated ( KAction::ActivationReason, Qt::ButtonState )),
00203
this, SLOT( slotBookmarkSelected( KAction::ActivationReason, Qt::ButtonState ) ));
00204
00205
action->setProperty(
"url", bm.url().url() );
00206
action->setProperty(
"address", bm.address() );
00207
00208
action->setToolTip( bm.url().prettyURL() );
00209
00210
action->plug(m_toolBar);
00211
00212 dptr()->m_actions.append( action );
00213 }
00214 }
00215
else
00216 {
00217
KActionMenu *
action =
new KBookmarkActionMenu( text, bm.icon(),
00218 m_actionCollection,
00219
"bookmarkbar-actionmenu");
00220
action->setProperty(
"address", bm.address() );
00221
action->setProperty(
"readOnly", dptr()->m_readOnly );
00222
action->setDelayed(
false );
00223
00224
00225
KGlobal::config()->
setGroup(
"Settings" );
00226
bool addEntriesBookmarkBar =
KGlobal::config()->
readBoolEntry(
"AddEntriesBookmarkBar",
true);
00227
00228
KBookmarkMenu *menu =
new KBookmarkMenu(CURRENT_MANAGER(), m_pOwner,
action->popupMenu(),
00229 m_actionCollection,
false, addEntriesBookmarkBar,
00230 bm.address());
00231
connect(menu, SIGNAL(
aboutToShowContextMenu(
const KBookmark &,
QPopupMenu * ) ),
00232
this, SIGNAL(
aboutToShowContextMenu(
const KBookmark &,
QPopupMenu * ) ));
00233
connect(menu, SIGNAL(
openBookmark(
const QString &, Qt::ButtonState) ),
00234
this, SIGNAL(
openBookmark(
const QString &, Qt::ButtonState) ));
00235 menu->
fillBookmarkMenu();
00236
action->plug(m_toolBar);
00237 m_lstSubMenus.
append( menu );
00238
00239 dptr()->m_actions.append( action );
00240 }
00241 }
00242 }
00243
00244 void KBookmarkBar::setReadOnly(
bool readOnly)
00245 {
00246 dptr()->m_readOnly = readOnly;
00247 }
00248
00249 bool KBookmarkBar::isReadOnly()
const
00250
{
00251
return dptr()->m_readOnly;
00252 }
00253
00254 void KBookmarkBar::slotBookmarkSelected( KAction::ActivationReason , Qt::ButtonState state )
00255 {
00256
if (!m_pOwner)
return;
00257
00258
const KAction* action = dynamic_cast<const KAction *>(
sender());
00259
if(action)
00260 {
00261
const QString & url =
sender()->property(
"url").toString();
00262 m_pOwner->
openBookmarkURL(url);
00263 emit
openBookmark( url, state );
00264 }
00265 }
00266
00267
void KBookmarkBar::slotBookmarkSelected()
00268 {
00269 slotBookmarkSelected(KAction::ToolBarActivation, Qt::NoButton);
00270 }
00271
00272
static const int const_sepId = -9999;
00273
00274
00275
00276
static void removeTempSep(KBookmarkBarPrivate* p)
00277 {
00278
if (p->m_sepToolBar) {
00279 p->m_sepToolBar->removeItem(const_sepId);
00280 p->m_sepToolBar = 0;
00281 }
00282 }
00283
00284
static KAction* findPluggedAction(
QPtrList<KAction> actions,
KToolBar *tb,
int id)
00285 {
00286
QPtrListIterator<KAction> it( actions );
00287
for (; (*it); ++it )
00288
if ((*it)->isPlugged(tb,
id))
00289
return (*it);
00290
return 0;
00291 }
00292
00303
static QString handleToolbarDragMoveEvent(
00304 KBookmarkBarPrivate *p,
KToolBar *tb,
QPoint pos,
QPtrList<KAction> actions,
00305
bool &atFirst,
KBookmarkManager *mgr
00306 ) {
00307 Q_UNUSED( mgr );
00308 Q_ASSERT( actions.
isEmpty() || (tb == dynamic_cast<KToolBar*>(actions.
first()->container(0))) );
00309 p->m_sepToolBar = tb;
00310 p->m_sepToolBar->removeItemDelayed(const_sepId);
00311
00312
int index;
00313
KToolBarButton* b;
00314
00315 b = dynamic_cast<KToolBarButton*>(tb->childAt(pos));
00316
KAction *a = 0;
00317
QString address;
00318 atFirst =
false;
00319
00320
if (b)
00321 {
00322 index = tb->
itemIndex(b->
id());
00323
QRect r = b->geometry();
00324
if (pos.
x() < ((r.
left() + r.
right())/2))
00325 {
00326
00327
00328
if ( index == 0 )
00329 atFirst =
true;
00330
else {
00331 index--;
00332 b = tb->
getButton(tb->
idAt(index));
00333 }
00334 }
00335 }
00336
else if (actions.
isEmpty())
00337 {
00338 atFirst =
true;
00339 index = 0;
00340
00341
00342
00343
00344
00345 p->m_sepIndex = 0;
00346
goto skipact;
00347 }
00348
else
00349 {
00350 index = actions.
count() - 1;
00351 b = tb->
getButton(tb->
idAt(index));
00352
00353
if (pos.
x() <= b->geometry().left())
00354
goto skipact;
00355 }
00356
00357
if ( !b )
00358
return QString::null;
00359
00360 a = findPluggedAction(actions, tb, b->
id());
00361 Q_ASSERT(a);
00362 address = a->
property(
"address").toString();
00363 p->m_sepIndex = index + (atFirst ? 0 : 1);
00364
00365
#if 0
00366
{
00367 KBookmark bk = mgr->
findByAddress( address );
00368
if (bk.isGroup())
00369 {
00370
kdDebug() <<
"kbookmarkbar:: popping up " << bk.text() <<
endl;
00371 KBookmarkActionMenu *menu = dynamic_cast<KBookmarkActionMenu*>(a);
00372 Q_ASSERT(menu);
00373 menu->popup(tb->mapToGlobal(b->geometry().center()));
00374 }
00375 }
00376
#endif
00377
00378 skipact:
00379 tb->
insertLineSeparator(p->m_sepIndex, const_sepId);
00380
return address;
00381 }
00382
00383
00384
static KAction* handleToolbarMouseButton(
QPoint pos,
QPtrList<KAction> actions,
00385
KBookmarkManager * ,
QPoint & pt)
00386 {
00387
KAction *act = actions.
first();
00388
if (!act) {
00389
return 0;
00390 }
00391
00392
KToolBar *tb = dynamic_cast<KToolBar*>(act->
container(0));
00393 Q_ASSERT(tb);
00394
00395
KToolBarButton *b;
00396 b = dynamic_cast<KToolBarButton*>(tb->childAt(pos));
00397
if (!b)
00398
return 0;
00399
00400
KAction *a = 0;
00401 a = findPluggedAction(actions, tb, b->
id());
00402 Q_ASSERT(a);
00403 pt = tb->mapToGlobal(pos);
00404
00405
return a;
00406 }
00407
00408
00409
00410
00411
00412
00413
00414
class KBookmarkBarRMBAssoc :
public dPtrTemplate<KBookmarkBar, RMB> { };
00415
template<>
QPtrDict<RMB>* dPtrTemplate<KBookmarkBar, RMB>::d_ptr = 0;
00416
00417
static RMB* rmbSelf(
KBookmarkBar *m) {
return KBookmarkBarRMBAssoc::d(m); }
00418
00419
void RMB::begin_rmb_action(
KBookmarkBar *
self)
00420 {
00421 RMB *s = rmbSelf(
self);
00422 s->recv =
self;
00423 s->m_parentAddress =
self->parentAddress();
00424 s->s_highlightedAddress =
self->dptr()->m_highlightedAddress;
00425 s->m_pManager =
self->m_pManager;
00426 s->m_pOwner =
self->m_pOwner;
00427 s->m_parentMenu = 0;
00428 }
00429
00430 void KBookmarkBar::slotRMBActionEditAt(
int val )
00431 { RMB::begin_rmb_action(
this); rmbSelf(
this)->slotRMBActionEditAt( val ); }
00432
00433 void KBookmarkBar::slotRMBActionProperties(
int val )
00434 { RMB::begin_rmb_action(
this); rmbSelf(
this)->slotRMBActionProperties( val ); }
00435
00436 void KBookmarkBar::slotRMBActionInsert(
int val )
00437 { RMB::begin_rmb_action(
this); rmbSelf(
this)->slotRMBActionInsert( val ); }
00438
00439 void KBookmarkBar::slotRMBActionRemove(
int val )
00440 { RMB::begin_rmb_action(
this); rmbSelf(
this)->slotRMBActionRemove( val ); }
00441
00442 void KBookmarkBar::slotRMBActionCopyLocation(
int val )
00443 { RMB::begin_rmb_action(
this); rmbSelf(
this)->slotRMBActionCopyLocation( val ); }
00444
00445
bool KBookmarkBar::eventFilter(
QObject *o,
QEvent *e )
00446 {
00447
if (dptr()->m_readOnly || dptr()->m_filteredMgr)
00448
00449
return false;
00450
00451
if ( (e->
type() == QEvent::MouseButtonRelease) || (e->
type() == QEvent::MouseButtonPress) )
00452 {
00453
QMouseEvent *mev = (
QMouseEvent*)e;
00454
00455
QPoint pt;
00456
KAction *_a;
00457
00458
00459 _a = handleToolbarMouseButton( mev->
pos(), dptr()->m_actions, m_pManager, pt );
00460
if (_a && mev->
button() == Qt::RightButton)
00461 {
00462 dptr()->m_highlightedAddress = _a->
property(
"address").toString();
00463 KBookmark bookmark = m_pManager->
findByAddress( dptr()->m_highlightedAddress );
00464 RMB::begin_rmb_action(
this);
00465
KPopupMenu *pm =
new KPopupMenu;
00466 rmbSelf(
this)->fillContextMenu( pm, dptr()->m_highlightedAddress, 0 );
00467 emit aboutToShowContextMenu( rmbSelf(
this)->atAddress( dptr()->m_highlightedAddress ), pm );
00468 rmbSelf(
this)->fillContextMenu2( pm, dptr()->m_highlightedAddress, 0 );
00469 pm->
popup( pt );
00470 mev->
accept();
00471 }
00472
00473
return !!_a;
00474 }
00475
else if ( e->
type() == QEvent::DragLeave )
00476 {
00477 removeTempSep(dptr());
00478 dptr()->m_dropAddress = QString::null;
00479 }
00480
else if ( e->
type() == QEvent::Drop )
00481 {
00482 removeTempSep(dptr());
00483
QDropEvent *dev = (
QDropEvent*)e;
00484
if ( !KBookmarkDrag::canDecode( dev ) )
00485
return false;
00486
QValueList<KBookmark> list =
KBookmarkDrag::decode( dev );
00487
if (list.
count() > 1)
00488
kdWarning(7043) <<
"Sorry, currently you can only drop one address "
00489
"onto the bookmark bar!" <<
endl;
00490 KBookmark toInsert = list.
first();
00491 KBookmark bookmark = m_pManager->
findByAddress( dptr()->m_dropAddress );
00492 Q_ASSERT(!bookmark.isNull());
00493
kdDebug(7043) <<
"inserting "
00494 <<
QString(dptr()->m_atFirst ?
"before" :
"after")
00495 <<
" dptr()->m_dropAddress == " << dptr()->m_dropAddress <<
endl;
00496
KBookmarkGroup parentBookmark = bookmark.parentGroup();
00497 Q_ASSERT(!parentBookmark.isNull());
00498 KBookmark newBookmark = parentBookmark.
addBookmark(
00499 m_pManager, toInsert.fullText(),
00500 toInsert.url() );
00501 parentBookmark.
moveItem( newBookmark, dptr()->m_atFirst ? KBookmark() : bookmark );
00502 m_pManager->
emitChanged( parentBookmark );
00503
return true;
00504 }
00505
else if ( e->
type() == QEvent::DragMove )
00506 {
00507
QDragMoveEvent *dme = (
QDragMoveEvent*)e;
00508
if (!KBookmarkDrag::canDecode( dme ))
00509
return false;
00510
bool _atFirst;
00511
QString dropAddress;
00512
KToolBar *tb = (
KToolBar*)o;
00513 dropAddress = handleToolbarDragMoveEvent(dptr(), tb, dme->pos(), dptr()->m_actions, _atFirst, m_pManager);
00514
if (!dropAddress.
isNull())
00515 {
00516 dptr()->m_dropAddress = dropAddress;
00517 dptr()->m_atFirst = _atFirst;
00518 dme->
accept();
00519 }
00520 }
00521
return false;
00522 }
00523
00524
static bool showInToolbar(
const KBookmark &bk ) {
00525
return (bk.internalElement().attributes().namedItem(
"showintoolbar").toAttr().value() ==
"yes");
00526 }
00527
00528
void ToolbarFilter::visit(
const KBookmark &bk ) {
00529
00530
if ( m_visible || showInToolbar(bk) )
00531 KXBELBookmarkImporterImpl::visit(bk);
00532 }
00533
00534
void ToolbarFilter::visitEnter(
const KBookmarkGroup &grp ) {
00535
00536
if ( !m_visible && showInToolbar(grp) )
00537 {
00538 m_visibleStart = grp;
00539 m_visible =
true;
00540 }
00541
if ( m_visible )
00542 KXBELBookmarkImporterImpl::visitEnter(grp);
00543 }
00544
00545
void ToolbarFilter::visitLeave(
const KBookmarkGroup &grp ) {
00546
00547
if ( m_visible )
00548 KXBELBookmarkImporterImpl::visitLeave(grp);
00549
if ( m_visible && grp.address() == m_visibleStart.address() )
00550 m_visible =
false;
00551 }
00552
00553
#include "kbookmarkbar.moc"