34#include <QtGui/QTextList>
45class 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)
81 RichTextSupport richTextSupport;
83 QTextCharFormat painterFormat;
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);
176void KRichTextWidget::Private::init()
202 return d->richTextSupport;
207 d->richTextSupport = support;
212 Q_ASSERT(actionCollection);
228 d->richTextActionList.clear();
230 if (d->richTextSupport & SupportTextForegroundColor) {
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;
242 if (d->richTextSupport & SupportTextBackgroundColor) {
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;
253 if (d->richTextSupport & SupportFontFamily) {
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);
258 connect(d->action_font_family, SIGNAL(triggered(QString)),
this, SLOT(
setFontFamily(QString)));
261 d->action_font_family = 0;
264 if (d->richTextSupport & SupportFontSize) {
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;
275 if (d->richTextSupport & SupportBold) {
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);
282 d->action_text_bold->setShortcut(
KShortcut(Qt::CTRL + Qt::Key_B));
283 connect(d->action_text_bold, SIGNAL(triggered(
bool)),
this, SLOT(
setTextBold(
bool)));
286 d->action_text_bold = 0;
289 if (d->richTextSupport & SupportItalic) {
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);
296 d->action_text_italic->setShortcut(
KShortcut(Qt::CTRL + Qt::Key_I));
297 connect(d->action_text_italic, SIGNAL(triggered(
bool)),
301 d->action_text_italic = 0;
304 if (d->richTextSupport & SupportUnderline) {
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);
311 d->action_text_underline->setShortcut(
KShortcut(Qt::CTRL + Qt::Key_U));
312 connect(d->action_text_underline, SIGNAL(triggered(
bool)),
315 actionCollection->
removeAction(d->action_text_underline);
316 d->action_text_underline = 0;
319 if (d->richTextSupport & SupportStrikeOut) {
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);
323 d->action_text_strikeout->setShortcut(
KShortcut(Qt::CTRL + Qt::Key_L));
324 connect(d->action_text_strikeout, SIGNAL(triggered(
bool)),
327 actionCollection->
removeAction(d->action_text_strikeout);
328 d->action_text_strikeout = 0;
331 if (d->richTextSupport & SupportAlignment) {
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;
379 if (d->richTextSupport & SupportDirection) {
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;
405 if (d->richTextSupport & SupportChangeListStyle) {
406 d->action_list_style =
new KSelectAction(
KIcon(
"format-list-unordered"),
i18nc(
"@title:menu",
"List Style"), actionCollection);
407 QStringList listStyles;
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 <<
i18nc(
"@item:inmenu lower case roman numerals",
"i ii iii")
416 <<
i18nc(
"@item:inmenu upper case roman numerals",
"I II III");
418 d->action_list_style->setItems(listStyles);
419 d->action_list_style->setCurrentItem(0);
420 d->richTextActionList.append((d->action_list_style));
421 actionCollection->
addAction(
"format_list_style", d->action_list_style);
422 connect(d->action_list_style, SIGNAL(triggered(
int)),
423 this, SLOT(_k_setListStyle(
int)));
424 connect(d->action_list_style, SIGNAL(triggered()),
425 this, SLOT(_k_updateMiscActions()));
429 d->action_list_style = 0;
432 if (d->richTextSupport & SupportIndentLists) {
433 d->action_list_indent =
new KAction(
KIcon(
"format-indent-more"),
i18nc(
"@action",
"Increase Indent"), actionCollection);
434 d->richTextActionList.append((d->action_list_indent));
435 actionCollection->
addAction(
"format_list_indent_more", d->action_list_indent);
436 connect(d->action_list_indent, SIGNAL(triggered()),
438 connect(d->action_list_indent, SIGNAL(triggered()),
439 this, SLOT(_k_updateMiscActions()));
442 d->action_list_indent = 0;
445 if (d->richTextSupport & SupportDedentLists) {
446 d->action_list_dedent =
new KAction(
KIcon(
"format-indent-less"),
i18nc(
"@action",
"Decrease Indent"), actionCollection);
447 d->richTextActionList.append((d->action_list_dedent));
448 actionCollection->
addAction(
"format_list_indent_less", d->action_list_dedent);
449 connect(d->action_list_dedent, SIGNAL(triggered()),
451 connect(d->action_list_dedent, SIGNAL(triggered()),
452 this, SLOT(_k_updateMiscActions()));
455 d->action_list_dedent = 0;
458 if (d->richTextSupport & SupportRuleLine) {
459 d->action_insert_horizontal_rule =
new KAction(
KIcon(
"insert-horizontal-rule"),
i18nc(
"@action",
"Insert Rule Line"), actionCollection);
460 d->richTextActionList.append((d->action_insert_horizontal_rule));
461 actionCollection->
addAction(
"insert_horizontal_rule", d->action_insert_horizontal_rule);
462 connect(d->action_insert_horizontal_rule, SIGNAL(triggered()),
465 actionCollection->
removeAction(d->action_insert_horizontal_rule);
466 d->action_insert_horizontal_rule = 0;
469 if (d->richTextSupport & SupportHyperlinks) {
470 d->action_manage_link =
new KAction(
KIcon(
"insert-link"),
i18nc(
"@action",
"Link"), actionCollection);
471 d->richTextActionList.append((d->action_manage_link));
472 actionCollection->
addAction(
"manage_link", d->action_manage_link);
473 connect(d->action_manage_link, SIGNAL(triggered()),
474 this, SLOT(_k_manageLink()));
477 d->action_manage_link = 0;
480 if (d->richTextSupport & SupportFormatPainting) {
481 d->action_format_painter =
new KToggleAction(
KIcon(
"draw-brush"),
i18nc(
"@action",
"Format Painter"), actionCollection);
482 d->richTextActionList.append((d->action_format_painter));
483 actionCollection->
addAction(
"format_painter", d->action_format_painter);
484 connect(d->action_format_painter, SIGNAL(toggled(
bool)),
485 this, SLOT(_k_formatPainter(
bool)));
487 actionCollection->
removeAction(d->action_format_painter);
488 d->action_format_painter = 0;
491 if (d->richTextSupport & SupportToPlainText) {
492 d->action_to_plain_text =
new KToggleAction(
i18nc(
"@action",
"To Plain Text"), actionCollection);
493 d->richTextActionList.append((d->action_to_plain_text));
494 actionCollection->
addAction(
"action_to_plain_text", d->action_to_plain_text);
495 connect(d->action_to_plain_text, SIGNAL(triggered()),
498 actionCollection->
removeAction(d->action_to_plain_text);
499 d->action_to_plain_text = 0;
502 if (d->richTextSupport & SupportSuperScriptAndSubScript) {
503 d->action_text_subscript =
new KToggleAction(
KIcon(
"format-text-subscript"),
i18nc(
"@action",
"Subscript"), actionCollection);
504 d->richTextActionList.append((d->action_text_subscript));
505 actionCollection->
addAction(
"format_text_subscript", d->action_text_subscript);
507 connect(d->action_text_subscript, SIGNAL(triggered(
bool)),
510 d->action_text_superscript =
new KToggleAction(
KIcon(
"format-text-superscript"),
i18nc(
"@action",
"Superscript"), actionCollection);
511 d->richTextActionList.append((d->action_text_superscript));
512 actionCollection->
addAction(
"format_text_superscript", d->action_text_superscript);
514 connect(d->action_text_superscript, SIGNAL(triggered(
bool)),
517 actionCollection->
removeAction(d->action_text_subscript);
518 d->action_text_subscript = 0;
520 actionCollection->
removeAction(d->action_text_superscript);
521 d->action_text_superscript = 0;
525 disconnect(
this, SIGNAL(currentCharFormatChanged(QTextCharFormat)),
526 this, SLOT(_k_updateCharFormatActions(QTextCharFormat)));
527 disconnect(
this, SIGNAL(cursorPositionChanged()),
528 this, SLOT(_k_updateMiscActions()));
529 connect(
this, SIGNAL(currentCharFormatChanged(QTextCharFormat)),
530 this, SLOT(_k_updateCharFormatActions(QTextCharFormat)));
531 connect(
this, SIGNAL(cursorPositionChanged()),
532 this, SLOT(_k_updateMiscActions()));
534 d->_k_updateMiscActions();
535 d->_k_updateCharFormatActions(currentCharFormat());
541 foreach(
QAction* action, d->richTextActionList)
543 action->setEnabled(enabled);
545 d->richTextEnabled = enabled;
548void KRichTextWidget::Private::_k_setListStyle(
int index)
550 q->setListStyle(index);
551 _k_updateMiscActions();
554void KRichTextWidget::Private::_k_updateCharFormatActions(
const QTextCharFormat &format)
556 QFont f = format.font();
558 if (richTextSupport & SupportFontFamily) {
559 action_font_family->setFont(f.family());
561 if (richTextSupport & SupportFontSize) {
562 if (f.pointSize() > 0)
563 action_font_size->setFontSize((
int)f.pointSize());
566 if (richTextSupport & SupportBold) {
567 action_text_bold->setChecked(f.bold());
570 if (richTextSupport & SupportItalic) {
571 action_text_italic->setChecked(f.italic());
574 if (richTextSupport & SupportUnderline) {
575 action_text_underline->setChecked(f.underline());
578 if (richTextSupport & SupportStrikeOut) {
579 action_text_strikeout->setChecked(f.strikeOut());
582 if (richTextSupport & SupportSuperScriptAndSubScript) {
583 QTextCharFormat::VerticalAlignment vAlign = format.verticalAlignment();
584 action_text_superscript->setChecked(vAlign == QTextCharFormat::AlignSuperScript);
585 action_text_subscript->setChecked(vAlign == QTextCharFormat::AlignSubScript);
589void KRichTextWidget::Private::_k_updateMiscActions()
591 if (richTextSupport & SupportAlignment) {
592 Qt::Alignment a = q->alignment();
593 if (a & Qt::AlignLeft) {
594 action_align_left->setChecked(
true);
595 }
else if (a & Qt::AlignHCenter) {
596 action_align_center->setChecked(
true);
597 }
else if (a & Qt::AlignRight) {
598 action_align_right->setChecked(
true);
599 }
else if (a & Qt::AlignJustify) {
600 action_align_justify->setChecked(
true);
605 if (richTextSupport & SupportChangeListStyle) {
606 if (q->textCursor().currentList()) {
607 action_list_style->setCurrentItem(-q->textCursor().currentList()->format().style());
609 action_list_style->setCurrentItem(0);
614 if ( richTextSupport & SupportIndentLists ) {
615 if ( richTextEnabled ) {
616 action_list_indent->setEnabled( q->canIndentList() );
618 action_list_indent->setEnabled(
false );
622 if ( richTextSupport & SupportDedentLists ) {
623 if ( richTextEnabled ) {
624 action_list_dedent->setEnabled( q->canDedentList() );
626 action_list_dedent->setEnabled(
false );
630 if (richTextSupport & SupportDirection) {
631 const Qt::LayoutDirection direction = q->textCursor().blockFormat().layoutDirection();
632 action_direction_ltr->setChecked(direction == Qt::LeftToRight);
633 action_direction_rtl->setChecked(direction == Qt::RightToLeft);
637void KRichTextWidget::Private::_k_setTextForegroundColor()
639 QColor currentTextForegroundColor = q->textColor();
642 if (result != QDialog::Accepted)
644 if (!currentTextForegroundColor.isValid())
647 q->setTextForegroundColor(currentTextForegroundColor);
651void KRichTextWidget::Private::_k_setTextBackgroundColor()
653 QTextCharFormat fmt = q->textCursor().charFormat();
654 QColor currentTextBackgroundColor = fmt.background().color();
657 if (result != QDialog::Accepted)
659 if (!currentTextBackgroundColor.isValid())
662 q->setTextBackgroundColor(currentTextBackgroundColor);
666void KRichTextWidget::Private::_k_manageLink()
669 KLinkDialog *linkDialog =
new KLinkDialog(q);
670 linkDialog->setLinkText(q->currentLinkText());
671 linkDialog->setLinkUrl(q->currentLinkUrl());
673 if (linkDialog->exec()) {
674 q->updateLink(linkDialog->linkUrl(), linkDialog->linkText());
683 if (d->painterActive) {
686 if (textCursor().hasSelection()) {
687 QTextCursor c = textCursor();
688 c.setCharFormat(d->painterFormat);
691 d->painterActive =
false;
692 d->action_format_painter->setChecked(
false);
694 KRichTextEdit::mouseReleaseEvent(event);
697void KRichTextWidget::Private::_k_formatPainter(
bool active)
700 painterFormat = q->currentCharFormat();
701 painterActive =
true;
702 q->viewport()->setCursor(
QCursor(
KIcon(
"draw-brush").pixmap(32, 32), 0, 32));
704 painterFormat = QTextCharFormat();
705 painterActive =
false;
706 q->viewport()->setCursor(Qt::IBeamCursor);
712 d->_k_updateMiscActions();
713 d->_k_updateCharFormatActions(currentCharFormat());
717#include "krichtextwidget.moc"
A container for a set of QAction objects.
QAction * addAction(const QString &name, QAction *action)
Add an action under the given name to the collection.
void removeAction(QAction *action)
Removes an action from the collection and deletes it.
Class to encapsulate user-driven action or event.
static int getColor(QColor &theColor, QWidget *parent=0L)
Creates a modal color dialog, let the user choose a color, and returns when the dialog is closed.
A set of methods used to work with colors.
@ View
Views; for example, frames, input fields, etc.
QBrush foreground(ForegroundRole=NormalText) const
Retrieve the requested foreground brush.
An action to select a font family.
An action to allow changing of the font size.
A wrapper around QIcon that provides KDE icon features.
The KRichTextEdit class provides a widget to edit and display rich text.
void setTextStrikeOut(bool strikeOut)
Toggles the strikeout formatting of the current word or selection at the current cursor position.
void setTextSubScript(bool subscript)
Toggles the subscript formatting of the current word or selection at the current cursor position.
void alignRight()
Sets the alignment of the current block to Right Aligned.
void insertHorizontalRule()
Inserts a horizontal rule below the current block.
void alignJustify()
Sets the alignment of the current block to Justified.
void switchToPlainText()
This will switch the editor to plain text mode.
void setTextUnderline(bool underline)
Toggles the underline formatting of the current word or selection at the current cursor position.
void setFontSize(int size)
Sets the current word or selection to the font size size.
void indentListLess()
Decreases the nesting level of the current block or selected blocks.
void setFontFamily(const QString &fontFamily)
Sets the current word or selection to the font family fontFamily.
void makeLeftToRight()
Sets the direction of the current block to Left-To-Right.
void indentListMore()
Increases the nesting level of the current block or selected blocks.
void alignLeft()
Sets the alignment of the current block to Left Aligned.
void setTextSuperScript(bool superscript)
Toggles the superscript formatting of the current word or selection at the current cursor position.
void setTextBold(bool bold)
Toggles the bold formatting of the current word or selection at the current cursor position.
void setTextItalic(bool italic)
Toggles the italic formatting of the current word or selection at the current cursor position.
void makeRightToLeft()
Sets the direction of the current block to Right-To-Left.
void alignCenter()
Sets the alignment of the current block to Centered.
A KRichTextEdit with common actions.
KRichTextWidget(QWidget *parent)
Constructor.
void setActionsEnabled(bool enabled)
Disables or enables all of the actions created by createActions().
virtual void createActions(KActionCollection *actionCollection)
Creates the actions and adds them to the given action collection.
RichTextSupport richTextSupport
void updateActionStates()
Tells KRichTextWidget to update the state of the actions created by createActions().
virtual void mouseReleaseEvent(QMouseEvent *event)
Reimplemented.
void setRichTextSupport(const KRichTextWidget::RichTextSupport &support)
Sets the supported rich text subset available.
~KRichTextWidget()
Destructor.
@ FullSupport
Includes all above actions for full rich text support.
Action for selecting one of several items.
Represents a keyboard shortcut.
QString i18nc(const char *ctxt, const char *text)