00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024
00025 #include <assert.h>
00026 #include <dirent.h>
00027 #include <errno.h>
00028 #include <fcntl.h>
00029 #include <stddef.h>
00030 #include <stdlib.h>
00031 #include <unistd.h>
00032
00033 #include "kbookmarkmenu.h"
00034 #include "kbookmarkimporter.h"
00035
00036 #include <qfile.h>
00037 #include <qregexp.h>
00038
00039 #include <kapplication.h>
00040 #include <kaction.h>
00041 #include <kdebug.h>
00042 #include <klocale.h>
00043 #include <kmessagebox.h>
00044 #include <kpopupmenu.h>
00045 #include <kstdaccel.h>
00046 #include <kstdaction.h>
00047
00048 template class QPtrList<KBookmarkMenu>;
00049
00050
00051
00052
00053
00054
00055
00056 KBookmarkMenu::KBookmarkMenu( KBookmarkManager* mgr,
00057 KBookmarkOwner * _owner, KPopupMenu * _parentMenu,
00058 KActionCollection *collec, bool _isRoot, bool _add,
00059 const QString & parentAddress )
00060 : m_bIsRoot(_isRoot), m_bAddBookmark(_add),
00061 m_pManager(mgr), m_pOwner(_owner),
00062 m_parentMenu( _parentMenu ),
00063 m_actionCollection( collec ),
00064 m_parentAddress( parentAddress )
00065 {
00066 m_parentMenu->setKeyboardShortcutsEnabled( true );
00067
00068 m_lstSubMenus.setAutoDelete( true );
00069 m_actions.setAutoDelete( true );
00070
00071 m_bNSBookmark = m_parentAddress.isNull();
00072 if ( !m_bNSBookmark )
00073 {
00074
00075
00076 connect( _parentMenu, SIGNAL( aboutToShow() ),
00077 SLOT( slotAboutToShow() ) );
00078
00079 if ( m_bIsRoot )
00080 {
00081 connect( m_pManager, SIGNAL( changed(const QString &, const QString &) ),
00082 SLOT( slotBookmarksChanged(const QString &) ) );
00083 }
00084 }
00085
00086
00087 if ( m_bIsRoot )
00088 {
00089 if ( m_bAddBookmark )
00090 addAddBookmark();
00091
00092 addEditBookmarks();
00093 }
00094
00095 m_bDirty = true;
00096 }
00097
00098 KBookmarkMenu::~KBookmarkMenu()
00099 {
00100
00101 QPtrListIterator<KAction> it( m_actions );
00102 for (; it.current(); ++it )
00103 it.current()->unplugAll();
00104
00105 m_lstSubMenus.clear();
00106 m_actions.clear();
00107 }
00108
00109 void KBookmarkMenu::ensureUpToDate()
00110 {
00111 slotAboutToShow();
00112 }
00113
00114
00115 void KBookmarkMenu::slotAboutToShow()
00116 {
00117
00118 if ( m_bDirty )
00119 {
00120 m_bDirty = false;
00121 refill();
00122 }
00123 }
00124
00125 void KBookmarkMenu::slotBookmarksChanged( const QString & groupAddress )
00126 {
00127 if (m_bNSBookmark)
00128 return;
00129
00130 if ( groupAddress == m_parentAddress )
00131 {
00132
00133 m_bDirty = true;
00134 }
00135 else
00136 {
00137
00138 QPtrListIterator<KBookmarkMenu> it( m_lstSubMenus );
00139 for (; it.current(); ++it )
00140 {
00141 it.current()->slotBookmarksChanged( groupAddress );
00142 }
00143 }
00144 }
00145
00146 void KBookmarkMenu::refill()
00147 {
00148
00149 m_lstSubMenus.clear();
00150
00151 QPtrListIterator<KAction> it( m_actions );
00152 for (; it.current(); ++it )
00153 it.current()->unplug( m_parentMenu );
00154
00155 m_parentMenu->clear();
00156 m_actions.clear();
00157
00158 fillBookmarkMenu();
00159 m_parentMenu->adjustSize();
00160 }
00161
00162 void KBookmarkMenu::addAddBookmark()
00163 {
00164 if (!kapp->authorizeKAction("bookmarks"))
00165 return;
00166
00167 QString title = i18n( "&Add Bookmark" );
00168 int p;
00169 while ( ( p = title.find( '&' ) ) >= 0 )
00170 title.remove( p, 1 );
00171
00172 KAction * paAddBookmarks = new KAction( title,
00173 "bookmark_add",
00174 m_bIsRoot ? KStdAccel::addBookmark() : KShortcut(),
00175 this,
00176 SLOT( slotAddBookmark() ),
00177 m_actionCollection, m_bIsRoot ? "add_bookmark" : 0 );
00178
00179 paAddBookmarks->setStatusText( i18n( "Add a bookmark for the current document" ) );
00180
00181 paAddBookmarks->plug( m_parentMenu );
00182 m_actions.append( paAddBookmarks );
00183 }
00184
00185 void KBookmarkMenu::addEditBookmarks()
00186 {
00187 if (!kapp->authorizeKAction("bookmarks"))
00188 return;
00189
00190 KAction * m_paEditBookmarks = KStdAction::editBookmarks( m_pManager, SLOT( slotEditBookmarks() ),
00191 m_actionCollection, "edit_bookmarks" );
00192 m_paEditBookmarks->plug( m_parentMenu );
00193 m_paEditBookmarks->setStatusText( i18n( "Edit your bookmark collection in a separate window" ) );
00194 m_actions.append( m_paEditBookmarks );
00195 }
00196
00197 void KBookmarkMenu::addNewFolder()
00198 {
00199 if (!kapp->authorizeKAction("bookmarks"))
00200 return;
00201
00202 QString title = i18n( "&New Bookmark Folder..." );
00203 int p;
00204 while ( ( p = title.find( '&' ) ) >= 0 )
00205 title.remove( p, 1 );
00206
00207 KAction * paNewFolder = new KAction( title,
00208 "folder_new",
00209 0,
00210 this,
00211 SLOT( slotNewFolder() ),
00212 m_actionCollection );
00213
00214 paNewFolder->setStatusText( i18n( "Create a new bookmark folder in this menu" ) );
00215
00216 paNewFolder->plug( m_parentMenu );
00217 m_actions.append( paNewFolder );
00218 }
00219
00220 void KBookmarkMenu::fillBookmarkMenu()
00221 {
00222 if (!kapp->authorizeKAction("bookmarks"))
00223 return;
00224
00225 if ( m_bIsRoot )
00226 {
00227 if ( m_bAddBookmark )
00228 addAddBookmark();
00229
00230 addEditBookmarks();
00231
00232 if ( m_bAddBookmark )
00233 addNewFolder();
00234
00235 if ( m_pManager->showNSBookmarks()
00236 && QFile::exists( KNSBookmarkImporter::netscapeBookmarksFile() ) )
00237 {
00238 m_parentMenu->insertSeparator();
00239
00240 KActionMenu * actionMenu = new KActionMenu( i18n("Netscape Bookmarks"), "netscape",
00241 m_actionCollection, 0L );
00242 actionMenu->plug( m_parentMenu );
00243 m_actions.append( actionMenu );
00244 KBookmarkMenu *subMenu = new KBookmarkMenu( m_pManager, m_pOwner, actionMenu->popupMenu(),
00245 m_actionCollection, false,
00246 m_bAddBookmark, QString::null );
00247 m_lstSubMenus.append(subMenu);
00248 connect(actionMenu->popupMenu(), SIGNAL(aboutToShow()), subMenu, SLOT(slotNSLoad()));
00249 }
00250 }
00251
00252 KBookmarkGroup parentBookmark = m_pManager->findByAddress( m_parentAddress ).toGroup();
00253 Q_ASSERT(!parentBookmark.isNull());
00254 bool separatorInserted = false;
00255 for ( KBookmark bm = parentBookmark.first(); !bm.isNull(); bm = parentBookmark.next(bm) )
00256 {
00257 QString text = bm.text();
00258 text.replace( QRegExp( "&" ), "&&" );
00259 if ( !separatorInserted && m_bIsRoot) {
00260 m_parentMenu->insertSeparator();
00261 separatorInserted = true;
00262 }
00263 if ( !bm.isGroup() )
00264 {
00265 if ( bm.isSeparator() )
00266 {
00267 m_parentMenu->insertSeparator();
00268 }
00269 else
00270 {
00271
00272
00273 KAction * action = new KAction( text, bm.icon(), 0,
00274 this, SLOT( slotBookmarkSelected() ),
00275 m_actionCollection, bm.url().url().utf8() );
00276
00277 action->setStatusText( bm.url().prettyURL() );
00278
00279 action->plug( m_parentMenu );
00280 m_actions.append( action );
00281 }
00282 }
00283 else
00284 {
00285
00286 KActionMenu * actionMenu = new KActionMenu( text, bm.icon(),
00287 m_actionCollection, 0L );
00288 actionMenu->plug( m_parentMenu );
00289 m_actions.append( actionMenu );
00290 KBookmarkMenu *subMenu = new KBookmarkMenu( m_pManager, m_pOwner, actionMenu->popupMenu(),
00291 m_actionCollection, false,
00292 m_bAddBookmark,
00293 bm.address() );
00294 m_lstSubMenus.append( subMenu );
00295 }
00296 }
00297
00298 if ( !m_bIsRoot && m_bAddBookmark )
00299 {
00300 if ( m_parentMenu->count() > 0 )
00301 m_parentMenu->insertSeparator();
00302 addAddBookmark();
00303 addNewFolder();
00304 }
00305 }
00306
00307 void KBookmarkMenu::slotAddBookmark()
00308 {
00309 QString url = m_pOwner->currentURL();
00310 if (url.isEmpty())
00311 {
00312 KMessageBox::error( 0L, i18n("Can't add bookmark with empty URL"));
00313 return;
00314 }
00315 QString title = m_pOwner->currentTitle();
00316 if (title.isEmpty())
00317 title = url;
00318
00319 KBookmarkGroup parentBookmark = m_pManager->findByAddress( m_parentAddress ).toGroup();
00320 Q_ASSERT(!parentBookmark.isNull());
00321
00322 KBookmark ch = parentBookmark.first();
00323 int count = 1;
00324 QString uniqueTitle = title;
00325 do
00326 {
00327 while ( !ch.isNull() )
00328 {
00329 if ( uniqueTitle == ch.text() )
00330 {
00331
00332 if ( url != ch.url().url() )
00333 {
00334 uniqueTitle = title + QString(" (%1)").arg(++count);
00335
00336 ch = parentBookmark.first();
00337 break;
00338 }
00339 else
00340 {
00341
00342 return;
00343 }
00344 }
00345 ch = parentBookmark.next( ch );
00346 }
00347 } while ( !ch.isNull() );
00348
00349 parentBookmark.addBookmark( m_pManager, uniqueTitle, url );
00350 m_pManager->emitChanged( parentBookmark );
00351 }
00352
00353 void KBookmarkMenu::slotNewFolder()
00354 {
00355 if ( !m_pOwner ) return;
00356 KBookmarkGroup parentBookmark = m_pManager->findByAddress( m_parentAddress ).toGroup();
00357 Q_ASSERT(!parentBookmark.isNull());
00358 KBookmarkGroup group = parentBookmark.createNewFolder( m_pManager );
00359 if ( !group.isNull() )
00360 {
00361 KBookmarkGroup parentGroup = group.parentGroup();
00362 m_pManager->emitChanged( parentGroup );
00363 }
00364 }
00365
00366 void KBookmarkMenu::slotBookmarkSelected()
00367 {
00368
00369 if ( !m_pOwner ) return;
00370
00371
00372
00373 m_pOwner->openBookmarkURL( QString::fromUtf8(sender()->name()) );
00374 }
00375
00376
00377
00378 void KBookmarkMenu::slotNSBookmarkSelected()
00379 {
00380 QString link(sender()->name()+8);
00381
00382 m_pOwner->openBookmarkURL( link );
00383 }
00384
00385 void KBookmarkMenu::slotNSLoad()
00386 {
00387 m_parentMenu->disconnect(SIGNAL(aboutToShow()));
00388
00389 KBookmarkMenuNSImporter importer( m_pManager, this, m_actionCollection );
00390 importer.openNSBookmarks();
00391 }
00392
00393 void KBookmarkMenuNSImporter::openNSBookmarks()
00394 {
00395 mstack.push(m_menu);
00396 KNSBookmarkImporter importer( KNSBookmarkImporter::netscapeBookmarksFile() );
00397 connect( &importer, SIGNAL( newBookmark( const QString &, const QCString &, const QString & ) ),
00398 SLOT( newBookmark( const QString &, const QCString &, const QString & ) ) );
00399 connect( &importer, SIGNAL( newFolder( const QString &, bool, const QString & ) ),
00400 SLOT( newFolder( const QString &, bool, const QString & ) ) );
00401 connect( &importer, SIGNAL( newSeparator() ), SLOT( newSeparator() ) );
00402 connect( &importer, SIGNAL( endFolder() ), SLOT( endFolder() ) );
00403 importer.parseNSBookmarks();
00404 }
00405
00406 void KBookmarkMenuNSImporter::newBookmark( const QString & text, const QCString & url, const QString & )
00407 {
00408 QCString actionLink = "bookmark" + url;
00409 QString _text = text;
00410 _text.replace( QRegExp( "&" ), "&&" );
00411 KAction * action = new KAction( _text, "html", 0, m_menu, SLOT( slotNSBookmarkSelected() ),
00412 m_actionCollection, actionLink.data());
00413 action->setStatusText( url );
00414 action->plug( mstack.top()->m_parentMenu );
00415 mstack.top()->m_actions.append( action );
00416 }
00417
00418 void KBookmarkMenuNSImporter::newFolder( const QString & text, bool, const QString & )
00419 {
00420 QString _text = text;
00421 _text.replace( QRegExp( "&" ), "&&" );
00422 KActionMenu * actionMenu = new KActionMenu( _text, "folder", m_actionCollection, 0L );
00423 actionMenu->plug( mstack.top()->m_parentMenu );
00424 mstack.top()->m_actions.append( actionMenu );
00425 KBookmarkMenu *subMenu = new KBookmarkMenu( m_pManager, m_menu->m_pOwner, actionMenu->popupMenu(),
00426 m_actionCollection, false,
00427 m_menu->m_bAddBookmark, QString::null );
00428 mstack.top()->m_lstSubMenus.append( subMenu );
00429
00430 mstack.push(subMenu);
00431 }
00432
00433 void KBookmarkMenuNSImporter::newSeparator()
00434 {
00435 mstack.top()->m_parentMenu->insertSeparator();
00436 }
00437
00438 void KBookmarkMenuNSImporter::endFolder()
00439 {
00440 mstack.pop();
00441 }
00442
00443 #include "kbookmarkmenu.moc"