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