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