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 }
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
00117 connect( m, SIGNAL(aboutToShow()),
00118 this, SLOT(bookmarkMenuAboutToShow()));
00119
00120
00121
00122
00123 connect( m, SIGNAL(aboutToHide()),
00124 this, SLOT(bookmarkMenuAboutToHide()) );
00125
00126
00127 return;
00128 }
00129
00130 if ( _tries > 3 )
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
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, "&&");
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
00240
00241 void KateBookmarks::bookmarkMenuAboutToHide()
00242 {
00243 QPopupMenu *menu = (QPopupMenu*)m_view->factory()->container("bookmarks", m_view);
00244
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