lib

KoSearchDia.cpp
1/* This file is part of the KDE project
2 Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
3 Copyright (C) 2001, S.R.Haque <srhaque@iee.org>
4 Copyright (C) 2001, David Faure <faure@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
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 "KoSearchDia.h"
23#include "KoTextParag.h"
24
25#include <KoGlobal.h>
26#include <KoTextObject.h>
27#include <KoTextView.h>
28
29#include <kcolorbutton.h>
30#include <kcommand.h>
31#include <kdebug.h>
32#include <tdefontcombo.h>
33#include <tdelocale.h>
34#include <kseparator.h>
35
36#include <tqbuttongroup.h>
37#include <tqcheckbox.h>
38#include <tqcombobox.h>
39#include <tqradiobutton.h>
40#include <tqregexp.h>
41#include <tqspinbox.h>
42#include <tqlayout.h>
43
44KoSearchContext::KoSearchContext()
45{
46 m_family = "times";
47 m_color = TQt::black;
48 m_backGroundColor = TQt::black;
49
50 m_size = 12;
51 m_vertAlign = KoTextFormat::AlignNormal;
52 m_optionsMask = 0;
53 m_options = KFindDialog::FromCursor | KReplaceDialog::PromptOnReplace;
54 m_underline = KoTextFormat::U_NONE;
55 m_strikeOut = KoTextFormat::S_NONE;
56 m_attribute = KoTextFormat::ATT_NONE;
57 m_language = TQString();
58}
59
60KoSearchContext::~KoSearchContext()
61{
62}
63
64
65KoSearchContextUI::KoSearchContextUI( KoSearchContext *ctx, TQWidget *parent )
66 : TQObject(parent), m_ctx(ctx), m_parent(parent)
67{
68 m_bOptionsShown = false;
69 m_btnShowOptions = new TQPushButton( i18n("Show Formatting Options"), parent );
70 connect( m_btnShowOptions, TQ_SIGNAL( clicked() ), TQ_SLOT( slotShowOptions() ) );
71
72 m_grid = new TQGridLayout( m_parent, 1, 1, 0, 6 );
73 m_grid->addWidget( m_btnShowOptions, 0, 0 );
74 m_btnShowOptions->setEnabled( true );
75}
76
77void KoSearchContextUI::slotShowOptions()
78{
79 KoFormatDia * dlg = new KoFormatDia( m_parent, i18n("Formatting Options"), m_ctx );
80 if ( dlg->exec())
81 {
82 dlg->ctxOptions( );
83 m_bOptionsShown = true;
84 }
85
86 delete dlg;
87}
88
89void KoSearchContextUI::setCtxOptions( long options )
90{
91 if ( m_bOptionsShown )
92 {
93 options |= m_ctx->m_options;
94 }
95 m_ctx->m_options = options;
96}
97
98void KoSearchContextUI::setCtxHistory( const TQStringList & history )
99{
100 m_ctx->m_strings = history;
101}
102
103KoSearchDia::KoSearchDia( TQWidget * parent,const char *name, KoSearchContext *find, bool hasSelection, bool hasCursor )
104 : KFindDialog( parent, name, find->m_options, find->m_strings )
105{
106 // The dialog extension.
107 m_findUI = new KoSearchContextUI( find, findExtension() );
108 setHasSelection(hasSelection);
109 setHasCursor(hasCursor);
110}
111
112void KoSearchDia::slotOk()
113{
114 KFindDialog::slotOk();
115
116 // Save the current state back into the context required.
117 if ( optionSelected() )
118 m_findUI->setCtxOptions( options() );
119 m_findUI->setCtxHistory( findHistory() );
120}
121
122KoReplaceDia::KoReplaceDia( TQWidget *parent, const char *name, KoSearchContext *find, KoSearchContext *replace, bool hasSelection, bool hasCursor )
123 : KReplaceDialog( parent, name, find->m_options, find->m_strings, replace->m_strings )
124{
125 // The dialog extension.
126 m_findUI = new KoSearchContextUI( find, findExtension() );
127 m_replaceUI = new KoSearchContextUI( replace, replaceExtension() );
128 // Look whether we have a selection, and/or a cursor
129 setHasSelection(hasSelection);
130 setHasCursor(hasCursor);
131}
132
133void KoReplaceDia::slotOk()
134{
135 KReplaceDialog::slotOk();
136
137 // Save the current state back into the context required.
138 m_findUI->setCtxHistory( findHistory() );
139 if ( optionFindSelected() )
140 m_findUI->setCtxOptions( KReplaceDialog::options() );
141
142 m_replaceUI->setCtxHistory( replacementHistory() );
143 if ( optionReplaceSelected() )
144 m_replaceUI->setCtxOptions( KReplaceDialog::options() );
145}
146
147
148
149KoFindReplace::KoFindReplace( TQWidget * parent, KoSearchDia * dialog, const TQValueList<KoTextObject *> & lstObject, KoTextView* textView )
150 : m_find( new KoTextFind( dialog->pattern(), dialog->options(), this, parent ) ),
151 m_replace( 0L ),
152 m_searchContext( *dialog->searchContext() ),
153 m_replaceContext(),
154 m_searchContextEnabled( dialog->optionSelected() ),
155 m_doCounting( true ),
156 m_macroCmd( 0L ),
157 m_offset( 0 ),
158 m_textIterator( lstObject, textView, dialog->options() ),
159 m_lastTextObjectHighlighted( 0 )
160{
161 connectFind( m_find );
162}
163
164KoFindReplace::KoFindReplace( TQWidget * parent, KoReplaceDia * dialog, const TQValueList<KoTextObject *> & lstObject, KoTextView* textView )
165 : m_find( 0L ),
166 m_replace( new KoTextReplace( dialog->pattern(), dialog->replacement(), dialog->options(), this, parent ) ),
167 m_searchContext( *dialog->searchContext() ),
168 m_replaceContext( *dialog->replaceContext() ),
169 m_searchContextEnabled( dialog->optionFindSelected() ),
170 m_doCounting( true ),
171 m_macroCmd( 0L ),
172 m_offset( 0 ),
173 m_textIterator( lstObject, textView, dialog->options() ),
174 m_lastTextObjectHighlighted( 0 )
175{
176 connectFind( m_replace );
177 connect( m_replace, TQ_SIGNAL( replace( const TQString &, int , int, int ) ),
178 this, TQ_SLOT( replace( const TQString &, int , int,int ) ) );
179}
180
181void KoFindReplace::connectFind( KFind* find )
182{
183 connect( find, TQ_SIGNAL( optionsChanged() ),
184 this, TQ_SLOT( optionsChanged() ) );
185 connect( find, TQ_SIGNAL( dialogClosed() ),
186 this, TQ_SLOT( dialogClosed() ) );
187 // Connect highlight signal to code which handles highlighting
188 // of found text.
189 connect( find, TQ_SIGNAL( highlight( const TQString &, int, int ) ),
190 this, TQ_SLOT( highlight( const TQString &, int, int ) ) );
191 // Connect findNext signal - called when pressing the button in the dialog
192 connect( find, TQ_SIGNAL( findNext() ),
193 this, TQ_SLOT( slotFindNext() ) );
194 m_bInit = true;
195 m_currentParagraphModified = false;
196 m_matchingIndex = -1;
197
198 // Also connect to the textiterator
199 connect( &m_textIterator, TQ_SIGNAL( currentParagraphModified( int, int, int ) ),
200 this, TQ_SLOT( slotCurrentParagraphModified( int, int, int ) ) );
201}
202
203KoFindReplace::~KoFindReplace()
204{
205 removeHighlight();
206 //kdDebug(32500) << "KoFindReplace::~KoFindReplace" << endl;
207 delete m_find;
208 delete m_replace;
209}
210
211void KoFindReplace::optionsChanged()
212{
213 m_textIterator.setOptions( options() );
214}
215
216void KoFindReplace::dialogClosed()
217{
218 removeHighlight();
219 emitUndoRedo();
220 // we have to stop the match counting when closing the dialog,
221 // because Shift-F3 (find previous) would keep increasing that count, wrongly.
222 m_doCounting = false;
223}
224
225void KoFindReplace::removeHighlight()
226{
227 if ( m_lastTextObjectHighlighted )
228 m_lastTextObjectHighlighted->removeHighlight(true);
229 m_lastTextObjectHighlighted = 0L;
230}
231
233{
234 // Emit the command containing the replace operations
235 // #### We allow editing text during a replace operation, so we need
236 // to call this more often... so that 'undo' undoes the last
237 // replace operations. TODO!
238 if(m_macroCmd)
239 emitNewCommand(m_macroCmd);
240 m_macroCmd = 0L;
241}
242
251
253{
254 KFind::Result res = KFind::NoMatch;
255 while ( res == KFind::NoMatch && !m_textIterator.atEnd() ) {
256 //kdDebug(32500) << "findNext loop. m_bInit=" << m_bInit << " needData=" << needData() << " m_currentParagraphModified=" << m_currentParagraphModified << endl;
257 if ( needData() || m_currentParagraphModified ) {
258 if ( !m_bInit && !m_currentParagraphModified ) {
259 ++m_textIterator;
260 if ( m_textIterator.atEnd() )
261 break;
262 }
263 m_bInit = false;
264 TQPair<int, TQString> c = m_textIterator.currentTextAndIndex();
265 m_offset = c.first;
266 if ( !m_currentParagraphModified )
267 setData( c.second );
268 else
269 setData( c.second, m_matchingIndex );
270 m_currentParagraphModified = false;
271 }
272
273 if ( m_find )
274 // Let KFind inspect the text fragment, and display a dialog if a match is found
275 res = m_find->find();
276 else
277 res = m_replace->replace();
278 }
279
280 //kdDebug(32500) << k_funcinfo << "we're done. res=" << res << endl;
281 if ( res == KFind::NoMatch ) // i.e. at end
282 {
283 emitUndoRedo();
284 removeHighlight();
285 if ( shouldRestart() ) {
286 m_textIterator.setOptions( m_textIterator.options() & ~KFindDialog::FromCursor );
287 m_textIterator.restart();
288 m_bInit = true;
289 if ( m_find )
290 m_find->resetCounts();
291 else
292 m_replace->resetCounts();
293 return findNext();
294 }
295 else { // done, close the 'find next' dialog
296 if ( m_find )
297 m_find->closeFindNextDialog();
298 else
299 m_replace->closeReplaceNextDialog();
300 }
301 return false;
302 }
303 return true;
304}
305
306void KoFindReplace::slotFindNext() // called by the button in the small "find next?" dialog
307{
308 bool ret = findNext();
309 Q_UNUSED(ret);
310}
311
313{
314 int opt = options();
315 bool forw = ! ( options() & KFindDialog::FindBackwards );
316 if ( forw )
317 setOptions( opt | KFindDialog::FindBackwards );
318 else
319 setOptions( opt & ~KFindDialog::FindBackwards );
320
321 bool ret = findNext();
322
323 setOptions( opt ); // restore initial options
324
325 return ret;
326}
327
328long KoFindReplace::options() const
329{
330 return m_find ? m_find->options() : m_replace->options();
331}
332
333void KoFindReplace::setOptions(long opt)
334{
335 if ( m_find )
336 m_find->setOptions(opt);
337 else
338 m_replace->setOptions(opt);
339 m_textIterator.setOptions( opt );
340}
341
342void KoFindReplace::slotCurrentParagraphModified( int, int pos, int )
343{
344 if ( pos >= m_offset )
345 m_currentParagraphModified = true;
346 // (this bool forces the next findNext() to call setData again)
347}
348
349// slot connected to the 'highlight' signal
350void KoFindReplace::highlight( const TQString &, int matchingIndex, int matchingLength )
351{
352 m_matchingIndex = matchingIndex;
353 if ( m_lastTextObjectHighlighted )
354 m_lastTextObjectHighlighted->removeHighlight(true);
355 m_lastTextObjectHighlighted = m_textIterator.currentTextObject();
356 //kdDebug(32500) << "KoFindReplace::highlight " << matchingIndex << "," << matchingLength << endl;
357 KDialogBase* dialog = m_find ? m_find->findNextDialog() : m_replace->replaceNextDialog();
358 highlightPortion(m_textIterator.currentParag(), m_offset + matchingIndex, matchingLength, m_lastTextObjectHighlighted->textDocument(), dialog );
359}
360
361// slot connected to the 'replace' signal
362void KoFindReplace::replace( const TQString &text, int matchingIndex,
363 int replacementLength, int matchedLength )
364{
365 //kdDebug(32500) << "KoFindReplace::replace m_offset=" << m_offset << " matchingIndex=" << matchingIndex << " matchedLength=" << matchedLength << " options=" << options() << endl;
366 m_matchingIndex = matchingIndex;
367 int index = m_offset + matchingIndex;
368
369 // highlight might not have happened (if 'prompt on replace' is off)
370 if ( (options() & KReplaceDialog::PromptOnReplace) == 0 )
371 highlight( text, matchingIndex, matchedLength );
372
373 KoTextObject* currentTextObj = m_textIterator.currentTextObject();
374 KoTextDocument * textdoc = currentTextObj->textDocument();
375 KoTextCursor cursor( textdoc );
376 cursor.setParag( m_textIterator.currentParag() );
377 cursor.setIndex( index );
378
379 //reactive spellchecking
380 currentTextObj->setNeedSpellCheck(true);
381 if ( m_replaceContext.m_optionsMask )
382 {
383 replaceWithAttribut( &cursor, index );
384 }
385 // Don't repaint if we're doing batch changes
386 bool repaint = options() & KReplaceDialog::PromptOnReplace;
387
388 // Grab replacement string
389 TQString rep = text.mid( matchingIndex, replacementLength );
390
391 // Don't let the replacement set the paragraph to "modified by user"
392 disconnect( &m_textIterator, TQ_SIGNAL( currentParagraphModified( int, int, int ) ),
393 this, TQ_SLOT( slotCurrentParagraphModified( int, int, int ) ) );
394
395 KCommand *cmd = currentTextObj->replaceSelectionCommand(
396 &cursor, rep, TQString(),
397 KoTextDocument::HighlightSelection,
398 repaint ? KoTextObject::DefaultInsertFlags : KoTextObject::DoNotRepaint );
399
400 connect( &m_textIterator, TQ_SIGNAL( currentParagraphModified( int, int, int ) ),
401 this, TQ_SLOT( slotCurrentParagraphModified( int, int, int ) ) );
402
403 if( cmd )
404 macroCommand()->addCommand(cmd);
405}
406
407void KoFindReplace::replaceWithAttribut( KoTextCursor * cursor, int index )
408{
409 KoTextFormat * lastFormat = m_textIterator.currentParag()->at( index )->format();
410 KoTextFormat * newFormat = new KoTextFormat(*lastFormat);
411 int flags = 0;
412 if (m_replaceContext.m_optionsMask & KoSearchContext::Bold)
413 {
414 flags |= KoTextFormat::Bold;
415 newFormat->setBold( (bool)(m_replaceContext.m_options & KoSearchContext::Bold) );
416 }
417 if (m_replaceContext.m_optionsMask & KoSearchContext::Size)
418 {
419 flags |= KoTextFormat::Size;
420 newFormat->setPointSize( m_replaceContext.m_size );
421
422 }
423 if ( m_replaceContext.m_optionsMask & KoSearchContext::Family)
424 {
425 flags |= KoTextFormat::Family;
426 newFormat->setFamily( m_replaceContext.m_family );
427 }
428 if ( m_replaceContext.m_optionsMask & KoSearchContext::Color)
429 {
430 flags |= KoTextFormat::Color;
431 newFormat->setColor( m_replaceContext.m_color );
432 }
433 if ( m_replaceContext.m_optionsMask & KoSearchContext::Italic)
434 {
435 flags |= KoTextFormat::Italic;
436 newFormat->setItalic( (bool)(m_replaceContext.m_options & KoSearchContext::Italic) );
437 }
438 if ( m_replaceContext.m_optionsMask & KoSearchContext::Underline)
439 {
440 flags |= KoTextFormat::ExtendUnderLine;
441 newFormat->setUnderlineType( m_replaceContext.m_underline );
442
443 }
444 if ( m_replaceContext.m_optionsMask & KoSearchContext::VertAlign)
445 {
446 flags |= KoTextFormat::VAlign;
447 newFormat->setVAlign( m_replaceContext.m_vertAlign);
448 }
449 if ( m_replaceContext.m_optionsMask & KoSearchContext::StrikeOut)
450 {
451 flags |= KoTextFormat::StrikeOut;
452 newFormat->setStrikeOutType( m_replaceContext.m_strikeOut);
453 }
454 if ( m_replaceContext.m_optionsMask & KoSearchContext::BgColor)
455 {
456 newFormat->setTextBackgroundColor(m_replaceContext.m_backGroundColor);
457 flags |= KoTextFormat::TextBackgroundColor;
458 }
459 if (m_replaceContext.m_optionsMask & KoSearchContext::Shadow)
460 {
461 flags |= KoTextFormat::ShadowText;
462 // If shadow has been selected, we set a shadow (any shadow) in the new format
463 if ( m_replaceContext.m_options & KoSearchContext::Shadow )
464 newFormat->setShadow( 1, 1, TQt::gray );
465 else
466 newFormat->setShadow( 0, 0, TQColor() );
467 }
468 if (m_replaceContext.m_optionsMask & KoSearchContext::WordByWord)
469 {
470 flags |= KoTextFormat::WordByWord;
471 newFormat->setWordByWord( (bool)(m_replaceContext.m_options & KoSearchContext::WordByWord) );
472 }
473 if (m_replaceContext.m_optionsMask & KoSearchContext::Language)
474 {
475 flags |= KoTextFormat::Language;
476 newFormat->setLanguage( m_replaceContext.m_language );
477 }
478
479
480 KCommand *cmd = m_textIterator.currentTextObject()->setFormatCommand( cursor, &lastFormat ,newFormat,flags , false, KoTextDocument::HighlightSelection );
481
482 if( cmd )
483 macroCommand()->addCommand(cmd);
484}
485
486KMacroCommand* KoFindReplace::macroCommand()
487{
488 // Create on demand, to avoid making an empty command
489 if(!m_macroCmd)
490 m_macroCmd = new KMacroCommand(i18n("Replace Text"));
491 return m_macroCmd;
492}
493
495{
496 KDialogBase* dialog = m_find ? m_find->findNextDialog() : m_replace->replaceNextDialog();
497 if ( dialog )
498 dialog->setActiveWindow();
499}
500
501/*int KoFindReplace::numMatches() const
502{
503 return m_find->numMatches();
504}
505
506int KoFindReplace::numReplacements() const
507{
508 return m_replace->numReplacements();
509}*/
510
512
513KoTextFind::KoTextFind( const TQString &pattern, long options, KoFindReplace *_findReplace, TQWidget *parent )
514 : KFind( pattern, options, parent),
515 m_findReplace( _findReplace)
516{
517}
518
519KoTextFind::~KoTextFind()
520{
521}
522
523bool KoTextFind::validateMatch( const TQString &text, int index, int matchedlength )
524{
525 return m_findReplace->validateMatch( text, index, matchedlength );
526}
527
528KoTextReplace::KoTextReplace(const TQString &pattern, const TQString &replacement, long options, KoFindReplace *_findReplace, TQWidget *parent )
529 : KReplace( pattern, replacement, options, parent),
530 m_findReplace( _findReplace)
531{
532}
533
534KoTextReplace::~KoTextReplace()
535{
536}
537
538bool KoTextReplace::validateMatch( const TQString &text, int index, int matchedlength )
539{
540 return m_findReplace->validateMatch( text, index, matchedlength );
541}
542
543KoFormatDia::KoFormatDia( TQWidget* parent, const TQString & _caption, KoSearchContext *_ctx , const char* name)
544 : KDialogBase( parent, name, true, _caption, Ok|Cancel|User1 |User2 ),
545 m_ctx(_ctx)
546{
547 TQWidget *page = new TQWidget( this );
548 setMainWidget(page);
549 setButtonText( KDialogBase::User1, i18n("Reset") );
550 setButtonText( KDialogBase::User2, i18n("Clear") );
551
552 connect( this, TQ_SIGNAL( user1Clicked() ), this, TQ_SLOT(slotReset()));
553 connect( this, TQ_SIGNAL( user2Clicked() ), this, TQ_SLOT(slotClear()));
554
555 TQGridLayout *m_grid = new TQGridLayout( page, 15, 2, 0, 6 );
556 m_checkFamily = new TQCheckBox( i18n( "Family:" ),page );
557 m_checkSize = new TQCheckBox( i18n( "Size:" ), page );
558 m_checkColor = new TQCheckBox( i18n( "Color:" ), page );
559 m_checkBgColor = new TQCheckBox( i18n( "Background color:" ), page );
560 m_checkBold = new TQCheckBox( i18n( "Bold:" ), page );
561 m_checkItalic = new TQCheckBox( i18n( "Italic:" ),page );
562 m_checkShadow = new TQCheckBox( i18n( "Shadow:" ), page );
563 m_checkWordByWord = new TQCheckBox( i18n( "Word by word:" ), page );
564
565 m_checkUnderline = new TQCheckBox( i18n( "Underline:" ), page);
566 m_underlineItem = new TQComboBox( page );
567 // This has to be the type list, not the style list (we need the "no underline" case).
568 // Of course we could even have both...
569 m_underlineItem->insertStringList( KoTextFormat::underlineTypeList() );
570 m_underlineItem->setCurrentItem( (int)m_ctx->m_underline );
571
572 m_checkStrikeOut= new TQCheckBox( i18n( "Strikeout:" ), page);
573
574 m_strikeOutItem = new TQComboBox( page );
575 m_strikeOutItem->insertStringList( KoTextFormat::strikeOutTypeList() );
576 m_strikeOutItem->setCurrentItem( (int)m_ctx->m_strikeOut );
577
578
579 m_checkFontAttribute = new TQCheckBox( i18n( "Capitalization:" ), page);
580 m_fontAttributeItem = new TQComboBox( page );
581 m_fontAttributeItem->insertStringList( KoTextFormat::fontAttributeList() );
582 m_fontAttributeItem->setCurrentItem( (int)m_ctx->m_attribute );
583
584 m_checkLanguage = new TQCheckBox( i18n( "Language:" ), page);
585 m_languageItem = new TQComboBox( page );
586 m_languageItem->insertStringList( KoGlobal::listOfLanguages() );
587 m_languageItem->setCurrentText( KoGlobal::languageFromTag( m_ctx->m_language ) );
588
589
590 m_checkVertAlign = new TQCheckBox( i18n( "Vertical alignment:" ), page );
591
592 m_familyItem = new TDEFontCombo(page);
593 m_familyItem->setCurrentFont(m_ctx->m_family);
594
595 m_sizeItem = new TQSpinBox( 4, 100, 1, page );
596 m_sizeItem->setValue( m_ctx->m_size );
597
598 m_colorItem = new KColorButton( page );
599 m_colorItem->setColor( m_ctx->m_color );
600
601 m_bgColorItem = new KColorButton( page );
602 m_bgColorItem->setColor( m_ctx->m_backGroundColor);
603
604
605
606 TQButtonGroup *grpBold = new TQButtonGroup( 1, TQt::Vertical, page );
607 grpBold->setRadioButtonExclusive( true );
608 grpBold->layout();
609 m_boldYes=new TQRadioButton( i18n("Yes"), grpBold );
610 m_boldNo=new TQRadioButton( i18n("No"), grpBold );
611
612 TQButtonGroup *grpItalic = new TQButtonGroup( 1, TQt::Vertical, page );
613 grpItalic->setRadioButtonExclusive( true );
614 grpItalic->layout();
615 m_italicYes=new TQRadioButton( i18n("Yes"), grpItalic );
616 m_italicNo=new TQRadioButton( i18n("No"), grpItalic );
617
618 TQButtonGroup *grpShadow = new TQButtonGroup( 1, TQt::Vertical, page );
619 grpShadow->setRadioButtonExclusive( true );
620 grpShadow->layout();
621 m_shadowYes=new TQRadioButton( i18n("Yes"), grpShadow );
622 m_shadowNo=new TQRadioButton( i18n("No"), grpShadow );
623
624 TQButtonGroup *grpWordByWord = new TQButtonGroup( 1, TQt::Vertical, page );
625 grpWordByWord->setRadioButtonExclusive( true );
626 grpWordByWord->layout();
627 m_wordByWordYes=new TQRadioButton( i18n("Yes"), grpWordByWord );
628 m_wordByWordNo=new TQRadioButton( i18n("No"), grpWordByWord );
629
630
631 m_vertAlignItem = new TQComboBox( false, page );
632 m_vertAlignItem->insertItem( i18n( "Normal" ), -1 );
633 m_vertAlignItem->insertItem( i18n( "Subscript" ), -1 );
634 m_vertAlignItem->insertItem( i18n( "Superscript" ), -1 );
635 m_vertAlignItem->setCurrentItem( (int)m_ctx->m_vertAlign );
636
637 m_grid->addWidget( m_checkFamily, 1, 0 );
638 m_grid->addWidget( m_checkSize, 2, 0 );
639 m_grid->addWidget( m_checkColor, 3, 0 );
640 m_grid->addWidget( m_checkBgColor, 4, 0);
641 m_grid->addWidget( m_checkBold, 5, 0 );
642 m_grid->addWidget( m_checkItalic, 6, 0 );
643 m_grid->addWidget( m_checkStrikeOut, 7, 0 );
644 m_grid->addWidget( m_checkUnderline, 8, 0 );
645 m_grid->addWidget( m_checkVertAlign, 9, 0 );
646 m_grid->addWidget( m_checkShadow, 10, 0 );
647 m_grid->addWidget( m_checkWordByWord, 11, 0 );
648 m_grid->addWidget( m_checkFontAttribute, 12, 0 );
649
650 m_grid->addWidget( m_familyItem, 1, 1 );
651 m_grid->addWidget( m_sizeItem, 2, 1 );
652 m_grid->addWidget( m_colorItem, 3, 1 );
653 m_grid->addWidget( m_bgColorItem, 4, 1);
654 m_grid->addWidget( grpBold, 5, 1 );
655 m_grid->addWidget( grpItalic, 6, 1 );
656
657 m_grid->addWidget( m_strikeOutItem, 7, 1 );
658 m_grid->addWidget( m_underlineItem, 8, 1 );
659
660 m_grid->addWidget( m_vertAlignItem, 9, 1 );
661 m_grid->addWidget( grpShadow, 10, 1 );
662 m_grid->addWidget( grpWordByWord, 11, 1 );
663
664 m_grid->addWidget( m_fontAttributeItem, 12, 1);
665
666 m_grid->addWidget( m_checkLanguage, 13, 0);
667 m_grid->addWidget( m_languageItem, 13, 1);
668
669 KSeparator *tmpSep = new KSeparator( page );
670 m_grid->addMultiCellWidget( tmpSep, 14, 14, 0, 1 );
671
672 // signals and slots connections
673 TQObject::connect( m_checkFamily, TQ_SIGNAL( toggled( bool ) ), m_familyItem, TQ_SLOT( setEnabled( bool ) ) );
674 TQObject::connect( m_checkSize, TQ_SIGNAL( toggled( bool ) ), m_sizeItem, TQ_SLOT( setEnabled( bool ) ) );
675 TQObject::connect( m_checkColor, TQ_SIGNAL( toggled( bool ) ), m_colorItem, TQ_SLOT( setEnabled( bool ) ) );
676 TQObject::connect( m_checkBgColor, TQ_SIGNAL( toggled( bool ) ), m_bgColorItem, TQ_SLOT( setEnabled( bool ) ) );
677
678 TQObject::connect( m_checkBold, TQ_SIGNAL( toggled( bool ) ), m_boldYes, TQ_SLOT( setEnabled( bool ) ) );
679 TQObject::connect( m_checkItalic, TQ_SIGNAL( toggled( bool ) ), m_italicYes, TQ_SLOT( setEnabled( bool ) ) );
680 TQObject::connect( m_checkStrikeOut, TQ_SIGNAL( toggled( bool ) ), m_strikeOutItem, TQ_SLOT( setEnabled( bool ) ) );
681 TQObject::connect( m_checkShadow, TQ_SIGNAL( toggled( bool ) ), m_shadowYes, TQ_SLOT( setEnabled( bool ) ) );
682 TQObject::connect( m_checkWordByWord, TQ_SIGNAL( toggled( bool ) ), m_wordByWordYes, TQ_SLOT( setEnabled( bool ) ) );
683 TQObject::connect( m_checkFontAttribute, TQ_SIGNAL( toggled( bool ) ), m_fontAttributeItem, TQ_SLOT( setEnabled( bool ) ) );
684 TQObject::connect( m_checkLanguage, TQ_SIGNAL( toggled( bool ) ), m_languageItem, TQ_SLOT( setEnabled( bool ) ) );
685
686
687 TQObject::connect( m_checkBold, TQ_SIGNAL( toggled( bool ) ), m_boldNo, TQ_SLOT( setEnabled( bool ) ) );
688 TQObject::connect( m_checkItalic, TQ_SIGNAL( toggled( bool ) ), m_italicNo, TQ_SLOT( setEnabled( bool ) ) );
689 TQObject::connect( m_checkShadow, TQ_SIGNAL( toggled( bool ) ), m_shadowNo, TQ_SLOT( setEnabled( bool ) ) );
690 TQObject::connect( m_checkWordByWord, TQ_SIGNAL( toggled( bool ) ), m_wordByWordNo, TQ_SLOT( setEnabled( bool ) ) );
691
692
693 TQObject::connect( m_checkVertAlign, TQ_SIGNAL( toggled( bool ) ), m_vertAlignItem, TQ_SLOT( setEnabled( bool ) ) );
694
695 TQObject::connect( m_checkUnderline, TQ_SIGNAL( toggled( bool ) ), m_underlineItem, TQ_SLOT( setEnabled( bool ) ) );
696
697 slotReset();
698}
699
700void KoFormatDia::slotClear()
701{
702 m_ctx->m_optionsMask = 0;
703 m_ctx->m_options = 0;
704 slotReset();
705}
706
707void KoFormatDia::slotReset()
708{
709 m_checkFamily->setChecked( m_ctx->m_optionsMask & KoSearchContext::Family );
710 m_familyItem->setEnabled(m_checkFamily->isChecked());
711
712 m_checkSize->setChecked( m_ctx->m_optionsMask & KoSearchContext::Size );
713 m_sizeItem->setEnabled(m_checkSize->isChecked());
714
715 m_checkColor->setChecked( m_ctx->m_optionsMask & KoSearchContext::Color );
716 m_colorItem->setEnabled(m_checkColor->isChecked());
717
718 m_checkBgColor->setChecked( m_ctx->m_optionsMask & KoSearchContext::BgColor );
719 m_bgColorItem->setEnabled(m_checkBgColor->isChecked());
720
721
722 m_checkBold->setChecked( m_ctx->m_optionsMask & KoSearchContext::Bold );
723 m_boldYes->setEnabled(m_checkBold->isChecked());
724 m_boldNo->setEnabled(m_checkBold->isChecked());
725
726 m_checkShadow->setChecked( m_ctx->m_optionsMask & KoSearchContext::Shadow );
727 m_shadowYes->setEnabled(m_checkShadow->isChecked());
728 m_shadowNo->setEnabled(m_checkShadow->isChecked());
729
730 m_checkWordByWord->setChecked( m_ctx->m_optionsMask & KoSearchContext::WordByWord );
731 m_wordByWordYes->setEnabled(m_checkWordByWord->isChecked());
732 m_wordByWordNo->setEnabled(m_checkWordByWord->isChecked());
733
734
735 m_checkStrikeOut->setChecked( m_ctx->m_optionsMask & KoSearchContext::StrikeOut );
736 m_strikeOutItem->setEnabled( m_checkStrikeOut->isChecked());
737
738
739 m_checkItalic->setChecked( m_ctx->m_optionsMask & KoSearchContext::Italic );
740 m_italicNo->setEnabled(m_checkItalic->isChecked());
741 m_italicYes->setEnabled(m_checkItalic->isChecked());
742
743 m_checkUnderline->setChecked( m_ctx->m_optionsMask & KoSearchContext::Underline );
744 m_underlineItem->setEnabled(m_checkUnderline->isChecked());
745
746 m_checkVertAlign->setChecked( m_ctx->m_optionsMask & KoSearchContext::VertAlign );
747 m_vertAlignItem->setEnabled(m_checkVertAlign->isChecked());
748
749 m_checkFontAttribute->setChecked( m_ctx->m_optionsMask & KoSearchContext::Attribute );
750 m_fontAttributeItem->setEnabled(m_checkFontAttribute->isChecked());
751
752
753 m_checkLanguage->setChecked( m_ctx->m_optionsMask & KoSearchContext::Language );
754 m_languageItem->setEnabled(m_checkLanguage->isChecked());
755
756
757 if (m_ctx->m_options & KoSearchContext::Bold)
758 m_boldYes->setChecked( true );
759 else
760 m_boldNo->setChecked( true );
761
762 if (m_ctx->m_options & KoSearchContext::Italic)
763 m_italicYes->setChecked( true );
764 else
765 m_italicNo->setChecked( true );
766
767 if (m_ctx->m_options & KoSearchContext::Shadow)
768 m_shadowYes->setChecked( true );
769 else
770 m_shadowNo->setChecked( true );
771
772 if (m_ctx->m_options & KoSearchContext::WordByWord)
773 m_wordByWordYes->setChecked( true );
774 else
775 m_wordByWordNo->setChecked( true );
776
777}
778
779void KoFormatDia::ctxOptions( )
780{
781 long optionsMask = 0;
782 long options = 0;
783 if ( m_checkFamily->isChecked() )
784 optionsMask |= KoSearchContext::Family;
785 if ( m_checkSize->isChecked() )
786 optionsMask |= KoSearchContext::Size;
787 if ( m_checkColor->isChecked() )
788 optionsMask |= KoSearchContext::Color;
789 if ( m_checkBgColor->isChecked() )
790 optionsMask |= KoSearchContext::BgColor;
791 if ( m_checkBold->isChecked() )
792 optionsMask |= KoSearchContext::Bold;
793 if ( m_checkItalic->isChecked() )
794 optionsMask |= KoSearchContext::Italic;
795 if ( m_checkUnderline->isChecked() )
796 optionsMask |= KoSearchContext::Underline;
797 if ( m_checkVertAlign->isChecked() )
798 optionsMask |= KoSearchContext::VertAlign;
799 if ( m_checkStrikeOut->isChecked() )
800 optionsMask |= KoSearchContext::StrikeOut;
801 if ( m_checkShadow->isChecked() )
802 optionsMask |= KoSearchContext::Shadow;
803 if ( m_checkWordByWord->isChecked() )
804 optionsMask |= KoSearchContext::WordByWord;
805 if ( m_checkLanguage->isChecked() )
806 optionsMask |= KoSearchContext::Language;
807
808
809 if ( m_boldYes->isChecked() )
810 options |= KoSearchContext::Bold;
811 if ( m_italicYes->isChecked() )
812 options |= KoSearchContext::Italic;
813 if ( m_shadowYes->isChecked() )
814 options |= KoSearchContext::Shadow;
815 if ( m_wordByWordYes->isChecked() )
816 options |= KoSearchContext::WordByWord;
817
818
819 m_ctx->m_optionsMask = optionsMask;
820 m_ctx->m_family = m_familyItem->currentText();
821 m_ctx->m_size = m_sizeItem->cleanText().toInt();
822 m_ctx->m_color = m_colorItem->color();
823 m_ctx->m_backGroundColor = m_bgColorItem->color();
824 m_ctx->m_vertAlign = (KoTextFormat::VerticalAlignment)m_vertAlignItem->currentItem();
825 m_ctx->m_underline = (KoTextFormat::UnderlineType)m_underlineItem->currentItem();
826 m_ctx->m_strikeOut = (KoTextFormat::StrikeOutType)m_strikeOutItem->currentItem();
827 m_ctx->m_attribute = (KoTextFormat::AttributeStyle)m_fontAttributeItem->currentItem();
828 m_ctx->m_language = KoGlobal::listTagOfLanguages()[m_languageItem->currentItem()];
829
830 m_ctx->m_options = options;
831}
832
833
834bool KoFindReplace::validateMatch( const TQString & /*text*/, int index, int matchedlength )
835{
836 if ( !m_searchContextEnabled || !m_searchContext.m_optionsMask )
837 return true;
838 KoTextString * s = currentParag()->string();
839 for ( int i = index ; i < index+matchedlength ; ++i )
840 {
841 KoTextStringChar & ch = s->at(i);
842 KoTextFormat *format = ch.format();
843 if (m_searchContext.m_optionsMask & KoSearchContext::Bold)
844 {
845 if ( (!format->font().bold() && (m_searchContext.m_options & KoSearchContext::Bold)) || (format->font().bold() && ((m_searchContext.m_options & KoSearchContext::Bold)==0)))
846 return false;
847 }
848 if (m_searchContext.m_optionsMask & KoSearchContext::Shadow)
849 {
850 bool hasShadow = format->shadowDistanceX() != 0 || format->shadowDistanceY() != 0;
851 if ( (!hasShadow && (m_searchContext.m_options & KoSearchContext::Shadow))
852 || (hasShadow && ((m_searchContext.m_options & KoSearchContext::Shadow)==0)) )
853 return false;
854 }
855
856 if (m_searchContext.m_optionsMask & KoSearchContext::WordByWord)
857 {
858 if ( (!format->wordByWord() && (m_searchContext.m_options & KoSearchContext::WordByWord)) || (format->wordByWord() && ((m_searchContext.m_options & KoSearchContext::WordByWord)==0)))
859 return false;
860 }
861
862
863 if (m_searchContext.m_optionsMask & KoSearchContext::Size)
864 {
865 if ( format->font().pointSize() != m_searchContext.m_size )
866 return false;
867 }
868 if ( m_searchContext.m_optionsMask & KoSearchContext::Family)
869 {
870 if (format->font().family() != m_searchContext.m_family)
871 return false;
872 }
873 if ( m_searchContext.m_optionsMask & KoSearchContext::Color)
874 {
875 if (format->color() != m_searchContext.m_color)
876 return false;
877 }
878 if ( m_searchContext.m_optionsMask & KoSearchContext::BgColor)
879 {
880 if (format->textBackgroundColor() != m_searchContext.m_backGroundColor)
881 return false;
882 }
883
884 if ( m_searchContext.m_optionsMask & KoSearchContext::Italic)
885 {
886 if ( (!format->font().italic() && (m_searchContext.m_options & KoSearchContext::Italic)) || (format->font().italic() && ((m_searchContext.m_options & KoSearchContext::Italic)==0)))
887 return false;
888
889 }
890 if ( m_searchContext.m_optionsMask & KoSearchContext::Underline)
891 {
892 if ( format->underlineType() != m_searchContext.m_underline )
893 return false;
894 }
895 if ( m_searchContext.m_optionsMask & KoSearchContext::StrikeOut)
896 {
897 if ( format->strikeOutType() != m_searchContext.m_strikeOut )
898 return false;
899 }
900
901 if ( m_searchContext.m_optionsMask & KoSearchContext::VertAlign)
902 {
903 if ( format->vAlign() != m_searchContext.m_vertAlign )
904 return false;
905 }
906 if ( m_searchContext.m_optionsMask & KoSearchContext::Language)
907 {
908 if ( format->language() != m_searchContext.m_language )
909 return false;
910 }
911
912 if ( m_searchContext.m_optionsMask & KoSearchContext::Attribute)
913 {
914 if ( format->attributeFont() != m_searchContext.m_attribute )
915 return false;
916 }
917
918 }
919 return true;
920}
921
922bool KoFindReplace::shouldRestart()
923{
924 if ( m_find )
925 return m_find->shouldRestart( true /*since text is editable*/, m_doCounting );
926 else
927 return m_replace->shouldRestart( true /*since text is editable*/, m_doCounting );
928}
929
930#include "KoSearchDia.moc"
This class implements the 'find' functionality ( the "search next, prompt" loop ) and the 'replace' f...
bool validateMatch(const TQString &text, int index, int matchedlength)
For KoTextFind and KoTextReplace.
bool findPrevious()
Look for the previous match.
bool findNext()
Look for the next match.
virtual void highlightPortion(KoTextParag *parag, int index, int length, KoTextDocument *textdoc, KDialogBase *dialog)=0
Highlight a match.
void setActiveWindow()
Bring to front (e.g.
void emitUndoRedo()
Emit undo/redo command for the last replacements made.
Reimplement KFind to provide our own validateMatch - for the formatting options.
Each character (KoTextStringChar) points to a KoTextFormat that defines the formatting of that charac...
@ DoNotRepaint
usually we repaint in insert(), this allows to turn it off
KoTextDocument * textDocument() const
Return the text document contained in this KoTextObject.
Reimplement KoReplace to provide our own validateMatch - for the formatting options.
Object that is created to edit a KoTextObject.
Definition KoTextView.h:54
TDEAction * replace(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)
TDEAction * find(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)
const char * name(StdAction id)