00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "krichtexteditpart.h"
00021
00022
00023 #include <QtCore/QEvent>
00024 #include <QKeyEvent>
00025 #include <QtGui/QTextCursor>
00026 #include <QtGui/QTextCharFormat>
00027
00028
00029 #include <kaction.h>
00030 #include <kactionmenu.h>
00031 #include <kcolordialog.h>
00032 #include <kconfig.h>
00033 #include <kdebug.h>
00034 #include <kfontaction.h>
00035 #include <kfontdialog.h>
00036 #include <kfontsizeaction.h>
00037 #include <kglobalsettings.h>
00038 #include <kcolorscheme.h>
00039 #include <kicon.h>
00040 #include <kparts/genericfactory.h>
00041 #include <kstandardaction.h>
00042 #include <ktextedit.h>
00043 #include <ktoggleaction.h>
00044 #include <kactioncollection.h>
00045
00046 typedef KParts::GenericFactory<KRichTextEditPart> KRichTextEditPartFactory;
00047 K_EXPORT_COMPONENT_FACTORY( librichtexteditpart, KRichTextEditPartFactory )
00048
00049
00050 class KopeteTextEdit : public KTextEdit
00051 {
00052 public:
00053 KopeteTextEdit( QWidget *parent )
00054 : KTextEdit( parent )
00055 {}
00056
00057 bool event(QEvent *event)
00058 {
00059 if ( event->type() == QEvent::ShortcutOverride )
00060 {
00061 QKeyEvent *keyEvent = dynamic_cast<QKeyEvent*>(event);
00062 if (keyEvent)
00063 {
00064 if( keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter )
00065 {
00066
00067
00068 return QWidget::event(event);
00069 }
00070 if ( keyEvent->matches(QKeySequence::Copy) && !textCursor().hasSelection() )
00071 {
00072
00073
00074
00075
00076 return QWidget::event(event);
00077 }
00078 }
00079 }
00080 return KTextEdit::event(event);
00081 }
00082 };
00083
00084 class KRichTextEditPart::Private
00085 {
00086 public:
00087 Private()
00088 : editor(0), richTextEnabled(false), richTextSupport(KRichTextEditPart::DisableRichText),
00089 configDirty(false), usingDefault(true), defualtFont(KGlobalSettings::generalFont()),
00090 updating(false)
00091 {}
00092
00093 KopeteTextEdit *editor;
00094 bool richTextEnabled;
00095 RichTextSupport richTextSupport;
00096
00097 KAction *checkSpelling;
00098 KToggleAction *enableRichText;
00099
00100 KAction *actionTextColor;
00101
00102 bool configDirty;
00103 bool usingDefault;
00104 QColor defualtTextColor;
00105 QFont defualtFont;
00106 QColor desiredTextColor;
00107 QFont desiredFont;
00108
00109 KToggleAction *action_bold;
00110 KToggleAction *action_italic;
00111 KToggleAction *action_underline;
00112
00113 KFontAction *action_font;
00114 KFontSizeAction *action_font_size;
00115
00116 KToggleAction *action_align_left;
00117 KToggleAction *action_align_right;
00118 KToggleAction *action_align_center;
00119 KToggleAction *action_align_justify;
00120
00121 bool updating;
00122 };
00123
00124 KRichTextEditPart::KRichTextEditPart(QWidget *wparent, QObject*, const QStringList&)
00125 : KParts::ReadOnlyPart( wparent ), d(new Private)
00126 {
00127
00128 setComponentData( KRichTextEditPartFactory::componentData() );
00129
00130 d->editor = new KopeteTextEdit( wparent );
00131 setWidget( d->editor );
00132
00133
00134 createActions();
00135
00136
00137 setXMLFile( "kopeterichtexteditpart/kopeterichtexteditpartfull.rc" );
00138 }
00139
00140 KRichTextEditPart::~KRichTextEditPart()
00141 {
00142 delete d;
00143 }
00144
00145 KTextEdit *KRichTextEditPart::textEdit()
00146 {
00147 return static_cast<KTextEdit*>(d->editor);
00148 }
00149
00150 QFont KRichTextEditPart::font() const
00151 {
00152 return d->editor->currentFont();
00153 }
00154
00155 void KRichTextEditPart::clear()
00156 {
00157 d->editor->clear();
00158 }
00159
00160 bool KRichTextEditPart::isRichTextEnabled() const
00161 {
00162 return d->richTextEnabled;
00163 }
00164
00165 bool KRichTextEditPart::isRichTextAvailable() const
00166 {
00167 return (d->richTextSupport & FormattingSupport ||
00168 d->richTextSupport & SupportAlignment ||
00169 d->richTextSupport & SupportFont ||
00170 d->richTextSupport & SupportTextColor);
00171 }
00172
00173 void KRichTextEditPart::setDefualtFont( const QFont& font )
00174 {
00175 d->defualtFont = font;
00176 if ( d->usingDefault && !d->configDirty )
00177 {
00178 d->desiredFont = d->defualtFont;
00179 updateCharFormat();
00180 }
00181 }
00182
00183 void KRichTextEditPart::setDefualtTextColor( const QColor& textColor )
00184 {
00185 d->defualtTextColor = textColor;
00186 if ( d->usingDefault && !d->configDirty )
00187 {
00188 d->desiredTextColor = d->defualtTextColor;
00189 updateCharFormat();
00190 }
00191 }
00192
00193 void KRichTextEditPart::setCheckSpellingEnabled( bool enabled )
00194 {
00195 d->editor->setCheckSpellingEnabled( enabled );
00196 }
00197
00198 bool KRichTextEditPart::checkSpellingEnabled() const
00199 {
00200 return d->editor->checkSpellingEnabled();
00201 }
00202
00203 bool KRichTextEditPart::useRichText() const
00204 {
00205 return isRichTextEnabled() && isRichTextAvailable();
00206 }
00207
00208 void KRichTextEditPart::setRichTextEnabled( bool enable )
00209 {
00210 d->richTextEnabled = enable;
00211 d->editor->setAcceptRichText( useRichText() );
00212
00213
00214 checkToolbarEnabled();
00215
00216
00217 updateActions();
00218
00219 d->enableRichText->setEnabled( useRichText() );
00220 d->enableRichText->setChecked( useRichText() );
00221
00222 emit richTextChanged();
00223 }
00224
00225 void KRichTextEditPart::setRichTextSupport(const KRichTextEditPart::RichTextSupport &support)
00226 {
00227 d->richTextSupport = support;
00228
00229
00230 setRichTextEnabled( isRichTextEnabled() );
00231 }
00232
00233 void KRichTextEditPart::checkToolbarEnabled()
00234 {
00235 emit toolbarToggled( useRichText() );
00236 }
00237
00238 KAboutData *KRichTextEditPart::createAboutData()
00239 {
00240 KAboutData *aboutData = new KAboutData("krichtexteditpart", 0, ki18n("KRichTextEditPart"), "0.1",
00241 ki18n("A simple rich text editor part"),
00242 KAboutData::License_LGPL );
00243 aboutData->addAuthor(ki18n("Richard J. Moore"), KLocalizedString(), "rich@kde.org", "http://xmelegance.org/" );
00244 aboutData->addAuthor(ki18n("Jason Keirstead"), KLocalizedString(), "jason@keirstead.org", "http://www.keirstead.org/" );
00245 aboutData->addAuthor(ki18n("Michaël Larouche"), KLocalizedString(), "larouche@kde.org" "http://www.tehbisnatch.org/" );
00246
00247 return aboutData;
00248 }
00249
00250 void KRichTextEditPart::createActions()
00251 {
00252 d->enableRichText = new KToggleAction( KIcon("draw-freehand"), i18n("Enable &Rich Text"), this );
00253 actionCollection()->addAction( "enableRichText", d->enableRichText );
00254 d->enableRichText->setCheckedState( KGuiItem( i18n("Disable &Rich Text") ) );
00255 connect( d->enableRichText, SIGNAL(toggled(bool)),
00256 this, SLOT(setRichTextEnabled(bool)) );
00257
00258 d->checkSpelling = new KAction( KIcon("tools-check-spelling"), i18n("Check &Spelling"), actionCollection() );
00259 actionCollection()->addAction( "check_spelling", d->checkSpelling );
00260 connect( d->checkSpelling, SIGNAL(triggered(bool)), d->editor, SLOT(checkSpelling()) );
00261
00262
00263 d->actionTextColor = new KAction( KIcon("color_line"), i18n("Text &Color..."), actionCollection() );
00264 actionCollection()->addAction( "format_textcolor", d->actionTextColor );
00265 connect( d->actionTextColor, SIGNAL(triggered(bool)), this, SLOT(setTextColor()) );
00266
00267
00268 d->action_font = new KFontAction( i18n("&Font"), actionCollection() );
00269 actionCollection()->addAction( "format_font", d->action_font );
00270 connect( d->action_font, SIGNAL(triggered(QString)), this, SLOT(setFont(QString)) );
00271
00272
00273 d->action_font_size = new KFontSizeAction( i18n("Font &Size"), actionCollection() );
00274 actionCollection()->addAction( "format_font_size", d->action_font_size );
00275 connect( d->action_font_size, SIGNAL(fontSizeChanged(int)), this, SLOT( setFontSize(int) ) );
00276
00277
00278 d->action_bold = new KToggleAction( KIcon("format-text-bold"), i18n("&Bold"), actionCollection() );
00279 actionCollection()->addAction( "format_bold", d->action_bold );
00280 d->action_bold->setShortcut( KShortcut(Qt::CTRL + Qt::Key_B) );
00281 connect( d->action_bold, SIGNAL(toggled(bool)), this, SLOT(setFontBold(bool)) );
00282
00283 d->action_italic = new KToggleAction( KIcon("format-text-italic"), i18n("&Italic"), actionCollection() );
00284 actionCollection()->addAction( "format_italic", d->action_italic );
00285 d->action_italic->setShortcut( KShortcut(Qt::CTRL + Qt::Key_I) );
00286 connect(d->action_italic, SIGNAL(toggled(bool)),
00287 this, SLOT(setFontItalic(bool)) );
00288
00289 d->action_underline = new KToggleAction( KIcon("format-text-underline"), i18n("&Underline"), actionCollection() );
00290 actionCollection()->addAction( "format_underline", d->action_underline );
00291 d->action_underline->setShortcut( KShortcut(Qt::CTRL + Qt::Key_U) );
00292 connect( d->action_underline, SIGNAL(toggled(bool)),
00293 this, SLOT(setFontUnderline(bool)) );
00294
00295
00296 connect( d->editor, SIGNAL(currentCharFormatChanged(QTextCharFormat)),
00297 this, SLOT( updateCharFormat() ) );
00298 updateCharFormat();
00299
00300
00301 d->action_align_left = new KToggleAction( KIcon("text-left"), i18n("Align &Left"), actionCollection() );
00302 actionCollection()->addAction( "format_align_left", d->action_align_left );
00303 connect( d->action_align_left, SIGNAL(toggled(bool)),
00304 this, SLOT(setAlignLeft(bool)) );
00305
00306 d->action_align_center = new KToggleAction( KIcon("text-center"), i18n("Align &Center"), actionCollection() );
00307 actionCollection()->addAction( "format_align_center", d->action_align_center );
00308 connect( d->action_align_center, SIGNAL(toggled(bool)),
00309 this, SLOT(setAlignCenter(bool)) );
00310
00311 d->action_align_right = new KToggleAction( KIcon("text-right"), i18n("Align &Right"), actionCollection() );
00312 actionCollection()->addAction( "format_align_right", d->action_align_right );
00313 connect( d->action_align_right, SIGNAL(toggled(bool)),
00314 this, SLOT(setAlignRight(bool)) );
00315
00316 d->action_align_justify = new KToggleAction( KIcon("format-justify-fill"), i18n("&Justify"), actionCollection() );
00317 actionCollection()->addAction( "format_align_justify", d->action_align_justify );
00318 connect( d->action_align_justify, SIGNAL(toggled(bool)),
00319 this, SLOT(setAlignJustify(bool)) );
00320
00321 QActionGroup *alignmentGroup = new QActionGroup(this);
00322 alignmentGroup->addAction(d->action_align_left);
00323 alignmentGroup->addAction(d->action_align_center);
00324 alignmentGroup->addAction(d->action_align_right);
00325 alignmentGroup->addAction(d->action_align_justify);
00326
00327 connect( d->editor, SIGNAL(cursorPositionChanged()),
00328 this, SLOT(updateAligment()) );
00329
00330 updateAligment();
00331 }
00332
00333 void KRichTextEditPart::updateActions()
00334 {
00335 bool useRichText = this->useRichText();
00336
00337 bool activateAlignment = useRichText && ( d->richTextSupport & KRichTextEditPart::SupportAlignment );
00338 bool activateFont = (d->richTextSupport & KRichTextEditPart::SupportFont);
00339
00340 d->actionTextColor->setEnabled( useRichText && (d->richTextSupport & KRichTextEditPart::SupportTextColor) );
00341
00342 d->action_font->setEnabled( useRichText && activateFont);
00343 d->action_font_size->setEnabled( useRichText && activateFont );
00344
00345 d->action_bold->setEnabled( useRichText && (d->richTextSupport & KRichTextEditPart::SupportBold) );
00346 d->action_italic->setEnabled( useRichText && (d->richTextSupport & KRichTextEditPart::SupportItalic) );
00347 d->action_underline->setEnabled( useRichText && (d->richTextSupport & KRichTextEditPart::SupportUnderline) );
00348
00349 d->action_align_left->setEnabled( activateAlignment );
00350 d->action_align_center->setEnabled( activateAlignment );
00351 d->action_align_right->setEnabled( activateAlignment );
00352 d->action_align_justify->setEnabled( activateAlignment );
00353 }
00354
00355 void KRichTextEditPart::updateCharFormat()
00356 {
00357 d->updating = true;
00358 if( d->editor->fontPointSize() > 0 )
00359 d->action_font_size->setFontSize( (int)d->editor->fontPointSize() );
00360 d->action_font->setFont( d->editor->fontFamily() );
00361
00362
00363 d->editor->setTextColor( d->desiredTextColor );
00364 if( useRichText() )
00365 {
00366 d->editor->setCurrentFont( d->desiredFont );
00367 d->action_bold->setChecked( d->desiredFont.bold() );
00368 d->action_italic->setChecked( d->desiredFont.italic() );
00369 d->action_underline->setChecked( d->desiredFont.underline() );
00370 }
00371 d->updating = false;
00372 }
00373
00374 void KRichTextEditPart::updateAligment()
00375 {
00376 Qt::Alignment align = d->editor->alignment();
00377
00378 switch ( align )
00379 {
00380 case Qt::AlignRight:
00381 d->action_align_right->setChecked( true );
00382 break;
00383 case Qt::AlignCenter:
00384 d->action_align_center->setChecked( true );
00385 break;
00386 case Qt::AlignLeft:
00387 d->action_align_left->setChecked( true );
00388 break;
00389 case Qt::AlignJustify:
00390 d->action_align_justify->setChecked( true );
00391 break;
00392 default:
00393 break;
00394 }
00395 }
00396
00397 void KRichTextEditPart::readConfig( KConfigGroup& config )
00398 {
00399 kDebug() << "Loading config";
00400
00401 d->usingDefault = ( !config.hasKey("TextColor") && !config.hasKey("Font") );
00402 d->desiredTextColor = config.readEntry( "TextColor", d->defualtTextColor );
00403 d->desiredFont = config.readEntry("Font", d->defualtFont );
00404 updateCharFormat();
00405
00406 switch( config.readEntry( "EditAlignment", int(Qt::AlignLeft) ) )
00407 {
00408 case Qt::AlignLeft:
00409 d->action_align_left->trigger();
00410 break;
00411 case Qt::AlignCenter:
00412 d->action_align_center->trigger();
00413 break;
00414 case Qt::AlignRight:
00415 d->action_align_right->trigger();
00416 break;
00417 case Qt::AlignJustify:
00418 d->action_align_justify->trigger();
00419 break;
00420 }
00421
00422
00423 d->configDirty = false;
00424 }
00425
00426 void KRichTextEditPart::writeConfig( KConfigGroup& config )
00427 {
00428 if ( d->configDirty == false )
00429 return;
00430
00431 kDebug() << "Saving config";
00432
00433 QFont currentFont = d->editor->currentFont();
00434 config.writeEntry( "Font", currentFont );
00435 config.writeEntry( "TextColor", d->editor->textColor() );
00436 config.writeEntry( "EditAlignment", int(d->editor->alignment()) );
00437 d->usingDefault = false;
00438
00439
00440 d->configDirty = false;
00441 }
00442
00443 void KRichTextEditPart::resetConfig( KConfigGroup& config )
00444 {
00445 kDebug() << "Setting default font style";
00446
00447 d->desiredTextColor = d->defualtTextColor;
00448 d->desiredFont = d->defualtFont;
00449 updateCharFormat();
00450
00451 d->action_align_left->trigger();
00452
00453 config.deleteEntry( "Font" );
00454 config.deleteEntry( "TextColor" );
00455 config.deleteEntry( "EditAlignment" );
00456
00457 d->usingDefault = true;
00458
00459 d->configDirty = false;
00460 }
00461
00462 void KRichTextEditPart::setTextColor()
00463 {
00464 QColor currentTextColor = d->desiredTextColor;
00465
00466 int result = KColorDialog::getColor( currentTextColor, KColorScheme(QPalette::Active, KColorScheme::View).foreground().color() , d->editor );
00467 if(!currentTextColor.isValid())
00468 currentTextColor = KColorScheme(QPalette::Active, KColorScheme::View).foreground().color() ;
00469 if ( result != QDialog::Accepted )
00470 return;
00471
00472 setTextColor( currentTextColor );
00473 }
00474
00475 void KRichTextEditPart::setTextColor(const QColor &newColor)
00476 {
00477 if( !d->updating && d->richTextSupport & KRichTextEditPart::SupportTextColor )
00478 {
00479 d->desiredTextColor = newColor;
00480 d->configDirty = true;
00481 updateCharFormat();
00482 }
00483 }
00484
00485 QColor KRichTextEditPart::textColor() const
00486 {
00487 if( d->editor->textColor() == KColorScheme(QPalette::Active, KColorScheme::View).foreground().color() )
00488 return QColor();
00489 return d->editor->textColor();
00490 }
00491
00492 void KRichTextEditPart::setFontSize(int size)
00493 {
00494 if( size < 1 )
00495 return;
00496
00497 if( !d->updating && d->richTextSupport & KRichTextEditPart::SupportFont )
00498 {
00499 d->desiredFont.setPointSize( size );
00500 d->configDirty = true;
00501 updateCharFormat();
00502 }
00503 }
00504
00505 void KRichTextEditPart::setFont()
00506 {
00507 QFont currentFont = d->desiredFont;
00508 KFontDialog::getFont( currentFont, false, d->editor );
00509 setFont( currentFont );
00510 }
00511
00512 void KRichTextEditPart::setFont(const QFont &newFont)
00513 {
00514 if( !d->updating && useRichText() )
00515 {
00516 d->desiredFont = newFont;
00517 d->configDirty = true;
00518 updateCharFormat();
00519 }
00520 }
00521
00522 void KRichTextEditPart::setFont(const QString &newFont)
00523 {
00524 if( !d->updating && (d->richTextSupport & KRichTextEditPart::SupportFont) && useRichText() )
00525 {
00526 d->desiredFont.setFamily( newFont );
00527 d->configDirty = true;
00528 updateCharFormat();
00529 }
00530 }
00531
00532
00533 void KRichTextEditPart::setFontBold(bool value)
00534 {
00535 if( !d->updating && (d->richTextSupport & KRichTextEditPart::SupportFont) && useRichText() )
00536 {
00537 d->desiredFont.setBold( value );
00538 d->configDirty = true;
00539 updateCharFormat();
00540 }
00541 }
00542
00543 void KRichTextEditPart::setFontItalic(bool value)
00544 {
00545 if( !d->updating && (d->richTextSupport & KRichTextEditPart::SupportItalic) && useRichText() )
00546 {
00547 d->desiredFont.setItalic( value );
00548 d->configDirty = true;
00549 updateCharFormat();
00550 }
00551 }
00552
00553 void KRichTextEditPart::setFontUnderline(bool value)
00554 {
00555 if( !d->updating && (d->richTextSupport & KRichTextEditPart::SupportUnderline) && useRichText() )
00556 {
00557 d->desiredFont.setUnderline( value );
00558 d->configDirty = true;
00559 updateCharFormat();
00560 }
00561 }
00562
00563
00564 void KRichTextEditPart::setAlignLeft( bool yes )
00565 {
00566 if( !d->updating && yes && useRichText() && (d->richTextSupport & KRichTextEditPart::SupportAlignment) )
00567 {
00568 d->editor->setAlignment( Qt::AlignLeft );
00569 d->configDirty = true;
00570 }
00571 }
00572
00573 void KRichTextEditPart::setAlignRight( bool yes )
00574 {
00575 if( !d->updating && yes && useRichText() && (d->richTextSupport & KRichTextEditPart::SupportAlignment) )
00576 {
00577 d->editor->setAlignment( Qt::AlignRight );
00578 d->configDirty = true;
00579 }
00580 }
00581
00582 void KRichTextEditPart::setAlignCenter( bool yes )
00583 {
00584 if( !d->updating && yes && useRichText() && (d->richTextSupport & KRichTextEditPart::SupportAlignment) )
00585 {
00586 d->editor->setAlignment( Qt::AlignCenter );
00587 d->configDirty = true;
00588 }
00589 }
00590
00591 void KRichTextEditPart::setAlignJustify( bool yes )
00592 {
00593 if( !d->updating && yes && useRichText() && (d->richTextSupport & KRichTextEditPart::SupportAlignment) )
00594 {
00595 d->editor->setAlignment( Qt::AlignJustify );
00596 d->configDirty = true;
00597 }
00598 }
00599
00600 QString KRichTextEditPart::text( Qt::TextFormat format ) const
00601 {
00602 if( (format == Qt::RichText || format == Qt::AutoText) && useRichText() )
00603 return d->editor->toHtml();
00604 else
00605 return d->editor->toPlainText();
00606 }
00607
00608 #include "krichtexteditpart.moc"
00609
00610