• 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
33K_EXPORT_COMPONENT_FACTORY( tdetexteditor_isearch, KGenericFactory<ISearchPlugin>( "tdetexteditor_isearch" ) )
34
35ISearchPluginView::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
145ISearchPluginView::~ISearchPluginView()
146{
147 writeConfig();
148 m_combo->lineEdit()->removeEventFilter( this );
149 delete m_combo;
150 delete m_label;
151}
152
153void 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
171void ISearchPluginView::readConfig()
172{
173 // TDEConfig* config = instance()->config();
174}
175
176void ISearchPluginView::writeConfig()
177{
178 // TDEConfig* config = instance()->config();
179}
180
181void ISearchPluginView::setCaseSensitive( bool caseSensitive )
182{
183 m_caseSensitive = caseSensitive;
184}
185
186void ISearchPluginView::setFromBeginning( bool fromBeginning )
187{
188 m_fromBeginning = fromBeginning;
189
190 if( m_fromBeginning ) {
191 m_searchLine = m_searchCol = 0;
192 }
193}
194
195void ISearchPluginView::setRegExp( bool regExp )
196{
197 m_regExp = regExp;
198}
199
200void ISearchPluginView::setAutoWrap( bool autoWrap )
201{
202 m_autoWrap = autoWrap;
203}
204
205bool 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.
236void 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
285void ISearchPluginView::slotSearchForwardAction()
286{
287 slotSearchAction( false );
288}
289
290void ISearchPluginView::slotSearchBackwardAction()
291{
292 slotSearchAction( true );
293}
294
295void 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
310void 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
337void 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
369void 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
381void 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
393void 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
403void ISearchPluginView::slotReturnPressed( const TQString& text )
404{
405 quitToView( text );
406}
407
408void 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
423bool 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
468ISearchPlugin::ISearchPlugin( TQObject *parent, const char* name, const TQStringList& )
469 : KTextEditor::Plugin ( (KTextEditor::Document*) parent, name )
470{
471}
472
473ISearchPlugin::~ISearchPlugin()
474{
475}
476
477void ISearchPlugin::addView(KTextEditor::View *view)
478{
479 ISearchPluginView *nview = new ISearchPluginView (view);
480 nview->setView (view);
481 m_views.append (nview);
482}
483
484void 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.4
This website is maintained by Timothy Pearson.