• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • applications API Reference
  • KDE Home
  • Contact Us
 

Kate

  • sources
  • kde-4.12
  • applications
  • kate
  • part
  • search
katesearchbar.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE libraries
2  Copyright (C) 2009-2010 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
3  Copyright (C) 2007 Sebastian Pipping <webmaster@hartwork.org>
4  Copyright (C) 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
5  Copyright (C) 2007 Thomas Friedrichsmeier <thomas.friedrichsmeier@ruhr-uni-bochum.de>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License version 2 as published by the Free Software Foundation.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 */
21 
22 #include "katesearchbar.h"
23 #include "katesearchbar.moc"
24 
25 #include "kateregexp.h"
26 #include "katematch.h"
27 #include "kateview.h"
28 #include "katedocument.h"
29 #include "kateundomanager.h"
30 #include "kateconfig.h"
31 #include "katerenderer.h"
32 
33 #include <ktexteditor/movingcursor.h>
34 #include <ktexteditor/movingrange.h>
35 #include <ktexteditor/messageinterface.h>
36 
37 #include "ui_searchbarincremental.h"
38 #include "ui_searchbarpower.h"
39 
40 #include <kcolorscheme.h>
41 #include <kmessagebox.h>
42 #include <kstandardaction.h>
43 
44 #include <QtGui/QVBoxLayout>
45 #include <QtGui/QComboBox>
46 #include <QtGui/QCheckBox>
47 #include <QtGui/QShortcut>
48 
49 // Turn debug messages on/off here
50 // #define FAST_DEBUG_ENABLE
51 
52 #ifdef FAST_DEBUG_ENABLE
53 # define FAST_DEBUG(x) kDebug() << x
54 #else
55 # define FAST_DEBUG(x)
56 #endif
57 
58 using namespace KTextEditor;
59 
60 namespace {
61 
62 class AddMenuManager {
63 
64 private:
65  QVector<QString> m_insertBefore;
66  QVector<QString> m_insertAfter;
67  QSet<QAction *> m_actionPointers;
68  uint m_indexWalker;
69  QMenu * m_menu;
70 
71 public:
72  AddMenuManager(QMenu * parent, int expectedItemCount)
73  : m_insertBefore(QVector<QString>(expectedItemCount)),
74  m_insertAfter(QVector<QString>(expectedItemCount)),
75  m_indexWalker(0),
76  m_menu(NULL) {
77  Q_ASSERT(parent != NULL);
78  m_menu = parent->addMenu(i18n("Add..."));
79  if (m_menu == NULL) {
80  return;
81  }
82  m_menu->setIcon(KIcon("list-add"));
83  }
84 
85  void enableMenu(bool enabled) {
86  if (m_menu == NULL) {
87  return;
88  }
89  m_menu->setEnabled(enabled);
90  }
91 
92  void addEntry(const QString & before, const QString after,
93  const QString description, const QString & realBefore = QString(),
94  const QString & realAfter = QString()) {
95  if (m_menu == NULL) {
96  return;
97  }
98  QAction * const action = m_menu->addAction(before + after + '\t' + description);
99  m_insertBefore[m_indexWalker] = QString(realBefore.isEmpty() ? before : realBefore);
100  m_insertAfter[m_indexWalker] = QString(realAfter.isEmpty() ? after : realAfter);
101  action->setData(QVariant(m_indexWalker++));
102  m_actionPointers.insert(action);
103  }
104 
105  void addSeparator() {
106  if (m_menu == NULL) {
107  return;
108  }
109  m_menu->addSeparator();
110  }
111 
112  void handle(QAction * action, QLineEdit * lineEdit) {
113  if (!m_actionPointers.contains(action)) {
114  return;
115  }
116 
117  const int cursorPos = lineEdit->cursorPosition();
118  const int index = action->data().toUInt();
119  const QString & before = m_insertBefore[index];
120  const QString & after = m_insertAfter[index];
121  lineEdit->insert(before + after);
122  lineEdit->setCursorPosition(cursorPos + before.count());
123  lineEdit->setFocus();
124  }
125 };
126 
127 } // anon namespace
128 
129 
130 
131 KateSearchBar::KateSearchBar(bool initAsPower, KateView* view, KateViewConfig *config)
132  : KateViewBarWidget(true, view),
133  m_view(view),
134  m_config(config),
135  m_layout(new QVBoxLayout()),
136  m_widget(NULL),
137  m_incUi(NULL),
138  m_incInitCursor(view->cursorPosition()),
139  m_powerUi(NULL),
140  highlightMatchAttribute (new Attribute()),
141  highlightReplacementAttribute (new Attribute()),
142  m_incHighlightAll(false),
143  m_incFromCursor(true),
144  m_incMatchCase(false),
145  m_powerMatchCase(true),
146  m_powerFromCursor(false),
147  m_powerHighlightAll(false),
148  m_powerMode(0),
149  m_unitTestMode(false)
150 {
151 
152  connect(view, SIGNAL(cursorPositionChanged(KTextEditor::View*,KTextEditor::Cursor)),
153  this, SLOT(updateIncInitCursor()));
154 
155  // init match attribute
156  Attribute::Ptr mouseInAttribute(new Attribute());
157  mouseInAttribute->setFontBold(true);
158  highlightMatchAttribute->setDynamicAttribute (Attribute::ActivateMouseIn, mouseInAttribute);
159 
160  Attribute::Ptr caretInAttribute(new Attribute());
161  caretInAttribute->setFontItalic(true);
162  highlightMatchAttribute->setDynamicAttribute (Attribute::ActivateCaretIn, caretInAttribute);
163 
164  updateHighlightColors();
165 
166  // Modify parent
167  QWidget * const widget = centralWidget();
168  widget->setLayout(m_layout);
169  m_layout->setMargin(0);
170 
171  // allow to have small size, for e.g. Kile
172  setMinimumWidth (100);
173 
174  // Copy global to local config backup
175  const long searchFlags = m_config->searchFlags();
176  m_incHighlightAll = (searchFlags & KateViewConfig::IncHighlightAll) != 0;
177  m_incFromCursor = (searchFlags & KateViewConfig::IncFromCursor) != 0;
178  m_incMatchCase = (searchFlags & KateViewConfig::IncMatchCase) != 0;
179  m_powerMatchCase = (searchFlags & KateViewConfig::PowerMatchCase) != 0;
180  m_powerFromCursor = (searchFlags & KateViewConfig::PowerFromCursor) != 0;
181  m_powerHighlightAll = (searchFlags & KateViewConfig::PowerHighlightAll) != 0;
182  m_powerMode = ((searchFlags & KateViewConfig::PowerModeRegularExpression) != 0)
183  ? MODE_REGEX
184  : (((searchFlags & KateViewConfig::PowerModeEscapeSequences) != 0)
185  ? MODE_ESCAPE_SEQUENCES
186  : (((searchFlags & KateViewConfig::PowerModeWholeWords) != 0)
187  ? MODE_WHOLE_WORDS
188  : MODE_PLAIN_TEXT));
189 
190 
191  // Load one of either dialogs
192  if (initAsPower) {
193  enterPowerMode();
194  } else {
195  enterIncrementalMode();
196  }
197 
198  updateSelectionOnly();
199  connect(view, SIGNAL(selectionChanged(KTextEditor::View*)),
200  this, SLOT(updateSelectionOnly()));
201 }
202 
203 
204 
205 KateSearchBar::~KateSearchBar() {
206  clearHighlights();
207  delete m_layout;
208  delete m_widget;
209 
210  delete m_incUi;
211  delete m_powerUi;
212 }
213 
214 void KateSearchBar::closed()
215 {
216  // remove search from the view bar, because it vertically bloats up the
217  // stacked layout in KateViewBar.
218  if (viewBar()) {
219  viewBar()->removeBarWidget(this);
220  }
221 
222  clearHighlights();
223 }
224 
225 
226 void KateSearchBar::setReplacementPattern(const QString &replacementPattern) {
227  Q_ASSERT(isPower());
228 
229  if (this->replacementPattern() == replacementPattern)
230  return;
231 
232  m_powerUi->replacement->setEditText(replacementPattern);
233 }
234 
235 
236 
237 QString KateSearchBar::replacementPattern() const
238 {
239  Q_ASSERT(isPower());
240 
241  return m_powerUi->replacement->currentText();
242 }
243 
244 
245 
246 void KateSearchBar::setSearchMode(KateSearchBar::SearchMode mode)
247 {
248  Q_ASSERT(isPower());
249 
250  m_powerUi->searchMode->setCurrentIndex(mode);
251 }
252 
253 
254 
255 void KateSearchBar::findNext()
256 {
257  const bool found = find();
258 
259  if (found) {
260  QComboBox *combo = m_powerUi != 0 ? m_powerUi->pattern : m_incUi->pattern;
261 
262  // Add to search history
263  addCurrentTextToHistory(combo);
264  }
265 }
266 
267 
268 
269 void KateSearchBar::findPrevious() {
270  const bool found = find(SearchBackward);
271 
272  if (found) {
273  QComboBox *combo = m_powerUi != 0 ? m_powerUi->pattern : m_incUi->pattern;
274 
275  // Add to search history
276  addCurrentTextToHistory(combo);
277  }
278 }
279 
280 void KateSearchBar::showInfoMessage(const QString& text)
281 {
282  delete m_infoMessage;
283 
284  m_infoMessage = new KTextEditor::Message(text, KTextEditor::Message::Positive);
285  m_infoMessage->setPosition(KTextEditor::Message::BottomInView);
286  m_infoMessage->setAutoHide(3000); // 3 seconds
287  m_infoMessage->setView(m_view);
288 
289  m_view->doc()->postMessage(m_infoMessage);
290 }
291 
292 void KateSearchBar::highlightMatch(const Range & range) {
293  KTextEditor::MovingRange* const highlight = m_view->doc()->newMovingRange(range, Kate::TextRange::DoNotExpand);
294  highlight->setView(m_view); // show only in this view
295  highlight->setAttributeOnlyForViews(true);
296  // use z depth defined in moving ranges interface
297  highlight->setZDepth (-10000.0);
298  highlight->setAttribute(highlightMatchAttribute);
299  m_hlRanges.append(highlight);
300 }
301 
302 void KateSearchBar::highlightReplacement(const Range & range) {
303  KTextEditor::MovingRange* const highlight = m_view->doc()->newMovingRange(range, Kate::TextRange::DoNotExpand);
304  highlight->setView(m_view); // show only in this view
305  highlight->setAttributeOnlyForViews(true);
306  // use z depth defined in moving ranges interface
307  highlight->setZDepth (-10000.0);
308  highlight->setAttribute(highlightReplacementAttribute);
309  m_hlRanges.append(highlight);
310 }
311 
312 void KateSearchBar::indicateMatch(MatchResult matchResult) {
313  QLineEdit * const lineEdit = isPower() ? m_powerUi->pattern->lineEdit()
314  : m_incUi->pattern->lineEdit();
315  QPalette background(lineEdit->palette());
316 
317  switch (matchResult) {
318  case MatchFound: // FALLTHROUGH
319  case MatchWrappedForward:
320  case MatchWrappedBackward:
321  // Green background for line edit
322  KColorScheme::adjustBackground(background, KColorScheme::PositiveBackground);
323  break;
324  case MatchMismatch:
325  // Red background for line edit
326  KColorScheme::adjustBackground(background, KColorScheme::NegativeBackground);
327  break;
328  case MatchNothing:
329  // Reset background of line edit
330  background = QPalette();
331  break;
332  case MatchNeutral:
333  KColorScheme::adjustBackground(background, KColorScheme::NeutralBackground);
334  break;
335  }
336 
337  // Update status label
338  if (m_incUi != NULL) {
339  QPalette foreground(m_incUi->status->palette());
340  switch (matchResult) {
341  case MatchFound: // FALLTHROUGH
342  case MatchNothing:
343  KColorScheme::adjustForeground(foreground, KColorScheme::NormalText, QPalette::WindowText, KColorScheme::Window);
344  m_incUi->status->clear();
345  break;
346  case MatchWrappedForward:
347  case MatchWrappedBackward:
348  KColorScheme::adjustForeground(foreground, KColorScheme::NormalText, QPalette::WindowText, KColorScheme::Window);
349  if (matchResult == MatchWrappedBackward) {
350  m_incUi->status->setText(i18n("Reached top, continued from bottom"));
351  } else {
352  m_incUi->status->setText(i18n("Reached bottom, continued from top"));
353  }
354  break;
355  case MatchMismatch:
356  KColorScheme::adjustForeground(foreground, KColorScheme::NegativeText, QPalette::WindowText, KColorScheme::Window);
357  m_incUi->status->setText(i18n("Not found"));
358  break;
359  case MatchNeutral:
360  /* do nothing */
361  break;
362  }
363  m_incUi->status->setPalette(foreground);
364  }
365 
366  lineEdit->setPalette(background);
367 }
368 
369 
370 
371 /*static*/ void KateSearchBar::selectRange(KateView * view, const KTextEditor::Range & range) {
372  view->setCursorPositionInternal(range.end());
373 
374  // don't make a selection if the vi input mode is used
375  if (!view->viInputMode())
376  view->setSelection(range);
377 }
378 
379 
380 
381 void KateSearchBar::selectRange2(const KTextEditor::Range & range) {
382  disconnect(m_view, SIGNAL(selectionChanged(KTextEditor::View*)), this, SLOT(updateSelectionOnly()));
383  selectRange(m_view, range);
384  connect(m_view, SIGNAL(selectionChanged(KTextEditor::View*)), this, SLOT(updateSelectionOnly()));
385 }
386 
387 
388 
389 void KateSearchBar::onIncPatternChanged(const QString & pattern)
390 {
391  if (!m_incUi)
392  return;
393 
394  // clear prior highlightings (deletes info message if present)
395  clearHighlights();
396 
397  m_incUi->next->setDisabled(pattern.isEmpty());
398  m_incUi->prev->setDisabled(pattern.isEmpty());
399 
400  KateMatch match(m_view->doc(), searchOptions());
401 
402  if (!pattern.isEmpty()) {
403  // Find, first try
404  const Range inputRange = KTextEditor::Range(m_incInitCursor, m_view->document()->documentEnd());
405  match.searchText(inputRange, pattern);
406  }
407 
408  const bool wrap = !match.isValid() && !pattern.isEmpty();
409 
410  if (wrap) {
411  // Find, second try
412  const KTextEditor::Range inputRange = m_view->document()->documentRange();
413  match.searchText(inputRange, pattern);
414  }
415 
416  const MatchResult matchResult = match.isValid() ? (wrap ? MatchWrappedForward : MatchFound) :
417  pattern.isEmpty() ? MatchNothing :
418  MatchMismatch;
419 
420  const Range selectionRange = pattern.isEmpty() ? Range(m_incInitCursor, m_incInitCursor) :
421  match.isValid() ? match.range() :
422  Range::invalid();
423 
424  // don't update m_incInitCursor when we move the cursor
425  disconnect(m_view, SIGNAL(cursorPositionChanged(KTextEditor::View*,KTextEditor::Cursor)),
426  this, SLOT(updateIncInitCursor()));
427  selectRange2(selectionRange);
428  connect(m_view, SIGNAL(cursorPositionChanged(KTextEditor::View*,KTextEditor::Cursor)),
429  this, SLOT(updateIncInitCursor()));
430 
431  indicateMatch(matchResult);
432 }
433 
434 
435 
436 void KateSearchBar::setMatchCase(bool matchCase) {
437  if (this->matchCase() == matchCase)
438  return;
439 
440  if (isPower())
441  m_powerUi->matchCase->setChecked(matchCase);
442  else
443  m_incUi->matchCase->setChecked(matchCase);
444 }
445 
446 
447 
448 void KateSearchBar::onMatchCaseToggled(bool /*matchCase*/) {
449  sendConfig();
450 
451  if (m_incUi != 0) {
452  // Re-search with new settings
453  const QString pattern = m_incUi->pattern->currentText();
454  onIncPatternChanged(pattern);
455  } else {
456  indicateMatch(MatchNothing);
457  }
458 }
459 
460 
461 
462 bool KateSearchBar::matchCase() const
463 {
464  return isPower() ? m_powerUi->matchCase->isChecked()
465  : m_incUi->matchCase->isChecked();
466 }
467 
468 
469 
470 void KateSearchBar::fixForSingleLine(Range & range, SearchDirection searchDirection) {
471  FAST_DEBUG("Single-line workaround checking BEFORE" << range);
472  if (searchDirection == SearchForward) {
473  const int line = range.start().line();
474  const int col = range.start().column();
475  const int maxColWithNewline = m_view->document()->lineLength(line) + 1;
476  if (col == maxColWithNewline) {
477  FAST_DEBUG("Starting on a newline" << range);
478  const int maxLine = m_view->document()->lines() - 1;
479  if (line < maxLine) {
480  range.setRange(Cursor(line + 1, 0), range.end());
481  FAST_DEBUG("Search range fixed to " << range);
482  } else {
483  FAST_DEBUG("Already at last line");
484  range = Range::invalid();
485  }
486  }
487  } else {
488  const int col = range.end().column();
489  if (col == 0) {
490  FAST_DEBUG("Ending after a newline" << range);
491  const int line = range.end().line();
492  if (line > 0) {
493  const int maxColWithNewline = m_view->document()->lineLength(line - 1);
494  range.setRange(range.start(), Cursor(line - 1, maxColWithNewline));
495  FAST_DEBUG("Search range fixed to " << range);
496  } else {
497  FAST_DEBUG("Already at first line");
498  range = Range::invalid();
499  }
500  }
501  }
502  FAST_DEBUG("Single-line workaround checking AFTER" << range);
503 }
504 
505 
506 
507 void KateSearchBar::onReturnPressed() {
508  const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
509  const bool shiftDown = (modifiers & Qt::ShiftModifier) != 0;
510  const bool controlDown = (modifiers & Qt::ControlModifier) != 0;
511 
512  // if vi input mode is active, the search box should be closed when hitting enter
513  if (m_view->viInputMode()) {
514  emit hideMe();
515  return;
516  }
517 
518  if (shiftDown) {
519  // Shift down, search backwards
520  findPrevious();
521  } else {
522  // Shift up, search forwards
523  findNext();
524  }
525 
526  if (controlDown) {
527  emit hideMe();
528  }
529 }
530 
531 
532 
533 bool KateSearchBar::find(SearchDirection searchDirection, const QString * replacement) {
534  // What to find?
535  if (searchPattern().isEmpty()) {
536  return false; // == Pattern error
537  }
538 
539  // don't let selectionChanged signal mess around in this routine
540  disconnect(m_view, SIGNAL(selectionChanged(KTextEditor::View*)), this, SLOT(updateSelectionOnly()));
541 
542  // clear previous highlights if there are any
543  clearHighlights();
544 
545  const Search::SearchOptions enabledOptions = searchOptions(searchDirection);
546 
547  // Where to find?
548  Range inputRange;
549  const Range selection = m_view->selection() ? m_view->selectionRange() : Range::invalid();
550  if (selection.isValid()) {
551  if (selectionOnly()) {
552  // First match in selection
553  inputRange = selection;
554  } else {
555  // Next match after/before selection if a match was selected before
556  if (searchDirection == SearchForward) {
557  inputRange.setRange(selection.start(), m_view->document()->documentEnd());
558  } else {
559  inputRange.setRange(Cursor(0, 0), selection.end());
560  }
561  }
562  } else {
563  // No selection
564  const Cursor cursorPos = m_view->cursorPosition();
565  if (searchDirection == SearchForward) {
566  // if the vi input mode is used, the cursor will stay a the first character of the
567  // matched pattern (no selection will be made), so the next search should start from
568  // match column + 1
569  if (!m_view->viInputMode()) {
570  inputRange.setRange(cursorPos, m_view->document()->documentEnd());
571  } else {
572  inputRange.setRange(Cursor(cursorPos.line(), cursorPos.column()+1), m_view->document()->documentEnd());
573  }
574  } else {
575  inputRange.setRange(Cursor(0, 0), cursorPos);
576  }
577  }
578  FAST_DEBUG("Search range is" << inputRange);
579 
580  {
581  const bool regexMode = enabledOptions.testFlag(Search::Regex);
582  const bool multiLinePattern = regexMode ? KateRegExp(searchPattern()).isMultiLine() : false;
583 
584  // Single-line pattern workaround
585  if (regexMode && !multiLinePattern) {
586  fixForSingleLine(inputRange, searchDirection);
587  }
588  }
589 
590  KateMatch match(m_view->doc(), enabledOptions);
591  Range afterReplace = Range::invalid();
592 
593  // Find, first try
594  match.searchText(inputRange, searchPattern());
595  if (match.isValid() && match.range() == selection) {
596  // Same match again
597  if (replacement != 0) {
598  // Selection is match -> replace
599  KTextEditor::MovingRange *smartInputRange = m_view->doc()->newMovingRange (inputRange, KTextEditor::MovingRange::ExpandLeft | KTextEditor::MovingRange::ExpandRight);
600  afterReplace = match.replace(*replacement, m_view->blockSelection());
601  inputRange = *smartInputRange;
602  delete smartInputRange;
603  }
604 
605  if (!selectionOnly()) {
606  // Find, second try after old selection
607  if (searchDirection == SearchForward) {
608  const Cursor start = (replacement != 0) ? afterReplace.end() : selection.end();
609  inputRange.setRange(start, inputRange.end());
610  } else {
611  const Cursor end = (replacement != 0) ? afterReplace.start() : selection.start();
612  inputRange.setRange(inputRange.start(), end);
613  }
614  }
615 
616  // Single-line pattern workaround
617  fixForSingleLine(inputRange, searchDirection);
618 
619  match.searchText(inputRange, searchPattern());
620  }
621 
622  bool askWrap = !match.isValid() && (!selection.isValid() || !selectionOnly());
623  bool wrap = false;
624 
625  if (m_unitTestMode && askWrap)
626  {
627  askWrap = false;
628  wrap = true;
629  }
630 
631  if (askWrap) {
632  QString question = searchDirection == SearchForward ? i18n("Bottom of file reached. Continue from top ?")
633  : i18n("Top of file reached. Continue from bottom ?");
634  wrap = (KMessageBox::questionYesNo( 0, question, i18n("Continue search ?"), KStandardGuiItem::yes(), KStandardGuiItem::no(),
635  QString("DoNotShowAgainContinueSearchDialog")) == KMessageBox::Yes );
636 
637  }
638  if (wrap) {
639  inputRange = m_view->document()->documentRange();
640  match.searchText(inputRange, searchPattern());
641  }
642 
643  if (match.isValid()) {
644  selectRange2(match.range());
645  }
646 
647  const MatchResult matchResult = !match.isValid() ? MatchMismatch :
648  !wrap ? MatchFound :
649  searchDirection == SearchForward ? MatchWrappedForward :
650  MatchWrappedBackward;
651  indicateMatch(matchResult);
652 
653  // highlight replacements if applicable
654  if (afterReplace.isValid()) {
655  highlightReplacement(afterReplace);
656  }
657 
658  // restore connection
659  connect(m_view, SIGNAL(selectionChanged(KTextEditor::View*)), this, SLOT(updateSelectionOnly()));
660 
661  return true; // == No pattern error
662 }
663 
664 
665 
666 
667 void KateSearchBar::findAll()
668 {
669  // clear highlightings of prior search&replace action
670  clearHighlights();
671 
672  Range inputRange = (m_view->selection() && selectionOnly())
673  ? m_view->selectionRange()
674  : m_view->document()->documentRange();
675  const int occurrences = findAll(inputRange, NULL);
676 
677  // send passive notification to view
678  showInfoMessage(i18ncp("short translation", "1 match found", "%1 matches found", occurrences));
679 
680  indicateMatch(occurrences > 0 ? MatchFound : MatchMismatch);
681 }
682 
683 
684 
685 void KateSearchBar::onPowerPatternChanged(const QString & /*pattern*/) {
686  givePatternFeedback();
687  indicateMatch(MatchNothing);
688 }
689 
690 
691 
692 bool KateSearchBar::isPatternValid() const {
693  if (searchPattern().isEmpty())
694  return false;
695 
696  return searchOptions().testFlag(Search::WholeWords) ? searchPattern().trimmed() == searchPattern() :
697  searchOptions().testFlag(Search::Regex) ? QRegExp(searchPattern()).isValid() :
698  true;
699 }
700 
701 
702 
703 void KateSearchBar::givePatternFeedback() {
704  // Enable/disable next/prev and replace next/all
705  m_powerUi->findNext->setEnabled(isPatternValid());
706  m_powerUi->findPrev->setEnabled(isPatternValid());
707  m_powerUi->replaceNext->setEnabled(isPatternValid());
708  m_powerUi->replaceAll->setEnabled(isPatternValid());
709 }
710 
711 
712 
713 void KateSearchBar::addCurrentTextToHistory(QComboBox * combo) {
714  const QString text = combo->currentText();
715  const int index = combo->findText(text);
716 
717  if (index > 0)
718  combo->removeItem(index);
719  if (index != 0) {
720  combo->insertItem(0, text);
721  combo->setCurrentIndex(0);
722  }
723 }
724 
725 
726 
727 void KateSearchBar::backupConfig(bool ofPower) {
728  if (ofPower) {
729  m_powerMatchCase = m_powerUi->matchCase->isChecked();
730  m_powerMode = m_powerUi->searchMode->currentIndex();
731  } else {
732  m_incMatchCase = m_incUi->matchCase->isChecked();
733  }
734 }
735 
736 
737 
738 void KateSearchBar::sendConfig() {
739  const long pastFlags = m_config->searchFlags();
740  long futureFlags = pastFlags;
741 
742  if (m_powerUi != NULL) {
743  const bool OF_POWER = true;
744  backupConfig(OF_POWER);
745 
746  // Update power search flags only
747  const long incFlagsOnly = pastFlags
748  & (KateViewConfig::IncHighlightAll
749  | KateViewConfig::IncFromCursor
750  | KateViewConfig::IncMatchCase);
751 
752  futureFlags = incFlagsOnly
753  | (m_powerMatchCase ? KateViewConfig::PowerMatchCase : 0)
754  | (m_powerFromCursor ? KateViewConfig::PowerFromCursor : 0)
755  | (m_powerHighlightAll ? KateViewConfig::PowerHighlightAll : 0)
756  | ((m_powerMode == MODE_REGEX)
757  ? KateViewConfig::PowerModeRegularExpression
758  : ((m_powerMode == MODE_ESCAPE_SEQUENCES)
759  ? KateViewConfig::PowerModeEscapeSequences
760  : ((m_powerMode == MODE_WHOLE_WORDS)
761  ? KateViewConfig::PowerModeWholeWords
762  : KateViewConfig::PowerModePlainText)));
763 
764  } else if (m_incUi != NULL) {
765  const bool OF_INCREMENTAL = false;
766  backupConfig(OF_INCREMENTAL);
767 
768  // Update incremental search flags only
769  const long powerFlagsOnly = pastFlags
770  & (KateViewConfig::PowerMatchCase
771  | KateViewConfig::PowerFromCursor
772  | KateViewConfig::PowerHighlightAll
773  | KateViewConfig::PowerModeRegularExpression
774  | KateViewConfig::PowerModeEscapeSequences
775  | KateViewConfig::PowerModeWholeWords
776  | KateViewConfig::PowerModePlainText);
777 
778  futureFlags = powerFlagsOnly
779  | (m_incHighlightAll ? KateViewConfig::IncHighlightAll : 0)
780  | (m_incFromCursor ? KateViewConfig::IncFromCursor : 0)
781  | (m_incMatchCase ? KateViewConfig::IncMatchCase : 0);
782  }
783 
784  // Adjust global config
785  m_config->setSearchFlags(futureFlags);
786 }
787 
788 
789 
790 void KateSearchBar::replaceNext() {
791  const QString replacement = m_powerUi->replacement->currentText();
792 
793  if (find(SearchForward, &replacement)) {
794  // Never merge replace actions with other replace actions/user actions
795  m_view->doc()->undoManager()->undoSafePoint();
796 
797  // Add to search history
798  addCurrentTextToHistory(m_powerUi->pattern);
799 
800  // Add to replace history
801  addCurrentTextToHistory(m_powerUi->replacement);
802  }
803 }
804 
805 
806 
807 // replacement == NULL --> Highlight all matches
808 // replacement != NULL --> Replace and highlight all matches
809 int KateSearchBar::findAll(Range inputRange, const QString * replacement)
810 {
811  // don't let selectionChanged signal mess around in this routine
812  disconnect(m_view, SIGNAL(selectionChanged(KTextEditor::View*)), this, SLOT(updateSelectionOnly()));
813 
814  const Search::SearchOptions enabledOptions = searchOptions(SearchForward);
815 
816  const bool regexMode = enabledOptions.testFlag(Search::Regex);
817  const bool multiLinePattern = regexMode ? KateRegExp(searchPattern()).isMultiLine() : false;
818 
819  KTextEditor::MovingRange * workingRange = m_view->doc()->newMovingRange(inputRange);
820  QList<Range> highlightRanges;
821  int matchCounter = 0;
822 
823  bool block = m_view->selection() && m_view->blockSelection();
824  int line = inputRange.start().line();
825  do {
826  if (block)
827  workingRange = m_view->doc()->newMovingRange(m_view->doc()->rangeOnLine(inputRange, line));
828 
829  for (;;) {
830  KateMatch match(m_view->doc(), enabledOptions);
831  match.searchText(*workingRange, searchPattern());
832  if (!match.isValid()) {
833  break;
834  }
835  bool const originalMatchEmpty = match.isEmpty();
836 
837  // Work with the match
838  if (replacement != NULL) {
839  if (matchCounter == 0) {
840  m_view->document()->startEditing();
841  }
842 
843  // Replace
844  const Range afterReplace = match.replace(*replacement, false, ++matchCounter);
845 
846  // Highlight and continue after adjusted match
847  //highlightReplacement(*afterReplace);
848  highlightRanges << afterReplace;
849  } else {
850  // Highlight and continue after original match
851  //highlightMatch(match);
852  highlightRanges << match.range();
853  matchCounter++;
854  }
855 
856  // Continue after match
857  if (highlightRanges.last().end() >= workingRange->end())
858  break;
859  KTextEditor::MovingCursor* workingStart =
860  static_cast<KateDocument*>(m_view->document())->newMovingCursor(highlightRanges.last().end());
861  if (originalMatchEmpty) {
862  // Can happen for regex patterns like "^".
863  // If we don't advance here we will loop forever...
864  workingStart->move(1);
865  } else if (regexMode && !multiLinePattern && workingStart->atEndOfLine()) {
866  // single-line regexps might match the naked line end
867  // therefore we better advance to the next line
868  workingStart->move(1);
869  }
870  workingRange->setRange(*workingStart, workingRange->end());
871 
872  const bool atEndOfDocument = workingStart->atEndOfDocument();
873  delete workingStart;
874  // Are we done?
875  if (!workingRange->toRange().isValid() || atEndOfDocument) {
876  break;
877  }
878  }
879 
880  } while (block && ++line <= inputRange.end().line());
881 
882  // After last match
883  if (matchCounter > 0) {
884  if (replacement != NULL) {
885  m_view->document()->endEditing();
886  }
887  }
888 
889  if (replacement == NULL)
890  foreach (const Range &r, highlightRanges) {
891  highlightMatch(r);
892  }
893  else
894  foreach (const Range &r, highlightRanges) {
895  highlightReplacement(r);
896  }
897 
898  delete workingRange;
899 
900  // restore connection
901  connect(m_view, SIGNAL(selectionChanged(KTextEditor::View*)), this, SLOT(updateSelectionOnly()));
902 
903  return matchCounter;
904 }
905 
906 
907 
908 void KateSearchBar::replaceAll()
909 {
910  // clear prior highlightings (deletes info message if present)
911  clearHighlights();
912 
913  // What to find/replace?
914  const QString replacement = m_powerUi->replacement->currentText();
915 
916  // Where to replace?
917  Range selection;
918  const bool selected = m_view->selection();
919  Range inputRange = (selected && selectionOnly())
920  ? m_view->selectionRange()
921  : m_view->document()->documentRange();
922 
923 
924  // Pass on the hard work
925  int replacementsDone=findAll(inputRange, &replacement);
926 
927  // send passive notification to view
928  showInfoMessage(i18ncp("short translation", "1 replacement made", "%1 replacements made", replacementsDone));
929 
930  // Never merge replace actions with other replace actions/user actions
931  m_view->doc()->undoManager()->undoSafePoint();
932 
933  // Add to search history
934  addCurrentTextToHistory(m_powerUi->pattern);
935 
936  // Add to replace history
937  addCurrentTextToHistory(m_powerUi->replacement);
938 }
939 
940 
941 
942 void KateSearchBar::setSearchPattern(const QString &searchPattern)
943 {
944  if (searchPattern == this->searchPattern())
945  return;
946 
947  if (isPower())
948  m_powerUi->pattern->setEditText(searchPattern);
949  else
950  m_incUi->pattern->setEditText(searchPattern);
951 }
952 
953 
954 
955 QString KateSearchBar::searchPattern() const {
956  return (m_powerUi != 0) ? m_powerUi->pattern->currentText()
957  : m_incUi->pattern->currentText();
958 }
959 
960 
961 
962 void KateSearchBar::setSelectionOnly(bool selectionOnly)
963 {
964  if (this->selectionOnly() == selectionOnly)
965  return;
966 
967  if (isPower())
968  m_powerUi->selectionOnly->setChecked(selectionOnly);
969 }
970 
971 
972 
973 
974 bool KateSearchBar::selectionOnly() const {
975  return isPower() ? m_powerUi->selectionOnly->isChecked()
976  : false;
977 }
978 
979 
980 
981 KTextEditor::Search::SearchOptions KateSearchBar::searchOptions(SearchDirection searchDirection) const {
982  Search::SearchOptions enabledOptions = KTextEditor::Search::Default;
983 
984  if (!matchCase()) {
985  enabledOptions |= Search::CaseInsensitive;
986  }
987 
988  if (searchDirection == SearchBackward) {
989  enabledOptions |= Search::Backwards;
990  }
991 
992  if (m_powerUi != NULL) {
993  switch (m_powerUi->searchMode->currentIndex()) {
994  case MODE_WHOLE_WORDS:
995  enabledOptions |= Search::WholeWords;
996  break;
997 
998  case MODE_ESCAPE_SEQUENCES:
999  enabledOptions |= Search::EscapeSequences;
1000  break;
1001 
1002  case MODE_REGEX:
1003  enabledOptions |= Search::Regex;
1004  break;
1005 
1006  case MODE_PLAIN_TEXT: // FALLTHROUGH
1007  default:
1008  break;
1009 
1010  }
1011  }
1012 
1013  return enabledOptions;
1014 }
1015 
1016 
1017 
1018 
1019 struct ParInfo {
1020  int openIndex;
1021  bool capturing;
1022  int captureNumber; // 1..9
1023 };
1024 
1025 
1026 
1027 QVector<QString> KateSearchBar::getCapturePatterns(const QString & pattern) const {
1028  QVector<QString> capturePatterns;
1029  capturePatterns.reserve(9);
1030  QStack<ParInfo> parInfos;
1031 
1032  const int inputLen = pattern.length();
1033  int input = 0; // walker index
1034  bool insideClass = false;
1035  int captureCount = 0;
1036 
1037  while (input < inputLen) {
1038  if (insideClass) {
1039  // Wait for closing, unescaped ']'
1040  if (pattern[input].unicode() == L']') {
1041  insideClass = false;
1042  }
1043  input++;
1044  }
1045  else
1046  {
1047  switch (pattern[input].unicode())
1048  {
1049  case L'\\':
1050  // Skip this and any next character
1051  input += 2;
1052  break;
1053 
1054  case L'(':
1055  ParInfo curInfo;
1056  curInfo.openIndex = input;
1057  curInfo.capturing = (input + 1 >= inputLen) || (pattern[input + 1].unicode() != '?');
1058  if (curInfo.capturing) {
1059  captureCount++;
1060  }
1061  curInfo.captureNumber = captureCount;
1062  parInfos.push(curInfo);
1063 
1064  input++;
1065  break;
1066 
1067  case L')':
1068  if (!parInfos.empty()) {
1069  ParInfo & top = parInfos.top();
1070  if (top.capturing && (top.captureNumber <= 9)) {
1071  const int start = top.openIndex + 1;
1072  const int len = input - start;
1073  if (capturePatterns.size() < top.captureNumber) {
1074  capturePatterns.resize(top.captureNumber);
1075  }
1076  capturePatterns[top.captureNumber - 1] = pattern.mid(start, len);
1077  }
1078  parInfos.pop();
1079  }
1080 
1081  input++;
1082  break;
1083 
1084  case L'[':
1085  input++;
1086  insideClass = true;
1087  break;
1088 
1089  default:
1090  input++;
1091  break;
1092 
1093  }
1094  }
1095  }
1096 
1097  return capturePatterns;
1098 }
1099 
1100 
1101 
1102 void KateSearchBar::showExtendedContextMenu(bool forPattern, const QPoint& pos) {
1103  // Make original menu
1104  QComboBox* comboBox = forPattern ? m_powerUi->pattern : m_powerUi->replacement;
1105  QMenu* const contextMenu = comboBox->lineEdit()->createStandardContextMenu();
1106 
1107  if (contextMenu == NULL) {
1108  return;
1109  }
1110 
1111  bool extendMenu = false;
1112  bool regexMode = false;
1113  switch (m_powerUi->searchMode->currentIndex()) {
1114  case MODE_REGEX:
1115  regexMode = true;
1116  // FALLTHROUGH
1117 
1118  case MODE_ESCAPE_SEQUENCES:
1119  extendMenu = true;
1120  break;
1121 
1122  default:
1123  break;
1124  }
1125 
1126  AddMenuManager addMenuManager(contextMenu, 37);
1127  if (!extendMenu) {
1128  addMenuManager.enableMenu(extendMenu);
1129  } else {
1130  // Build menu
1131  if (forPattern) {
1132  if (regexMode) {
1133  addMenuManager.addEntry("^", "", i18n("Beginning of line"));
1134  addMenuManager.addEntry("$", "", i18n("End of line"));
1135  addMenuManager.addSeparator();
1136  addMenuManager.addEntry(".", "", i18n("Any single character (excluding line breaks)"));
1137  addMenuManager.addSeparator();
1138  addMenuManager.addEntry("+", "", i18n("One or more occurrences"));
1139  addMenuManager.addEntry("*", "", i18n("Zero or more occurrences"));
1140  addMenuManager.addEntry("?", "", i18n("Zero or one occurrences"));
1141  addMenuManager.addEntry("{a", ",b}", i18n("<a> through <b> occurrences"), "{", ",}");
1142  addMenuManager.addSeparator();
1143  addMenuManager.addEntry("(", ")", i18n("Group, capturing"));
1144  addMenuManager.addEntry("|", "", i18n("Or"));
1145  addMenuManager.addEntry("[", "]", i18n("Set of characters"));
1146  addMenuManager.addEntry("[^", "]", i18n("Negative set of characters"));
1147  addMenuManager.addSeparator();
1148  }
1149  } else {
1150  addMenuManager.addEntry("\\0", "", i18n("Whole match reference"));
1151  addMenuManager.addSeparator();
1152  if (regexMode) {
1153  const QString pattern = m_powerUi->pattern->currentText();
1154  const QVector<QString> capturePatterns = getCapturePatterns(pattern);
1155 
1156  const int captureCount = capturePatterns.count();
1157  for (int i = 1; i <= 9; i++) {
1158  const QString number = QString::number(i);
1159  const QString & captureDetails = (i <= captureCount)
1160  ? (QString(" = (") + capturePatterns[i - 1].left(30)) + QString(")")
1161  : QString();
1162  addMenuManager.addEntry("\\" + number, "",
1163  i18n("Reference") + ' ' + number + captureDetails);
1164  }
1165 
1166  addMenuManager.addSeparator();
1167  }
1168  }
1169 
1170  addMenuManager.addEntry("\\n", "", i18n("Line break"));
1171  addMenuManager.addEntry("\\t", "", i18n("Tab"));
1172 
1173  if (forPattern && regexMode) {
1174  addMenuManager.addEntry("\\b", "", i18n("Word boundary"));
1175  addMenuManager.addEntry("\\B", "", i18n("Not word boundary"));
1176  addMenuManager.addEntry("\\d", "", i18n("Digit"));
1177  addMenuManager.addEntry("\\D", "", i18n("Non-digit"));
1178  addMenuManager.addEntry("\\s", "", i18n("Whitespace (excluding line breaks)"));
1179  addMenuManager.addEntry("\\S", "", i18n("Non-whitespace (excluding line breaks)"));
1180  addMenuManager.addEntry("\\w", "", i18n("Word character (alphanumerics plus '_')"));
1181  addMenuManager.addEntry("\\W", "", i18n("Non-word character"));
1182  }
1183 
1184  addMenuManager.addEntry("\\0???", "", i18n("Octal character 000 to 377 (2^8-1)"), "\\0");
1185  addMenuManager.addEntry("\\x????", "", i18n("Hex character 0000 to FFFF (2^16-1)"), "\\x");
1186  addMenuManager.addEntry("\\\\", "", i18n("Backslash"));
1187 
1188  if (forPattern && regexMode) {
1189  addMenuManager.addSeparator();
1190  addMenuManager.addEntry("(?:E", ")", i18n("Group, non-capturing"), "(?:");
1191  addMenuManager.addEntry("(?=E", ")", i18n("Lookahead"), "(?=");
1192  addMenuManager.addEntry("(?!E", ")", i18n("Negative lookahead"), "(?!");
1193  }
1194 
1195  if (!forPattern) {
1196  addMenuManager.addSeparator();
1197  addMenuManager.addEntry("\\L", "", i18n("Begin lowercase conversion"));
1198  addMenuManager.addEntry("\\U", "", i18n("Begin uppercase conversion"));
1199  addMenuManager.addEntry("\\E", "", i18n("End case conversion"));
1200  addMenuManager.addEntry("\\l", "", i18n("Lowercase first character conversion"));
1201  addMenuManager.addEntry("\\u", "", i18n("Uppercase first character conversion"));
1202  addMenuManager.addEntry("\\#[#..]", "", i18n("Replacement counter (for Replace All)"), "\\#");
1203  }
1204  }
1205 
1206  // Show menu
1207  QAction * const result = contextMenu->exec(comboBox->mapToGlobal(pos));
1208  if (result != NULL) {
1209  addMenuManager.handle(result, comboBox->lineEdit());
1210  }
1211 }
1212 
1213 
1214 
1215 void KateSearchBar::onPowerModeChanged(int /*index*/) {
1216  if (m_powerUi->searchMode->currentIndex() == MODE_REGEX) {
1217  m_powerUi->matchCase->setChecked(true);
1218  }
1219 
1220  sendConfig();
1221  indicateMatch(MatchNothing);
1222 
1223  givePatternFeedback();
1224 }
1225 
1226 
1227 
1228 /*static*/ void KateSearchBar::nextMatchForSelection(KateView * view, SearchDirection searchDirection) {
1229  const bool selected = view->selection();
1230  if (selected) {
1231  const QString pattern = view->selectionText();
1232 
1233  // How to find?
1234  Search::SearchOptions enabledOptions(KTextEditor::Search::Default);
1235  if (searchDirection == SearchBackward) {
1236  enabledOptions |= Search::Backwards;
1237  }
1238 
1239  // Where to find?
1240  const Range selRange = view->selectionRange();
1241  Range inputRange;
1242  if (searchDirection == SearchForward) {
1243  inputRange.setRange(selRange.end(), view->doc()->documentEnd());
1244  } else {
1245  inputRange.setRange(Cursor(0, 0), selRange.start());
1246  }
1247 
1248  // Find, first try
1249  KateMatch match(view->doc(), enabledOptions);
1250  match.searchText(inputRange, pattern);
1251 
1252  if (match.isValid()) {
1253  selectRange(view, match.range());
1254  } else {
1255  // Find, second try
1256  if (searchDirection == SearchForward) {
1257  inputRange.setRange(Cursor(0, 0), selRange.start());
1258  } else {
1259  inputRange.setRange(selRange.end(), view->doc()->documentEnd());
1260  }
1261  KateMatch match2(view->doc(), enabledOptions);
1262  match2.searchText(inputRange, pattern);
1263  if (match2.isValid()) {
1264  selectRange(view, match2.range());
1265  }
1266  }
1267  } else {
1268  // Select current word so we can search for that the next time
1269  const Cursor cursorPos = view->cursorPosition();
1270  view->selectWord(cursorPos);
1271  }
1272 }
1273 
1274 
1275 
1276 void KateSearchBar::enterPowerMode() {
1277  QString initialPattern;
1278  bool selectionOnly = false;
1279 
1280  // Guess settings from context: init pattern with current selection
1281  const bool selected = m_view->selection();
1282  if (selected) {
1283  const Range & selection = m_view->selectionRange();
1284  if (selection.onSingleLine()) {
1285  // ... with current selection
1286  initialPattern = m_view->selectionText();
1287  } else {
1288  // Enable selection only
1289  selectionOnly = true;
1290  }
1291  }
1292 
1293  // If there's no new selection, we'll use the existing pattern
1294  if (initialPattern.isNull()) {
1295  // Coming from power search?
1296  const bool fromReplace = (m_powerUi != NULL) && (m_widget->isVisible());
1297  if (fromReplace) {
1298  QLineEdit * const patternLineEdit = m_powerUi->pattern->lineEdit();
1299  Q_ASSERT(patternLineEdit != NULL);
1300  patternLineEdit->selectAll();
1301  m_powerUi->pattern->setFocus(Qt::MouseFocusReason);
1302  return;
1303  }
1304 
1305  // Coming from incremental search?
1306  const bool fromIncremental = (m_incUi != NULL) && (m_widget->isVisible());
1307  if (fromIncremental) {
1308  initialPattern = m_incUi->pattern->currentText();
1309  }
1310  }
1311 
1312  // Create dialog
1313  const bool create = (m_powerUi == NULL);
1314  if (create) {
1315  // Kill incremental widget
1316  if (m_incUi != NULL) {
1317  // Backup current settings
1318  const bool OF_INCREMENTAL = false;
1319  backupConfig(OF_INCREMENTAL);
1320 
1321  // Kill widget
1322  delete m_incUi;
1323  m_incUi = NULL;
1324  m_layout->removeWidget(m_widget);
1325  m_widget->deleteLater(); // I didn't get a crash here but for symmetrie to the other mutate slot^
1326  }
1327 
1328  // Add power widget
1329  m_widget = new QWidget(this);
1330  m_powerUi = new Ui::PowerSearchBar;
1331  m_powerUi->setupUi(m_widget);
1332  m_layout->addWidget(m_widget);
1333 
1334  // Bind to shared history models
1335  m_powerUi->pattern->setDuplicatesEnabled(false);
1336  m_powerUi->pattern->setInsertPolicy(QComboBox::InsertAtTop);
1337  m_powerUi->pattern->setMaxCount(m_config->maxHistorySize());
1338  m_powerUi->pattern->setModel(m_config->patternHistoryModel());
1339  m_powerUi->replacement->setDuplicatesEnabled(false);
1340  m_powerUi->replacement->setInsertPolicy(QComboBox::InsertAtTop);
1341  m_powerUi->replacement->setMaxCount(m_config->maxHistorySize());
1342  m_powerUi->replacement->setModel(m_config->replacementHistoryModel());
1343 
1344  // Icons
1345  m_powerUi->mutate->setIcon(KIcon("arrow-down-double"));
1346  m_powerUi->findNext->setIcon(KIcon("go-down-search"));
1347  m_powerUi->findPrev->setIcon(KIcon("go-up-search"));
1348  m_powerUi->findAll->setIcon(KIcon("edit-find"));
1349 
1350  // Focus proxy
1351  centralWidget()->setFocusProxy(m_powerUi->pattern);
1352 
1353  // Make completers case-sensitive
1354  m_powerUi->pattern->completionObject()->setIgnoreCase(false);
1355  m_powerUi->replacement->completionObject()->setIgnoreCase(false);
1356  }
1357 
1358  m_powerUi->selectionOnly->setChecked(selectionOnly);
1359 
1360  // Restore previous settings
1361  if (create) {
1362  m_powerUi->matchCase->setChecked(m_powerMatchCase);
1363  m_powerUi->searchMode->setCurrentIndex(m_powerMode);
1364  }
1365 
1366  // force current index of -1 --> <cursor down> shows 1st completion entry instead of 2nd
1367  m_powerUi->pattern->setCurrentIndex(-1);
1368  m_powerUi->replacement->setCurrentIndex(-1);
1369 
1370  // Set initial search pattern
1371  QLineEdit * const patternLineEdit = m_powerUi->pattern->lineEdit();
1372  Q_ASSERT(patternLineEdit != NULL);
1373  patternLineEdit->setText(initialPattern);
1374  patternLineEdit->selectAll();
1375 
1376  // Set initial replacement text
1377  QLineEdit * const replacementLineEdit = m_powerUi->replacement->lineEdit();
1378  Q_ASSERT(replacementLineEdit != NULL);
1379  replacementLineEdit->setText("");
1380 
1381  // Propagate settings (slots are still inactive on purpose)
1382  onPowerPatternChanged(initialPattern);
1383  givePatternFeedback();
1384 
1385  if (create) {
1386  // Slots
1387  connect(m_powerUi->mutate, SIGNAL(clicked()), this, SLOT(enterIncrementalMode()));
1388  connect(patternLineEdit, SIGNAL(textChanged(QString)), this, SLOT(onPowerPatternChanged(QString)));
1389  connect(m_powerUi->findNext, SIGNAL(clicked()), this, SLOT(findNext()));
1390  connect(m_powerUi->findPrev, SIGNAL(clicked()), this, SLOT(findPrevious()));
1391  connect(m_powerUi->replaceNext, SIGNAL(clicked()), this, SLOT(replaceNext()));
1392  connect(m_powerUi->replaceAll, SIGNAL(clicked()), this, SLOT(replaceAll()));
1393  connect(m_powerUi->searchMode, SIGNAL(currentIndexChanged(int)), this, SLOT(onPowerModeChanged(int)));
1394  connect(m_powerUi->matchCase, SIGNAL(toggled(bool)), this, SLOT(onMatchCaseToggled(bool)));
1395  connect(m_powerUi->findAll, SIGNAL(clicked()), this, SLOT(findAll()));
1396 
1397  // Make [return] in pattern line edit trigger <find next> action
1398  connect(patternLineEdit, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
1399  connect(replacementLineEdit, SIGNAL(returnPressed()), this, SLOT(replaceNext()));
1400 
1401  // Hook into line edit context menus
1402  m_powerUi->pattern->setContextMenuPolicy(Qt::CustomContextMenu);
1403  connect(m_powerUi->pattern, SIGNAL(customContextMenuRequested(QPoint)), this,
1404  SLOT(onPowerPatternContextMenuRequest(QPoint)));
1405  m_powerUi->replacement->setContextMenuPolicy(Qt::CustomContextMenu);
1406  connect(m_powerUi->replacement, SIGNAL(customContextMenuRequested(QPoint)), this,
1407  SLOT(onPowerReplacmentContextMenuRequest(QPoint)));
1408  }
1409 
1410  // Focus
1411  if (m_widget->isVisible()) {
1412  m_powerUi->pattern->setFocus(Qt::MouseFocusReason);
1413  }
1414 }
1415 
1416 
1417 
1418 void KateSearchBar::enterIncrementalMode() {
1419  QString initialPattern;
1420 
1421  // Guess settings from context: init pattern with current selection
1422  const bool selected = m_view->selection();
1423  if (selected) {
1424  const Range & selection = m_view->selectionRange();
1425  if (selection.onSingleLine()) {
1426  // ... with current selection
1427  initialPattern = m_view->selectionText();
1428  }
1429  }
1430 
1431  // If there's no new selection, we'll use the existing pattern
1432  if (initialPattern.isNull()) {
1433  // Coming from incremental search?
1434  const bool fromIncremental = (m_incUi != NULL) && (m_widget->isVisible());
1435  if (fromIncremental) {
1436  m_incUi->pattern->lineEdit()->selectAll();
1437  m_incUi->pattern->setFocus(Qt::MouseFocusReason);
1438  return;
1439  }
1440 
1441  // Coming from power search?
1442  const bool fromReplace = (m_powerUi != NULL) && (m_widget->isVisible());
1443  if (fromReplace) {
1444  initialPattern = m_powerUi->pattern->currentText();
1445  }
1446  }
1447 
1448  // Still no search pattern? Use the word under the cursor
1449  if (initialPattern.isNull()) {
1450  const KTextEditor::Cursor cursorPosition = m_view->cursorPosition();
1451  initialPattern = m_view->doc()->getWord( cursorPosition );
1452  }
1453 
1454  // Create dialog
1455  const bool create = (m_incUi == NULL);
1456  if (create) {
1457  // Kill power widget
1458  if (m_powerUi != NULL) {
1459  // Backup current settings
1460  const bool OF_POWER = true;
1461  backupConfig(OF_POWER);
1462 
1463  // Kill widget
1464  delete m_powerUi;
1465  m_powerUi = NULL;
1466  m_layout->removeWidget(m_widget);
1467  m_widget->deleteLater(); //deleteLater, because it's not a good idea too delete the widget and there for the button triggering this slot
1468  }
1469 
1470  // Add incremental widget
1471  m_widget = new QWidget(this);
1472  m_incUi = new Ui::IncrementalSearchBar;
1473  m_incUi->setupUi(m_widget);
1474  m_layout->addWidget(m_widget);
1475 
1476 // new QShortcut(KStandardShortcut::paste().primary(), m_incUi->pattern, SLOT(paste()), 0, Qt::WidgetWithChildrenShortcut);
1477 // if (!KStandardShortcut::paste().alternate().isEmpty())
1478 // new QShortcut(KStandardShortcut::paste().alternate(), m_incUi->pattern, SLOT(paste()), 0, Qt::WidgetWithChildrenShortcut);
1479 
1480 
1481  // Icons
1482  m_incUi->mutate->setIcon(KIcon("arrow-up-double"));
1483  m_incUi->next->setIcon(KIcon("go-down-search"));
1484  m_incUi->prev->setIcon(KIcon("go-up-search"));
1485 
1486  // Ensure minimum size
1487  m_incUi->pattern->setMinimumWidth(12 * m_incUi->pattern->fontMetrics().height());
1488 
1489  // Customize status area
1490  m_incUi->status->setTextElideMode(Qt::ElideLeft);
1491 
1492  // Focus proxy
1493  centralWidget()->setFocusProxy(m_incUi->pattern);
1494 
1495  m_incUi->pattern->setDuplicatesEnabled(false);
1496  m_incUi->pattern->setInsertPolicy(QComboBox::InsertAtTop);
1497  m_incUi->pattern->setMaxCount(m_config->maxHistorySize());
1498  m_incUi->pattern->setModel(m_config->patternHistoryModel());
1499  m_incUi->pattern->setAutoCompletion(false);
1500  }
1501 
1502  // Restore previous settings
1503  if (create) {
1504  m_incUi->matchCase->setChecked(m_incMatchCase);
1505  }
1506 
1507  // force current index of -1 --> <cursor down> shows 1st completion entry instead of 2nd
1508  m_incUi->pattern->setCurrentIndex(-1);
1509 
1510  // Set initial search pattern
1511  if (!create)
1512  disconnect(m_incUi->pattern, SIGNAL(editTextChanged(QString)), this, SLOT(onIncPatternChanged(QString)));
1513  m_incUi->pattern->setEditText(initialPattern);
1514  connect(m_incUi->pattern, SIGNAL(editTextChanged(QString)), this, SLOT(onIncPatternChanged(QString)));
1515  m_incUi->pattern->lineEdit()->selectAll();
1516 
1517  // Propagate settings (slots are still inactive on purpose)
1518  if (initialPattern.isEmpty()) {
1519  // Reset edit color
1520  indicateMatch(MatchNothing);
1521  }
1522 
1523  // Enable/disable next/prev
1524  m_incUi->next->setDisabled(initialPattern.isEmpty());
1525  m_incUi->prev->setDisabled(initialPattern.isEmpty());
1526 
1527  if (create) {
1528  // Slots
1529  connect(m_incUi->mutate, SIGNAL(clicked()), this, SLOT(enterPowerMode()));
1530  connect(m_incUi->pattern->lineEdit(), SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
1531  connect(m_incUi->next, SIGNAL(clicked()), this, SLOT(findNext()));
1532  connect(m_incUi->prev, SIGNAL(clicked()), this, SLOT(findPrevious()));
1533  connect(m_incUi->matchCase, SIGNAL(toggled(bool)), this, SLOT(onMatchCaseToggled(bool)));
1534  }
1535 
1536  // Focus
1537  if (m_widget->isVisible()) {
1538  m_incUi->pattern->setFocus(Qt::MouseFocusReason);
1539  }
1540 }
1541 
1542 bool KateSearchBar::clearHighlights()
1543 {
1544  if (m_infoMessage) {
1545  delete m_infoMessage;
1546  }
1547 
1548  if (m_hlRanges.isEmpty()) {
1549  return false;
1550  }
1551  qDeleteAll(m_hlRanges);
1552  m_hlRanges.clear();
1553  return true;
1554 }
1555 
1556 void KateSearchBar::updateHighlightColors()
1557 {
1558  const QColor& searchColor = m_view->renderer()->config()->searchHighlightColor();
1559  const QColor& replaceColor = m_view->renderer()->config()->replaceHighlightColor();
1560 
1561  // init match attribute
1562  highlightMatchAttribute->setBackground(searchColor);
1563  highlightMatchAttribute->dynamicAttribute (Attribute::ActivateMouseIn)->setBackground(searchColor);
1564  highlightMatchAttribute->dynamicAttribute (Attribute::ActivateCaretIn)->setBackground(searchColor);
1565 
1566  // init replacement attribute
1567  highlightReplacementAttribute->setBackground(replaceColor);
1568 }
1569 
1570 
1571 void KateSearchBar::showEvent(QShowEvent * event) {
1572  // Update init cursor
1573  if (m_incUi != NULL) {
1574  m_incInitCursor = m_view->cursorPosition();
1575  }
1576 
1577  updateSelectionOnly();
1578  KateViewBarWidget::showEvent(event);
1579 }
1580 
1581 
1582 void KateSearchBar::updateSelectionOnly() {
1583  if (m_powerUi == NULL) {
1584  return;
1585  }
1586 
1587  // Re-init "Selection only" checkbox if power search bar open
1588  const bool selected = m_view->selection();
1589  bool selectionOnly = selected;
1590  if (selected) {
1591  Range const & selection = m_view->selectionRange();
1592  selectionOnly = !selection.onSingleLine();
1593  }
1594  m_powerUi->selectionOnly->setChecked(selectionOnly);
1595 }
1596 
1597 
1598 void KateSearchBar::updateIncInitCursor() {
1599  if (m_incUi == NULL) {
1600  return;
1601  }
1602 
1603  // Update init cursor
1604  m_incInitCursor = m_view->cursorPosition();
1605 }
1606 
1607 
1608 void KateSearchBar::onPowerPatternContextMenuRequest(const QPoint& pos) {
1609  const bool FOR_PATTERN = true;
1610  showExtendedContextMenu(FOR_PATTERN, pos);
1611 }
1612 
1613 void KateSearchBar::onPowerPatternContextMenuRequest() {
1614  onPowerPatternContextMenuRequest(m_powerUi->pattern->mapFromGlobal(QCursor::pos()));
1615 }
1616 
1617 
1618 void KateSearchBar::onPowerReplacmentContextMenuRequest(const QPoint& pos) {
1619  const bool FOR_REPLACEMENT = false;
1620  showExtendedContextMenu(FOR_REPLACEMENT, pos);
1621 }
1622 
1623 void KateSearchBar::onPowerReplacmentContextMenuRequest() {
1624  onPowerReplacmentContextMenuRequest(m_powerUi->replacement->mapFromGlobal(QCursor::pos()));
1625 }
1626 
1627 
1628 bool KateSearchBar::isPower() const {
1629  return m_powerUi != 0;
1630 }
1631 
1632 void KateSearchBar::slotReadWriteChanged ()
1633 {
1634  if (!KateSearchBar::isPower())
1635  return;
1636 
1637  // perhaps disable/enable
1638  m_powerUi->replaceNext->setEnabled (m_view->doc()->isReadWrite() && isPatternValid());
1639  m_powerUi->replaceAll->setEnabled (m_view->doc()->isReadWrite() && isPatternValid());
1640 }
1641 
1642 // kate: space-indent on; indent-width 4; replace-tabs on;
QVariant
QColor
KTextEditor::Range::start
Cursor & start()
KSharedPtr< Attribute >
KateViewBarWidget::viewBar
KateViewBar * viewBar()
returns the currently associated KateViewBar and 0, if it is not associated
Definition: kateviewhelpers.h:299
KateSearchBar::closed
virtual void closed()
Definition: katesearchbar.cpp:214
KateSearchBar::setReplacementPattern
void setReplacementPattern(const QString &replacementPattern)
Set the current replacement pattern.
Definition: katesearchbar.cpp:226
kateview.h
Kate::Script::i18n
QScriptValue i18n(QScriptContext *context, QScriptEngine *engine)
i18n("text", arguments [optional])
Definition: katescripthelpers.cpp:186
KateSearchBar::MatchFound
Definition: katesearchbar.h:63
KateRegExp
Definition: kateregexp.h:27
FAST_DEBUG
#define FAST_DEBUG(x)
Definition: katesearchbar.cpp:55
KateSearchBar::setSearchPattern
void setSearchPattern(const QString &searchPattern)
Set the current search pattern.
Definition: katesearchbar.cpp:942
KateDocument::newMovingRange
virtual KTextEditor::MovingRange * newMovingRange(const KTextEditor::Range &range, KTextEditor::MovingRange::InsertBehaviors insertBehaviors=KTextEditor::MovingRange::DoNotExpand, KTextEditor::MovingRange::EmptyBehavior emptyBehavior=KTextEditor::MovingRange::AllowEmpty)
Create a new moving range for this document.
Definition: katedocument.cpp:4742
KColorScheme::NegativeText
KateView::selectWord
void selectWord(const KTextEditor::Cursor &cursor)
Definition: kateview.cpp:2129
KateView::renderer
KateRenderer * renderer()
Definition: kateview.cpp:1653
KateView::document
KTextEditor::Document * document() const
Definition: kateview.cpp:2769
KateViewConfig::IncMatchCase
Definition: kateconfig.h:461
katerenderer.h
KTextEditor::Attribute
KTextEditor::MovingCursor::atEndOfLine
bool atEndOfLine() const
KateSearchBar::setSelectionOnly
void setSelectionOnly(bool selectionOnly)
Definition: katesearchbar.cpp:962
KateViewConfig::PowerHighlightAll
Definition: kateconfig.h:465
KTextEditor::Range::isValid
virtual bool isValid() const
KateRendererConfig::replaceHighlightColor
const QColor & replaceHighlightColor() const
Definition: kateconfig.cpp:2559
KateSearchBar::clearHighlights
bool clearHighlights()
Definition: katesearchbar.cpp:1542
KateSearchBar::searchPattern
QString searchPattern() const
Definition: katesearchbar.cpp:955
KateViewConfig::PowerModeEscapeSequences
Definition: kateconfig.h:470
QWidget
KTextEditor::Document::documentEnd
virtual Cursor documentEnd() const =0
KTextEditor::MovingCursor
katedocument.h
KateSearchBar::SearchBackward
Definition: katesearchbar.h:73
movingrange.h
KTextEditor::MovingRange::toRange
const Range toRange() const
KTextEditor::MovingRange
KateDocument::undoManager
KateUndoManager * undoManager()
Definition: katedocument.h:338
KTextEditor::MovingRange::DoNotExpand
QString
KateSearchBar::MatchMismatch
Definition: katesearchbar.h:66
KTextEditor::Range::setRange
virtual void setRange(const Range &range)
KateSearchBar::MatchWrappedBackward
Definition: katesearchbar.h:65
KateSearchBar::enterIncrementalMode
void enterIncrementalMode()
Definition: katesearchbar.cpp:1418
KColorScheme::adjustForeground
static void adjustForeground(QPalette &, ForegroundRole newRole=NormalText, QPalette::ColorRole color=QPalette::Text, ColorSet set=View, KSharedConfigPtr=KSharedConfigPtr())
KTextEditor::Cursor
KateSearchBar::MODE_ESCAPE_SEQUENCES
Definition: katesearchbar.h:58
KColorScheme::Window
Kate::Script::i18ncp
QScriptValue i18ncp(QScriptContext *context, QScriptEngine *engine)
i18ncp("context", "singular", "plural", number, arguments [optional])
Definition: katescripthelpers.cpp:273
KateSearchBar::MatchNothing
Definition: katesearchbar.h:67
KateViewConfig::PowerModeWholeWords
Definition: kateconfig.h:469
KTextEditor::MovingRange::setAttributeOnlyForViews
virtual void setAttributeOnlyForViews(bool onlyForViews)=0
KateMatch
Definition: katematch.h:30
Regex
kateregexp.h
KateView::selectionRange
virtual const KTextEditor::Range & selectionRange() const
Definition: kateview.cpp:2760
KateSearchBar::showEvent
virtual void showEvent(QShowEvent *event)
Definition: katesearchbar.cpp:1571
KateViewBarWidget
Definition: kateviewhelpers.h:288
KateViewConfig::IncFromCursor
Definition: kateconfig.h:463
KateSearchBar::MODE_WHOLE_WORDS
Definition: katesearchbar.h:57
KateSearchBar::isPower
bool isPower() const
Definition: katesearchbar.cpp:1628
KTextEditor::Document::startEditing
virtual bool startEditing()=0
KTextEditor::MovingRange::ExpandLeft
KateViewBarWidget::centralWidget
QWidget * centralWidget()
Definition: kateviewhelpers.h:305
KateViewBar::removeBarWidget
void removeBarWidget(KateViewBarWidget *barWidget)
Removes a widget from this viewbar.
Definition: kateviewhelpers.cpp:2452
KTextEditor::MovingCursor::atEndOfDocument
bool atEndOfDocument() const
KateSearchBar::selectionOnly
bool selectionOnly() const
Definition: katesearchbar.cpp:974
KateRenderer::config
KateRendererConfig * config() const
Configuration.
Definition: katerenderer.h:362
KateView::setSelection
virtual bool setSelection(const KTextEditor::Range &selection)
Definition: kateview.cpp:1931
messageinterface.h
KateSearchBar::updateHighlightColors
void updateHighlightColors()
Definition: katesearchbar.cpp:1556
KateSearchBar::setMatchCase
void setMatchCase(bool matchCase)
Definition: katesearchbar.cpp:436
KateViewConfig::PowerMatchCase
Definition: kateconfig.h:464
KColorScheme::PositiveBackground
QComboBox
KTextEditor::Attribute::setFontBold
void setFontBold(bool bold=true)
KateViewConfig::PowerFromCursor
Definition: kateconfig.h:466
KateSearchBar::findAll
void findAll()
Definition: katesearchbar.cpp:667
KateViewBarWidget::hideMe
void hideMe()
KateSearchBar::findPrevious
void findPrevious()
Definition: katesearchbar.cpp:269
KateSearchBar::slotReadWriteChanged
void slotReadWriteChanged()
Definition: katesearchbar.cpp:1632
KateSearchBar::SearchDirection
SearchDirection
Definition: katesearchbar.h:71
KParts::ReadWritePart::isReadWrite
bool isReadWrite() const
KIcon
KateDocument::documentEnd
virtual KTextEditor::Cursor documentEnd() const
Definition: katedocument.cpp:4682
KateViewConfig::replacementHistoryModel
QStringListModel * replacementHistoryModel()
Definition: kateconfig.cpp:1629
KateDocument::rangeOnLine
KTextEditor::Range rangeOnLine(KTextEditor::Range range, int line) const
Definition: katedocument.cpp:319
katesearchbar.h
KTextEditor::MovingRange::setAttribute
virtual void setAttribute(Attribute::Ptr attribute)=0
KateView::blockSelection
virtual bool blockSelection() const
Definition: kateview.cpp:2196
kstandardaction.h
KateRegExp::isMultiLine
bool isMultiLine() const
States, whether the pattern matches multiple lines, even if it was repaired using repairPattern()...
Definition: kateregexp.cpp:206
KateSearchBar::MatchWrappedForward
Definition: katesearchbar.h:64
KateSearchBar::KateSearchBar
KateSearchBar(bool initAsPower, KateView *view, KateViewConfig *config)
Definition: katesearchbar.cpp:131
KateSearchBar::replacementPattern
QString replacementPattern() const
Definition: katesearchbar.cpp:237
KTextEditor::MovingRange::setRange
virtual void setRange(const KTextEditor::Range &range)=0
KTextEditor::Document::documentRange
Range documentRange() const
KateView::selection
virtual bool selection() const
Definition: kateview.cpp:2008
KateSearchBar::SearchForward
Definition: katesearchbar.h:72
KateView
Definition: kateview.h:78
KTextEditor::Range
KMessageBox::questionYesNo
static int questionYesNo(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonYes=KStandardGuiItem::yes(), const KGuiItem &buttonNo=KStandardGuiItem::no(), const QString &dontAskAgainName=QString(), Options options=Notify)
KateSearchBar::MODE_REGEX
Definition: katesearchbar.h:59
KateSearchBar::replaceNext
void replaceNext()
Definition: katesearchbar.cpp:790
KTextEditor::Range::onSingleLine
bool onSingleLine() const
KateDocument
Definition: katedocument.h:74
KTextEditor::MovingRange::setView
virtual void setView(View *view)=0
QSet
KateSearchBar::MatchNeutral
Definition: katesearchbar.h:68
KateSearchBar::nextMatchForSelection
static void nextMatchForSelection(KateView *view, SearchDirection searchDirection)
Definition: katesearchbar.cpp:1228
KateUndoManager::undoSafePoint
void undoSafePoint()
Prevent latest KateUndoGroup from being merged with the next one.
Definition: kateundomanager.cpp:190
KColorScheme::NegativeBackground
KTextEditor::MovingRange::ExpandRight
QMenu
KateView::cursorPosition
KTextEditor::Cursor cursorPosition() const
Definition: kateview.cpp:2398
KTextEditor::Cursor::line
virtual int line() const
KateSearchBar::enterPowerMode
void enterPowerMode()
Definition: katesearchbar.cpp:1276
KTextEditor::Attribute::setDynamicAttribute
void setDynamicAttribute(ActivationType type, Attribute::Ptr attribute)
KateView::viInputMode
bool viInputMode() const
Definition: kateview.cpp:1515
KateDocument::getWord
QString getWord(const KTextEditor::Cursor &cursor)
Definition: katedocument.cpp:3537
KateViewConfig::PowerModePlainText
Definition: kateconfig.h:468
KColorScheme::adjustBackground
static void adjustBackground(QPalette &, BackgroundRole newRole=NormalBackground, QPalette::ColorRole color=QPalette::Base, ColorSet set=View, KSharedConfigPtr=KSharedConfigPtr())
QPoint
KateSearchBar::MODE_PLAIN_TEXT
Definition: katesearchbar.h:56
KTextEditor::Document::endEditing
virtual bool endEditing()=0
movingcursor.h
KTextEditor::Document::lineLength
virtual int lineLength(int line) const =0
KateSearchBar::SearchMode
SearchMode
Definition: katesearchbar.h:53
KateSearchBar::matchCase
bool matchCase() const
Definition: katesearchbar.cpp:462
KTextEditor::Range::end
Cursor & end()
KStandardGuiItem::no
KGuiItem no()
KTextEditor::Message::Positive
create
KAction * create(StandardAction id, const QObject *recvr, const char *slot, QObject *parent)
KTextEditor::MovingRange::setZDepth
virtual void setZDepth(qreal zDepth)=0
KateRendererConfig::searchHighlightColor
const QColor & searchHighlightColor() const
Definition: kateconfig.cpp:2538
QLineEdit
KateView::selectionText
virtual QString selectionText() const
Definition: kateview.cpp:2016
KateSearchBar::MatchResult
MatchResult
Definition: katesearchbar.h:62
kateundomanager.h
KateViewConfig::IncHighlightAll
Definition: kateconfig.h:462
KColorScheme::NormalText
KTextEditor::MovingCursor::move
bool move(int chars, WrapBehavior wrapBehavior=Wrap)
KateView::doc
KateDocument * doc()
accessor to katedocument pointer
Definition: kateview.h:552
KMessageBox::Yes
KTextEditor::MovingRange::end
virtual const MovingCursor & end() const =0
KateViewConfig::PowerModeRegularExpression
Definition: kateconfig.h:471
KateDocument::postMessage
virtual bool postMessage(KTextEditor::Message *message)
Definition: katedocument.cpp:5498
KateViewConfig
Definition: kateconfig.h:381
KateSearchBar::replaceAll
void replaceAll()
Definition: katesearchbar.cpp:908
KateViewConfig::maxHistorySize
int maxHistorySize() const
Definition: kateconfig.cpp:1624
KTextEditor::View
kmessagebox.h
KTextEditor::Range::isEmpty
bool isEmpty() const
KateSearchBar::findNext
void findNext()
Definition: katesearchbar.cpp:255
KateSearchBar::~KateSearchBar
~KateSearchBar()
Definition: katesearchbar.cpp:205
KTextEditor::Message::BottomInView
end
const KShortcut & end()
kateconfig.h
KTextEditor::Cursor::column
int column() const
KTextEditor::Message
KateView::setCursorPositionInternal
bool setCursorPositionInternal(const KTextEditor::Cursor &position, uint tabwidth=1, bool calledExternally=false)
Definition: kateview.cpp:1278
KColorScheme::NeutralBackground
KStandardGuiItem::yes
KGuiItem yes()
kcolorscheme.h
KTextEditor::Search::Default
QAction
KateViewConfig::patternHistoryModel
QStringListModel * patternHistoryModel()
Definition: kateconfig.cpp:1615
KateViewConfig::setSearchFlags
void setSearchFlags(long flags)
Definition: kateconfig.cpp:1602
QList
number
QString number(KIO::filesize_t size)
KTextEditor::Document::lines
virtual int lines() const =0
KateViewConfig::searchFlags
long searchFlags() const
Definition: kateconfig.cpp:1594
KateMatch::searchText
KTextEditor::Range searchText(const KTextEditor::Range &range, const QString &pattern)
Definition: katematch.cpp:34
katematch.h
KateSearchBar::setSearchMode
void setSearchMode(SearchMode mode)
Definition: katesearchbar.cpp:246
KTextEditor::Attribute::dynamicAttribute
Attribute::Ptr dynamicAttribute(ActivationType type) const
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:31:52 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Kate

Skip menu "Kate"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

applications API Reference

Skip menu "applications API Reference"
  •   kate
  •       kate
  •   KTextEditor
  •   Kate
  • Applications
  •   Libraries
  •     libkonq
  • Konsole

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal