00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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
00129 disconnect( m_bookmarksMenu, SIGNAL(aboutToShow()),
00130 0, 0);
00131 connect( m_bookmarksMenu, SIGNAL(aboutToShow()),
00132 this, SLOT(bookmarkMenuAboutToShow()));
00133
00134
00135
00136
00137 disconnect( m_bookmarksMenu, SIGNAL(aboutToHide()),
00138 0, 0);
00139 connect( m_bookmarksMenu, SIGNAL(aboutToHide()),
00140 this, SLOT(bookmarkMenuAboutToHide()) );
00141
00142
00143
00144
00145 return;
00146 }
00147 ++it;
00148 }
00149 }
00150
00151
00152 if ( _tries > 3 )
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
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, "&&");
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
00260
00261 void KateBookmarks::bookmarkMenuAboutToHide()
00262 {
00263
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