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 _tries=0; 00069 m_bookmarksMenu = 0L; 00070 } 00071 00072 KateBookmarks::~KateBookmarks() 00073 { 00074 } 00075 00076 void KateBookmarks::createActions( KActionCollection* ac ) 00077 { 00078 m_bookmarkToggle = new KAction( 00079 i18n("Toggle &Bookmark"), "bookmark", CTRL+Key_B, 00080 this, SLOT(toggleBookmark()), 00081 ac, "bookmarks_toggle" ); 00082 m_bookmarkToggle->setWhatsThis(i18n("If a line has no bookmark then add one, otherwise remove it.")); 00083 00084 m_bookmarkClear = new KAction( 00085 i18n("Clear Bookmarks"), 0, 00086 this, SLOT(clearBookmarks()), 00087 ac, "bookmarks_clear"); 00088 m_bookmarkClear->setWhatsThis(i18n("Remove all bookmarks of the current document.")); 00089 00090 m_goNext = new KAction( 00091 i18n("Next Bookmark"), "next", ALT + Key_PageDown, 00092 this, SLOT(goNext()), 00093 ac, "bookmarks_next"); 00094 m_goNext->setWhatsThis(i18n("Go to the next bookmark.")); 00095 00096 m_goPrevious = new KAction( 00097 i18n("Previous Bookmark"), "previous", ALT + Key_PageUp, 00098 this, SLOT(goPrevious()), 00099 ac, "bookmarks_previous"); 00100 m_goPrevious->setWhatsThis(i18n("Go to the previous bookmark.")); 00101 00102 marksChanged (); 00103 } 00104 00105 bool KateBookmarks::eventFilter( QObject *o, QEvent *e ) 00106 { 00107 if ( o == m_view && e->type() == QEvent::Show ) 00108 connectMenuAndDisConnectAgain(); 00109 return false; 00110 } 00111 00112 00113 void KateBookmarks::connectMenuAndDisConnectAgain() 00114 { 00115 kdDebug()<<"KateBookmarks::connectMenuAndDisConnectAgain()"<<endl; 00116 00117 if (m_view->factory()) 00118 { 00119 QPtrList<KXMLGUIClient> clients = m_view->factory()->clients(); 00120 QPtrListIterator<KXMLGUIClient> it(clients); 00121 KXMLGUIClient *client; 00122 while ((client = it.current()) != 0) 00123 { 00124 m_bookmarksMenu = static_cast<QPopupMenu*>(client->factory()->container("bookmarks", client)); 00125 00126 if (m_bookmarksMenu) 00127 { 00128 // connect bookmarks menu aboutToshow 00129 disconnect( m_bookmarksMenu, SIGNAL(aboutToShow()), 00130 0, 0); 00131 connect( m_bookmarksMenu, SIGNAL(aboutToShow()), 00132 this, SLOT(bookmarkMenuAboutToShow())); 00133 00134 // anders: I ensure the next/prev actions are available 00135 // and reset their texts (for edit shortcuts dialog, call me picky!). 00136 // TODO - come up with a better solution, please anyone? 00137 disconnect( m_bookmarksMenu, SIGNAL(aboutToHide()), 00138 0, 0); 00139 connect( m_bookmarksMenu, SIGNAL(aboutToHide()), 00140 this, SLOT(bookmarkMenuAboutToHide()) ); 00141 00142 // ### don't remove the event filter, since in kate we will otherwise loose 00143 // the document menu :( 00144 // m_view->removeEventFilter( this ); 00145 return; 00146 } 00147 ++it; 00148 } 00149 } 00150 00151 // FUCKY-SUCKY -- try later 00152 if ( _tries > 3 ) // give up 00153 { 00154 m_view->removeEventFilter( this ); 00155 return; 00156 } 00157 00158 if ( m_view->isVisible() ) 00159 QTimer::singleShot( 0, this, SLOT(connectMenuAndDisConnectAgain())); 00160 00161 _tries++; 00162 } 00163 00164 void KateBookmarks::toggleBookmark () 00165 { 00166 uint mark = m_view->getDoc()->mark( m_view->cursorLine() ); 00167 if( mark & KTextEditor::MarkInterface::markType01 ) 00168 m_view->getDoc()->removeMark( m_view->cursorLine(), 00169 KTextEditor::MarkInterface::markType01 ); 00170 else 00171 m_view->getDoc()->addMark( m_view->cursorLine(), 00172 KTextEditor::MarkInterface::markType01 ); 00173 } 00174 00175 void KateBookmarks::clearBookmarks () 00176 { 00177 QPtrList<KTextEditor::Mark> m = m_view->getDoc()->marks(); 00178 for (uint i=0; i < m.count(); i++) 00179 m_view->getDoc()->removeMark( m.at(i)->line, KTextEditor::MarkInterface::markType01 ); 00180 00181 // just to be sure ;) 00182 marksChanged (); 00183 } 00184 00185 void KateBookmarks::bookmarkMenuAboutToShow() 00186 { 00187 QPtrList<KTextEditor::Mark> m = m_view->getDoc()->marks(); 00188 00189 m_bookmarksMenu->clear(); 00190 m_bookmarkToggle->plug( m_bookmarksMenu ); 00191 m_bookmarkClear->plug( m_bookmarksMenu ); 00192 KTextEditor::Mark *next = 0; 00193 KTextEditor::Mark *prev = 0; 00194 uint line = m_view->cursorLine(); 00195 00196 const QRegExp re("&(?!&)"); 00197 00198 int idx( -1 ); 00199 QMemArray<uint> sortArray( m.count() ); 00200 QPtrListIterator<KTextEditor::Mark> it( m ); 00201 00202 if ( it.count() > 0 ) 00203 m_bookmarksMenu->insertSeparator(); 00204 00205 for( int i = 0; *it; ++it, ++i ) 00206 { 00207 if( (*it)->type & KTextEditor::MarkInterface::markType01 ) 00208 { 00209 QString bText = KStringHandler::rEmSqueeze 00210 ( m_view->getDoc()->textLine( (*it)->line ), 00211 m_bookmarksMenu->fontMetrics(), 32 ); 00212 bText.replace(re, "&&"); // kill undesired accellerators! 00213 00214 if ( m_sorting == Position ) 00215 { 00216 sortArray[i] = (*it)->line; 00217 ssort( sortArray, i ); 00218 idx = sortArray.find( (*it)->line ) + 3; 00219 } 00220 00221 m_bookmarksMenu->insertItem( 00222 QString("%1 - \"%2\"").arg( (*it)->line+1 ).arg( bText ), 00223 m_view, SLOT(gotoLineNumber(int)), 0, (*it)->line, idx ); 00224 00225 if ( (*it)->line < line ) 00226 { 00227 if ( ! prev || prev->line < (*it)->line ) 00228 prev = (*it); 00229 } 00230 00231 else if ( (*it)->line > line ) 00232 { 00233 if ( ! next || next->line > (*it)->line ) 00234 next = (*it); 00235 } 00236 } 00237 } 00238 00239 idx = 3; 00240 if ( next ) 00241 { 00242 m_goNext->setText( i18n("&Next: %1 - \"%2\"").arg( next->line + 1 ) 00243 .arg( KStringHandler::rsqueeze( m_view->getDoc()->textLine( next->line ), 24 ) ) ); 00244 m_goNext->plug( m_bookmarksMenu, idx ); 00245 idx++; 00246 } 00247 if ( prev ) 00248 { 00249 m_goPrevious->setText( i18n("&Previous: %1 - \"%2\"").arg(prev->line + 1 ) 00250 .arg( KStringHandler::rsqueeze( m_view->getDoc()->textLine( prev->line ), 24 ) ) ); 00251 m_goPrevious->plug( m_bookmarksMenu, idx ); 00252 idx++; 00253 } 00254 if ( next || prev ) 00255 m_bookmarksMenu->insertSeparator( idx ); 00256 } 00257 00258 /* 00259 Make sure next/prev actions are plugged, and have a clean text 00260 */ 00261 void KateBookmarks::bookmarkMenuAboutToHide() 00262 { 00263 //menu->clear(); 00264 00265 m_bookmarkToggle->plug( m_bookmarksMenu ); 00266 m_bookmarkClear->plug( m_bookmarksMenu ); 00267 m_goNext->setText( i18n("Next Bookmark") ); 00268 m_goNext->plug( m_bookmarksMenu ); 00269 m_goPrevious->setText( i18n("Previous Bookmark") ); 00270 m_goPrevious->plug( m_bookmarksMenu ); 00271 } 00272 00273 void KateBookmarks::goNext() 00274 { 00275 QPtrList<KTextEditor::Mark> m = m_view->getDoc()->marks(); 00276 if (m.isEmpty()) 00277 return; 00278 00279 uint line = m_view->cursorLine(); 00280 int found = -1; 00281 00282 for (uint z=0; z < m.count(); z++) 00283 if ( (m.at(z)->line > line) && ((found == -1) || (uint(found) > m.at(z)->line)) ) 00284 found = m.at(z)->line; 00285 00286 if (found != -1) 00287 m_view->gotoLineNumber ( found ); 00288 } 00289 00290 void KateBookmarks::goPrevious() 00291 { 00292 QPtrList<KTextEditor::Mark> m = m_view->getDoc()->marks(); 00293 if (m.isEmpty()) 00294 return; 00295 00296 uint line = m_view->cursorLine(); 00297 int found = -1; 00298 00299 for (uint z=0; z < m.count(); z++) 00300 if ((m.at(z)->line < line) && ((found == -1) || (uint(found) < m.at(z)->line))) 00301 found = m.at(z)->line; 00302 00303 if (found != -1) 00304 m_view->gotoLineNumber ( found ); 00305 } 00306 00307 void KateBookmarks::marksChanged () 00308 { 00309 m_bookmarkClear->setEnabled( !m_view->getDoc()->marks().isEmpty() ); 00310 } 00311 00312 // 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.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 16 17:24:00 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003