mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-23 18:32:50 +00:00
295 lines
9.8 KiB
C++
295 lines
9.8 KiB
C++
/* This file is part of the KDE libraries
|
|
Copyright (C) 2002, 2003, 2004 Anders Lund <anders.lund@lund.tdcadsl.dk>
|
|
Copyright (C) 2002 John Firebaugh <jfirebaugh@kde.org>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License version 2 as published by the Free Software Foundation.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "katebookmarks.h"
|
|
#include "moc_katebookmarks.cpp"
|
|
|
|
#include "katedocument.h"
|
|
#include "kateview.h"
|
|
|
|
#include <klocale.h>
|
|
#include <kaction.h>
|
|
#include <kactioncollection.h>
|
|
#include <kguiitem.h>
|
|
#include <kicon.h>
|
|
#include <kmenu.h>
|
|
#include <kstringhandler.h>
|
|
#include <kxmlguiclient.h>
|
|
#include <kxmlguifactory.h>
|
|
#include <ktoggleaction.h>
|
|
#include <kactionmenu.h>
|
|
|
|
#include <QtCore/QRegExp>
|
|
#include <QtCore/QEvent>
|
|
#include <QtCore/QVector>
|
|
|
|
namespace KTextEditor{ class Document; }
|
|
|
|
KateBookmarks::KateBookmarks( KateView* view, Sorting sort )
|
|
: QObject( view )
|
|
, m_view( view )
|
|
, m_bookmarkClear (0)
|
|
, m_sorting( sort )
|
|
{
|
|
setObjectName( "kate bookmarks" );
|
|
connect (view->doc(), SIGNAL(marksChanged(KTextEditor::Document*)), this, SLOT(marksChanged()));
|
|
_tries=0;
|
|
m_bookmarksMenu = 0L;
|
|
}
|
|
|
|
KateBookmarks::~KateBookmarks()
|
|
{
|
|
}
|
|
|
|
void KateBookmarks::createActions( KActionCollection* ac )
|
|
{
|
|
m_bookmarkToggle = new KToggleAction( i18n("Set &Bookmark"), this );
|
|
ac->addAction( "bookmarks_toggle", m_bookmarkToggle );
|
|
m_bookmarkToggle->setIcon( KIcon( "bookmark-new" ) );
|
|
m_bookmarkToggle->setShortcut( Qt::CTRL+Qt::Key_B );
|
|
m_bookmarkToggle->setWhatsThis(i18n("If a line has no bookmark then add one, otherwise remove it."));
|
|
connect( m_bookmarkToggle, SIGNAL(triggered()), this, SLOT(toggleBookmark()) );
|
|
|
|
m_bookmarkClear = new KAction( i18n("Clear &All Bookmarks"), this );
|
|
ac->addAction("bookmarks_clear", m_bookmarkClear);
|
|
m_bookmarkClear->setWhatsThis(i18n("Remove all bookmarks of the current document."));
|
|
connect( m_bookmarkClear, SIGNAL(triggered()), this, SLOT(clearBookmarks()) );
|
|
|
|
m_goNext = new KAction( i18n("Next Bookmark"), this);
|
|
ac->addAction("bookmarks_next", m_goNext);
|
|
m_goNext->setIcon( KIcon( "go-down-search" ) );
|
|
m_goNext->setShortcut( Qt::ALT + Qt::Key_PageDown );
|
|
m_goNext->setWhatsThis(i18n("Go to the next bookmark."));
|
|
connect( m_goNext, SIGNAL(triggered()), this, SLOT(goNext()) );
|
|
|
|
m_goPrevious = new KAction( i18n("Previous Bookmark"), this);
|
|
ac->addAction("bookmarks_previous", m_goPrevious);
|
|
m_goPrevious->setIcon( KIcon( "go-up-search" ) );
|
|
m_goPrevious->setShortcut( Qt::ALT + Qt::Key_PageUp );
|
|
m_goPrevious->setWhatsThis(i18n("Go to the previous bookmark."));
|
|
connect( m_goPrevious, SIGNAL(triggered()), this, SLOT(goPrevious()) );
|
|
|
|
KActionMenu *actionMenu = new KActionMenu(i18n("&Bookmarks"), this);
|
|
ac->addAction("bookmarks", actionMenu);
|
|
m_bookmarksMenu = actionMenu->menu();
|
|
|
|
connect( m_bookmarksMenu, SIGNAL(aboutToShow()), this, SLOT(bookmarkMenuAboutToShow()));
|
|
|
|
marksChanged ();
|
|
|
|
// Always want the actions with shortcuts plugged into something so their shortcuts can work
|
|
m_view->addAction(m_bookmarkToggle);
|
|
m_view->addAction(m_bookmarkClear);
|
|
m_view->addAction(m_goNext);
|
|
m_view->addAction(m_goPrevious);
|
|
}
|
|
|
|
void KateBookmarks::toggleBookmark ()
|
|
{
|
|
uint mark = m_view->doc()->mark( m_view->cursorPosition().line() );
|
|
if( mark & KTextEditor::MarkInterface::markType01 )
|
|
m_view->doc()->removeMark( m_view->cursorPosition().line(),
|
|
KTextEditor::MarkInterface::markType01 );
|
|
else
|
|
m_view->doc()->addMark( m_view->cursorPosition().line(),
|
|
KTextEditor::MarkInterface::markType01 );
|
|
}
|
|
|
|
void KateBookmarks::clearBookmarks ()
|
|
{
|
|
QHash<int, KTextEditor::Mark*> m = m_view->doc()->marks();
|
|
for (QHash<int, KTextEditor::Mark*>::const_iterator i = m.constBegin(); i != m.constEnd(); ++i)
|
|
m_view->doc()->removeMark( i.value()->line, KTextEditor::MarkInterface::markType01 );
|
|
|
|
// just to be sure ;)
|
|
// dominik: the following line can be deleted afaics, as Document::removeMark emits this signal.
|
|
marksChanged ();
|
|
}
|
|
|
|
void KateBookmarks::insertBookmarks( QMenu& menu )
|
|
{
|
|
int line = m_view->cursorPosition().line();
|
|
const QRegExp re("&(?!&)");
|
|
int next = -1; // -1 means next bookmark doesn't exist
|
|
int prev = -1; // -1 means previous bookmark doesn't exist
|
|
|
|
const QHash<int, KTextEditor::Mark*> &m = m_view->doc()->marks();
|
|
QVector<int> bookmarkLineArray; // Array of line numbers which have bookmarks
|
|
|
|
if ( m.isEmpty() )
|
|
return;
|
|
|
|
// Find line numbers where bookmarks are set & store those line numbers in bookmarkLineArray
|
|
for (QHash<int, KTextEditor::Mark*>::const_iterator it = m.constBegin(); it != m.constEnd(); ++it)
|
|
{
|
|
if( it.value()->type & KTextEditor::MarkInterface::markType01 )
|
|
{
|
|
bookmarkLineArray.append(it.value()->line);
|
|
}
|
|
}
|
|
|
|
if ( m_sorting == Position )
|
|
{
|
|
qSort(bookmarkLineArray.begin(), bookmarkLineArray.end());
|
|
}
|
|
|
|
QAction* firstNewAction = menu.addSeparator();
|
|
// Consider each line with a bookmark one at a time
|
|
for (int i = 0; i < bookmarkLineArray.size(); ++i)
|
|
{
|
|
// Get text in this particular line in a QString
|
|
QString bText = menu.fontMetrics().elidedText
|
|
( m_view->doc()->line( bookmarkLineArray.at(i) ),
|
|
Qt::ElideRight,
|
|
menu.fontMetrics().maxWidth() * 32 );
|
|
bText.replace(re, "&&"); // kill undesired accellerators!
|
|
bText.replace('\t', ' '); // kill tabs, as they are interpreted as shortcuts
|
|
|
|
QAction *before=0;
|
|
if ( m_sorting == Position )
|
|
{
|
|
// 3 actions already present
|
|
if (menu.actions().size() <= i+3)
|
|
before=0;
|
|
else
|
|
before=menu.actions()[i+3];
|
|
}
|
|
|
|
// Adding action for this bookmark in menu
|
|
if (before) {
|
|
QAction *a=new QAction(QString("%1 %3 - \"%2\"")
|
|
.arg( bookmarkLineArray.at(i) + 1 ).arg( bText )
|
|
.arg(false),&menu);
|
|
menu.insertAction(before,a);
|
|
connect(a,SIGNAL(activated()),this,SLOT(gotoLine()));
|
|
a->setData(bookmarkLineArray.at(i));
|
|
if (!firstNewAction) firstNewAction = a;
|
|
|
|
} else {
|
|
QAction* a = menu.addAction(QString("%1 %3 - \"%2\"")
|
|
.arg( bookmarkLineArray.at(i) + 1 ).arg( bText )
|
|
.arg(false),
|
|
this, SLOT(gotoLine()));
|
|
a->setData(bookmarkLineArray.at(i));
|
|
}
|
|
|
|
// Find the line number of previous & next bookmark (if present) in relation to the cursor
|
|
if ( bookmarkLineArray.at(i) < line )
|
|
{
|
|
if ( (prev == -1) || prev < (bookmarkLineArray.at(i)) )
|
|
prev = bookmarkLineArray.at(i);
|
|
}
|
|
else if ( bookmarkLineArray.at(i) > line )
|
|
{
|
|
if ( (next == -1) || next > (bookmarkLineArray.at(i)) )
|
|
next = bookmarkLineArray.at(i);
|
|
}
|
|
}
|
|
|
|
if ( next != -1 )
|
|
{
|
|
// Insert action for next bookmark
|
|
m_goNext->setText( i18n("&Next: %1 - \"%2\"", next + 1 ,
|
|
KStringHandler::rsqueeze( m_view->doc()->line( next ), 24 ) ) );
|
|
menu.insertAction(firstNewAction, m_goNext);
|
|
firstNewAction = m_goNext;
|
|
}
|
|
if ( prev != -1 )
|
|
{
|
|
// Insert action for previous bookmark
|
|
m_goPrevious->setText( i18n("&Previous: %1 - \"%2\"", prev + 1 ,
|
|
KStringHandler::rsqueeze( m_view->doc()->line( prev ), 24 ) ) );
|
|
menu.insertAction(firstNewAction, m_goPrevious);
|
|
firstNewAction = m_goPrevious;
|
|
}
|
|
|
|
if ( next != -1 || prev != -1 )
|
|
menu.insertSeparator(firstNewAction);
|
|
}
|
|
|
|
void KateBookmarks::gotoLine()
|
|
{
|
|
if (!sender()) return;
|
|
gotoLine(((QAction*)(sender()))->data().toInt());
|
|
}
|
|
|
|
void KateBookmarks::gotoLine (int line)
|
|
{
|
|
m_view->setCursorPosition(KTextEditor::Cursor(line, 0));
|
|
}
|
|
|
|
void KateBookmarks::bookmarkMenuAboutToShow()
|
|
{
|
|
m_bookmarksMenu->clear();
|
|
m_bookmarkToggle->setChecked( m_view->doc()->mark( m_view->cursorPosition().line() )
|
|
& KTextEditor::MarkInterface::markType01 );
|
|
m_bookmarksMenu->addAction(m_bookmarkToggle);
|
|
m_bookmarksMenu->addAction(m_bookmarkClear);
|
|
|
|
m_goNext->setText( i18n("Next Bookmark") );
|
|
m_goPrevious->setText( i18n("Previous Bookmark") );
|
|
|
|
insertBookmarks(*m_bookmarksMenu);
|
|
}
|
|
|
|
void KateBookmarks::goNext()
|
|
{
|
|
const QHash<int, KTextEditor::Mark*> &m = m_view->doc()->marks();
|
|
if (m.isEmpty())
|
|
return;
|
|
|
|
int line = m_view->cursorPosition().line();
|
|
int found = -1;
|
|
|
|
for (QHash<int, KTextEditor::Mark*>::const_iterator it = m.constBegin(); it != m.constEnd(); ++it)
|
|
{
|
|
if ( (it.value()->line > line) && ((found == -1) || (found > it.value()->line)) )
|
|
found = it.value()->line;
|
|
}
|
|
|
|
if (found != -1)
|
|
gotoLine ( found );
|
|
}
|
|
|
|
void KateBookmarks::goPrevious()
|
|
{
|
|
const QHash<int, KTextEditor::Mark*> &m = m_view->doc()->marks();
|
|
if (m.isEmpty())
|
|
return;
|
|
|
|
int line = m_view->cursorPosition().line();
|
|
int found = -1;
|
|
|
|
for (QHash<int, KTextEditor::Mark*>::const_iterator it = m.constBegin(); it != m.constEnd(); ++it)
|
|
{
|
|
if ((it.value()->line < line) && ((found == -1) || (found < it.value()->line)))
|
|
found = it.value()->line;
|
|
}
|
|
|
|
if (found != -1)
|
|
gotoLine ( found );
|
|
}
|
|
|
|
void KateBookmarks::marksChanged ()
|
|
{
|
|
if (m_bookmarkClear)
|
|
m_bookmarkClear->setEnabled( !m_view->doc()->marks().isEmpty() );
|
|
}
|
|
|
|
// kate: space-indent on; indent-width 2; replace-tabs on;
|