TDE core libraries
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

288 lines
8.4KB

  1. /* This file is part of the KDE libraries
  2. Copyright (C) 2002, 2003, 2004 Anders Lund <anders.lund@lund.tdcadsl.dk>
  3. Copyright (C) 2002 John Firebaugh <jfirebaugh@kde.org>
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License version 2 as published by the Free Software Foundation.
  7. This library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Library General Public License for more details.
  11. You should have received a copy of the GNU Library General Public License
  12. along with this library; see the file COPYING.LIB. If not, write to
  13. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  14. Boston, MA 02110-1301, USA.
  15. */
  16. #include "katebookmarks.h"
  17. #include "katebookmarks.moc"
  18. #include "katedocument.h"
  19. #include "kateview.h"
  20. #include <tdelocale.h>
  21. #include <tdeaction.h>
  22. #include <tdepopupmenu.h>
  23. #include <kstringhandler.h>
  24. #include <kxmlguiclient.h>
  25. #include <kxmlguifactory.h>
  26. #include <tqregexp.h>
  27. #include <tqmemarray.h>
  28. #include <tqevent.h>
  29. /**
  30. Utility: selection sort
  31. sort a TQMemArray<uint> in ascending order.
  32. max it the largest (zerobased) index to sort.
  33. To sort the entire array: ssort( *array, array.size() -1 );
  34. This is only efficient if ran only once.
  35. */
  36. static void ssort( TQMemArray<uint> &a, int max )
  37. {
  38. uint tmp, j, maxpos;
  39. for ( uint h = max; h >= 1; h-- )
  40. {
  41. maxpos = 0;
  42. for ( j = 0; j <= h; j++ )
  43. maxpos = a[j] > a[maxpos] ? j : maxpos;
  44. tmp = a[maxpos];
  45. a[maxpos] = a[h];
  46. a[h] = tmp;
  47. }
  48. }
  49. // TODO add a insort() or bubble_sort - more efficient for aboutToShow() ?
  50. KateBookmarks::KateBookmarks( KateView* view, Sorting sort )
  51. : TQObject( view, "kate bookmarks" )
  52. , m_view( view )
  53. , m_sorting( sort )
  54. {
  55. connect (view->getDoc(), TQT_SIGNAL(marksChanged()), this, TQT_SLOT(marksChanged()));
  56. _tries=0;
  57. m_bookmarksMenu = 0L;
  58. }
  59. KateBookmarks::~KateBookmarks()
  60. {
  61. }
  62. void KateBookmarks::createActions( TDEActionCollection* ac )
  63. {
  64. m_bookmarkToggle = new TDEToggleAction(
  65. i18n("Set &Bookmark"), "bookmark", CTRL+Key_B,
  66. this, TQT_SLOT(toggleBookmark()),
  67. ac, "bookmarks_toggle" );
  68. m_bookmarkToggle->setWhatsThis(i18n("If a line has no bookmark then add one, otherwise remove it."));
  69. m_bookmarkToggle->setCheckedState( i18n("Clear &Bookmark") );
  70. m_bookmarkClear = new TDEAction(
  71. i18n("Clear &All Bookmarks"), 0,
  72. this, TQT_SLOT(clearBookmarks()),
  73. ac, "bookmarks_clear");
  74. m_bookmarkClear->setWhatsThis(i18n("Remove all bookmarks of the current document."));
  75. m_goNext = new TDEAction(
  76. i18n("Next Bookmark"), "next", ALT + Key_PageDown,
  77. this, TQT_SLOT(goNext()),
  78. ac, "bookmarks_next");
  79. m_goNext->setWhatsThis(i18n("Go to the next bookmark."));
  80. m_goPrevious = new TDEAction(
  81. i18n("Previous Bookmark"), "previous", ALT + Key_PageUp,
  82. this, TQT_SLOT(goPrevious()),
  83. ac, "bookmarks_previous");
  84. m_goPrevious->setWhatsThis(i18n("Go to the previous bookmark."));
  85. m_bookmarksMenu = (new TDEActionMenu(i18n("&Bookmarks"), ac, "bookmarks"))->popupMenu();
  86. //connect the aboutToShow() and aboutToHide() signals with
  87. //the bookmarkMenuAboutToShow() and bookmarkMenuAboutToHide() slots
  88. connect( m_bookmarksMenu, TQT_SIGNAL(aboutToShow()), this, TQT_SLOT(bookmarkMenuAboutToShow()));
  89. connect( m_bookmarksMenu, TQT_SIGNAL(aboutToHide()), this, TQT_SLOT(bookmarkMenuAboutToHide()) );
  90. marksChanged ();
  91. bookmarkMenuAboutToHide();
  92. connect( m_view, TQT_SIGNAL( gotFocus( Kate::View * ) ), this, TQT_SLOT( slotViewGotFocus( Kate::View * ) ) );
  93. connect( m_view, TQT_SIGNAL( lostFocus( Kate::View * ) ), this, TQT_SLOT( slotViewLostFocus( Kate::View * ) ) );
  94. }
  95. void KateBookmarks::toggleBookmark ()
  96. {
  97. uint mark = m_view->getDoc()->mark( m_view->cursorLine() );
  98. if( mark & KTextEditor::MarkInterface::markType01 )
  99. m_view->getDoc()->removeMark( m_view->cursorLine(),
  100. KTextEditor::MarkInterface::markType01 );
  101. else
  102. m_view->getDoc()->addMark( m_view->cursorLine(),
  103. KTextEditor::MarkInterface::markType01 );
  104. }
  105. void KateBookmarks::clearBookmarks ()
  106. {
  107. TQPtrList<KTextEditor::Mark> m = m_view->getDoc()->marks();
  108. for (uint i=0; i < m.count(); i++)
  109. m_view->getDoc()->removeMark( m.at(i)->line, KTextEditor::MarkInterface::markType01 );
  110. // just to be sure ;)
  111. marksChanged ();
  112. }
  113. void KateBookmarks::slotViewGotFocus( Kate::View *v )
  114. {
  115. if ( v == (Kate::View*)m_view )
  116. bookmarkMenuAboutToHide();
  117. }
  118. void KateBookmarks::slotViewLostFocus( Kate::View *v )
  119. {
  120. if ( v == (Kate::View*)m_view )
  121. m_bookmarksMenu->clear();
  122. }
  123. void KateBookmarks::insertBookmarks( TQPopupMenu& menu )
  124. {
  125. uint line = m_view->cursorLine();
  126. const TQRegExp re("&(?!&)");
  127. int idx( -1 );
  128. int old_menu_count = menu.count();
  129. KTextEditor::Mark *next = 0;
  130. KTextEditor::Mark *prev = 0;
  131. TQPtrList<KTextEditor::Mark> m = m_view->getDoc()->marks();
  132. TQMemArray<uint> sortArray( m.count() );
  133. TQPtrListIterator<KTextEditor::Mark> it( m );
  134. if ( it.count() > 0 )
  135. menu.insertSeparator();
  136. for( int i = 0; *it; ++it, ++i )
  137. {
  138. if( (*it)->type & KTextEditor::MarkInterface::markType01 )
  139. {
  140. TQString bText = KStringHandler::rEmSqueeze
  141. ( m_view->getDoc()->textLine( (*it)->line ),
  142. menu.fontMetrics(), 32 );
  143. bText.replace(re, "&&"); // kill undesired accellerators!
  144. bText.replace('\t', ' '); // kill tabs, as they are interpreted as shortcuts
  145. if ( m_sorting == Position )
  146. {
  147. sortArray[i] = (*it)->line;
  148. ssort( sortArray, i );
  149. idx = sortArray.find( (*it)->line ) + 3;
  150. }
  151. menu.insertItem(
  152. TQString("%1 - \"%2\"").arg( (*it)->line+1 ).arg( bText ),
  153. m_view, TQT_SLOT(gotoLineNumber(int)), 0, (*it)->line, idx );
  154. if ( (*it)->line < line )
  155. {
  156. if ( ! prev || prev->line < (*it)->line )
  157. prev = (*it);
  158. }
  159. else if ( (*it)->line > line )
  160. {
  161. if ( ! next || next->line > (*it)->line )
  162. next = (*it);
  163. }
  164. }
  165. }
  166. idx = ++old_menu_count;
  167. if ( next )
  168. {
  169. m_goNext->setText( i18n("&Next: %1 - \"%2\"").arg( next->line + 1 )
  170. .arg( KStringHandler::rsqueeze( m_view->getDoc()->textLine( next->line ), 24 ) ) );
  171. m_goNext->plug( &menu, idx );
  172. idx++;
  173. }
  174. if ( prev )
  175. {
  176. m_goPrevious->setText( i18n("&Previous: %1 - \"%2\"").arg(prev->line + 1 )
  177. .arg( KStringHandler::rsqueeze( m_view->getDoc()->textLine( prev->line ), 24 ) ) );
  178. m_goPrevious->plug( &menu, idx );
  179. idx++;
  180. }
  181. if ( next || prev )
  182. menu.insertSeparator( idx );
  183. }
  184. void KateBookmarks::bookmarkMenuAboutToShow()
  185. {
  186. TQPtrList<KTextEditor::Mark> m = m_view->getDoc()->marks();
  187. m_bookmarksMenu->clear();
  188. m_bookmarkToggle->setChecked( m_view->getDoc()->mark( m_view->cursorLine() )
  189. & KTextEditor::MarkInterface::markType01 );
  190. m_bookmarkToggle->plug( m_bookmarksMenu );
  191. m_bookmarkClear->plug( m_bookmarksMenu );
  192. insertBookmarks(*m_bookmarksMenu);
  193. }
  194. /*
  195. Make sure next/prev actions are plugged, and have a clean text
  196. */
  197. void KateBookmarks::bookmarkMenuAboutToHide()
  198. {
  199. m_bookmarkToggle->plug( m_bookmarksMenu );
  200. m_bookmarkClear->plug( m_bookmarksMenu );
  201. m_goNext->setText( i18n("Next Bookmark") );
  202. m_goNext->plug( m_bookmarksMenu );
  203. m_goPrevious->setText( i18n("Previous Bookmark") );
  204. m_goPrevious->plug( m_bookmarksMenu );
  205. }
  206. void KateBookmarks::goNext()
  207. {
  208. TQPtrList<KTextEditor::Mark> m = m_view->getDoc()->marks();
  209. if (m.isEmpty())
  210. return;
  211. uint line = m_view->cursorLine();
  212. int found = -1;
  213. for (uint z=0; z < m.count(); z++)
  214. if ( (m.at(z)->line > line) && ((found == -1) || (uint(found) > m.at(z)->line)) )
  215. found = m.at(z)->line;
  216. if (found != -1)
  217. m_view->gotoLineNumber ( found );
  218. }
  219. void KateBookmarks::goPrevious()
  220. {
  221. TQPtrList<KTextEditor::Mark> m = m_view->getDoc()->marks();
  222. if (m.isEmpty())
  223. return;
  224. uint line = m_view->cursorLine();
  225. int found = -1;
  226. for (uint z=0; z < m.count(); z++)
  227. if ((m.at(z)->line < line) && ((found == -1) || (uint(found) < m.at(z)->line)))
  228. found = m.at(z)->line;
  229. if (found != -1)
  230. m_view->gotoLineNumber ( found );
  231. }
  232. void KateBookmarks::marksChanged ()
  233. {
  234. m_bookmarkClear->setEnabled( !m_view->getDoc()->marks().isEmpty() );
  235. }
  236. // kate: space-indent on; indent-width 2; replace-tabs on;