• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kate
 

kate

  • kate
  • plugins
  • isearch
ISearchPlugin.cpp
1  /* This file is part of the KDE libraries
2  Copyright (C) 2002 by John Firebaugh <jfirebaugh@kde.org>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License version 2 as published by the Free Software Foundation.
7 
8  This library is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  Library General Public License for more details.
12 
13  You should have received a copy of the GNU Library General Public License
14  along with this library; see the file COPYING.LIB. If not, write to
15  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  Boston, MA 02110-1301, USA.
17  */
18 
19 #include <tqlabel.h>
20 #include <tqregexp.h>
21 #include <tqstyle.h>
22 #include <tqpopupmenu.h>
23 #include <kgenericfactory.h>
24 #include <tdelocale.h>
25 #include <tdeaction.h>
26 #include <kcombobox.h>
27 #include <tdeconfig.h>
28 #include <kdebug.h>
29 
30 #include "ISearchPlugin.h"
31 #include "ISearchPlugin.moc"
32 
33 K_EXPORT_COMPONENT_FACTORY( tdetexteditor_isearch, KGenericFactory<ISearchPlugin>( "tdetexteditor_isearch" ) )
34 
35 ISearchPluginView::ISearchPluginView( KTextEditor::View *view )
36  : TQObject ( view ), KXMLGUIClient (view)
37  , m_view( 0L )
38  , m_doc( 0L )
39  , m_searchIF( 0L )
40  , m_cursorIF( 0L )
41  , m_selectIF( 0L )
42 // , m_toolBarAction( 0L )
43  , m_searchForwardAction( 0L )
44  , m_searchBackwardAction( 0L )
45  , m_label( 0L )
46  , m_combo( 0L )
47  , m_lastString( "" )
48  , m_searchBackward( false )
49  , m_caseSensitive( false )
50  , m_fromBeginning( false )
51  , m_regExp( false )
52  , m_autoWrap( false )
53  , m_wrapped( false )
54  , m_startLine( 0 )
55  , m_startCol( 0 )
56  , m_searchLine( 0 )
57  , m_searchCol( 0 )
58  , m_foundLine( 0 )
59  , m_foundCol( 0 )
60  , m_matchLen( 0 )
61  , m_toolBarWasHidden( false )
62 {
63  view->insertChildClient (this);
64 
65  setInstance( KGenericFactory<ISearchPlugin>::instance() );
66 
67  m_searchForwardAction = new TDEAction(
68  i18n("Search Incrementally"), CTRL+ALT+Key_F,
69  this, TQ_SLOT(slotSearchForwardAction()),
70  actionCollection(), "edit_isearch" );
71  m_searchBackwardAction = new TDEAction(
72  i18n("Search Incrementally Backwards"), CTRL+ALT+SHIFT+Key_F,
73  this, TQ_SLOT(slotSearchBackwardAction()),
74  actionCollection(), "edit_isearch_reverse" );
75 
76  m_label = new TQLabel( i18n("I-Search:"), 0L, "tde toolbar widget" );
77  KWidgetAction* labelAction = new KWidgetAction(
78  m_label,
79  i18n("I-Search:"), 0, 0, 0,
80  actionCollection(), "isearch_label" );
81  labelAction->setShortcutConfigurable( false );
82 
83  m_combo = new KHistoryCombo();
84  m_combo->setDuplicatesEnabled( false );
85  m_combo->setMaximumWidth( 300 );
86  m_combo->lineEdit()->installEventFilter( this );
87  connect( m_combo, TQ_SIGNAL(textChanged(const TQString&)),
88  this, TQ_SLOT(slotTextChanged(const TQString&)) );
89  connect( m_combo, TQ_SIGNAL(returnPressed(const TQString&)),
90  this, TQ_SLOT(slotReturnPressed(const TQString&)) );
91  connect( m_combo, TQ_SIGNAL(aboutToShowContextMenu(TQPopupMenu*)),
92  this, TQ_SLOT(slotAddContextMenuItems(TQPopupMenu*)) );
93  m_comboAction = new KWidgetAction(
94  m_combo,
95  i18n("Search"), 0, 0, 0,
96  actionCollection(), "isearch_combo" );
97  m_comboAction->setAutoSized( true );
98  m_comboAction->setShortcutConfigurable( false );
99 
100  TDEActionMenu* optionMenu = new TDEActionMenu(
101  i18n("Search Options"), "configure",
102  actionCollection(), "isearch_options" );
103  optionMenu->setDelayed( false );
104 
105  TDEToggleAction* action = new TDEToggleAction(
106  i18n("Case Sensitive"), TDEShortcut(),
107  actionCollection(), "isearch_case_sensitive" );
108  action->setShortcutConfigurable( false );
109  connect( action, TQ_SIGNAL(toggled(bool)),
110  this, TQ_SLOT(setCaseSensitive(bool)) );
111  action->setChecked( m_caseSensitive );
112  optionMenu->insert( action );
113 
114  action = new TDEToggleAction(
115  i18n("From Beginning"), TDEShortcut(),
116  actionCollection(), "isearch_from_beginning" );
117  action->setShortcutConfigurable( false );
118  connect( action, TQ_SIGNAL(toggled(bool)),
119  this, TQ_SLOT(setFromBeginning(bool)) );
120  action->setChecked( m_fromBeginning );
121  optionMenu->insert( action );
122 
123  action = new TDEToggleAction(
124  i18n("Regular Expression"), TDEShortcut(),
125  actionCollection(), "isearch_reg_exp" );
126  action->setShortcutConfigurable( false );
127  connect( action, TQ_SIGNAL(toggled(bool)),
128  this, TQ_SLOT(setRegExp(bool)) );
129  action->setChecked( m_regExp );
130  optionMenu->insert( action );
131 
132 // optionMenu->insert( new TDEActionSeparator() );
133 //
134 // action = new TDEToggleAction(
135 // i18n("Auto-Wrap Search"), TDEShortcut(),
136 // actionCollection(), "isearch_auto_wrap" );
137 // connect( action, TQ_SIGNAL(toggled(bool)),
138 // this, TQ_SLOT(setAutoWrap(bool)) );
139 // action->setChecked( m_autoWrap );
140 // optionMenu->insert( action );
141 
142  setXMLFile( "tdetexteditor_isearchui.rc" );
143 }
144 
145 ISearchPluginView::~ISearchPluginView()
146 {
147  writeConfig();
148  m_combo->lineEdit()->removeEventFilter( this );
149  delete m_combo;
150  delete m_label;
151 }
152 
153 void ISearchPluginView::setView( KTextEditor::View* view )
154 {
155  m_view = view;
156  m_doc = m_view->document();
157  m_searchIF = KTextEditor::searchInterface ( m_doc );
158  m_cursorIF = KTextEditor::viewCursorInterface ( m_view );
159  m_selectIF = KTextEditor::selectionInterface ( m_doc );
160  if( !m_doc || !m_cursorIF || !m_selectIF ) {
161  m_view = 0L;
162  m_doc = 0L;
163  m_searchIF = 0L;
164  m_cursorIF = 0L;
165  m_selectIF = 0L;
166  }
167 
168  readConfig();
169 }
170 
171 void ISearchPluginView::readConfig()
172 {
173  // TDEConfig* config = instance()->config();
174 }
175 
176 void ISearchPluginView::writeConfig()
177 {
178  // TDEConfig* config = instance()->config();
179 }
180 
181 void ISearchPluginView::setCaseSensitive( bool caseSensitive )
182 {
183  m_caseSensitive = caseSensitive;
184 }
185 
186 void ISearchPluginView::setFromBeginning( bool fromBeginning )
187 {
188  m_fromBeginning = fromBeginning;
189 
190  if( m_fromBeginning ) {
191  m_searchLine = m_searchCol = 0;
192  }
193 }
194 
195 void ISearchPluginView::setRegExp( bool regExp )
196 {
197  m_regExp = regExp;
198 }
199 
200 void ISearchPluginView::setAutoWrap( bool autoWrap )
201 {
202  m_autoWrap = autoWrap;
203 }
204 
205 bool ISearchPluginView::eventFilter( TQObject* o, TQEvent* e )
206 {
207  if( o != m_combo->lineEdit() )
208  return false;
209 
210  if( e->type() == TQEvent::FocusIn ) {
211  TQFocusEvent* focusEvent = (TQFocusEvent*)e;
212  if( focusEvent->reason() == TQFocusEvent::ActiveWindow ||
213  focusEvent->reason() == TQFocusEvent::Popup )
214  return false;
215  startSearch();
216  }
217 
218  if( e->type() == TQEvent::FocusOut ) {
219  TQFocusEvent* focusEvent = (TQFocusEvent*)e;
220  if( focusEvent->reason() == TQFocusEvent::ActiveWindow ||
221  focusEvent->reason() == TQFocusEvent::Popup )
222  return false;
223  endSearch();
224  }
225 
226  if( e->type() == TQEvent::KeyPress ) {
227  TQKeyEvent *keyEvent = (TQKeyEvent*)e;
228  if( keyEvent->key() == TQt::Key_Escape )
229  quitToView( TQString::null );
230  }
231 
232  return false;
233 }
234 
235 // Sigh... i18n hell.
236 void ISearchPluginView::updateLabelText(
237  bool failing /* = false */, bool reverse /* = false */,
238  bool wrapped /* = false */, bool overwrapped /* = false */ )
239 {
240  TQString text;
241  // Reverse binary:
242  // 0000
243  if( !failing && !reverse && !wrapped && !overwrapped ) {
244  text = i18n("Incremental Search", "I-Search:");
245  // 1000
246  } else if ( failing && !reverse && !wrapped && !overwrapped ) {
247  text = i18n("Incremental Search found no match", "Failing I-Search:");
248  // 0100
249  } else if ( !failing && reverse && !wrapped && !overwrapped ) {
250  text = i18n("Incremental Search in the reverse direction", "I-Search Backward:");
251  // 1100
252  } else if ( failing && reverse && !wrapped && !overwrapped ) {
253  text = i18n("Failing I-Search Backward:");
254  // 0010
255  } else if ( !failing && !reverse && wrapped && !overwrapped ) {
256  text = i18n("Incremental Search has passed the end of the document", "Wrapped I-Search:");
257  // 1010
258  } else if ( failing && !reverse && wrapped && !overwrapped ) {
259  text = i18n("Failing Wrapped I-Search:");
260  // 0110
261  } else if ( !failing && reverse && wrapped && !overwrapped ) {
262  text = i18n("Wrapped I-Search Backward:");
263  // 1110
264  } else if ( failing && reverse && wrapped && !overwrapped ) {
265  text = i18n("Failing Wrapped I-Search Backward:");
266  // 0011
267  } else if ( !failing && !reverse && overwrapped ) {
268  text = i18n("Incremental Search has passed both the end of the document "
269  "and the original starting position", "Overwrapped I-Search:");
270  // 1011
271  } else if ( failing && !reverse && overwrapped ) {
272  text = i18n("Failing Overwrapped I-Search:");
273  // 0111
274  } else if ( !failing && reverse && overwrapped ) {
275  text = i18n("Overwrapped I-Search Backwards:");
276  // 1111
277  } else if ( failing && reverse && overwrapped ) {
278  text = i18n("Failing Overwrapped I-Search Backward:");
279  } else {
280  text = i18n("Error: unknown i-search state!");
281  }
282  m_label->setText( text );
283 }
284 
285 void ISearchPluginView::slotSearchForwardAction()
286 {
287  slotSearchAction( false );
288 }
289 
290 void ISearchPluginView::slotSearchBackwardAction()
291 {
292  slotSearchAction( true );
293 }
294 
295 void ISearchPluginView::slotSearchAction( bool reverse )
296 {
297  if( !m_combo->hasFocus() ) {
298  if( m_comboAction->container(0) && m_comboAction->container(0)->isHidden() ) {
299  m_toolBarWasHidden = true;
300  m_comboAction->container(0)->setHidden( false );
301  } else {
302  m_toolBarWasHidden = false;
303  }
304  m_combo->setFocus(); // Will call startSearch()
305  } else {
306  nextMatch( reverse );
307  }
308 }
309 
310 void ISearchPluginView::nextMatch( bool reverse )
311 {
312  TQString text = m_combo->currentText();
313  if( text.isEmpty() )
314  return;
315  if( state != MatchSearch ) {
316  // Last search was performed by typing, start from that match.
317  if( !reverse ) {
318  m_searchLine = m_foundLine;
319  m_searchCol = m_foundCol + m_matchLen;
320  } else {
321  m_searchLine = m_foundLine;
322  m_searchCol = m_foundCol;
323  }
324  state = MatchSearch;
325  }
326 
327  bool found = iSearch( m_searchLine, m_searchCol, text, reverse, m_autoWrap );
328  if( found ) {
329  m_searchLine = m_foundLine;
330  m_searchCol = m_foundCol + m_matchLen;
331  } else {
332  m_wrapped = true;
333  m_searchLine = m_searchCol = 0;
334  }
335 }
336 
337 void ISearchPluginView::startSearch()
338 {
339  if( !m_view ) return;
340 
341  m_searchForwardAction->setText( i18n("Next Incremental Search Match") );
342  m_searchBackwardAction->setText( i18n("Previous Incremental Search Match") );
343 
344  m_wrapped = false;
345 
346  if( m_fromBeginning ) {
347  m_startLine = m_startCol = 0;
348  } else {
349  m_cursorIF->cursorPositionReal( &m_startLine, &m_startCol );
350  }
351  m_searchLine = m_startLine;
352  m_searchCol = m_startCol;
353 
354  updateLabelText( false, m_searchBackward );
355 
356  m_combo->blockSignals( true );
357 
358  TQString text = m_selectIF->selection();
359  if( text.isEmpty() )
360  text = m_lastString;
361  m_combo->setCurrentText( text );
362 
363  m_combo->blockSignals( false );
364  m_combo->lineEdit()->selectAll();
365 
366 // kdDebug() << "Starting search at " << m_startLine << ", " << m_startCol << endl;
367 }
368 
369 void ISearchPluginView::endSearch()
370 {
371  m_searchForwardAction->setText( i18n("Search Incrementally") );
372  m_searchBackwardAction->setText( i18n("Search Incrementally Backwards") );
373 
374  updateLabelText();
375 
376  if( m_toolBarWasHidden && m_comboAction->containerCount() > 0 ) {
377  m_comboAction->container(0)->setHidden( true );
378  }
379 }
380 
381 void ISearchPluginView::quitToView( const TQString &text )
382 {
383  if( !text.isNull() && !text.isEmpty() ) {
384  m_combo->addToHistory( text );
385  m_lastString = text;
386  }
387 
388  if( m_view ) {
389  m_view->setFocus(); // Will call endSearch()
390  }
391 }
392 
393 void ISearchPluginView::slotTextChanged( const TQString& text )
394 {
395  state = TextSearch;
396 
397  if( text.isEmpty() )
398  return;
399 
400  iSearch( m_searchLine, m_searchCol, text, m_searchBackward, m_autoWrap );
401 }
402 
403 void ISearchPluginView::slotReturnPressed( const TQString& text )
404 {
405  quitToView( text );
406 }
407 
408 void ISearchPluginView::slotAddContextMenuItems( TQPopupMenu *menu )
409 {
410  if( menu ) {
411  menu->insertSeparator();
412  menu->insertItem( i18n("Case Sensitive"), this,
413  TQ_SLOT(setCaseSensitive(bool)));
414  menu->insertItem( i18n("From Beginning"), this,
415  TQ_SLOT(setFromBeginning(bool)));
416  menu->insertItem( i18n("Regular Expression"), this,
417  TQ_SLOT(setRegExp(bool)));
418  //menu->insertItem( i18n("Auto-Wrap Search"), this,
419  // TQ_SLOT(setAutoWrap(bool)));
420  }
421 }
422 
423 bool ISearchPluginView::iSearch(
424  uint startLine, uint startCol,
425  const TQString& text, bool reverse,
426  bool autoWrap )
427 {
428  if( !m_view ) return false;
429 
430 // kdDebug() << "Searching for " << text << " at " << startLine << ", " << startCol << endl;
431  bool found = false;
432  if( !m_regExp ) {
433  found = m_searchIF->searchText( startLine,
434  startCol,
435  text,
436  &m_foundLine,
437  &m_foundCol,
438  &m_matchLen,
439  m_caseSensitive,
440  reverse );
441  } else {
442  found = m_searchIF->searchText( startLine,
443  startCol,
444  TQRegExp( text ),
445  &m_foundLine,
446  &m_foundCol,
447  &m_matchLen,
448  reverse );
449  }
450  if( found ) {
451 // kdDebug() << "Found '" << text << "' at " << m_foundLine << ", " << m_foundCol << endl;
452 // v->gotoLineNumber( m_foundLine );
453  m_cursorIF->setCursorPositionReal( m_foundLine, m_foundCol + m_matchLen );
454  m_selectIF->setSelection( m_foundLine, m_foundCol, m_foundLine, m_foundCol + m_matchLen );
455  } else if ( autoWrap ) {
456  m_wrapped = true;
457  found = iSearch( 0, 0, text, reverse, false );
458  }
459  // FIXME
460  bool overwrapped = ( m_wrapped &&
461  ((m_foundLine > m_startLine ) ||
462  (m_foundLine == m_startLine && m_foundCol >= m_startCol)) );
463 // kdDebug() << "Overwrap = " << overwrapped << ". Start was " << m_startLine << ", " << m_startCol << endl;
464  updateLabelText( !found, reverse, m_wrapped, overwrapped );
465  return found;
466 }
467 
468 ISearchPlugin::ISearchPlugin( TQObject *parent, const char* name, const TQStringList& )
469  : KTextEditor::Plugin ( (KTextEditor::Document*) parent, name )
470 {
471 }
472 
473 ISearchPlugin::~ISearchPlugin()
474 {
475 }
476 
477 void ISearchPlugin::addView(KTextEditor::View *view)
478 {
479  ISearchPluginView *nview = new ISearchPluginView (view);
480  nview->setView (view);
481  m_views.append (nview);
482 }
483 
484 void ISearchPlugin::removeView(KTextEditor::View *view)
485 {
486  for (uint z=0; z < m_views.count(); z++)
487  {
488  if (m_views.at(z)->parentClient() == view)
489  {
490  ISearchPluginView *nview = m_views.at(z);
491  m_views.remove (nview);
492  delete nview;
493  }
494  }
495 }
KGenericFactory
KHistoryCombo
KWidgetAction
KXMLGUIClient
TDEActionMenu
TDEActionMenu::setDelayed
void setDelayed(bool _delayed)
TDEAction
TDEAction::setShortcutConfigurable
virtual void setShortcutConfigurable(bool)
TDEShortcut
TDEToggleAction
TDEStdAccel::name
TQString name(StdAccel id)
TDEStdAccel::action
TQString action(StdAccel id)
tdelocale.h

kate

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

kate

Skip menu "kate"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for kate by doxygen 1.9.1
This website is maintained by Timothy Pearson.