diff options
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/widgets/mrichtextedit.cpp | 76 | ||||
-rw-r--r-- | src/corelib/widgets/mrichtextedit.h | 1 | ||||
-rw-r--r-- | src/corelib/widgets/mrichtextedit_p.h | 4 | ||||
-rw-r--r-- | src/corelib/widgets/mrichtexteditdialogsmanager.cpp | 256 | ||||
-rw-r--r-- | src/corelib/widgets/mrichtexteditdialogsmanager_p.h | 96 |
5 files changed, 423 insertions, 10 deletions
diff --git a/src/corelib/widgets/mrichtextedit.cpp b/src/corelib/widgets/mrichtextedit.cpp index 3c161bf7..c7f2e061 100644 --- a/src/corelib/widgets/mrichtextedit.cpp +++ b/src/corelib/widgets/mrichtextedit.cpp @@ -23,6 +23,7 @@ #include <QApplication> #include <QClipboard> #include <MInputMethodState> +#include <MDeviceProfile> #include "mrichtextedit.h" #include "mrichtextedit_p.h" #include "mrichtexteditdialogsmanager_p.h" @@ -145,10 +146,13 @@ void MRichTextEditPrivate::showTextStylingOptions() q->connect(dialogsManager, SIGNAL(fontFamilySelected(QString)), SLOT(_q_setFontFamily(QString))); + q->connect(dialogsManager, SIGNAL(fontSizeSelected(int)), + SLOT(_q_setFontSize(int))); QString fontFamily; + int fontPointSize = -1; - textStyleValues(&fontFamily); + textStyleValues(&fontFamily, &fontPointSize); int startPos = -1; int endPos = -1; @@ -168,19 +172,20 @@ void MRichTextEditPrivate::showTextStylingOptions() q->setSelection(startPos, endPos - startPos); } - dialogsManager->showTextStylingDialog(fontFamily); + dialogsManager->showTextStylingDialog(fontFamily, fontPointSize); q->setFocus(); q->disconnect(dialogsManager, 0, q, 0); } -void MRichTextEditPrivate::textStyleValues(QString *fontfamily) +void MRichTextEditPrivate::textStyleValues(QString *fontfamily, int *fontPointSize) { Q_Q(MRichTextEdit); QTextCursor textcursor = q->textCursor(); *fontfamily = textcursor.charFormat().font().family(); + *fontPointSize = MDeviceProfile::instance()->pixelsToPt(textcursor.charFormat().font().pixelSize()); if (!q->hasSelectedText()) { return; @@ -190,7 +195,9 @@ void MRichTextEditPrivate::textStyleValues(QString *fontfamily) int startPos = textcursor.selectionStart(); int endPos = textcursor.selectionEnd(); bool familyDiffers = false; + bool sizeDiffers = false; + int fontPixelSize = textcursor.charFormat().font().pixelSize(); // Starting from startPos + 1 to get the style that would be used when // text is inserted in the positions for (int i = startPos + 1; i <= endPos; i++) { @@ -200,6 +207,15 @@ void MRichTextEditPrivate::textStyleValues(QString *fontfamily) familyDiffers = true; fontfamily->clear(); } + + if (!sizeDiffers && (fontPixelSize != textcursor.charFormat().font().pixelSize())) { + sizeDiffers = true; + *fontPointSize = -1; + } + + if (familyDiffers && sizeDiffers) { + break; + } } } @@ -216,6 +232,60 @@ void MRichTextEditPrivate::_q_setFontFamily(const QString &fontFamily) q->setTextCursor(textcursor); } + +void MRichTextEditPrivate::_q_setFontSize(int fontPointSize) +{ + Q_Q(MRichTextEdit); + + QTextCursor textcursor = q->textCursor(); + const bool hasSelectedText = q->hasSelectedText(); + int pixelSize = MDeviceProfile::instance()->ptToPixels(fontPointSize); + + // Since the QTextCharFormat doesn't have method for setting the font pixel size, updating the + // font pixel size using QFont::setPixelSize + if (!hasSelectedText) { + QTextCharFormat curFormat = textcursor.charFormat(); + QFont font = curFormat.font(); + font.setPixelSize(pixelSize); + + // QTextCharFormat::setFontPointSize() is required to retain font size during copy/paste + curFormat.setFontPointSize(fontPointSize); + curFormat.setFont(font); + + textcursor.setCharFormat(curFormat); + q->setTextCursor(textcursor); + return; + } + + // To avoid losing style, processing each character in the selection individually + int startPos = textcursor.selectionStart(); + int endPos = textcursor.selectionEnd(); + for (int i = startPos; i < endPos; i++) { + textcursor.setPosition(i); + // Setting the char format atBlockEnd applies it to the whole block, it is causing problem when the + // block has different styles, just skipping to set there. + if (textcursor.atBlockEnd()) { + continue; + } + // Selecting the current character. QTextCharFormat::setCharFormat doesn't applies the + // char format to an existing character if it is not selected. + textcursor.setPosition(i + 1, QTextCursor::KeepAnchor); + QTextCharFormat curFormat = textcursor.charFormat(); + QFont font = curFormat.font(); + font.setPixelSize(pixelSize); + + curFormat.setFontPointSize(fontPointSize); + curFormat.setFont(font); + textcursor.setCharFormat(curFormat); + } + + q->setTextCursor(textcursor); + + if (hasSelectedText) { + q->setSelection(startPos, endPos - startPos); + } +} + /////////////////////////////////////////////// // Actual class implementation diff --git a/src/corelib/widgets/mrichtextedit.h b/src/corelib/widgets/mrichtextedit.h index a177a0ab..dfc1c444 100644 --- a/src/corelib/widgets/mrichtextedit.h +++ b/src/corelib/widgets/mrichtextedit.h @@ -105,6 +105,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_updateStyle()) Q_PRIVATE_SLOT(d_func(), void _q_setFontFamily(const QString &)) + Q_PRIVATE_SLOT(d_func(), void _q_setFontSize(int)) Q_DISABLE_COPY(MRichTextEdit) diff --git a/src/corelib/widgets/mrichtextedit_p.h b/src/corelib/widgets/mrichtextedit_p.h index 15c32dc5..d0189f85 100644 --- a/src/corelib/widgets/mrichtextedit_p.h +++ b/src/corelib/widgets/mrichtextedit_p.h @@ -71,9 +71,11 @@ public: /*! * \brief gets the current text style values to be shown in the text styling ui */ - void textStyleValues(QString *fontfamily); + void textStyleValues(QString *fontfamily, int *fontPointSize); void _q_setFontFamily(const QString &fontFamily); + + void _q_setFontSize(int fontPointSize); }; #endif diff --git a/src/corelib/widgets/mrichtexteditdialogsmanager.cpp b/src/corelib/widgets/mrichtexteditdialogsmanager.cpp index c0d78202..3ea1a263 100644 --- a/src/corelib/widgets/mrichtexteditdialogsmanager.cpp +++ b/src/corelib/widgets/mrichtexteditdialogsmanager.cpp @@ -19,18 +19,150 @@ #include <QFontDatabase> #include <QStringListModel> +#include <QGraphicsSceneMouseEvent> #include <QDebug> +#include <MApplication> +#include <MApplicationWindow> +#include <MBasicListItem> #include <MComboBox> #include <MDialog> #include <MLayout> #include <MLinearLayoutPolicy> +#include <MSceneManager> #include "mrichtexteditdialogsmanager_p.h" MRichTextEditDialogsManager *MRichTextEditDialogsManager::dialogsManager = 0; +MRichTextEditFontStyleWidget::MRichTextEditFontStyleWidget(QGraphicsItem *parent) + : QGraphicsWidget(parent) +{ +} + + +MRichTextEditFontStyleWidget::~MRichTextEditFontStyleWidget() +{ +} + +void MRichTextEditFontStyleWidget::updateSize(int numRows, int numColumns) +{ + QSizeF boundingRect = maximumSize(); + // TODO: Yet to get the layout guide and need to align accordingly + static const int translateX = 10; + static const int translateY = 10; + static const int rectWidth = 70; + static const int rectHeight = 50; + + qreal width = numColumns * rectWidth; + qreal height = numRows * rectHeight; + + // Using 75% width and height of the parent (MDialog) + qreal boundingRectWidth = 0.75 * boundingRect.width(); + qreal boundingRectHeight = 0.75 * boundingRect.height(); + + qreal horizontalGapSize = (boundingRectWidth - width - translateX) / (numColumns + 1); + qreal verticalGapSize = (boundingRectHeight - height - translateY) / (numRows + 1); + + items.clear(); + int size = numRows * numColumns; + for (int index = 0; index < size; index++) { + QRectF rect; + rect.setX(translateX + ((index % numColumns) * horizontalGapSize) + + ((index % numColumns) * rectWidth)); + rect.setY(translateY + ((index / numColumns) * verticalGapSize) + + ((index / numColumns) * rectHeight)); + rect.setWidth(rectWidth); + rect.setHeight(rectHeight); + + items << rect; + } +} + + +void MRichTextEditFontStyleWidget::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + QPointF curPos = event->pos(); + event->accept(); + + int size = items.size(); + for (int index = 0; index < size; index++) { + if (items[index].contains(curPos)) { + selectItem(index); + update(); + break; + } + } +} + + +void MRichTextEditFontStyleWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + event->accept(); +} + + +MRichTextEditFontSizeWidget::MRichTextEditFontSizeWidget(const QList<int> &fontSizeValues, + QGraphicsItem *parent) + : MRichTextEditFontStyleWidget(parent), + sizeValues(fontSizeValues), + activeIndex(-1) +{ +} + + +MRichTextEditFontSizeWidget::~MRichTextEditFontSizeWidget() +{ +} + +void MRichTextEditFontSizeWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + QBrush brush(Qt::gray, Qt::SolidPattern); + painter->setBrush(brush); + + int size = items.size(); + for (int index = 0; index < size; index++) { + if (activeIndex == index) { + painter->drawRect(items[index]); + } else { + painter->fillRect(items[index], brush); + } + // Draw the font size value as text + painter->drawText(items[index], Qt::AlignCenter, QString::number(sizeValues[index])); + } +} + + +void MRichTextEditFontSizeWidget::selectItem(int index) +{ + if (index >= 0 && index < sizeValues.size()) { + activeIndex = index; + emit fontSizeSelected(sizeValues[index]); + } +} + + +void MRichTextEditFontSizeWidget::updateOrientation(M::Orientation orientation) +{ + Q_UNUSED(orientation); + + // Update the size of the items in the ui when the orientation changes + updateSize(sizeValues.size() / 4, 4); +} + + +void MRichTextEditFontSizeWidget::setActiveSize(int size) +{ + activeIndex = sizeValues.indexOf(size); +} + MRichTextEditDialogsManager::MRichTextEditDialogsManager() - : fontFamilyCombo(0) + : fontFamilyCombo(0), + fontSizeListItem(0), + fontSizeWidget(0) { } @@ -38,6 +170,7 @@ MRichTextEditDialogsManager::MRichTextEditDialogsManager() MRichTextEditDialogsManager::~MRichTextEditDialogsManager() { delete dialogs.textStyles.first; + delete dialogs.fontSize.first; } @@ -78,10 +211,114 @@ void MRichTextEditDialogsManager::initTextStylingDialog() connect(fontFamilyCombo, SIGNAL(activated(QString)), this, SIGNAL(fontFamilySelected(QString))); + + fontSizeListItem = new MBasicListItem(MBasicListItem::TitleWithSubtitle, centralWidget); + //% "Font size" + fontSizeData.titleName = qtTrId("qtn_comm_font_size"); + fontSizeListItem->setTitle(fontSizeData.titleName); + + fontSizeData.sizeValues << 8 << 9 << 10 << 11 + << 12 << 14 << 16 << 18 + << 20 << 22 << 24 << 26 + << 28 << 32 << 48 << 72; + + fontSizeListItem->setSubtitle(QString::number(fontSizeData.sizeValues[0])); + + connect(fontSizeListItem, SIGNAL(clicked()), + this, SLOT(showFontSizeDialog())); + policy->addItem(fontSizeListItem); +} + + +void MRichTextEditDialogsManager::initFontSizeDialog() +{ + if (dialogs.fontSize.first) { + return; + } + + dialogs.fontSize.first = new MDialog(); + dialogs.fontSize.first->setTitle(fontSizeData.titleName); + dialogs.fontSize.second = false; + + QGraphicsWidget *centralWidget = dialogs.fontSize.first->centralWidget(); + MLayout *layout = new MLayout(centralWidget); + MLinearLayoutPolicy *policy = new MLinearLayoutPolicy(layout, Qt::Vertical); + + fontSizeWidget = new MRichTextEditFontSizeWidget(fontSizeData.sizeValues, centralWidget); + policy->addItem(fontSizeWidget); + + connect(fontSizeWidget, SIGNAL(fontSizeSelected(int)), + SLOT(setFontSize(int))); +} + + +void MRichTextEditDialogsManager::showFontSizeDialog() +{ + initFontSizeDialog(); + + Q_ASSERT(MApplication::activeApplicationWindow()); + + const MSceneManager *sceneManager = MApplication::activeApplicationWindow()->sceneManager(); + + // Orientation could be changing when the font size widget is not active, so + // update the orientation change before showing the widget + updateFontSizeWidgetOrientation(sceneManager->orientation()); + + Q_ASSERT(fontSizeWidget); + + int activeSizeIndex = fontSizeData.activeSizeIndex; + if (activeSizeIndex >= 0 && activeSizeIndex < fontSizeData.sizeValues.size()) { + fontSizeWidget->setActiveSize(fontSizeData.sizeValues[activeSizeIndex]); + } else { + fontSizeWidget->setActiveSize(-1); + } + + // For getting the orientation change when the font size widget is active + connect(sceneManager, SIGNAL(orientationChanged(M::Orientation)), + SLOT(updateFontSizeWidgetOrientation(M::Orientation))); + + execDialog(&dialogs.fontSize); + + disconnect(sceneManager, SIGNAL(orientationChanged(M::Orientation)), + this, SLOT(updateFontSizeWidgetOrientation(M::Orientation))); } -void MRichTextEditDialogsManager::setTextStyleValues(const QString &fontfamily) +void MRichTextEditDialogsManager::updateFontSizeWidgetOrientation(M::Orientation orientation) +{ + Q_ASSERT(fontSizeWidget); + if (dialogs.fontSize.first) { + // Update the font widget size when the orientation changes + fontSizeWidget->setMinimumSize(dialogs.fontSize.first->maximumSize()); + fontSizeWidget->setMaximumSize(dialogs.fontSize.first->maximumSize()); + fontSizeWidget->updateOrientation(orientation); + } +} + + +void MRichTextEditDialogsManager::setFontSize(int fontSize) +{ + Q_ASSERT(fontSizeListItem); + + fontSizeData.activeSizeIndex = fontSizeData.sizeValues.indexOf(fontSize); + + if (fontSizeData.activeSizeIndex >= 0 && + fontSizeData.activeSizeIndex < fontSizeData.sizeValues.size()) { + int fontSize = fontSizeData.sizeValues[fontSizeData.activeSizeIndex]; + fontSizeListItem->setSubtitle(QString::number(fontSize)); + } else { + fontSizeListItem->setSubtitle(QString()); + } + + if (dialogs.fontSize.first) { + dialogs.fontSize.first->done(MDialog::Accepted); + } + + emit fontSizeSelected(fontSize); +} + + +void MRichTextEditDialogsManager::setTextStyleValues(const QString &fontfamily, int fontPointSize) { Q_ASSERT(fontFamilyCombo); @@ -93,6 +330,17 @@ void MRichTextEditDialogsManager::setTextStyleValues(const QString &fontfamily) } fontFamilyCombo->setCurrentIndex(familyIndex); + + Q_ASSERT(fontSizeListItem); + + fontSizeData.activeSizeIndex = fontSizeData.sizeValues.indexOf(fontPointSize); + if (fontSizeData.activeSizeIndex >= 0 && + fontSizeData.activeSizeIndex < fontSizeData.sizeValues.size()) { + int fontSize = fontSizeData.sizeValues[fontSizeData.activeSizeIndex]; + fontSizeListItem->setSubtitle(QString::number(fontSize)); + } else { + fontSizeListItem->setSubtitle(QString()); + } } @@ -107,10 +355,10 @@ void MRichTextEditDialogsManager::execDialog(ActiveDialog *activeDialog) } } -void MRichTextEditDialogsManager::showTextStylingDialog(const QString &fontfamily) +void MRichTextEditDialogsManager::showTextStylingDialog(const QString &fontfamily, int fontPointSize) { initTextStylingDialog(); - setTextStyleValues(fontfamily); + setTextStyleValues(fontfamily, fontPointSize); execDialog(&dialogs.textStyles); } diff --git a/src/corelib/widgets/mrichtexteditdialogsmanager_p.h b/src/corelib/widgets/mrichtexteditdialogsmanager_p.h index 652f5363..83752b7c 100644 --- a/src/corelib/widgets/mrichtexteditdialogsmanager_p.h +++ b/src/corelib/widgets/mrichtexteditdialogsmanager_p.h @@ -20,11 +20,77 @@ #ifndef MRICHTEXTEDITDIALOGSMANAGER_P_H #define MRICHTEXTEDITDIALOGSMANAGER_P_H +#include <QGraphicsWidget> #include <QPointer> #include <QPair> +#include <MNamespace> class MDialog; class MComboBox; +class MBasicListItem; + +// Rich text edit's FontStyle widget contains the implementation required for creating the +// ui of the font widgets (Font Size and Font Color widgets). It holds the items that +// are part of the font widgets' ui. +class MRichTextEditFontStyleWidget : public QGraphicsWidget +{ + Q_OBJECT + +public: + MRichTextEditFontStyleWidget(QGraphicsItem *parent = 0); + + ~MRichTextEditFontStyleWidget(); + + // Updates the ui for the given orientation + virtual void updateOrientation(M::Orientation orientation) = 0; + +protected: + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + + // Selects an item in the ui as current active item. /param index - item's index + virtual void selectItem(int index) = 0; + + // Updates the size of the ui items using \param numRows and \param numColumns + void updateSize(int numRows, int numColumns); + + // Each QRectF in the list represents an item in the ui + QList<QRectF> items; +}; + +class MRichTextEditFontSizeWidget : public MRichTextEditFontStyleWidget +{ + Q_OBJECT + +public: + MRichTextEditFontSizeWidget(const QList<int> &fontSizeValues, QGraphicsItem *parent = 0); + + ~MRichTextEditFontSizeWidget(); + + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + + virtual void updateOrientation(M::Orientation orientation); + + // Sets the current font size will be used for highlighting the corresponding item in the ui + void setActiveSize(int size); + +protected: + + virtual void selectItem(int index); + +Q_SIGNALS: + /** + * \brief Emitted whenever a font size is selected + */ + void fontSizeSelected(int fontSize); + +private: + // List of font size values shown in the ui + QList<int> sizeValues; + // Active item index used for highlighting + int activeIndex; +}; class MRichTextEditDialogsManager : public QObject { @@ -38,7 +104,7 @@ public: /*! * \brief shows the text styling dialog with the current style */ - void showTextStylingDialog(const QString &fontfamily = ""); + void showTextStylingDialog(const QString &fontfamily = "", int fontPointSize = -1); Q_SIGNALS: @@ -47,6 +113,17 @@ Q_SIGNALS: */ void fontFamilySelected(const QString &fontFamily); + /** + * \brief Emitted whenever a font size is selected + */ + void fontSizeSelected(int fontPointSize); + +private Q_SLOTS: + + void setFontSize(int fontSize); + void showFontSizeDialog(); + void updateFontSizeWidgetOrientation(M::Orientation orientation); + private: // QPointer<MDialog> in ActiveDialog will hold a dialog // bool in ActiveDialog is used to avoid calling its dialog's exec() when it is active @@ -65,9 +142,13 @@ private: */ void initTextStylingDialog(); /*! + * \brief initializes the FontSize dialog + */ + void initFontSizeDialog(); + /*! * \brief updates the ui components of the TextStyles dialog to show the current style */ - void setTextStyleValues(const QString &fontfamily); + void setTextStyleValues(const QString &fontfamily, int fontPointSize); /*! * \brief launches the dialog of given type */ @@ -78,10 +159,21 @@ private: struct Dialogs { ActiveDialog textStyles; + ActiveDialog fontSize; }; Dialogs dialogs; + struct FontSizeData + { + QList<int> sizeValues; + QString titleName; + int activeSizeIndex; + }; + FontSizeData fontSizeData; + MComboBox *fontFamilyCombo; + MBasicListItem *fontSizeListItem; + MRichTextEditFontSizeWidget *fontSizeWidget; }; #endif |