kate Library API Documentation

katebookmarks.cpp

00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2002, 2003, 2004 Anders Lund <anders.lund@lund.tdcadsl.dk>
00003    Copyright (C) 2002 John Firebaugh <jfirebaugh@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License version 2 as published by the Free Software Foundation.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #include "katebookmarks.h"
00021 #include "katebookmarks.moc"
00022 
00023 #include "katedocument.h"
00024 #include "kateview.h"
00025 
00026 #include <klocale.h>
00027 #include <kaction.h>
00028 #include <kpopupmenu.h>
00029 #include <kstringhandler.h>
00030 #include <kxmlguiclient.h>
00031 #include <kxmlguifactory.h>
00032 #include <kdebug.h>
00033 
00034 #include <qregexp.h>
00035 #include <qmemarray.h>
00036 #include <qevent.h>
00037 
00045 static void ssort( QMemArray<uint> &a, int max )
00046 {
00047   uint tmp, j, maxpos;
00048   for ( uint h = max; h >= 1; h-- )
00049   {
00050     maxpos = 0;
00051     for ( j = 0; j <= h; j++ )
00052       maxpos = a[j] > a[maxpos] ? j : maxpos;
00053     tmp = a[maxpos];
00054     a[maxpos] = a[h];
00055     a[h] = tmp;
00056   }
00057 }
00058 
00059 // TODO add a insort() or bubble_sort - more efficient for aboutToShow() ?
00060 
00061 KateBookmarks::KateBookmarks( KateView* view, Sorting sort )
00062   : QObject( view, "kate bookmarks" )
00063   , m_view( view )
00064   , m_sorting( sort )
00065 {
00066   connect (view->getDoc(), SIGNAL(marksChanged()), this, SLOT(marksChanged()));
00067   m_view->installEventFilter( this );
00068 }
00069 
00070 KateBookmarks::~KateBookmarks()
00071 {
00072 }
00073 
00074 bool KateBookmarks::eventFilter( QObject *o, QEvent *e )
00075 {
00076   if ( o == m_view && e->type() == QEvent::Show )
00077     connectMenuAndDisConnectAgain();
00078   return false;
00079 }
00080 
00081 void KateBookmarks::createActions( KActionCollection* ac )
00082 {
00083   m_bookmarkToggle = new KAction(
00084     i18n("Toggle &Bookmark"), "bookmark", CTRL+Key_B,
00085     this, SLOT(toggleBookmark()),
00086     ac, "bookmarks_toggle" );
00087   m_bookmarkToggle->setWhatsThis(i18n("If a line has no bookmark then add one, otherwise remove it."));
00088 
00089   m_bookmarkClear = new KAction(
00090     i18n("Clear Bookmarks"), 0,
00091     this, SLOT(clearBookmarks()),
00092     ac, "bookmarks_clear");
00093   m_bookmarkClear->setWhatsThis(i18n("Remove all bookmarks of the current document."));
00094 
00095   m_goNext = new KAction(
00096     i18n("Next Bookmark"), "next", ALT + Key_PageDown,
00097     this, SLOT(goNext()),
00098     ac, "bookmarks_next");
00099   m_goNext->setWhatsThis(i18n("Go to the next bookmark."));
00100 
00101   m_goPrevious = new KAction(
00102     i18n("Previous Bookmark"), "previous", ALT + Key_PageUp,
00103     this, SLOT(goPrevious()),
00104     ac, "bookmarks_previous");
00105   m_goPrevious->setWhatsThis(i18n("Go to the previous bookmark."));
00106 
00107   marksChanged ();
00108 }
00109 
00110 void KateBookmarks::connectMenuAndDisConnectAgain()
00111 {
00112     if ( m_view->factory() )
00113     {
00114       QPopupMenu *m = static_cast<QPopupMenu*>(m_view->factory()->container("bookmarks", m_view));
00115 
00116       // connect bookmarks menu aboutToshow
00117       connect( m, SIGNAL(aboutToShow()),
00118               this, SLOT(bookmarkMenuAboutToShow()));
00119 
00120       // anders: I ensure the next/prev actions are available
00121       // and reset their texts (for edit shortcuts dialog, call me picky!).
00122       // TODO - come up with a better solution, please anyone?
00123       connect( m, SIGNAL(aboutToHide()),
00124               this, SLOT(bookmarkMenuAboutToHide()) );
00125 
00126 //       m_view->removeEventFilter( this );
00127       return;
00128     }
00129     // FUCKY-SUCKY -- try later
00130     if ( _tries > 3 ) // give up
00131     {
00132       m_view->removeEventFilter( this );
00133       return;
00134     }
00135 
00136     if ( m_view->isVisible() )
00137       QTimer::singleShot( 0, this, SLOT(connectMenuAndDisConnectAgain()));
00138 
00139     _tries++;
00140 }
00141 
00142 void KateBookmarks::toggleBookmark ()
00143 {
00144   uint mark = m_view->getDoc()->mark( m_view->cursorLine() );
00145   if( mark & KTextEditor::MarkInterface::markType01 )
00146     m_view->getDoc()->removeMark( m_view->cursorLine(),
00147         KTextEditor::MarkInterface::markType01 );
00148   else
00149     m_view->getDoc()->addMark( m_view->cursorLine(),
00150         KTextEditor::MarkInterface::markType01 );
00151 }
00152 
00153 void KateBookmarks::clearBookmarks ()
00154 {
00155   QPtrList<KTextEditor::Mark> m = m_view->getDoc()->marks();
00156   for (uint i=0; i < m.count(); i++)
00157     m_view->getDoc()->removeMark( m.at(i)->line, KTextEditor::MarkInterface::markType01 );
00158 
00159   // just to be sure ;)
00160   marksChanged ();
00161 }
00162 
00163 void KateBookmarks::bookmarkMenuAboutToShow()
00164 {
00165   QPtrList<KTextEditor::Mark> m = m_view->getDoc()->marks();
00166 
00167   QPopupMenu *menu = (QPopupMenu*)m_view->factory()->container("bookmarks", m_view);
00168 
00169   menu->clear();
00170   m_bookmarkToggle->plug( menu );
00171   m_bookmarkClear->plug( menu );
00172   KTextEditor::Mark *next = 0;
00173   KTextEditor::Mark *prev = 0;
00174   uint line = m_view->cursorLine();
00175 
00176   const QRegExp re("&(?!&)");
00177 
00178   int idx( -1 );
00179   QMemArray<uint> sortArray( m.count() );
00180   QPtrListIterator<KTextEditor::Mark> it( m );
00181 
00182   if ( it.count() > 0 )
00183     menu->insertSeparator();
00184 
00185   for( int i = 0; *it; ++it, ++i )
00186   {
00187     if( (*it)->type & KTextEditor::MarkInterface::markType01 )
00188     {
00189       QString bText = KStringHandler::rEmSqueeze
00190                       ( m_view->getDoc()->textLine( (*it)->line ),
00191                         menu->fontMetrics(), 32 );
00192       bText.replace(re, "&&"); // kill undesired accellerators!
00193 
00194       if ( m_sorting == Position )
00195       {
00196         sortArray[i] = (*it)->line;
00197         ssort( sortArray, i );
00198         idx = sortArray.find( (*it)->line ) + 3;
00199       }
00200 
00201       menu->insertItem(
00202           QString("%1 - \"%2\"").arg( (*it)->line+1 ).arg( bText ),
00203           m_view, SLOT(gotoLineNumber(int)), 0, (*it)->line, idx );
00204 
00205       if ( (*it)->line < line )
00206       {
00207         if ( ! prev || prev->line < (*it)->line )
00208           prev = (*it);
00209       }
00210 
00211       else if ( (*it)->line > line )
00212       {
00213         if ( ! next || next->line > (*it)->line )
00214           next = (*it);
00215       }
00216     }
00217   }
00218 
00219   idx = 3;
00220   if ( next )
00221   {
00222     m_goNext->setText( i18n("&Next: %1 - \"%2\"").arg( next->line + 1 )
00223         .arg( KStringHandler::rsqueeze( m_view->getDoc()->textLine( next->line ), 24 ) ) );
00224     m_goNext->plug( menu, idx );
00225     idx++;
00226   }
00227   if ( prev )
00228   {
00229     m_goPrevious->setText( i18n("&Previous: %1 - \"%2\"").arg(prev->line + 1 )
00230         .arg( KStringHandler::rsqueeze( m_view->getDoc()->textLine( prev->line ), 24 ) ) );
00231     m_goPrevious->plug( menu, idx );
00232     idx++;
00233   }
00234   if ( next || prev )
00235     menu->insertSeparator( idx );
00236 }
00237 
00238 /*
00239    Make sure next/prev actions are plugged, and have a clean text
00240 */
00241 void KateBookmarks::bookmarkMenuAboutToHide()
00242 {
00243   QPopupMenu *menu = (QPopupMenu*)m_view->factory()->container("bookmarks", m_view);
00244   //menu->clear();
00245 
00246   m_bookmarkToggle->plug( menu );
00247   m_bookmarkClear->plug( menu );
00248   m_goNext->setText( i18n("Next Bookmark") );
00249   m_goNext->plug( menu );
00250   m_goPrevious->setText( i18n("Previous Bookmark") );
00251   m_goPrevious->plug( menu );
00252 }
00253 
00254 void KateBookmarks::goNext()
00255 {
00256   QPtrList<KTextEditor::Mark> m = m_view->getDoc()->marks();
00257   if (m.isEmpty())
00258     return;
00259 
00260   uint line = m_view->cursorLine();
00261   int found = -1;
00262 
00263   for (uint z=0; z < m.count(); z++)
00264     if ( (m.at(z)->line > line) && ((found == -1) || (uint(found) > m.at(z)->line)) )
00265       found = m.at(z)->line;
00266 
00267   if (found != -1)
00268     m_view->gotoLineNumber ( found );
00269 }
00270 
00271 void KateBookmarks::goPrevious()
00272 {
00273   QPtrList<KTextEditor::Mark> m = m_view->getDoc()->marks();
00274   if (m.isEmpty())
00275     return;
00276 
00277   uint line = m_view->cursorLine();
00278   int found = -1;
00279 
00280   for (uint z=0; z < m.count(); z++)
00281     if ((m.at(z)->line < line) && ((found == -1) || (uint(found) < m.at(z)->line)))
00282       found = m.at(z)->line;
00283 
00284   if (found != -1)
00285     m_view->gotoLineNumber ( found );
00286 }
00287 
00288 void KateBookmarks::marksChanged ()
00289 {
00290   m_bookmarkClear->setEnabled( !m_view->getDoc()->marks().isEmpty() );
00291 }
00292 
00293 // kate: space-indent on; indent-width 2; replace-tabs on;
KDE Logo
This file is part of the documentation for kate Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed May 5 07:18:42 2004 by doxygen 1.3.6 written by Dimitri van Heesch, © 1997-2003