22 #include <tqpopupmenu.h>
23 #include <kgenericfactory.h>
25 #include <tdeaction.h>
26 #include <kcombobox.h>
27 #include <tdeconfig.h>
30 #include "ISearchPlugin.h"
31 #include "ISearchPlugin.moc"
35 ISearchPluginView::ISearchPluginView( KTextEditor::View *view )
43 , m_searchForwardAction( 0L )
44 , m_searchBackwardAction( 0L )
48 , m_searchBackward( false )
49 , m_caseSensitive( false )
50 , m_fromBeginning( false )
61 , m_toolBarWasHidden( false )
63 view->insertChildClient (
this);
68 i18n(
"Search Incrementally"), CTRL+ALT+Key_F,
69 this, TQ_SLOT(slotSearchForwardAction()),
70 actionCollection(),
"edit_isearch" );
72 i18n(
"Search Incrementally Backwards"), CTRL+ALT+SHIFT+Key_F,
73 this, TQ_SLOT(slotSearchBackwardAction()),
74 actionCollection(),
"edit_isearch_reverse" );
76 m_label =
new TQLabel( i18n(
"I-Search:"), 0L,
"tde toolbar widget" );
79 i18n(
"I-Search:"), 0, 0, 0,
80 actionCollection(),
"isearch_label" );
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*)) );
95 i18n(
"Search"), 0, 0, 0,
96 actionCollection(),
"isearch_combo" );
97 m_comboAction->setAutoSized(
true );
98 m_comboAction->setShortcutConfigurable(
false );
101 i18n(
"Search Options"),
"configure",
102 actionCollection(),
"isearch_options" );
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 );
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 );
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 );
142 setXMLFile(
"tdetexteditor_isearchui.rc" );
145 ISearchPluginView::~ISearchPluginView()
148 m_combo->lineEdit()->removeEventFilter(
this );
153 void ISearchPluginView::setView( KTextEditor::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 ) {
171 void ISearchPluginView::readConfig()
176 void ISearchPluginView::writeConfig()
181 void ISearchPluginView::setCaseSensitive(
bool caseSensitive )
183 m_caseSensitive = caseSensitive;
186 void ISearchPluginView::setFromBeginning(
bool fromBeginning )
188 m_fromBeginning = fromBeginning;
190 if( m_fromBeginning ) {
191 m_searchLine = m_searchCol = 0;
195 void ISearchPluginView::setRegExp(
bool regExp )
200 void ISearchPluginView::setAutoWrap(
bool autoWrap )
202 m_autoWrap = autoWrap;
205 bool ISearchPluginView::eventFilter( TQObject* o, TQEvent* e )
207 if( o != m_combo->lineEdit() )
210 if( e->type() == TQEvent::FocusIn ) {
211 TQFocusEvent* focusEvent = (TQFocusEvent*)e;
212 if( focusEvent->reason() == TQFocusEvent::ActiveWindow ||
213 focusEvent->reason() == TQFocusEvent::Popup )
218 if( e->type() == TQEvent::FocusOut ) {
219 TQFocusEvent* focusEvent = (TQFocusEvent*)e;
220 if( focusEvent->reason() == TQFocusEvent::ActiveWindow ||
221 focusEvent->reason() == TQFocusEvent::Popup )
226 if( e->type() == TQEvent::KeyPress ) {
227 TQKeyEvent *keyEvent = (TQKeyEvent*)e;
228 if( keyEvent->key() == TQt::Key_Escape )
229 quitToView( TQString::null );
236 void ISearchPluginView::updateLabelText(
237 bool failing ,
bool reverse ,
238 bool wrapped ,
bool overwrapped )
243 if( !failing && !reverse && !wrapped && !overwrapped ) {
244 text = i18n(
"Incremental Search",
"I-Search:");
246 }
else if ( failing && !reverse && !wrapped && !overwrapped ) {
247 text = i18n(
"Incremental Search found no match",
"Failing I-Search:");
249 }
else if ( !failing && reverse && !wrapped && !overwrapped ) {
250 text = i18n(
"Incremental Search in the reverse direction",
"I-Search Backward:");
252 }
else if ( failing && reverse && !wrapped && !overwrapped ) {
253 text = i18n(
"Failing I-Search Backward:");
255 }
else if ( !failing && !reverse && wrapped && !overwrapped ) {
256 text = i18n(
"Incremental Search has passed the end of the document",
"Wrapped I-Search:");
258 }
else if ( failing && !reverse && wrapped && !overwrapped ) {
259 text = i18n(
"Failing Wrapped I-Search:");
261 }
else if ( !failing && reverse && wrapped && !overwrapped ) {
262 text = i18n(
"Wrapped I-Search Backward:");
264 }
else if ( failing && reverse && wrapped && !overwrapped ) {
265 text = i18n(
"Failing Wrapped I-Search Backward:");
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:");
271 }
else if ( failing && !reverse && overwrapped ) {
272 text = i18n(
"Failing Overwrapped I-Search:");
274 }
else if ( !failing && reverse && overwrapped ) {
275 text = i18n(
"Overwrapped I-Search Backwards:");
277 }
else if ( failing && reverse && overwrapped ) {
278 text = i18n(
"Failing Overwrapped I-Search Backward:");
280 text = i18n(
"Error: unknown i-search state!");
282 m_label->setText( text );
285 void ISearchPluginView::slotSearchForwardAction()
287 slotSearchAction(
false );
290 void ISearchPluginView::slotSearchBackwardAction()
292 slotSearchAction(
true );
295 void ISearchPluginView::slotSearchAction(
bool reverse )
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 );
302 m_toolBarWasHidden =
false;
306 nextMatch( reverse );
310 void ISearchPluginView::nextMatch(
bool reverse )
312 TQString text = m_combo->currentText();
315 if( state != MatchSearch ) {
318 m_searchLine = m_foundLine;
319 m_searchCol = m_foundCol + m_matchLen;
321 m_searchLine = m_foundLine;
322 m_searchCol = m_foundCol;
327 bool found = iSearch( m_searchLine, m_searchCol, text, reverse, m_autoWrap );
329 m_searchLine = m_foundLine;
330 m_searchCol = m_foundCol + m_matchLen;
333 m_searchLine = m_searchCol = 0;
337 void ISearchPluginView::startSearch()
339 if( !m_view )
return;
341 m_searchForwardAction->setText( i18n(
"Next Incremental Search Match") );
342 m_searchBackwardAction->setText( i18n(
"Previous Incremental Search Match") );
346 if( m_fromBeginning ) {
347 m_startLine = m_startCol = 0;
349 m_cursorIF->cursorPositionReal( &m_startLine, &m_startCol );
351 m_searchLine = m_startLine;
352 m_searchCol = m_startCol;
354 updateLabelText(
false, m_searchBackward );
356 m_combo->blockSignals(
true );
358 TQString text = m_selectIF->selection();
361 m_combo->setCurrentText( text );
363 m_combo->blockSignals(
false );
364 m_combo->lineEdit()->selectAll();
369 void ISearchPluginView::endSearch()
371 m_searchForwardAction->setText( i18n(
"Search Incrementally") );
372 m_searchBackwardAction->setText( i18n(
"Search Incrementally Backwards") );
376 if( m_toolBarWasHidden && m_comboAction->containerCount() > 0 ) {
377 m_comboAction->container(0)->setHidden(
true );
381 void ISearchPluginView::quitToView(
const TQString &text )
383 if( !text.isNull() && !text.isEmpty() ) {
384 m_combo->addToHistory( text );
393 void ISearchPluginView::slotTextChanged(
const TQString& text )
400 iSearch( m_searchLine, m_searchCol, text, m_searchBackward, m_autoWrap );
403 void ISearchPluginView::slotReturnPressed(
const TQString& text )
408 void ISearchPluginView::slotAddContextMenuItems( TQPopupMenu *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)));
423 bool ISearchPluginView::iSearch(
424 uint startLine, uint startCol,
425 const TQString& text,
bool reverse,
428 if( !m_view )
return false;
433 found = m_searchIF->searchText( startLine,
442 found = m_searchIF->searchText( startLine,
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 ) {
457 found = iSearch( 0, 0, text, reverse,
false );
460 bool overwrapped = ( m_wrapped &&
461 ((m_foundLine > m_startLine ) ||
462 (m_foundLine == m_startLine && m_foundCol >= m_startCol)) );
464 updateLabelText( !found, reverse, m_wrapped, overwrapped );
468 ISearchPlugin::ISearchPlugin( TQObject *parent,
const char* name,
const TQStringList& )
469 : KTextEditor::Plugin ( (KTextEditor::Document*) parent,
name )
473 ISearchPlugin::~ISearchPlugin()
477 void ISearchPlugin::addView(KTextEditor::View *view)
479 ISearchPluginView *nview =
new ISearchPluginView (view);
480 nview->setView (view);
481 m_views.append (nview);
484 void ISearchPlugin::removeView(KTextEditor::View *view)
486 for (uint z=0; z < m_views.count(); z++)
488 if (m_views.at(z)->parentClient() == view)
490 ISearchPluginView *nview = m_views.at(z);
491 m_views.remove (nview);
virtual void setShortcutConfigurable(bool)
TQString name(StdAccel id)
TQString action(StdAccel id)