tools/designer/src/lib/shared/richtexteditor.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Designer of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "richtexteditor_p.h"
       
    43 #include "htmlhighlighter_p.h"
       
    44 #include "iconselector_p.h"
       
    45 #include "ui_addlinkdialog.h"
       
    46 #include "abstractsettings_p.h"
       
    47 
       
    48 #include "iconloader_p.h"
       
    49 
       
    50 #include <QtDesigner/QDesignerFormEditorInterface>
       
    51 
       
    52 #include <QtCore/QList>
       
    53 #include <QtCore/QMap>
       
    54 #include <QtCore/QPointer>
       
    55 
       
    56 #include <QtGui/QAction>
       
    57 #include <QtGui/QColorDialog>
       
    58 #include <QtGui/QComboBox>
       
    59 #include <QtGui/QFontDatabase>
       
    60 #include <QtGui/QTextCursor>
       
    61 #include <QtGui/QPainter>
       
    62 #include <QtGui/QIcon>
       
    63 #include <QtGui/QMenu>
       
    64 #include <QtGui/QMoveEvent>
       
    65 #include <QtGui/QTabWidget>
       
    66 #include <QtGui/QTextDocument>
       
    67 #include <QtGui/QTextBlock>
       
    68 #include <QtGui/QToolBar>
       
    69 #include <QtGui/QToolButton>
       
    70 #include <QtGui/QVBoxLayout>
       
    71 #include <QtGui/QHBoxLayout>
       
    72 #include <QtGui/QPushButton>
       
    73 #include <QtGui/QDialogButtonBox>
       
    74 
       
    75 QT_BEGIN_NAMESPACE
       
    76 
       
    77 static const char *RichTextDialogC = "RichTextDialog";
       
    78 static const char *Geometry = "Geometry";
       
    79 
       
    80 namespace qdesigner_internal {
       
    81 
       
    82 class RichTextEditor : public QTextEdit
       
    83 {
       
    84     Q_OBJECT
       
    85 public:
       
    86     RichTextEditor(QWidget *parent = 0);
       
    87     void setDefaultFont(const QFont &font);
       
    88 
       
    89     QToolBar *createToolBar(QDesignerFormEditorInterface *core, QWidget *parent = 0);
       
    90 
       
    91 public slots:
       
    92     void setFontBold(bool b);
       
    93     void setFontPointSize(double);
       
    94     void setText(const QString &text);
       
    95     QString text(Qt::TextFormat format) const;
       
    96 
       
    97 signals:
       
    98     void stateChanged();
       
    99 };
       
   100 
       
   101 class AddLinkDialog : public QDialog
       
   102 {
       
   103     Q_OBJECT
       
   104 
       
   105 public:
       
   106     AddLinkDialog(RichTextEditor *editor, QWidget *parent = 0);
       
   107     ~AddLinkDialog();
       
   108 
       
   109     int showDialog();
       
   110 
       
   111 public slots:
       
   112     void accept();
       
   113 
       
   114 private:
       
   115     RichTextEditor *m_editor;
       
   116     Ui::AddLinkDialog *m_ui;
       
   117 };
       
   118 
       
   119 AddLinkDialog::AddLinkDialog(RichTextEditor *editor, QWidget *parent) :
       
   120     QDialog(parent),
       
   121     m_ui(new Ui::AddLinkDialog)
       
   122 {
       
   123     m_ui->setupUi(this);
       
   124 
       
   125     setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
       
   126 
       
   127     m_editor = editor;
       
   128 }
       
   129 
       
   130 AddLinkDialog::~AddLinkDialog()
       
   131 {
       
   132     delete m_ui;
       
   133 }
       
   134 
       
   135 int AddLinkDialog::showDialog()
       
   136 {
       
   137     // Set initial focus
       
   138     const QTextCursor cursor = m_editor->textCursor();
       
   139     if (cursor.hasSelection()) {
       
   140         m_ui->titleInput->setText(cursor.selectedText());
       
   141         m_ui->urlInput->setFocus();
       
   142     } else {
       
   143         m_ui->titleInput->setFocus();
       
   144     }
       
   145 
       
   146     return exec();
       
   147 }
       
   148 
       
   149 void AddLinkDialog::accept()
       
   150 {
       
   151     const QString title = m_ui->titleInput->text();
       
   152     const QString url = m_ui->urlInput->text();
       
   153 
       
   154     if (!title.isEmpty()) {
       
   155         QString html = QLatin1String("<a href=\"");
       
   156         html += url;
       
   157         html += QLatin1String("\">");
       
   158         html += title;
       
   159         html += QLatin1String("</a>");
       
   160 
       
   161         m_editor->insertHtml(html);
       
   162     }
       
   163 
       
   164     m_ui->titleInput->clear();
       
   165     m_ui->urlInput->clear();
       
   166 
       
   167     QDialog::accept();
       
   168 }
       
   169 
       
   170 class HtmlTextEdit : public QTextEdit
       
   171 {
       
   172     Q_OBJECT
       
   173 
       
   174 public:
       
   175     HtmlTextEdit(QWidget *parent = 0)
       
   176         : QTextEdit(parent)
       
   177     {}
       
   178 
       
   179     void contextMenuEvent(QContextMenuEvent *event);
       
   180 
       
   181 private slots:
       
   182     void actionTriggered(QAction *action);
       
   183 };
       
   184 
       
   185 void HtmlTextEdit::contextMenuEvent(QContextMenuEvent *event)
       
   186 {
       
   187     QMenu *menu = createStandardContextMenu();
       
   188     QMenu *htmlMenu = new QMenu(tr("Insert HTML entity"), menu);
       
   189 
       
   190     typedef struct {
       
   191         const char *text;
       
   192         const char *entity;
       
   193     } Entry;
       
   194 
       
   195     const Entry entries[] = {
       
   196         { "&&amp; (&&)", "&amp;" },
       
   197         { "&&nbsp;", "&nbsp;" },
       
   198         { "&&lt; (<)", "&lt;" },
       
   199         { "&&gt; (>)", "&gt;" },
       
   200         { "&&copy; (Copyright)", "&copy;" },
       
   201         { "&&reg; (Trade Mark)", "&reg;" },
       
   202     };
       
   203 
       
   204     for (int i = 0; i < 6; ++i) {
       
   205         QAction *entityAction = new QAction(QLatin1String(entries[i].text),
       
   206                                             htmlMenu);
       
   207         entityAction->setData(QLatin1String(entries[i].entity));
       
   208         htmlMenu->addAction(entityAction);
       
   209     }
       
   210 
       
   211     menu->addMenu(htmlMenu);
       
   212     connect(htmlMenu, SIGNAL(triggered(QAction*)),
       
   213                       SLOT(actionTriggered(QAction*)));
       
   214     menu->exec(event->globalPos());
       
   215     delete menu;
       
   216 }
       
   217 
       
   218 void HtmlTextEdit::actionTriggered(QAction *action)
       
   219 {
       
   220     insertPlainText(action->data().toString());
       
   221 }
       
   222 
       
   223 class ColorAction : public QAction
       
   224 {
       
   225     Q_OBJECT
       
   226 
       
   227 public:
       
   228     ColorAction(QObject *parent);
       
   229 
       
   230     const QColor& color() const { return m_color; }
       
   231     void setColor(const QColor &color);
       
   232 
       
   233 signals:
       
   234     void colorChanged(const QColor &color);
       
   235 
       
   236 private slots:
       
   237     void chooseColor();
       
   238 
       
   239 private:
       
   240     QColor m_color;
       
   241 };
       
   242 
       
   243 ColorAction::ColorAction(QObject *parent):
       
   244     QAction(parent)
       
   245 {
       
   246     setText(tr("Text Color"));
       
   247     setColor(Qt::black);
       
   248     connect(this, SIGNAL(triggered()), this, SLOT(chooseColor()));
       
   249 }
       
   250 
       
   251 void ColorAction::setColor(const QColor &color)
       
   252 {
       
   253     if (color == m_color)
       
   254         return;
       
   255     m_color = color;
       
   256     QPixmap pix(24, 24);
       
   257     QPainter painter(&pix);
       
   258     painter.setRenderHint(QPainter::Antialiasing, false);
       
   259     painter.fillRect(pix.rect(), m_color);
       
   260     painter.setPen(m_color.darker());
       
   261     painter.drawRect(pix.rect().adjusted(0, 0, -1, -1));
       
   262     setIcon(pix);
       
   263 }
       
   264 
       
   265 void ColorAction::chooseColor()
       
   266 {
       
   267     const QColor col = QColorDialog::getColor(m_color, 0);
       
   268     if (col.isValid() && col != m_color) {
       
   269         setColor(col);
       
   270         emit colorChanged(m_color);
       
   271     }
       
   272 }
       
   273 
       
   274 class RichTextEditorToolBar : public QToolBar
       
   275 {
       
   276     Q_OBJECT
       
   277 public:
       
   278     RichTextEditorToolBar(QDesignerFormEditorInterface *core,
       
   279                           RichTextEditor *editor,
       
   280                           QWidget *parent = 0);
       
   281 
       
   282 public slots:
       
   283     void updateActions();
       
   284 
       
   285 private slots:
       
   286     void alignmentActionTriggered(QAction *action);
       
   287     void sizeInputActivated(const QString &size);
       
   288     void colorChanged(const QColor &color);
       
   289     void setVAlignSuper(bool super);
       
   290     void setVAlignSub(bool sub);
       
   291     void insertLink();
       
   292     void insertImage();
       
   293 
       
   294 private:
       
   295     QAction *m_bold_action;
       
   296     QAction *m_italic_action;
       
   297     QAction *m_underline_action;
       
   298     QAction *m_valign_sup_action;
       
   299     QAction *m_valign_sub_action;
       
   300     QAction *m_align_left_action;
       
   301     QAction *m_align_center_action;
       
   302     QAction *m_align_right_action;
       
   303     QAction *m_align_justify_action;
       
   304     QAction *m_link_action;
       
   305     QAction *m_image_action;
       
   306     ColorAction *m_color_action;
       
   307     QComboBox *m_font_size_input;
       
   308 
       
   309     QDesignerFormEditorInterface *m_core;
       
   310     QPointer<RichTextEditor> m_editor;
       
   311 };
       
   312 
       
   313 static QAction *createCheckableAction(const QIcon &icon, const QString &text,
       
   314                                       QObject *receiver, const char *slot,
       
   315                                       QObject *parent = 0)
       
   316 {
       
   317     QAction *result = new QAction(parent);
       
   318     result->setIcon(icon);
       
   319     result->setText(text);
       
   320     result->setCheckable(true);
       
   321     result->setChecked(false);
       
   322     if (slot)
       
   323         QObject::connect(result, SIGNAL(triggered(bool)), receiver, slot);
       
   324     return result;
       
   325 }
       
   326 
       
   327 RichTextEditorToolBar::RichTextEditorToolBar(QDesignerFormEditorInterface *core,
       
   328                                              RichTextEditor *editor,
       
   329                                              QWidget *parent) :
       
   330     QToolBar(parent),
       
   331     m_link_action(new QAction(this)),
       
   332     m_image_action(new QAction(this)),
       
   333     m_color_action(new ColorAction(this)),
       
   334     m_font_size_input(new QComboBox),
       
   335     m_core(core),
       
   336     m_editor(editor)
       
   337 {
       
   338     // Font size combo box
       
   339     m_font_size_input->setEditable(false);
       
   340     const QList<int> font_sizes = QFontDatabase::standardSizes();
       
   341     foreach (int font_size, font_sizes)
       
   342         m_font_size_input->addItem(QString::number(font_size));
       
   343 
       
   344     connect(m_font_size_input, SIGNAL(activated(QString)),
       
   345             this, SLOT(sizeInputActivated(QString)));
       
   346     addWidget(m_font_size_input);
       
   347 
       
   348     addSeparator();
       
   349 
       
   350     // Bold, italic and underline buttons
       
   351 
       
   352     m_bold_action = createCheckableAction(
       
   353             createIconSet(QLatin1String("textbold.png")),
       
   354             tr("Bold"), editor, SLOT(setFontBold(bool)), this);
       
   355     m_bold_action->setShortcut(tr("CTRL+B"));
       
   356     addAction(m_bold_action);
       
   357 
       
   358     m_italic_action = createCheckableAction(
       
   359             createIconSet(QLatin1String("textitalic.png")),
       
   360             tr("Italic"), editor, SLOT(setFontItalic(bool)), this);
       
   361     m_italic_action->setShortcut(tr("CTRL+I"));
       
   362     addAction(m_italic_action);
       
   363 
       
   364     m_underline_action = createCheckableAction(
       
   365             createIconSet(QLatin1String("textunder.png")),
       
   366             tr("Underline"), editor, SLOT(setFontUnderline(bool)), this);
       
   367     m_underline_action->setShortcut(tr("CTRL+U"));
       
   368     addAction(m_underline_action);
       
   369 
       
   370     addSeparator();
       
   371 
       
   372     // Left, center, right and justified alignment buttons
       
   373 
       
   374     QActionGroup *alignment_group = new QActionGroup(this);
       
   375     connect(alignment_group, SIGNAL(triggered(QAction*)),
       
   376                              SLOT(alignmentActionTriggered(QAction*)));
       
   377 
       
   378     m_align_left_action = createCheckableAction(
       
   379             createIconSet(QLatin1String("textleft.png")),
       
   380             tr("Left Align"), editor, 0, alignment_group);
       
   381     addAction(m_align_left_action);
       
   382 
       
   383     m_align_center_action = createCheckableAction(
       
   384             createIconSet(QLatin1String("textcenter.png")),
       
   385             tr("Center"), editor, 0, alignment_group);
       
   386     addAction(m_align_center_action);
       
   387 
       
   388     m_align_right_action = createCheckableAction(
       
   389             createIconSet(QLatin1String("textright.png")),
       
   390             tr("Right Align"), editor, 0, alignment_group);
       
   391     addAction(m_align_right_action);
       
   392 
       
   393     m_align_justify_action = createCheckableAction(
       
   394             createIconSet(QLatin1String("textjustify.png")),
       
   395             tr("Justify"), editor, 0, alignment_group);
       
   396     addAction(m_align_justify_action);
       
   397 
       
   398     addSeparator();
       
   399 
       
   400     // Superscript and subscript buttons
       
   401 
       
   402     m_valign_sup_action = createCheckableAction(
       
   403             createIconSet(QLatin1String("textsuperscript.png")),
       
   404             tr("Superscript"),
       
   405             this, SLOT(setVAlignSuper(bool)), this);
       
   406     addAction(m_valign_sup_action);
       
   407 
       
   408     m_valign_sub_action = createCheckableAction(
       
   409             createIconSet(QLatin1String("textsubscript.png")),
       
   410             tr("Subscript"),
       
   411             this, SLOT(setVAlignSub(bool)), this);
       
   412     addAction(m_valign_sub_action);
       
   413 
       
   414     addSeparator();
       
   415 
       
   416     // Insert hyperlink and image buttons
       
   417 
       
   418     m_link_action->setIcon(createIconSet(QLatin1String("textanchor.png")));
       
   419     m_link_action->setText(tr("Insert &Link"));
       
   420     connect(m_link_action, SIGNAL(triggered()), SLOT(insertLink()));
       
   421     addAction(m_link_action);
       
   422 
       
   423     m_image_action->setIcon(createIconSet(QLatin1String("insertimage.png")));
       
   424     m_image_action->setText(tr("Insert &Image"));
       
   425     connect(m_image_action, SIGNAL(triggered()), SLOT(insertImage()));
       
   426     addAction(m_image_action);
       
   427 
       
   428     addSeparator();
       
   429 
       
   430     // Text color button
       
   431     connect(m_color_action, SIGNAL(colorChanged(QColor)),
       
   432             this, SLOT(colorChanged(QColor)));
       
   433     addAction(m_color_action);
       
   434 
       
   435     connect(editor, SIGNAL(textChanged()), this, SLOT(updateActions()));
       
   436     connect(editor, SIGNAL(stateChanged()), this, SLOT(updateActions()));
       
   437 
       
   438     updateActions();
       
   439 }
       
   440 
       
   441 void RichTextEditorToolBar::alignmentActionTriggered(QAction *action)
       
   442 {
       
   443     Qt::Alignment new_alignment;
       
   444 
       
   445     if (action == m_align_left_action) {
       
   446         new_alignment = Qt::AlignLeft;
       
   447     } else if (action == m_align_center_action) {
       
   448         new_alignment = Qt::AlignCenter;
       
   449     } else if (action == m_align_right_action) {
       
   450         new_alignment = Qt::AlignRight;
       
   451     } else {
       
   452         new_alignment = Qt::AlignJustify;
       
   453     }
       
   454 
       
   455     m_editor->setAlignment(new_alignment);
       
   456 }
       
   457 
       
   458 void RichTextEditorToolBar::colorChanged(const QColor &color)
       
   459 {
       
   460     m_editor->setTextColor(color);
       
   461     m_editor->setFocus();
       
   462 }
       
   463 
       
   464 void RichTextEditorToolBar::sizeInputActivated(const QString &size)
       
   465 {
       
   466     bool ok;
       
   467     int i = size.toInt(&ok);
       
   468     if (!ok)
       
   469         return;
       
   470 
       
   471     m_editor->setFontPointSize(i);
       
   472     m_editor->setFocus();
       
   473 }
       
   474 
       
   475 void RichTextEditorToolBar::setVAlignSuper(bool super)
       
   476 {
       
   477     const QTextCharFormat::VerticalAlignment align = super ?
       
   478         QTextCharFormat::AlignSuperScript : QTextCharFormat::AlignNormal;
       
   479 
       
   480     QTextCharFormat charFormat = m_editor->currentCharFormat();
       
   481     charFormat.setVerticalAlignment(align);
       
   482     m_editor->setCurrentCharFormat(charFormat);
       
   483 
       
   484     m_valign_sub_action->setChecked(false);
       
   485 }
       
   486 
       
   487 void RichTextEditorToolBar::setVAlignSub(bool sub)
       
   488 {
       
   489     const QTextCharFormat::VerticalAlignment align = sub ?
       
   490         QTextCharFormat::AlignSubScript : QTextCharFormat::AlignNormal;
       
   491 
       
   492     QTextCharFormat charFormat = m_editor->currentCharFormat();
       
   493     charFormat.setVerticalAlignment(align);
       
   494     m_editor->setCurrentCharFormat(charFormat);
       
   495 
       
   496     m_valign_sup_action->setChecked(false);
       
   497 }
       
   498 
       
   499 void RichTextEditorToolBar::insertLink()
       
   500 {
       
   501     AddLinkDialog linkDialog(m_editor, this);
       
   502     linkDialog.showDialog();
       
   503     m_editor->setFocus();
       
   504 }
       
   505 
       
   506 void RichTextEditorToolBar::insertImage()
       
   507 {
       
   508     const QString path = IconSelector::choosePixmapResource(m_core, m_core->resourceModel(), QString(), this);
       
   509     if (!path.isEmpty())
       
   510         m_editor->insertHtml(QLatin1String("<img src=\"") + path + QLatin1String("\"/>"));
       
   511 }
       
   512 
       
   513 void RichTextEditorToolBar::updateActions()
       
   514 {
       
   515     if (m_editor == 0) {
       
   516         setEnabled(false);
       
   517         return;
       
   518     }
       
   519 
       
   520     const Qt::Alignment alignment = m_editor->alignment();
       
   521     const QTextCursor cursor = m_editor->textCursor();
       
   522     const QTextCharFormat charFormat = cursor.charFormat();
       
   523     const QFont font = charFormat.font();
       
   524     const QTextCharFormat::VerticalAlignment valign =
       
   525         charFormat.verticalAlignment();
       
   526     const bool superScript = valign == QTextCharFormat::AlignSuperScript;
       
   527     const bool subScript = valign == QTextCharFormat::AlignSubScript;
       
   528 
       
   529     if (alignment & Qt::AlignLeft) {
       
   530         m_align_left_action->setChecked(true);
       
   531     } else if (alignment & Qt::AlignRight) {
       
   532         m_align_right_action->setChecked(true);
       
   533     } else if (alignment & Qt::AlignHCenter) {
       
   534         m_align_center_action->setChecked(true);
       
   535     } else {
       
   536         m_align_justify_action->setChecked(true);
       
   537     }
       
   538 
       
   539     m_bold_action->setChecked(font.bold());
       
   540     m_italic_action->setChecked(font.italic());
       
   541     m_underline_action->setChecked(font.underline());
       
   542     m_valign_sup_action->setChecked(superScript);
       
   543     m_valign_sub_action->setChecked(subScript);
       
   544 
       
   545     const int size = font.pointSize();
       
   546     const int idx = m_font_size_input->findText(QString::number(size));
       
   547     if (idx != -1)
       
   548         m_font_size_input->setCurrentIndex(idx);
       
   549 
       
   550     m_color_action->setColor(m_editor->textColor());
       
   551 }
       
   552 
       
   553 RichTextEditor::RichTextEditor(QWidget *parent)
       
   554     : QTextEdit(parent)
       
   555 {
       
   556     connect(this, SIGNAL(currentCharFormatChanged(QTextCharFormat)),
       
   557             this, SIGNAL(stateChanged()));
       
   558     connect(this, SIGNAL(cursorPositionChanged()),
       
   559             this, SIGNAL(stateChanged()));
       
   560 }
       
   561 
       
   562 QToolBar *RichTextEditor::createToolBar(QDesignerFormEditorInterface *core, QWidget *parent)
       
   563 {
       
   564     return new RichTextEditorToolBar(core, this, parent);
       
   565 }
       
   566 
       
   567 void RichTextEditor::setFontBold(bool b)
       
   568 {
       
   569     if (b)
       
   570         setFontWeight(QFont::Bold);
       
   571     else
       
   572         setFontWeight(QFont::Normal);
       
   573 }
       
   574 
       
   575 void RichTextEditor::setFontPointSize(double d)
       
   576 {
       
   577     QTextEdit::setFontPointSize(qreal(d));
       
   578 }
       
   579 
       
   580 void RichTextEditor::setText(const QString &text)
       
   581 {
       
   582     if (Qt::mightBeRichText(text))
       
   583         setHtml(text);
       
   584     else
       
   585         setPlainText(text);
       
   586 }
       
   587 
       
   588 void RichTextEditor::setDefaultFont(const QFont &font)
       
   589 {
       
   590     document()->setDefaultFont(font);
       
   591     if (font.pointSize() > 0)
       
   592         setFontPointSize(font.pointSize());
       
   593     else
       
   594         setFontPointSize(QFontInfo(font).pointSize());
       
   595     emit textChanged();
       
   596 }
       
   597 
       
   598 QString RichTextEditor::text(Qt::TextFormat format) const
       
   599 {
       
   600     switch (format) {
       
   601     case Qt::LogText:
       
   602     case Qt::PlainText:
       
   603         return toPlainText();
       
   604     case Qt::RichText:
       
   605         return toHtml();
       
   606     case Qt::AutoText:
       
   607         break;
       
   608     }
       
   609     const QString html = toHtml();
       
   610     const QString plain = toPlainText();
       
   611     QTextEdit tester;
       
   612     tester.setPlainText(plain);
       
   613     return tester.toHtml() == html ? plain : html;
       
   614 }
       
   615 
       
   616 RichTextEditorDialog::RichTextEditorDialog(QDesignerFormEditorInterface *core, QWidget *parent)  :
       
   617     QDialog(parent),
       
   618     m_editor(new RichTextEditor()),
       
   619     m_text_edit(new HtmlTextEdit),
       
   620     m_tab_widget(new QTabWidget),
       
   621     m_state(Clean),
       
   622     m_core(core)
       
   623 {
       
   624     setWindowTitle(tr("Edit text"));
       
   625     setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
       
   626 
       
   627     m_text_edit->setAcceptRichText(false);
       
   628     new HtmlHighlighter(m_text_edit);
       
   629 
       
   630     connect(m_editor, SIGNAL(textChanged()), this, SLOT(richTextChanged()));
       
   631     connect(m_text_edit, SIGNAL(textChanged()), this, SLOT(sourceChanged()));
       
   632 
       
   633     // The toolbar needs to be created after the RichTextEditor
       
   634     QToolBar *tool_bar = m_editor->createToolBar(core);
       
   635     tool_bar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
       
   636 
       
   637     QWidget *rich_edit = new QWidget;
       
   638     QVBoxLayout *rich_edit_layout = new QVBoxLayout(rich_edit);
       
   639     rich_edit_layout->addWidget(tool_bar);
       
   640     rich_edit_layout->addWidget(m_editor);
       
   641 
       
   642     QWidget *plain_edit = new QWidget;
       
   643     QVBoxLayout *plain_edit_layout = new QVBoxLayout(plain_edit);
       
   644     plain_edit_layout->addWidget(m_text_edit);
       
   645 
       
   646     m_tab_widget->setTabPosition(QTabWidget::South);
       
   647     m_tab_widget->addTab(rich_edit, tr("Rich Text"));
       
   648     m_tab_widget->addTab(plain_edit, tr("Source"));
       
   649     connect(m_tab_widget, SIGNAL(currentChanged(int)),
       
   650                           SLOT(tabIndexChanged(int)));
       
   651 
       
   652     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);
       
   653     QPushButton *ok_button = buttonBox->button(QDialogButtonBox::Ok);
       
   654     ok_button->setText(tr("&OK"));
       
   655     ok_button->setDefault(true);
       
   656     buttonBox->button(QDialogButtonBox::Cancel)->setText(tr("&Cancel"));
       
   657     connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
       
   658     connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
       
   659 
       
   660     QVBoxLayout *layout = new QVBoxLayout(this);
       
   661     layout->addWidget(m_tab_widget);
       
   662     layout->addWidget(buttonBox);
       
   663 
       
   664     m_editor->setFocus();
       
   665 
       
   666     QDesignerSettingsInterface *settings = core->settingsManager();
       
   667     settings->beginGroup(QLatin1String(RichTextDialogC));
       
   668 
       
   669     if (settings->contains(QLatin1String(Geometry)))
       
   670         restoreGeometry(settings->value(QLatin1String(Geometry)).toByteArray());
       
   671 
       
   672     settings->endGroup();
       
   673 }
       
   674 
       
   675 RichTextEditorDialog::~RichTextEditorDialog()
       
   676 {
       
   677     QDesignerSettingsInterface *settings = m_core->settingsManager();
       
   678     settings->beginGroup(QLatin1String(RichTextDialogC));
       
   679 
       
   680     settings->setValue(QLatin1String(Geometry), saveGeometry());
       
   681     settings->endGroup();
       
   682 }
       
   683 
       
   684 int RichTextEditorDialog::showDialog()
       
   685 {
       
   686     m_tab_widget->setCurrentIndex(0);
       
   687     m_editor->selectAll();
       
   688     m_editor->setFocus();
       
   689 
       
   690     return exec();
       
   691 }
       
   692 
       
   693 void RichTextEditorDialog::setDefaultFont(const QFont &font)
       
   694 {
       
   695     m_editor->setDefaultFont(font);
       
   696 }
       
   697 
       
   698 void RichTextEditorDialog::setText(const QString &text)
       
   699 {
       
   700     m_editor->setText(text);
       
   701     m_text_edit->setPlainText(text);
       
   702     m_state = Clean;
       
   703 }
       
   704 
       
   705 QString RichTextEditorDialog::text(Qt::TextFormat format) const
       
   706 {
       
   707     // In autotext mode, if the user has changed the source, use that
       
   708     if (format == Qt::AutoText && (m_state == Clean || m_state == SourceChanged))
       
   709         return m_text_edit->toPlainText();
       
   710     // If the plain text HTML editor is selected, first copy its contents over
       
   711     // to the rich text editor so that it is converted to Qt-HTML or actual
       
   712     // plain text.
       
   713     if (m_tab_widget->currentIndex() == SourceIndex && m_state == SourceChanged)
       
   714         m_editor->setHtml(m_text_edit->toPlainText());
       
   715     return m_editor->text(format);
       
   716 }
       
   717 
       
   718 void RichTextEditorDialog::tabIndexChanged(int newIndex)
       
   719 {
       
   720     // Anything changed, is there a need for a conversion?
       
   721     if (newIndex == SourceIndex && m_state != RichTextChanged)
       
   722         return;
       
   723     if (newIndex == RichTextIndex && m_state != SourceChanged)
       
   724         return;
       
   725     const State oldState = m_state;
       
   726     // Remember the cursor position, since it is invalidated by setPlainText
       
   727     QTextEdit *new_edit = (newIndex == SourceIndex) ? m_text_edit : m_editor;
       
   728     const int position = new_edit->textCursor().position();
       
   729 
       
   730     if (newIndex == SourceIndex)
       
   731         m_text_edit->setPlainText(m_editor->text(Qt::RichText));
       
   732     else
       
   733         m_editor->setHtml(m_text_edit->toPlainText());
       
   734 
       
   735     QTextCursor cursor = new_edit->textCursor();
       
   736     cursor.movePosition(QTextCursor::End);
       
   737     if (cursor.position() > position) {
       
   738         cursor.setPosition(position);
       
   739     }
       
   740     new_edit->setTextCursor(cursor);
       
   741     m_state = oldState; // Changed is triggered by setting the text
       
   742 }
       
   743 
       
   744 void RichTextEditorDialog::richTextChanged()
       
   745 {
       
   746     m_state = RichTextChanged;
       
   747 }
       
   748 
       
   749 void RichTextEditorDialog::sourceChanged()
       
   750 {
       
   751     m_state = SourceChanged;
       
   752 }
       
   753 
       
   754 } // namespace qdesigner_internal
       
   755 
       
   756 QT_END_NAMESPACE
       
   757 
       
   758 #include "richtexteditor.moc"