34 #include <QtGui/QTextList>
45 class KRichTextWidget::Private
51 richTextEnabled(false),
53 action_text_foreground_color(0),
54 action_text_background_color(0),
56 action_text_italic(0),
57 action_text_underline(0),
58 action_text_strikeout(0),
59 action_font_family(0),
62 action_list_indent(0),
63 action_list_dedent(0),
64 action_manage_link(0),
65 action_insert_horizontal_rule(0),
66 action_format_painter(0),
67 action_to_plain_text(0),
69 action_align_right(0),
70 action_align_center(0),
71 action_align_justify(0),
72 action_direction_ltr(0),
73 action_direction_rtl(0),
74 action_text_superscript(0),
75 action_text_subscript(0)
83 QTextCharFormat painterFormat;
86 QList<KAction*> richTextActionList;
91 KAction *action_text_foreground_color;
92 KAction *action_text_background_color;
107 KAction *action_insert_horizontal_rule;
108 KAction *action_format_painter;
134 void _k_setTextForegroundColor();
139 void _k_setTextBackgroundColor();
148 void _k_manageLink();
155 void _k_formatPainter(
bool active);
160 void _k_updateCharFormatActions(
const QTextCharFormat &format);
166 void _k_updateMiscActions();
171 void _k_setListStyle(
int index);
176 void KRichTextWidget::Private::init()
202 return d->richTextSupport;
207 d->richTextSupport = support;
212 Q_ASSERT(actionCollection);
228 d->richTextActionList.clear();
232 d->action_text_foreground_color =
new KAction(
KIcon(
"format-stroke-color"),
i18nc(
"@action",
"Text &Color..."), actionCollection);
233 d->action_text_foreground_color->setIconText(
i18nc(
"@label stroke color",
"Color"));
234 d->richTextActionList.append((d->action_text_foreground_color));
235 actionCollection->
addAction(
"format_text_foreground_color", d->action_text_foreground_color);
236 connect(d->action_text_foreground_color, SIGNAL(triggered()),
this, SLOT(_k_setTextForegroundColor()));
238 actionCollection->
removeAction(d->action_text_foreground_color);
239 d->action_text_foreground_color = 0;
244 d->action_text_background_color =
new KAction(
KIcon(
"format-fill-color"),
i18nc(
"@action",
"Text &Highlight..."), actionCollection);
245 d->richTextActionList.append((d->action_text_background_color));
246 actionCollection->
addAction(
"format_text_background_color", d->action_text_background_color);
247 connect(d->action_text_background_color, SIGNAL(triggered()),
this, SLOT(_k_setTextBackgroundColor()));
249 actionCollection->
removeAction(d->action_text_background_color);
250 d->action_text_background_color = 0;
255 d->action_font_family =
new KFontAction(
i18nc(
"@action",
"&Font"), actionCollection);
256 d->richTextActionList.append((d->action_font_family));
257 actionCollection->
addAction(
"format_font_family", d->action_font_family);
261 d->action_font_family = 0;
267 d->richTextActionList.append((d->action_font_size));
268 actionCollection->
addAction(
"format_font_size", d->action_font_size);
269 connect(d->action_font_size, SIGNAL(fontSizeChanged(
int)),
this, SLOT(
setFontSize(
int)));
272 d->action_font_size = 0;
276 d->action_text_bold =
new KToggleAction(
KIcon(
"format-text-bold"),
i18nc(
"@action boldify selected text",
"&Bold"), actionCollection);
279 d->action_text_bold->setFont(bold);
280 d->richTextActionList.append((d->action_text_bold));
281 actionCollection->
addAction(
"format_text_bold", d->action_text_bold);
283 connect(d->action_text_bold, SIGNAL(triggered(
bool)),
this, SLOT(
setTextBold(
bool)));
286 d->action_text_bold = 0;
290 d->action_text_italic =
new KToggleAction(
KIcon(
"format-text-italic"),
i18nc(
"@action italicize selected text",
"&Italic"), actionCollection);
292 italic.setItalic(
true);
293 d->action_text_italic->setFont(italic);
294 d->richTextActionList.append((d->action_text_italic));
295 actionCollection->
addAction(
"format_text_italic", d->action_text_italic);
297 connect(d->action_text_italic, SIGNAL(triggered(
bool)),
301 d->action_text_italic = 0;
305 d->action_text_underline =
new KToggleAction(
KIcon(
"format-text-underline"),
i18nc(
"@action underline selected text",
"&Underline"), actionCollection);
307 underline.setUnderline(
true);
308 d->action_text_underline->setFont(underline);
309 d->richTextActionList.append((d->action_text_underline));
310 actionCollection->
addAction(
"format_text_underline", d->action_text_underline);
312 connect(d->action_text_underline, SIGNAL(triggered(
bool)),
315 actionCollection->
removeAction(d->action_text_underline);
316 d->action_text_underline = 0;
320 d->action_text_strikeout =
new KToggleAction(
KIcon(
"format-text-strikethrough"),
i18nc(
"@action",
"&Strike Out"), actionCollection);
321 d->richTextActionList.append((d->action_text_strikeout));
322 actionCollection->
addAction(
"format_text_strikeout", d->action_text_strikeout);
324 connect(d->action_text_strikeout, SIGNAL(triggered(
bool)),
327 actionCollection->
removeAction(d->action_text_strikeout);
328 d->action_text_strikeout = 0;
333 d->action_align_left =
new KToggleAction(
KIcon(
"format-justify-left"),
i18nc(
"@action",
"Align &Left"), actionCollection);
334 d->action_align_left->setIconText(
i18nc(
"@label left justify",
"Left"));
335 d->richTextActionList.append((d->action_align_left));
336 actionCollection->
addAction(
"format_align_left", d->action_align_left);
337 connect(d->action_align_left, SIGNAL(triggered()),
340 d->action_align_center =
new KToggleAction(
KIcon(
"format-justify-center"),
i18nc(
"@action",
"Align &Center"), actionCollection);
341 d->action_align_center->setIconText(
i18nc(
"@label center justify",
"Center"));
342 d->richTextActionList.append((d->action_align_center));
343 actionCollection->
addAction(
"format_align_center", d->action_align_center);
344 connect(d->action_align_center, SIGNAL(triggered()),
347 d->action_align_right =
new KToggleAction(
KIcon(
"format-justify-right"),
i18nc(
"@action",
"Align &Right"), actionCollection);
348 d->action_align_right->setIconText(
i18nc(
"@label right justify",
"Right"));
349 d->richTextActionList.append((d->action_align_right));
350 actionCollection->
addAction(
"format_align_right", d->action_align_right);
351 connect(d->action_align_right, SIGNAL(triggered()),
354 d->action_align_justify =
new KToggleAction(
KIcon(
"format-justify-fill"),
i18nc(
"@action",
"&Justify"), actionCollection);
355 d->action_align_justify->setIconText(
i18nc(
"@label justify fill",
"Justify"));
356 d->richTextActionList.append((d->action_align_justify));
357 actionCollection->
addAction(
"format_align_justify", d->action_align_justify);
358 connect(d->action_align_justify, SIGNAL(triggered()),
361 QActionGroup *alignmentGroup =
new QActionGroup(
this);
362 alignmentGroup->addAction(d->action_align_left);
363 alignmentGroup->addAction(d->action_align_center);
364 alignmentGroup->addAction(d->action_align_right);
365 alignmentGroup->addAction(d->action_align_justify);
371 actionCollection->
removeAction(d->action_align_justify);
373 d->action_align_left = 0;
374 d->action_align_center = 0;
375 d->action_align_right = 0;
376 d->action_align_justify = 0;
380 d->action_direction_ltr =
new KToggleAction(
KIcon(
"format-text-direction-ltr"),
i18nc(
"@action",
"Left-to-Right"), actionCollection);
381 d->action_direction_ltr->setIconText(
i18nc(
"@label left-to-right",
"Left-to-Right"));
382 d->richTextActionList.append(d->action_direction_ltr);
383 actionCollection->
addAction(
"direction_ltr", d->action_direction_ltr);
384 connect(d->action_direction_ltr, SIGNAL(triggered()),
387 d->action_direction_rtl =
new KToggleAction(
KIcon(
"format-text-direction-rtl"),
i18nc(
"@action",
"Right-to-Left"), actionCollection);
388 d->action_direction_rtl->setIconText(
i18nc(
"@label right-to-left",
"Right-to-Left"));
389 d->richTextActionList.append(d->action_direction_rtl);
390 actionCollection->
addAction(
"direction_rtl", d->action_direction_rtl);
391 connect(d->action_direction_rtl, SIGNAL(triggered()),
394 QActionGroup *directionGroup =
new QActionGroup(
this);
395 directionGroup->addAction(d->action_direction_ltr);
396 directionGroup->addAction(d->action_direction_rtl);
398 actionCollection->
removeAction(d->action_direction_ltr);
399 actionCollection->
removeAction(d->action_direction_rtl);
401 d->action_direction_ltr = 0;
402 d->action_direction_rtl = 0;
406 d->action_list_style =
new KSelectAction(
KIcon(
"format-list-unordered"),
i18nc(
"@title:menu",
"List Style"), actionCollection);
408 listStyles <<
i18nc(
"@item:inmenu no list style",
"None")
409 <<
i18nc(
"@item:inmenu disc list style",
"Disc")
410 <<
i18nc(
"@item:inmenu circle list style",
"Circle")
411 <<
i18nc(
"@item:inmenu square list style",
"Square")
412 <<
i18nc(
"@item:inmenu numbered lists",
"123")
413 <<
i18nc(
"@item:inmenu lowercase abc lists",
"abc")
414 <<
i18nc(
"@item:inmenu uppercase abc lists",
"ABC");
415 d->action_list_style->setItems(listStyles);
416 d->action_list_style->setCurrentItem(0);
417 d->richTextActionList.append((d->action_list_style));
418 actionCollection->
addAction(
"format_list_style", d->action_list_style);
419 connect(d->action_list_style, SIGNAL(triggered(
int)),
420 this, SLOT(_k_setListStyle(
int)));
421 connect(d->action_list_style, SIGNAL(triggered()),
422 this, SLOT(_k_updateMiscActions()));
426 d->action_list_style = 0;
430 d->action_list_indent =
new KAction(
KIcon(
"format-indent-more"),
i18nc(
"@action",
"Increase Indent"), actionCollection);
431 d->richTextActionList.append((d->action_list_indent));
432 actionCollection->
addAction(
"format_list_indent_more", d->action_list_indent);
433 connect(d->action_list_indent, SIGNAL(triggered()),
435 connect(d->action_list_indent, SIGNAL(triggered()),
436 this, SLOT(_k_updateMiscActions()));
439 d->action_list_indent = 0;
443 d->action_list_dedent =
new KAction(
KIcon(
"format-indent-less"),
i18nc(
"@action",
"Decrease Indent"), actionCollection);
444 d->richTextActionList.append((d->action_list_dedent));
445 actionCollection->
addAction(
"format_list_indent_less", d->action_list_dedent);
446 connect(d->action_list_dedent, SIGNAL(triggered()),
448 connect(d->action_list_dedent, SIGNAL(triggered()),
449 this, SLOT(_k_updateMiscActions()));
452 d->action_list_dedent = 0;
456 d->action_insert_horizontal_rule =
new KAction(
KIcon(
"insert-horizontal-rule"),
i18nc(
"@action",
"Insert Rule Line"), actionCollection);
457 d->richTextActionList.append((d->action_insert_horizontal_rule));
458 actionCollection->
addAction(
"insert_horizontal_rule", d->action_insert_horizontal_rule);
459 connect(d->action_insert_horizontal_rule, SIGNAL(triggered()),
462 actionCollection->
removeAction(d->action_insert_horizontal_rule);
463 d->action_insert_horizontal_rule = 0;
467 d->action_manage_link =
new KAction(
KIcon(
"insert-link"),
i18nc(
"@action",
"Link"), actionCollection);
468 d->richTextActionList.append((d->action_manage_link));
469 actionCollection->
addAction(
"manage_link", d->action_manage_link);
470 connect(d->action_manage_link, SIGNAL(triggered()),
471 this, SLOT(_k_manageLink()));
474 d->action_manage_link = 0;
478 d->action_format_painter =
new KToggleAction(
KIcon(
"draw-brush"),
i18nc(
"@action",
"Format Painter"), actionCollection);
479 d->richTextActionList.append((d->action_format_painter));
480 actionCollection->
addAction(
"format_painter", d->action_format_painter);
481 connect(d->action_format_painter, SIGNAL(toggled(
bool)),
482 this, SLOT(_k_formatPainter(
bool)));
484 actionCollection->
removeAction(d->action_format_painter);
485 d->action_format_painter = 0;
489 d->action_to_plain_text =
new KToggleAction(
i18nc(
"@action",
"To Plain Text"), actionCollection);
490 d->richTextActionList.append((d->action_to_plain_text));
491 actionCollection->
addAction(
"action_to_plain_text", d->action_to_plain_text);
492 connect(d->action_to_plain_text, SIGNAL(triggered()),
495 actionCollection->
removeAction(d->action_to_plain_text);
496 d->action_to_plain_text = 0;
500 d->action_text_subscript =
new KToggleAction(
KIcon(
"format-text-subscript"),
i18nc(
"@action",
"Subscript"), actionCollection);
501 d->richTextActionList.append((d->action_text_subscript));
502 actionCollection->
addAction(
"format_text_subscript", d->action_text_subscript);
504 connect(d->action_text_subscript, SIGNAL(triggered(
bool)),
507 d->action_text_superscript =
new KToggleAction(
KIcon(
"format-text-superscript"),
i18nc(
"@action",
"Superscript"), actionCollection);
508 d->richTextActionList.append((d->action_text_superscript));
509 actionCollection->
addAction(
"format_text_superscript", d->action_text_superscript);
511 connect(d->action_text_superscript, SIGNAL(triggered(
bool)),
514 actionCollection->
removeAction(d->action_text_subscript);
515 d->action_text_subscript = 0;
517 actionCollection->
removeAction(d->action_text_superscript);
518 d->action_text_superscript = 0;
522 disconnect(
this, SIGNAL(currentCharFormatChanged(QTextCharFormat)),
523 this, SLOT(_k_updateCharFormatActions(QTextCharFormat)));
524 disconnect(
this, SIGNAL(cursorPositionChanged()),
525 this, SLOT(_k_updateMiscActions()));
526 connect(
this, SIGNAL(currentCharFormatChanged(QTextCharFormat)),
527 this, SLOT(_k_updateCharFormatActions(QTextCharFormat)));
528 connect(
this, SIGNAL(cursorPositionChanged()),
529 this, SLOT(_k_updateMiscActions()));
531 d->_k_updateMiscActions();
532 d->_k_updateCharFormatActions(currentCharFormat());
538 foreach(
QAction* action, d->richTextActionList)
540 action->setEnabled(enabled);
542 d->richTextEnabled = enabled;
545 void KRichTextWidget::Private::_k_setListStyle(
int index)
547 q->setListStyle(index);
548 _k_updateMiscActions();
551 void KRichTextWidget::Private::_k_updateCharFormatActions(
const QTextCharFormat &format)
553 QFont f = format.font();
555 if (richTextSupport & SupportFontFamily) {
556 action_font_family->setFont(f.family());
558 if (richTextSupport & SupportFontSize) {
559 if (f.pointSize() > 0)
560 action_font_size->setFontSize((
int)f.pointSize());
563 if (richTextSupport & SupportBold) {
564 action_text_bold->setChecked(f.bold());
567 if (richTextSupport & SupportItalic) {
568 action_text_italic->setChecked(f.italic());
571 if (richTextSupport & SupportUnderline) {
572 action_text_underline->setChecked(f.underline());
575 if (richTextSupport & SupportStrikeOut) {
576 action_text_strikeout->setChecked(f.strikeOut());
579 if (richTextSupport & SupportSuperScriptAndSubScript) {
580 QTextCharFormat::VerticalAlignment vAlign = format.verticalAlignment();
581 action_text_superscript->setChecked(vAlign == QTextCharFormat::AlignSuperScript);
582 action_text_subscript->setChecked(vAlign == QTextCharFormat::AlignSubScript);
586 void KRichTextWidget::Private::_k_updateMiscActions()
588 if (richTextSupport & SupportAlignment) {
589 Qt::Alignment a = q->alignment();
590 if (a & Qt::AlignLeft) {
591 action_align_left->setChecked(
true);
592 }
else if (a & Qt::AlignHCenter) {
593 action_align_center->setChecked(
true);
594 }
else if (a & Qt::AlignRight) {
595 action_align_right->setChecked(
true);
596 }
else if (a & Qt::AlignJustify) {
597 action_align_justify->setChecked(
true);
602 if (richTextSupport & SupportChangeListStyle) {
603 if (q->textCursor().currentList()) {
604 action_list_style->setCurrentItem(-q->textCursor().currentList()->format().style());
606 action_list_style->setCurrentItem(0);
611 if ( richTextSupport & SupportIndentLists ) {
612 if ( richTextEnabled ) {
613 action_list_indent->setEnabled( q->canIndentList() );
615 action_list_indent->setEnabled(
false );
619 if ( richTextSupport & SupportDedentLists ) {
620 if ( richTextEnabled ) {
621 action_list_dedent->setEnabled( q->canDedentList() );
623 action_list_dedent->setEnabled(
false );
627 if (richTextSupport & SupportDirection) {
628 const Qt::LayoutDirection direction = q->textCursor().blockFormat().layoutDirection();
629 action_direction_ltr->setChecked(direction == Qt::LeftToRight);
630 action_direction_rtl->setChecked(direction == Qt::RightToLeft);
634 void KRichTextWidget::Private::_k_setTextForegroundColor()
636 QColor currentTextForegroundColor = q->textColor();
639 if (!currentTextForegroundColor.isValid())
641 if (result != QDialog::Accepted)
644 q->setTextForegroundColor(currentTextForegroundColor);
648 void KRichTextWidget::Private::_k_setTextBackgroundColor()
650 QTextCharFormat fmt = q->textCursor().charFormat();
651 QColor currentTextBackgroundColor = fmt.background().color();
654 if (!currentTextBackgroundColor.isValid())
656 if (result != QDialog::Accepted)
659 q->setTextBackgroundColor(currentTextBackgroundColor);
663 void KRichTextWidget::Private::_k_manageLink()
666 KLinkDialog *linkDialog =
new KLinkDialog(q);
667 linkDialog->setLinkText(q->currentLinkText());
668 linkDialog->setLinkUrl(q->currentLinkUrl());
670 if (linkDialog->exec()) {
671 q->updateLink(linkDialog->linkUrl(), linkDialog->linkText());
680 if (d->painterActive) {
683 if (textCursor().hasSelection()) {
684 textCursor().setCharFormat(d->painterFormat);
686 d->painterActive =
false;
687 d->action_format_painter->setChecked(
false);
692 void KRichTextWidget::Private::_k_formatPainter(
bool active)
695 painterFormat = q->currentCharFormat();
696 painterActive =
true;
697 q->viewport()->setCursor(
QCursor(
KIcon(
"draw-brush").pixmap(32, 32), 0, 32));
699 painterFormat = QTextCharFormat();
700 painterActive =
false;
701 q->viewport()->setCursor(Qt::IBeamCursor);
707 d->_k_updateMiscActions();
708 d->_k_updateCharFormatActions(currentCharFormat());
712 #include "krichtextwidget.moc"