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