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

Kate

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