kio Library API Documentation

kbookmarkmenu.cc

00001 // -*- c-basic-offset:4; indent-tabs-mode:nil -*- 00002 // vim: set ts=4 sts=4 sw=4 et: 00003 /* This file is part of the KDE project 00004 Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00019 Boston, MA 02111-1307, USA. 00020 */ 00021 00022 #include "kbookmarkmenu.h" 00023 #include "kbookmarkmenu_p.h" 00024 #include "kbookmarkimporter.h" 00025 #include "kbookmarkimporter_opera.h" 00026 #include "kbookmarkimporter_ie.h" 00027 #include "kbookmarkdrag.h" 00028 00029 #include <kstringhandler.h> 00030 #include <qstring.h> 00031 #include <qlineedit.h> 00032 #include <qlabel.h> 00033 #include <kdialogbase.h> 00034 #include <qlayout.h> 00035 #include <qpushbutton.h> 00036 00037 #include <qclipboard.h> 00038 00039 #include <klineedit.h> 00040 00041 #include <qfile.h> 00042 00043 #include <kapplication.h> 00044 #include <kaction.h> 00045 #include <kdebug.h> 00046 #include <klocale.h> 00047 #include <kmessagebox.h> 00048 #include <kpopupmenu.h> 00049 #include <kstdaccel.h> 00050 #include <kstdaction.h> 00051 #include <kconfig.h> 00052 00053 #include <qlistview.h> 00054 #include <qheader.h> 00055 00056 #include <kiconloader.h> 00057 00058 #include <dptrtemplate.h> 00059 00060 template class QPtrList<KBookmarkMenu>; 00061 00062 static QString makeTextNodeMod(KBookmark bk, const QString &m_nodename, const QString &m_newText) { 00063 QDomNode subnode = bk.internalElement().namedItem(m_nodename); 00064 if (subnode.isNull()) { 00065 subnode = bk.internalElement().ownerDocument().createElement(m_nodename); 00066 bk.internalElement().appendChild(subnode); 00067 } 00068 00069 if (subnode.firstChild().isNull()) { 00070 QDomText domtext = subnode.ownerDocument().createTextNode(""); 00071 subnode.appendChild(domtext); 00072 } 00073 00074 QDomText domtext = subnode.firstChild().toText(); 00075 00076 QString m_oldText = domtext.data(); 00077 domtext.setData(m_newText); 00078 00079 return m_oldText; 00080 } 00081 00082 /********************************************************************/ 00083 /********************************************************************/ 00084 /********************************************************************/ 00085 00086 KBookmarkMenu::KBookmarkMenu( KBookmarkManager* mgr, 00087 KBookmarkOwner * _owner, KPopupMenu * _parentMenu, 00088 KActionCollection *collec, bool _isRoot, bool _add, 00089 const QString & parentAddress ) 00090 : m_bIsRoot(_isRoot), m_bAddBookmark(_add), 00091 m_bAddShortcuts(true), 00092 m_pManager(mgr), m_pOwner(_owner), 00093 m_parentMenu( _parentMenu ), 00094 m_actionCollection( collec ), 00095 m_parentAddress( parentAddress ) 00096 { 00097 m_parentMenu->setKeyboardShortcutsEnabled( true ); 00098 00099 m_lstSubMenus.setAutoDelete( true ); 00100 m_actions.setAutoDelete( true ); 00101 00102 if (m_actionCollection) 00103 { 00104 m_actionCollection->setHighlightingEnabled(true); 00105 disconnect( m_actionCollection, SIGNAL( actionHighlighted( KAction * ) ), 0, 0 ); 00106 connect( m_actionCollection, SIGNAL( actionHighlighted( KAction * ) ), 00107 this, SLOT( slotActionHighlighted( KAction * ) ) ); 00108 } 00109 00110 m_bNSBookmark = m_parentAddress.isNull(); 00111 if ( !m_bNSBookmark ) // not for the netscape bookmark 00112 { 00113 //kdDebug(7043) << "KBookmarkMenu::KBookmarkMenu " << this << " address : " << m_parentAddress << endl; 00114 00115 connect( _parentMenu, SIGNAL( aboutToShow() ), 00116 SLOT( slotAboutToShow() ) ); 00117 00118 if ( KBookmarkSettings::self()->m_contextmenu ) 00119 { 00120 (void) _parentMenu->contextMenu(); 00121 connect( _parentMenu, SIGNAL( aboutToShowContextMenu(KPopupMenu*, int, QPopupMenu*) ), 00122 this, SLOT( slotAboutToShowContextMenu(KPopupMenu*, int, QPopupMenu*) )); 00123 } 00124 00125 if ( m_bIsRoot ) 00126 { 00127 connect( m_pManager, SIGNAL( changed(const QString &, const QString &) ), 00128 SLOT( slotBookmarksChanged(const QString &) ) ); 00129 } 00130 } 00131 00132 // add entries that possibly have a shortcut, so they are available _before_ first popup 00133 if ( m_bIsRoot ) 00134 { 00135 if ( m_bAddBookmark ) 00136 { 00137 addAddBookmark(); 00138 if ( extOwner() ) 00139 addAddBookmarksList(); // FIXME 00140 } 00141 00142 addEditBookmarks(); 00143 } 00144 00145 m_bDirty = true; 00146 } 00147 00148 KBookmarkMenu::~KBookmarkMenu() 00149 { 00150 //kdDebug(7043) << "KBookmarkMenu::~KBookmarkMenu() " << this << endl; 00151 QPtrListIterator<KAction> it( m_actions ); 00152 for (; it.current(); ++it ) 00153 it.current()->unplugAll(); 00154 00155 m_lstSubMenus.clear(); 00156 m_actions.clear(); 00157 } 00158 00159 void KBookmarkMenu::ensureUpToDate() 00160 { 00161 slotAboutToShow(); 00162 } 00163 00164 void KBookmarkMenu::slotAboutToShow() 00165 { 00166 // Did the bookmarks change since the last time we showed them ? 00167 if ( m_bDirty ) 00168 { 00169 m_bDirty = false; 00170 refill(); 00171 } 00172 } 00173 00174 QString KBookmarkMenu::s_highlightedAddress; 00175 QString KBookmarkMenu::s_highlightedImportType; 00176 QString KBookmarkMenu::s_highlightedImportLocation; 00177 00178 void KBookmarkMenu::slotActionHighlighted( KAction* action ) 00179 { 00180 if (action->isA("KBookmarkActionMenu") || action->isA("KBookmarkAction")) 00181 { 00182 s_highlightedAddress = action->property("address").toString(); 00183 //kdDebug() << "KBookmarkMenu::slotActionHighlighted" << s_highlightedAddress << endl; 00184 } 00185 else if (action->isA("KImportedBookmarksActionMenu")) 00186 { 00187 s_highlightedImportType = action->property("type").toString(); 00188 s_highlightedImportLocation = action->property("location").toString(); 00189 } 00190 else 00191 { 00192 s_highlightedAddress = QString::null; 00193 s_highlightedImportType = QString::null; 00194 s_highlightedImportLocation = QString::null; 00195 } 00196 } 00197 00198 /********************************************************************/ 00199 /********************************************************************/ 00200 /********************************************************************/ 00201 00202 class KBookmarkMenuRMBAssoc : public dPtrTemplate<KBookmarkMenu, RMB> { }; 00203 template<> QPtrDict<RMB>* dPtrTemplate<KBookmarkMenu, RMB>::d_ptr = 0; 00204 00205 static RMB* rmbSelf(KBookmarkMenu *m) { return KBookmarkMenuRMBAssoc::d(m); } 00206 00207 // TODO check via dcop before making any changes to the bookmarks file??? 00208 00209 void RMB::begin_rmb_action(KBookmarkMenu *self) 00210 { 00211 RMB *s = rmbSelf(self); 00212 s->recv = self; 00213 s->m_parentAddress = self->m_parentAddress; 00214 s->s_highlightedAddress = KBookmarkMenu::s_highlightedAddress; 00215 s->m_pManager = self->m_pManager; 00216 s->m_pOwner = self->m_pOwner; 00217 s->m_parentMenu = self->m_parentMenu; 00218 } 00219 00220 bool RMB::invalid( int val ) 00221 { 00222 bool valid = true; 00223 00224 if (val == 1) 00225 s_highlightedAddress = m_parentAddress; 00226 00227 if (s_highlightedAddress.isNull()) 00228 valid = false; 00229 00230 return !valid; 00231 } 00232 00233 KBookmark RMB::atAddress(const QString & address) 00234 { 00235 KBookmark bookmark = m_pManager->findByAddress( address ); 00236 Q_ASSERT(!bookmark.isNull()); 00237 return bookmark; 00238 } 00239 00240 void KBookmarkMenu::slotAboutToShowContextMenu( KPopupMenu*, int, QPopupMenu* contextMenu ) 00241 { 00242 //kdDebug(7043) << "KBookmarkMenu::slotAboutToShowContextMenu" << s_highlightedAddress << endl; 00243 if (s_highlightedAddress.isNull()) 00244 { 00245 KPopupMenu::contextMenuFocus()->hideContextMenu(); 00246 return; 00247 } 00248 contextMenu->clear(); 00249 fillContextMenu( contextMenu, s_highlightedAddress, 0 ); 00250 } 00251 00252 void RMB::fillContextMenu( QPopupMenu* contextMenu, const QString & address, int val ) 00253 { 00254 KBookmark bookmark = atAddress(address); 00255 00256 int id; 00257 00258 // binner: 00259 // "Add Bookmark Here" when pointing at a bookmark looks strange and if you 00260 // call it you have to close and reopen the menu to see an entry was added? 00261 // 00262 // TODO rename these, but, message freeze... umm... 00263 00264 // if (bookmark.isGroup()) { 00265 id = contextMenu->insertItem( SmallIcon("bookmark_add"), i18n( "Add Bookmark Here" ), recv, SLOT(slotRMBActionInsert(int)) ); 00266 contextMenu->setItemParameter( id, val ); 00267 /* } 00268 else 00269 { 00270 id = contextMenu->insertItem( SmallIcon("bookmark_add"), i18n( "Add Bookmark Here" ), recv, SLOT(slotRMBActionInsert(int)) ); 00271 contextMenu->setItemParameter( id, val ); 00272 }*/ 00273 } 00274 00275 void RMB::fillContextMenu2( QPopupMenu* contextMenu, const QString & address, int val ) 00276 { 00277 KBookmark bookmark = atAddress(address); 00278 00279 int id; 00280 00281 if (bookmark.isGroup()) { 00282 id = contextMenu->insertItem( i18n( "Open Folder in Bookmark Editor" ), recv, SLOT(slotRMBActionEditAt(int)) ); 00283 contextMenu->setItemParameter( id, val ); 00284 contextMenu->insertSeparator(); 00285 id = contextMenu->insertItem( SmallIcon("editdelete"), i18n( "Delete Folder" ), recv, SLOT(slotRMBActionRemove(int)) ); 00286 contextMenu->setItemParameter( id, val ); 00287 contextMenu->insertSeparator(); 00288 id = contextMenu->insertItem( i18n( "Properties" ), recv, SLOT(slotRMBActionProperties(int)) ); 00289 contextMenu->setItemParameter( id, val ); 00290 } 00291 else 00292 { 00293 id = contextMenu->insertItem( i18n( "Copy Link Location" ), recv, SLOT(slotRMBActionCopyLocation(int)) ); 00294 contextMenu->setItemParameter( id, val ); 00295 contextMenu->insertSeparator(); 00296 id = contextMenu->insertItem( SmallIcon("editdelete"), i18n( "Delete Bookmark" ), recv, SLOT(slotRMBActionRemove(int)) ); 00297 contextMenu->setItemParameter( id, val ); 00298 contextMenu->insertSeparator(); 00299 id = contextMenu->insertItem( i18n( "Properties" ), recv, SLOT(slotRMBActionProperties(int)) ); 00300 contextMenu->setItemParameter( id, val ); 00301 } 00302 } 00303 00304 void RMB::slotRMBActionEditAt( int val ) 00305 { 00306 kdDebug(7043) << "KBookmarkMenu::slotRMBActionEditAt" << s_highlightedAddress << endl; 00307 if (invalid(val)) { hidePopup(); return; } 00308 00309 KBookmark bookmark = atAddress(s_highlightedAddress); 00310 00311 m_pManager->slotEditBookmarksAtAddress( s_highlightedAddress ); 00312 } 00313 00314 void RMB::slotRMBActionProperties( int val ) 00315 { 00316 kdDebug(7043) << "KBookmarkMenu::slotRMBActionProperties" << s_highlightedAddress << endl; 00317 if (invalid(val)) { hidePopup(); return; } 00318 00319 KBookmark bookmark = atAddress(s_highlightedAddress); 00320 00321 QString folder = bookmark.isGroup() ? QString::null : bookmark.url().url(); 00322 KBookmarkEditDialog dlg( bookmark.fullText(), folder, 00323 m_pManager, KBookmarkEditDialog::ModifyMode ); 00324 if ( dlg.exec() != KDialogBase::Accepted ) 00325 return; 00326 00327 makeTextNodeMod(bookmark, "title", dlg.finalTitle()); 00328 if ( !dlg.finalUrl().isNull() ) 00329 bookmark.internalElement().setAttribute("href", dlg.finalUrl()); 00330 00331 kdDebug(7043) << "Requested move to " << dlg.finalAddress() << "!" << endl; 00332 00333 KBookmarkGroup parentBookmark = atAddress(m_parentAddress).toGroup(); 00334 m_pManager->emitChanged( parentBookmark ); 00335 } 00336 00337 void RMB::slotRMBActionInsert( int val ) 00338 { 00339 kdDebug(7043) << "KBookmarkMenu::slotRMBActionInsert" << s_highlightedAddress << endl; 00340 if (invalid(val)) { hidePopup(); return; } 00341 00342 QString url = m_pOwner->currentURL(); 00343 if (url.isEmpty()) 00344 { 00345 KMessageBox::error( 0L, i18n("Can't add bookmark with empty URL")); 00346 return; 00347 } 00348 QString title = m_pOwner->currentTitle(); 00349 if (title.isEmpty()) 00350 title = url; 00351 00352 KBookmark bookmark = atAddress( s_highlightedAddress ); 00353 00354 // TODO use unique title 00355 00356 if (bookmark.isGroup()) 00357 { 00358 KBookmarkGroup parentBookmark = bookmark.toGroup(); 00359 Q_ASSERT(!parentBookmark.isNull()); 00360 parentBookmark.addBookmark( m_pManager, title, KURL( url ) ); 00361 m_pManager->emitChanged( parentBookmark ); 00362 } 00363 else 00364 { 00365 KBookmarkGroup parentBookmark = bookmark.parentGroup(); 00366 Q_ASSERT(!parentBookmark.isNull()); 00367 KBookmark newBookmark = parentBookmark.addBookmark( m_pManager, title, KURL( url ) ); 00368 parentBookmark.moveItem( newBookmark, parentBookmark.previous(bookmark) ); 00369 m_pManager->emitChanged( parentBookmark ); 00370 } 00371 } 00372 00373 void RMB::slotRMBActionRemove( int val ) 00374 { 00375 //kdDebug(7043) << "KBookmarkMenu::slotRMBActionRemove" << s_highlightedAddress << endl; 00376 if (invalid(val)) { hidePopup(); return; } 00377 00378 KBookmark bookmark = atAddress( s_highlightedAddress ); 00379 bool folder = bookmark.isGroup(); 00380 00381 if (KMessageBox::warningYesNo( 00382 m_parentMenu, 00383 folder ? i18n("Are you sure you wish to remove this bookmark folder?") 00384 : i18n("Are you sure you wish to remove this bookmark?"), 00385 folder ? i18n("Bookmark Folder Removal") 00386 : i18n("Bookmark Removal"), 00387 KGuiItem( i18n("Remove"), "editdelete"), KStdGuiItem::cancel()) 00388 != KMessageBox::Yes 00389 ) 00390 return; 00391 00392 KBookmarkGroup parentBookmark = atAddress( m_parentAddress ).toGroup(); 00393 parentBookmark.deleteBookmark( bookmark ); 00394 m_pManager->emitChanged( parentBookmark ); 00395 if (m_parentMenu) 00396 m_parentMenu->hide(); 00397 } 00398 00399 void RMB::slotRMBActionCopyLocation( int val ) 00400 { 00401 //kdDebug(7043) << "KBookmarkMenu::slotRMBActionCopyLocation" << s_highlightedAddress << endl; 00402 if (invalid(val)) { hidePopup(); return; } 00403 00404 KBookmark bookmark = atAddress( s_highlightedAddress ); 00405 00406 if ( !bookmark.isGroup() ) 00407 { 00408 kapp->clipboard()->setData( KBookmarkDrag::newDrag(bookmark, 0), 00409 QClipboard::Selection ); 00410 kapp->clipboard()->setData( KBookmarkDrag::newDrag(bookmark, 0), 00411 QClipboard::Clipboard ); 00412 } 00413 } 00414 00415 void RMB::hidePopup() { 00416 KPopupMenu::contextMenuFocus()->hideContextMenu(); 00417 } 00418 00419 /********************************************************************/ 00420 /********************************************************************/ 00421 /********************************************************************/ 00422 00423 void KBookmarkMenu::fillContextMenu( QPopupMenu* contextMenu, const QString & address, int val ) 00424 { 00425 RMB::begin_rmb_action(this); 00426 rmbSelf(this)->fillContextMenu(contextMenu, address, val); 00427 emit aboutToShowContextMenu( rmbSelf(this)->atAddress(address), contextMenu); 00428 rmbSelf(this)->fillContextMenu2(contextMenu, address, val); 00429 } 00430 00431 void KBookmarkMenu::slotRMBActionEditAt( int val ) 00432 { RMB::begin_rmb_action(this); rmbSelf(this)->slotRMBActionEditAt( val ); } 00433 00434 void KBookmarkMenu::slotRMBActionProperties( int val ) 00435 { RMB::begin_rmb_action(this); rmbSelf(this)->slotRMBActionProperties( val ); } 00436 00437 void KBookmarkMenu::slotRMBActionInsert( int val ) 00438 { RMB::begin_rmb_action(this); rmbSelf(this)->slotRMBActionInsert( val ); } 00439 00440 void KBookmarkMenu::slotRMBActionRemove( int val ) 00441 { RMB::begin_rmb_action(this); rmbSelf(this)->slotRMBActionRemove( val ); } 00442 00443 void KBookmarkMenu::slotRMBActionCopyLocation( int val ) 00444 { RMB::begin_rmb_action(this); rmbSelf(this)->slotRMBActionCopyLocation( val ); } 00445 00446 void KBookmarkMenu::slotBookmarksChanged( const QString & groupAddress ) 00447 { 00448 if (m_bNSBookmark) 00449 return; 00450 00451 if ( groupAddress == m_parentAddress ) 00452 { 00453 //kdDebug(7043) << "KBookmarkMenu::slotBookmarksChanged -> setting m_bDirty on " << groupAddress << endl; 00454 m_bDirty = true; 00455 } 00456 else 00457 { 00458 // Iterate recursively into child menus 00459 QPtrListIterator<KBookmarkMenu> it( m_lstSubMenus ); 00460 for (; it.current(); ++it ) 00461 { 00462 it.current()->slotBookmarksChanged( groupAddress ); 00463 } 00464 } 00465 } 00466 00467 void KBookmarkMenu::refill() 00468 { 00469 //kdDebug(7043) << "KBookmarkMenu::refill()" << endl; 00470 m_lstSubMenus.clear(); 00471 00472 QPtrListIterator<KAction> it( m_actions ); 00473 for (; it.current(); ++it ) 00474 it.current()->unplug( m_parentMenu ); 00475 00476 m_parentMenu->clear(); 00477 m_actions.clear(); 00478 00479 fillBookmarkMenu(); 00480 m_parentMenu->adjustSize(); 00481 } 00482 00483 void KBookmarkMenu::addAddBookmarksList() 00484 { 00485 if (!kapp->authorizeKAction("bookmarks")) 00486 return; 00487 00488 QString title = i18n( "Bookmark Tabs as Folder..." ); 00489 00490 KAction * paAddBookmarksList = new KAction( title, 00491 "bookmarks_list_add", 00492 0, 00493 this, 00494 SLOT( slotAddBookmarksList() ), 00495 m_actionCollection, m_bIsRoot ? "add_bookmarks_list" : 0 ); 00496 00497 paAddBookmarksList->setToolTip( i18n( "Add a folder of bookmarks for all open tabs." ) ); 00498 00499 paAddBookmarksList->plug( m_parentMenu ); 00500 m_actions.append( paAddBookmarksList ); 00501 } 00502 00503 void KBookmarkMenu::addAddBookmark() 00504 { 00505 if (!kapp->authorizeKAction("bookmarks")) 00506 return; 00507 00508 QString title = i18n( "&Add Bookmark" ); 00509 int p; 00510 while ( ( p = title.find( '&' ) ) >= 0 ) 00511 title.remove( p, 1 ); 00512 00513 KAction * paAddBookmarks = new KAction( title, 00514 "bookmark_add", 00515 m_bIsRoot && m_bAddShortcuts ? KStdAccel::addBookmark() : KShortcut(), 00516 this, 00517 SLOT( slotAddBookmark() ), 00518 m_actionCollection, m_bIsRoot ? "add_bookmark" : 0 ); 00519 00520 paAddBookmarks->setToolTip( i18n( "Add a bookmark for the current document" ) ); 00521 00522 paAddBookmarks->plug( m_parentMenu ); 00523 m_actions.append( paAddBookmarks ); 00524 } 00525 00526 void KBookmarkMenu::addEditBookmarks() 00527 { 00528 if (!kapp->authorizeKAction("bookmarks")) 00529 return; 00530 00531 KAction * m_paEditBookmarks = KStdAction::editBookmarks( m_pManager, SLOT( slotEditBookmarks() ), 00532 m_actionCollection, "edit_bookmarks" ); 00533 m_paEditBookmarks->plug( m_parentMenu ); 00534 m_paEditBookmarks->setToolTip( i18n( "Edit your bookmark collection in a separate window" ) ); 00535 m_actions.append( m_paEditBookmarks ); 00536 } 00537 00538 void KBookmarkMenu::addNewFolder() 00539 { 00540 if (!kapp->authorizeKAction("bookmarks")) 00541 return; 00542 00543 QString title = i18n( "&New Bookmark Folder..." ); 00544 int p; 00545 while ( ( p = title.find( '&' ) ) >= 0 ) 00546 title.remove( p, 1 ); 00547 00548 KAction * paNewFolder = new KAction( title, 00549 "folder_new", //"folder", 00550 0, 00551 this, 00552 SLOT( slotNewFolder() ), 00553 m_actionCollection ); 00554 00555 paNewFolder->setToolTip( i18n( "Create a new bookmark folder in this menu" ) ); 00556 00557 paNewFolder->plug( m_parentMenu ); 00558 m_actions.append( paNewFolder ); 00559 } 00560 00561 void KBookmarkMenu::fillBookmarkMenu() 00562 { 00563 if (!kapp->authorizeKAction("bookmarks")) 00564 return; 00565 00566 if ( m_bIsRoot ) 00567 { 00568 if ( m_bAddBookmark ) 00569 { 00570 addAddBookmark(); 00571 if ( extOwner() ) 00572 addAddBookmarksList(); // FIXME 00573 } 00574 00575 addEditBookmarks(); 00576 00577 if ( m_bAddBookmark && !KBookmarkSettings::self()->m_advancedaddbookmark ) 00578 addNewFolder(); 00579 } 00580 00581 if ( m_bIsRoot 00582 && KBookmarkManager::userBookmarksManager()->path() == m_pManager->path() ) 00583 { 00584 bool haveSep = false; 00585 00586 QValueList<QString> keys = KBookmarkMenu::dynamicBookmarksList(); 00587 QValueList<QString>::const_iterator it; 00588 for ( it = keys.begin(); it != keys.end(); ++it ) 00589 { 00590 DynMenuInfo info; 00591 info = showDynamicBookmarks((*it)); 00592 00593 if ( !info.show || !QFile::exists( info.location ) ) 00594 continue; 00595 00596 if (!haveSep) 00597 { 00598 m_parentMenu->insertSeparator(); 00599 haveSep = true; 00600 } 00601 00602 KActionMenu * actionMenu; 00603 actionMenu = new KImportedBookmarksActionMenu( 00604 info.name, info.type, 00605 m_actionCollection, "kbookmarkmenu" ); 00606 00607 actionMenu->setProperty( "type", info.type ); 00608 actionMenu->setProperty( "location", info.location ); 00609 00610 actionMenu->plug( m_parentMenu ); 00611 m_actions.append( actionMenu ); 00612 00613 KBookmarkMenu *subMenu = 00614 new KBookmarkMenu( m_pManager, m_pOwner, actionMenu->popupMenu(), 00615 m_actionCollection, false, 00616 m_bAddBookmark, QString::null ); 00617 m_lstSubMenus.append(subMenu); 00618 00619 connect(actionMenu->popupMenu(), SIGNAL(aboutToShow()), subMenu, SLOT(slotNSLoad())); 00620 } 00621 } 00622 00623 KBookmarkGroup parentBookmark = m_pManager->findByAddress( m_parentAddress ).toGroup(); 00624 Q_ASSERT(!parentBookmark.isNull()); 00625 bool separatorInserted = false; 00626 for ( KBookmark bm = parentBookmark.first(); !bm.isNull(); bm = parentBookmark.next(bm) ) 00627 { 00628 QString text = bm.text(); 00629 text.replace( '&', "&&" ); 00630 if ( !separatorInserted && m_bIsRoot) { 00631 // inserted before the first konq bookmark, to avoid the separator if no konq bookmark 00632 m_parentMenu->insertSeparator(); 00633 separatorInserted = true; 00634 } 00635 if ( !bm.isGroup() ) 00636 { 00637 if ( bm.isSeparator() ) 00638 { 00639 m_parentMenu->insertSeparator(); 00640 } 00641 else 00642 { 00643 //kdDebug(7043) << "Creating URL bookmark menu item for " << bm.text() << endl; 00644 KAction * action = new KBookmarkAction( text, bm.icon(), 0, 00645 this, SLOT( slotBookmarkSelected() ), 00646 m_actionCollection, 0 ); 00647 00648 action->setProperty( "url", bm.url().url() ); 00649 action->setProperty( "address", bm.address() ); 00650 00651 action->setToolTip( bm.url().prettyURL() ); 00652 00653 action->plug( m_parentMenu ); 00654 m_actions.append( action ); 00655 } 00656 } 00657 else 00658 { 00659 //kdDebug(7043) << "Creating bookmark submenu named " << bm.text() << endl; 00660 KActionMenu * actionMenu = new KBookmarkActionMenu( text, bm.icon(), 00661 m_actionCollection, 00662 "kbookmarkmenu" ); 00663 actionMenu->setProperty( "address", bm.address() ); 00664 actionMenu->plug( m_parentMenu ); 00665 m_actions.append( actionMenu ); 00666 00667 KBookmarkMenu *subMenu = new KBookmarkMenu( m_pManager, m_pOwner, actionMenu->popupMenu(), 00668 m_actionCollection, false, 00669 m_bAddBookmark, 00670 bm.address() ); 00671 connect(subMenu, SIGNAL( aboutToShowContextMenu(const KBookmark &, QPopupMenu * ) ), 00672 this, SIGNAL( aboutToShowContextMenu(const KBookmark &, QPopupMenu * ) )); 00673 m_lstSubMenus.append( subMenu ); 00674 } 00675 } 00676 00677 if ( !m_bIsRoot && m_bAddBookmark ) 00678 { 00679 if ( m_parentMenu->count() > 0 ) 00680 m_parentMenu->insertSeparator(); 00681 00682 if ( KBookmarkSettings::self()->m_quickactions ) 00683 { 00684 KActionMenu * actionMenu = new KActionMenu( i18n("Quick Actions"), m_actionCollection, 0L ); 00685 fillContextMenu( actionMenu->popupMenu(), m_parentAddress, 1 ); 00686 actionMenu->plug( m_parentMenu ); 00687 m_actions.append( actionMenu ); 00688 } 00689 else 00690 { 00691 addAddBookmark(); 00692 if ( extOwner() ) 00693 addAddBookmarksList(); // FIXME 00694 addNewFolder(); 00695 } 00696 } 00697 } 00698 00699 void KBookmarkMenu::slotAddBookmarksList() 00700 { 00701 KExtendedBookmarkOwner *extOwner = dynamic_cast<KExtendedBookmarkOwner*>(m_pOwner); 00702 if (!extOwner) 00703 { 00704 kdWarning() << "erm, sorry ;-)" << endl; 00705 return; 00706 } 00707 00708 KExtendedBookmarkOwner::QStringPairList list; 00709 extOwner->fillBookmarksList( list ); 00710 00711 KBookmarkGroup parentBookmark = m_pManager->findByAddress( m_parentAddress ).toGroup(); 00712 Q_ASSERT(!parentBookmark.isNull()); 00713 KBookmarkGroup group = parentBookmark.createNewFolder( m_pManager ); 00714 if ( group.isNull() ) 00715 return; // user canceled i guess 00716 00717 KExtendedBookmarkOwner::QStringPairList::const_iterator it; 00718 for ( it = list.begin(); it != list.end(); ++it ) 00719 group.addBookmark( m_pManager, (*it).first, KURL((*it).second) ); 00720 00721 m_pManager->emitChanged( parentBookmark ); 00722 } 00723 00724 00725 void KBookmarkMenu::slotAddBookmark() 00726 { 00727 KBookmarkGroup parentBookmark; 00728 parentBookmark = m_pManager->addBookmarkDialog(m_pOwner->currentURL(), m_pOwner->currentTitle(), m_parentAddress); 00729 if (!parentBookmark.isNull()) 00730 m_pManager->emitChanged( parentBookmark ); 00731 } 00732 00733 void KBookmarkMenu::slotNewFolder() 00734 { 00735 if ( !m_pOwner ) return; // this view doesn't handle bookmarks... 00736 KBookmarkGroup parentBookmark = m_pManager->findByAddress( m_parentAddress ).toGroup(); 00737 Q_ASSERT(!parentBookmark.isNull()); 00738 KBookmarkGroup group = parentBookmark.createNewFolder( m_pManager ); 00739 if ( !group.isNull() ) 00740 { 00741 KBookmarkGroup parentGroup = group.parentGroup(); 00742 m_pManager->emitChanged( parentGroup ); 00743 } 00744 } 00745 00746 void KBookmarkMenu::slotBookmarkSelected() 00747 { 00748 //kdDebug(7043) << "KBookmarkMenu::slotBookmarkSelected()" << endl; 00749 if ( !m_pOwner ) return; // this view doesn't handle bookmarks... 00750 m_pOwner->openBookmarkURL( sender()->property("url").toString() ); 00751 } 00752 00753 KExtendedBookmarkOwner* KBookmarkMenu::extOwner() 00754 { 00755 return dynamic_cast<KExtendedBookmarkOwner*>(m_pOwner); 00756 } 00757 00758 void KBookmarkMenu::slotNSLoad() 00759 { 00760 // only fill menu once 00761 m_parentMenu->disconnect(SIGNAL(aboutToShow())); 00762 00763 // not NSImporter, but kept old name for BC reasons 00764 KBookmarkMenuNSImporter importer( m_pManager, this, m_actionCollection ); 00765 importer.openBookmarks(s_highlightedImportLocation, s_highlightedImportType); 00766 } 00767 00768 /********************************************************************/ 00769 /********************************************************************/ 00770 /********************************************************************/ 00771 00772 KBookmarkEditFields::KBookmarkEditFields(QWidget *main, QBoxLayout *vbox, FieldsSet fieldsSet) 00773 { 00774 bool isF = (fieldsSet != FolderFieldsSet); 00775 00776 QGridLayout *grid = new QGridLayout( vbox, 2, isF ? 2 : 1 ); 00777 00778 m_title = new KLineEdit( main ); 00779 grid->addWidget( m_title, 0, 1 ); 00780 grid->addWidget( new QLabel( m_title, i18n( "Name:" ), main ), 0, 0 ); 00781 m_title->setFocus(); 00782 if (isF) 00783 { 00784 m_url = new KLineEdit( main ); 00785 grid->addWidget( m_url, 1, 1 ); 00786 grid->addWidget( new QLabel( m_url, i18n( "Location:" ), main ), 1, 0 ); 00787 } 00788 else 00789 { 00790 m_url = 0; 00791 } 00792 main->setMinimumSize( 300, 0 ); 00793 } 00794 00795 void KBookmarkEditFields::setName(const QString &str) 00796 { 00797 m_title->setText(str); 00798 } 00799 00800 void KBookmarkEditFields::setLocation(const QString &str) 00801 { 00802 m_url->setText(str); 00803 } 00804 00805 /********************************************************************/ 00806 /********************************************************************/ 00807 /********************************************************************/ 00808 00809 // TODO - make the dialog use Properties as a title when in Modify mode... (dirk noticed the bug...) 00810 KBookmarkEditDialog::KBookmarkEditDialog(const QString& title, const QString& url, KBookmarkManager * mgr, BookmarkEditType editType, const QString& address, 00811 QWidget * parent, const char * name, const QString& caption ) 00812 : KDialogBase(parent, name, true, caption, 00813 (editType == InsertionMode) ? (User1|Ok|Cancel) : (Ok|Cancel), 00814 Ok, false, KGuiItem()), 00815 m_folderTree(0), m_mgr(mgr), m_editType(editType), m_address(address) 00816 { 00817 setButtonOK( KGuiItem((editType == InsertionMode) ? i18n( "Add" ) : i18n( "Update" )) ); 00818 if (editType == InsertionMode) { 00819 setButtonText( User1, i18n( "New Folder..." ) ); 00820 if (KGlobalSettings::showIconsOnPushButtons()) { 00821 actionButton( User1 )->setIconSet( SmallIcon( "folder_new" ) ); 00822 actionButton( Ok )->setIconSet( SmallIcon( "bookmark_add" ) ); 00823 } 00824 } 00825 00826 bool folder = url.isNull(); 00827 00828 m_main = new QWidget( this ); 00829 setMainWidget( m_main ); 00830 00831 QBoxLayout *vbox = new QVBoxLayout( m_main, spacingHint() ); 00832 KBookmarkEditFields::FieldsSet fs = 00833 folder ? KBookmarkEditFields::FolderFieldsSet 00834 : KBookmarkEditFields::BookmarkFieldsSet; 00835 m_fields = new KBookmarkEditFields(m_main, vbox, fs); 00836 m_fields->setName(title); 00837 if ( !folder ) 00838 m_fields->setLocation(url); 00839 00840 if ( editType == InsertionMode ) 00841 { 00842 m_folderTree = KBookmarkFolderTree::createTree( m_mgr, m_main, name, m_address ); 00843 connect( m_folderTree, SIGNAL( doubleClicked(QListViewItem*) ), 00844 this, SLOT( slotDoubleClicked(QListViewItem*) ) ); 00845 vbox->addWidget( m_folderTree ); 00846 connect( this, SIGNAL( user1Clicked() ), SLOT( slotUser1() ) ); 00847 } 00848 } 00849 00850 void KBookmarkEditDialog::slotDoubleClicked( QListViewItem* item ) 00851 { 00852 Q_ASSERT( m_folderTree ); 00853 m_folderTree->setCurrentItem( item ); 00854 accept(); 00855 } 00856 00857 void KBookmarkEditDialog::slotOk() 00858 { 00859 accept(); 00860 } 00861 00862 void KBookmarkEditDialog::slotCancel() 00863 { 00864 reject(); 00865 } 00866 00867 QString KBookmarkEditDialog::finalAddress() const 00868 { 00869 Q_ASSERT( m_folderTree ); 00870 return KBookmarkFolderTree::selectedAddress( m_folderTree ); 00871 } 00872 00873 QString KBookmarkEditDialog::finalUrl() const 00874 { 00875 return m_fields->m_url ? m_fields->m_url->text() : QString::null; 00876 } 00877 00878 QString KBookmarkEditDialog::finalTitle() const 00879 { 00880 return m_fields->m_title ? m_fields->m_title->text() : QString::null; 00881 } 00882 00883 void KBookmarkEditDialog::slotUser1() 00884 { 00885 // kdDebug(7043) << "KBookmarkEditDialog::slotUser1" << endl; 00886 Q_ASSERT( m_folderTree ); 00887 00888 QString address = KBookmarkFolderTree::selectedAddress( m_folderTree ); 00889 if ( address.isNull() ) return; 00890 KBookmarkGroup bm = m_mgr->findByAddress( address ).toGroup(); 00891 Q_ASSERT(!bm.isNull()); 00892 Q_ASSERT(m_editType == InsertionMode); 00893 00894 KBookmarkGroup group = bm.createNewFolder( m_mgr ); 00895 if ( !group.isNull() ) 00896 { 00897 KBookmarkGroup parentGroup = group.parentGroup(); 00898 m_mgr->emitChanged( parentGroup ); 00899 } 00900 KBookmarkFolderTree::fillTree( m_folderTree, m_mgr ); 00901 } 00902 00903 /********************************************************************/ 00904 /********************************************************************/ 00905 /********************************************************************/ 00906 00907 static void fillGroup( QListView* listview, KBookmarkFolderTreeItem * parentItem, KBookmarkGroup group, bool expandOpenGroups = true, const QString& address = QString::null ) 00908 { 00909 bool noSubGroups = true; 00910 KBookmarkFolderTreeItem * lastItem = 0L; 00911 KBookmarkFolderTreeItem * item = 0L; 00912 for ( KBookmark bk = group.first() ; !bk.isNull() ; bk = group.next(bk) ) 00913 { 00914 if ( bk.isGroup() ) 00915 { 00916 KBookmarkGroup grp = bk.toGroup(); 00917 item = new KBookmarkFolderTreeItem( parentItem, lastItem, grp ); 00918 fillGroup( listview, item, grp, expandOpenGroups, address ); 00919 if ( expandOpenGroups && grp.isOpen() ) 00920 item->setOpen( true ); 00921 lastItem = item; 00922 noSubGroups = false; 00923 } 00924 if (bk.address() == address) { 00925 listview->setCurrentItem( lastItem ); 00926 listview->ensureItemVisible( item ); 00927 } 00928 } 00929 if ( noSubGroups ) { 00930 parentItem->setOpen( true ); 00931 } 00932 } 00933 00934 QListView* KBookmarkFolderTree::createTree( KBookmarkManager* mgr, QWidget* parent, const char* name, const QString& address ) 00935 { 00936 QListView *listview = new QListView( parent, name ); 00937 00938 listview->setRootIsDecorated( false ); 00939 listview->header()->hide(); 00940 listview->addColumn( i18n("Bookmark"), 200 ); 00941 listview->setSorting( -1, false ); 00942 listview->setSelectionMode( QListView::Single ); 00943 listview->setAllColumnsShowFocus( true ); 00944 listview->setResizeMode( QListView::AllColumns ); 00945 listview->setMinimumSize( 60, 100 ); 00946 00947 fillTree( listview, mgr, address ); 00948 00949 return listview; 00950 } 00951 00952 void KBookmarkFolderTree::fillTree( QListView *listview, KBookmarkManager* mgr, const QString& address ) 00953 { 00954 listview->clear(); 00955 00956 KBookmarkGroup root = mgr->root(); 00957 KBookmarkFolderTreeItem * rootItem = new KBookmarkFolderTreeItem( listview, root ); 00958 listview->setCurrentItem( rootItem ); 00959 rootItem->setSelected( true ); 00960 fillGroup( listview, rootItem, root, (address == root.groupAddress() || address == QString::null) ? true : false, address ); 00961 rootItem->setOpen( true ); 00962 } 00963 00964 static KBookmarkFolderTreeItem* ft_cast( QListViewItem *i ) 00965 { 00966 return static_cast<KBookmarkFolderTreeItem*>( i ); 00967 } 00968 00969 QString KBookmarkFolderTree::selectedAddress( QListView *listview ) 00970 { 00971 if ( !listview) 00972 return QString::null; 00973 KBookmarkFolderTreeItem *item = ft_cast( listview->currentItem() ); 00974 return item ? item->m_bookmark.address() : QString::null; 00975 } 00976 00977 void KBookmarkFolderTree::setAddress( QListView *listview, const QString & address ) 00978 { 00979 KBookmarkFolderTreeItem* it = ft_cast( listview->firstChild() ); 00980 while ( true ) { 00981 kdDebug(7043) << it->m_bookmark.address() << endl; 00982 it = ft_cast( it->itemBelow() ); 00983 if ( !it ) 00984 return; 00985 if ( it->m_bookmark.address() == address ) 00986 break; 00987 } 00988 it->setSelected( true ); 00989 listview->setCurrentItem( it ); 00990 } 00991 00992 /********************************************************************/ 00993 /********************************************************************/ 00994 /********************************************************************/ 00995 00996 // toplevel item 00997 KBookmarkFolderTreeItem::KBookmarkFolderTreeItem( QListView *parent, const KBookmark & gp ) 00998 : QListViewItem(parent, i18n("Bookmarks")), m_bookmark(gp) 00999 { 01000 setPixmap(0, SmallIcon("bookmark")); 01001 setExpandable(true); 01002 } 01003 01004 // group 01005 KBookmarkFolderTreeItem::KBookmarkFolderTreeItem( KBookmarkFolderTreeItem *parent, QListViewItem *after, const KBookmarkGroup & gp ) 01006 : QListViewItem(parent, after, gp.fullText()), m_bookmark(gp) 01007 { 01008 setPixmap(0, SmallIcon( gp.icon() ) ); 01009 setExpandable(true); 01010 } 01011 01012 /********************************************************************/ 01013 /********************************************************************/ 01014 /********************************************************************/ 01015 01016 // NOTE - KBookmarkMenuNSImporter is really === KBookmarkMenuImporter 01017 // i.e, it is _not_ ns specific. and in KDE4 it should be renamed. 01018 01019 void KBookmarkMenuNSImporter::openNSBookmarks() 01020 { 01021 openBookmarks( KNSBookmarkImporter::netscapeBookmarksFile(), "netscape" ); 01022 } 01023 01024 void KBookmarkMenuNSImporter::openBookmarks( const QString &location, const QString &type ) 01025 { 01026 mstack.push(m_menu); 01027 01028 KBookmarkImporterBase *importer = KBookmarkImporterBase::factory(type); 01029 if (!importer) 01030 return; 01031 importer->setFilename(location); 01032 connectToImporter(*importer); 01033 importer->parse(); 01034 01035 delete importer; 01036 } 01037 01038 void KBookmarkMenuNSImporter::connectToImporter(const QObject &importer) 01039 { 01040 connect( &importer, SIGNAL( newBookmark( const QString &, const QCString &, const QString & ) ), 01041 SLOT( newBookmark( const QString &, const QCString &, const QString & ) ) ); 01042 connect( &importer, SIGNAL( newFolder( const QString &, bool, const QString & ) ), 01043 SLOT( newFolder( const QString &, bool, const QString & ) ) ); 01044 connect( &importer, SIGNAL( newSeparator() ), SLOT( newSeparator() ) ); 01045 connect( &importer, SIGNAL( endFolder() ), SLOT( endFolder() ) ); 01046 } 01047 01048 void KBookmarkMenuNSImporter::newBookmark( const QString & text, const QCString & url, const QString & ) 01049 { 01050 QString _text = KStringHandler::csqueeze(text); 01051 _text.replace( '&', "&&" ); 01052 KAction * action = new KBookmarkAction(_text, "html", 0, 01053 m_menu, SLOT( slotBookmarkSelected() ), 01054 m_actionCollection, 0); 01055 action->setProperty( "url", url ); 01056 action->setToolTip( url ); 01057 action->plug( mstack.top()->m_parentMenu ); 01058 mstack.top()->m_actions.append( action ); 01059 } 01060 01061 void KBookmarkMenuNSImporter::newFolder( const QString & text, bool, const QString & ) 01062 { 01063 QString _text = KStringHandler::csqueeze(text); 01064 _text.replace( '&', "&&" ); 01065 KActionMenu * actionMenu = new KActionMenu( _text, "folder", m_actionCollection, 0L ); 01066 actionMenu->plug( mstack.top()->m_parentMenu ); 01067 mstack.top()->m_actions.append( actionMenu ); 01068 KBookmarkMenu *subMenu = new KBookmarkMenu( m_pManager, m_menu->m_pOwner, actionMenu->popupMenu(), 01069 m_actionCollection, false, 01070 m_menu->m_bAddBookmark, QString::null ); 01071 mstack.top()->m_lstSubMenus.append( subMenu ); 01072 01073 mstack.push(subMenu); 01074 } 01075 01076 void KBookmarkMenuNSImporter::newSeparator() 01077 { 01078 mstack.top()->m_parentMenu->insertSeparator(); 01079 } 01080 01081 void KBookmarkMenuNSImporter::endFolder() 01082 { 01083 mstack.pop(); 01084 } 01085 01086 /********************************************************************/ 01087 /********************************************************************/ 01088 /********************************************************************/ 01089 01090 KBookmarkMenu::DynMenuInfo KBookmarkMenu::showDynamicBookmarks( const QString &id ) 01091 { 01092 KConfig config("kbookmarkrc", false, false); 01093 config.setGroup("Bookmarks"); 01094 01095 DynMenuInfo info; 01096 info.show = false; 01097 01098 if (!config.hasKey("DynamicMenus")) { 01099 // upgrade path 01100 if (id == "netscape") { 01101 KBookmarkManager *manager = KBookmarkManager::userBookmarksManager(); 01102 info.show = manager->root().internalElement().attribute("hide_nsbk") != "yes"; 01103 info.location = KNSBookmarkImporter::netscapeBookmarksFile(); 01104 info.type = "netscape"; 01105 info.name = i18n("Netscape Bookmarks"); 01106 } // else, no show 01107 01108 } else { 01109 // have new version config 01110 if (config.hasGroup("DynamicMenu-" + id)) { 01111 config.setGroup("DynamicMenu-" + id); 01112 info.show = config.readBoolEntry("Show"); 01113 info.location = config.readPathEntry("Location"); 01114 info.type = config.readEntry("Type"); 01115 info.name = config.readEntry("Name"); 01116 } // else, no show 01117 } 01118 01119 return info; 01120 } 01121 01122 QStringList KBookmarkMenu::dynamicBookmarksList() 01123 { 01124 KConfig config("kbookmarkrc", false, false); 01125 config.setGroup("Bookmarks"); 01126 01127 QStringList mlist; 01128 if (config.hasKey("DynamicMenus")) 01129 mlist = config.readListEntry("DynamicMenus"); 01130 else 01131 mlist << "netscape"; 01132 01133 return mlist; 01134 } 01135 01136 void KBookmarkMenu::setDynamicBookmarks(const QString &id, const DynMenuInfo &newMenu) 01137 { 01138 KConfig config("kbookmarkrc", false, false); 01139 01140 // add group unconditionally 01141 config.setGroup("DynamicMenu-" + id); 01142 config.writeEntry("Show", newMenu.show); 01143 config.writePathEntry("Location", newMenu.location); 01144 config.writeEntry("Type", newMenu.type); 01145 config.writeEntry("Name", newMenu.name); 01146 01147 QStringList elist; 01148 01149 config.setGroup("Bookmarks"); 01150 if (!config.hasKey("DynamicMenus")) { 01151 if (newMenu.type != "netscape") { 01152 // update from old xbel method to new rc method 01153 // though only if not writing the netscape setting 01154 config.setGroup("DynamicMenu-" "netscape"); 01155 DynMenuInfo xbelSetting; 01156 xbelSetting = showDynamicBookmarks("netscape"); 01157 config.writeEntry("Show", xbelSetting.show); 01158 config.writePathEntry("Location", xbelSetting.location); 01159 config.writeEntry("Type", xbelSetting.type); 01160 config.writeEntry("Name", xbelSetting.name); 01161 } 01162 } else { 01163 elist = config.readListEntry("DynamicMenus"); 01164 } 01165 01166 // make sure list includes type 01167 config.setGroup("Bookmarks"); 01168 if (elist.contains(id) < 1) { 01169 elist << id; 01170 config.writeEntry("DynamicMenus", elist); 01171 } 01172 01173 config.sync(); 01174 } 01175 01176 #include "kbookmarkmenu.moc" 01177 #include "kbookmarkmenu_p.moc"
KDE Logo
This file is part of the documentation for kio Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 10 18:55:25 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003