MDIApplication Example

#include <QApplication>
#include <QMessageBox>
#include <QTextStream>
#include <QClipboard>
#include <QFileDialog>
#include <QFontComboBox>
#include <QTextList>
#include <QActionGroup>
#include <qevent.h>

#include <QtitanRibbon.h>

#include "texteditchild.h"

/* TextEditChildPrivate */
class TextEditChildPrivate
{
public:
    TextEditChildPrivate(TextEditChild* p);
public:
    RibbonPage* m_pageHome;
public:
    static int m_currentPageIndex;
private:
    TextEditChild* m_parent;
};

int TextEditChildPrivate::m_currentPageIndex = -1;
TextEditChildPrivate::TextEditChildPrivate(TextEditChild* p)
    : m_parent(p)
{
    Q_UNUSED(m_parent);
}

//#undef m_pimpl
//#define m_pimpl this->m_pimpl

/* TextEditChild */
TextEditChild::TextEditChild()
{
    setWindowIcon(QIcon(QStringLiteral(":/res/editorchild.png")));
    m_pimpl = new TextEditChildPrivate(this);
    setAttribute(Qt::WA_DeleteOnClose);
    m_isUntitled = true;

    createActions();

    connect(this, SIGNAL(currentCharFormatChanged(QTextCharFormat)), this, SLOT(currentCharFormatChanged(QTextCharFormat)));
    connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(cursorPositionChanged()));

    m_actionCut->setEnabled(false);
    m_actionCopy->setEnabled(false);

    connect(m_actionCut, SIGNAL(triggered()), this, SLOT(cut()));
    connect(m_actionCopy, SIGNAL(triggered()), this, SLOT(copy()));
    connect(m_actionPaste, SIGNAL(triggered()), this, SLOT(paste()));

    connect(this, SIGNAL(copyAvailable(bool)), m_actionCut, SLOT(setEnabled(bool)));
    connect(this, SIGNAL(copyAvailable(bool)), m_actionCopy, SLOT(setEnabled(bool)));

#ifndef QT_NO_CLIPBOARD
    connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(clipboardDataChanged()));
#endif
}

TextEditChild::~TextEditChild()
{
    delete m_pimpl;
}

void TextEditChild::buildUserInterface(RibbonBar* rib, QStatusBar* statusBar, RibbonPage* pageHome)
{
    Q_UNUSED(statusBar);
    Q_UNUSED(pageHome);
    m_pimpl->m_pageHome = rib->insertPage(0, tr("&Home"));
    createGroupClipboard(m_pimpl->m_pageHome);
    createGroupFont(m_pimpl->m_pageHome);
    createGroupParagraph(m_pimpl->m_pageHome);
//        createGroupEditing(page);
    fontChanged(font());
    colorChanged(this->QTextEdit::textColor());
    alignmentChanged(alignment());

    if (!rib->isMinimized())
    {
        int pageIndex = m_pimpl->m_currentPageIndex != -1 ? m_pimpl->m_currentPageIndex : 0;
        rib->setCurrentPageIndex(pageIndex);
    }
}

void TextEditChild::removeUserInterface(RibbonBar* rib, QStatusBar* statusBar, RibbonPage* pageHome)
{
    Q_UNUSED(statusBar);
    Q_UNUSED(pageHome);
    if (m_pimpl->m_pageHome)
    {
        m_pimpl->m_currentPageIndex = rib->currentPageIndex();
        rib->removePage(m_pimpl->m_pageHome);
        m_pimpl->m_pageHome = Q_NULL;
    }
}

void TextEditChild::newFile()
{
    static int sequenceNumber = 1;

    m_isUntitled = true;
    m_curFile = tr("document%1.txt").arg(sequenceNumber++);
    setWindowTitle(m_curFile + QStringLiteral("[*]"));

    connect(document(), SIGNAL(contentsChanged()), this, SLOT(documentWasModified()));
}

bool TextEditChild::loadFile(const QString &fileName)
{
    QFile file(fileName);
    if (!file.open(QFile::ReadOnly | QFile::Text))
    {
        QMessageBox::warning(this, tr("MDI"), tr("Cannot read file %1:\n%2.")
                             .arg(fileName).arg(file.errorString()));
        return false;
    }

    QTextStream in(&file);
    QApplication::setOverrideCursor(Qt::WaitCursor);
    setPlainText(in.readAll());
    QApplication::restoreOverrideCursor();

    setCurrentFile(fileName);
    connect(document(), SIGNAL(contentsChanged()),this, SLOT(documentWasModified()));
    return true;
}

bool TextEditChild::save()
{
    if (m_isUntitled)
        return saveAs();
    else
        return saveFile(m_curFile);
}

bool TextEditChild::saveAs()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), m_curFile);
    if (fileName.isEmpty())
        return false;
    return saveFile(fileName);
}

bool TextEditChild::saveFile(const QString &fileName)
{
    QFile file(fileName);
    if (!file.open(QFile::WriteOnly | QFile::Text))
    {
        QMessageBox::warning(this, tr("MDI"), tr("Cannot write file %1:\n%2.")
                             .arg(fileName).arg(file.errorString()));
        return false;
    }

    QTextStream out(&file);
    QApplication::setOverrideCursor(Qt::WaitCursor);
    out << toPlainText();
    QApplication::restoreOverrideCursor();
    setCurrentFile(fileName);
    return true;
}

QString TextEditChild::userFriendlyCurrentFile()
{
    return strippedName(m_curFile);
}

bool TextEditChild::hasSelection() const
{
    return textCursor().hasSelection();
}

void TextEditChild::createActions()
{
    m_actionPaste = new QAction(QIcon(QStringLiteral(":/res/paste.png")), tr("&Paste"), this);
    m_actionPaste->setPriority(QAction::LowPriority);
    m_actionPaste->setShortcut(QKeySequence::Paste);
    m_actionCut = new QAction(QIcon(QStringLiteral(":/res/smallcut.png")), tr("&Cut"), this);
    m_actionCut->setShortcut(QKeySequence::Cut);
    m_actionCopy = new QAction(QIcon(QStringLiteral(":/res/smallcopy.png")), tr("&Copy"), this);
    m_actionCopy->setShortcut(QKeySequence::Copy);
    m_actionFormatPointer = new QAction(QIcon(QStringLiteral(":/res/smallformatpainter.png")), tr("&Format Pointer"), this);

    m_actionTextBold = new QAction(QIcon(QStringLiteral(":/res/smalltextbold.png")), tr("&Bold"), this);
    m_actionTextBold->setShortcut(Qt::CTRL + Qt::Key_B);
    m_actionTextBold->setPriority(QAction::LowPriority);
    QFont bold;
    bold.setBold(true);
    m_actionTextBold->setFont(bold);
    connect(m_actionTextBold, SIGNAL(triggered()), this, SLOT(textBold()));
    m_actionTextBold->setCheckable(true);

    m_actionTextItalic = new QAction(QIcon(QStringLiteral(":/res/smalltextitalic.png")), tr("&Italic"), this);
    m_actionTextItalic->setPriority(QAction::LowPriority);
    m_actionTextItalic->setShortcut(Qt::CTRL + Qt::Key_I);
    QFont italic;
    italic.setItalic(true);
    m_actionTextItalic->setFont(italic);
    connect(m_actionTextItalic, SIGNAL(triggered()), this, SLOT(textItalic()));
    m_actionTextItalic->setCheckable(true);

    m_actionTextUnderline = new QAction(QIcon(QStringLiteral(":/res/smalltextunder.png")), tr("&Underline"), this);
    m_actionTextUnderline->setShortcut(Qt::CTRL + Qt::Key_U);
    m_actionTextUnderline->setPriority(QAction::LowPriority);
    QFont underline;
    underline.setUnderline(true);
    m_actionTextUnderline->setFont(underline);
    connect(m_actionTextUnderline, SIGNAL(triggered()), this, SLOT(textUnderline()));
    m_actionTextUnderline->setCheckable(true);

    QActionGroup *grp = new QActionGroup(this);
    connect(grp, SIGNAL(triggered(QAction*)), this, SLOT(textAlign(QAction*)));

    m_actionAlignLeft = new QAction(QIcon(QStringLiteral(":/res/smallalignleft.png")), tr("Align Left"), this);
    m_actionAlignLeft->setActionGroup(grp);
    m_actionAlignLeft->setShortcut(Qt::CTRL + Qt::Key_L);
    m_actionAlignLeft->setCheckable(true);
    m_actionAlignLeft->setPriority(QAction::LowPriority);

    m_actionAlignCenter = new QAction(QIcon(QStringLiteral(":/res/smallcenter.png")), tr("Center"), this);
    m_actionAlignCenter->setActionGroup(grp);
    m_actionAlignCenter->setShortcut(Qt::CTRL + Qt::Key_E);
    m_actionAlignCenter->setCheckable(true);
    m_actionAlignCenter->setPriority(QAction::LowPriority);

    m_actionAlignRight = new QAction(QIcon(QStringLiteral(":/res/smallalignright.png")), tr("Align Right"), this);
    m_actionAlignRight->setActionGroup(grp);
    m_actionAlignRight->setShortcut(Qt::CTRL + Qt::Key_R);
    m_actionAlignRight->setCheckable(true);
    m_actionAlignRight->setPriority(QAction::LowPriority);

    m_actionAlignJustify = new QAction(QIcon(QStringLiteral(":/res/smalljustify.png")), tr("Justify"), this);
    m_actionAlignJustify->setActionGroup(grp);
    m_actionAlignJustify->setShortcut(Qt::CTRL + Qt::Key_J);
    m_actionAlignJustify->setCheckable(true);
    m_actionAlignJustify->setPriority(QAction::LowPriority);
}

void TextEditChild::createGroupClipboard(RibbonPage* page)
{
    RibbonGroup * groupClipboard = page->addGroup(tr("Clipboard"));
#ifndef QT_NO_CLIPBOARD
    m_actionPaste->setEnabled(!QApplication::clipboard()->text().isEmpty());
#endif
    groupClipboard->addAction(m_actionPaste, Qt::ToolButtonTextUnderIcon);
    RibbonControl* control = groupClipboard->controlByAction(m_actionPaste);
    control->sizeDefinition(RibbonControlSizeDefinition::GroupLarge)->setImageSize(RibbonControlSizeDefinition::ImageLarge);
    control->sizeDefinition(RibbonControlSizeDefinition::GroupMedium)->setImageSize(RibbonControlSizeDefinition::ImageLarge);
    control->sizeDefinition(RibbonControlSizeDefinition::GroupSmall)->setImageSize(RibbonControlSizeDefinition::ImageLarge);
    m_actionPaste->setPriority(QAction::LowPriority);
    m_actionPaste->setShortcut(QKeySequence::Paste);
    m_actionPaste->setToolTip(tr("Insert Clipboard contents"));

    groupClipboard->addAction(m_actionCut, Qt::ToolButtonTextBesideIcon);
    control = groupClipboard->controlByAction(m_actionCut);
    control->sizeDefinition(RibbonControlSizeDefinition::GroupLarge)->setImageSize(RibbonControlSizeDefinition::ImageSmall);
    control->sizeDefinition(RibbonControlSizeDefinition::GroupMedium)->setImageSize(RibbonControlSizeDefinition::ImageSmall);
    control->sizeDefinition(RibbonControlSizeDefinition::GroupSmall)->setImageSize(RibbonControlSizeDefinition::ImageSmall);
    control->sizeDefinition(RibbonControlSizeDefinition::GroupPopup)->setImageSize(RibbonControlSizeDefinition::ImageSmall);
    m_actionCut->setShortcut(QKeySequence::Cut);
    m_actionCut->setToolTip(tr("Cut the selection and put it on the Clipboard"));

    groupClipboard->addAction(m_actionCopy, Qt::ToolButtonTextBesideIcon);
    control = groupClipboard->controlByAction(m_actionCopy);
    control->sizeDefinition(RibbonControlSizeDefinition::GroupLarge)->setImageSize(RibbonControlSizeDefinition::ImageSmall);
    control->sizeDefinition(RibbonControlSizeDefinition::GroupMedium)->setImageSize(RibbonControlSizeDefinition::ImageSmall);
    control->sizeDefinition(RibbonControlSizeDefinition::GroupSmall)->setImageSize(RibbonControlSizeDefinition::ImageSmall);
    control->sizeDefinition(RibbonControlSizeDefinition::GroupPopup)->setImageSize(RibbonControlSizeDefinition::ImageSmall);
    m_actionCopy->setShortcut(QKeySequence::Copy);

    groupClipboard->addAction(m_actionFormatPointer, Qt::ToolButtonTextBesideIcon);
    control = groupClipboard->controlByAction(m_actionFormatPointer);
    control->sizeDefinition(RibbonControlSizeDefinition::GroupLarge)->setImageSize(RibbonControlSizeDefinition::ImageSmall);
    control->sizeDefinition(RibbonControlSizeDefinition::GroupMedium)->setImageSize(RibbonControlSizeDefinition::ImageSmall);
    control->sizeDefinition(RibbonControlSizeDefinition::GroupSmall)->setImageSize(RibbonControlSizeDefinition::ImageSmall);
    control->sizeDefinition(RibbonControlSizeDefinition::GroupPopup)->setImageSize(RibbonControlSizeDefinition::ImageSmall);
    m_actionFormatPointer->setEnabled(false);
}

void TextEditChild::createGroupFont(RibbonPage* page)
{
    RibbonGroup* fontGroup = page->addGroup(tr("Font"));
    RibbonToolBarControl* toolBar = new RibbonToolBarControl(fontGroup);
    m_comboFont = new QFontComboBox(fontGroup);
    toolBar->addWidget(m_comboFont);
    connect(m_comboFont, SIGNAL(activated(QString)), this, SLOT(textFamily(QString)));

    m_comboSize = new QComboBox(fontGroup);
    toolBar->addWidget(m_comboSize);
    m_comboSize->setEditable(true);
    QFontDatabase db;
    foreach(int size, db.standardSizes())
        m_comboSize->addItem(QString::number(size));

    connect(m_comboSize, SIGNAL(activated(QString)), this, SLOT(textSize(QString)));
    m_comboSize->setCurrentIndex(m_comboSize->findText(QString::number(QApplication::font().pointSize())));

    toolBar->addSeparator();
    toolBar->addAction(QIcon(QStringLiteral(":/res/smallfontgrow.png")), tr("Grow Font"), Qt::ToolButtonIconOnly);
    toolBar->addAction(QIcon(QStringLiteral(":/res/smallfontshrink.png")), tr("Shrink Font"), Qt::ToolButtonIconOnly);
    toolBar->addSeparator();
    toolBar->addAction(QIcon(QStringLiteral(":/res/smallfontclear.png")), tr("&Clear Formatting"), Qt::ToolButtonIconOnly);
    toolBar->addSeparator();

    toolBar->addAction(m_actionTextBold , Qt::ToolButtonIconOnly);
    toolBar->addAction(m_actionTextItalic, Qt::ToolButtonIconOnly);
    toolBar->addAction(m_actionTextUnderline, Qt::ToolButtonIconOnly);

    QAction* pCharStrikethrough = toolBar->addAction(QIcon(QStringLiteral(":/res/smallstrikethrough.png")), tr("Strikethrough"), Qt::ToolButtonIconOnly);
    pCharStrikethrough->setEnabled(false);
    toolBar->addSeparator();
    QAction* pTextSubscript = toolBar->addAction(QIcon(QStringLiteral(":/res/smallsubscript.png")), tr("Subscript"), Qt::ToolButtonIconOnly);
    pTextSubscript->setEnabled(false);
    QAction* pTextSuperscript = toolBar->addAction(QIcon(QStringLiteral(":/res/smallsuperscript.png")), tr("Superscript"), Qt::ToolButtonIconOnly);
    pTextSuperscript->setEnabled(false);
    QAction* pTextChangecase = toolBar->addAction(QIcon(QStringLiteral(":/res/smallchangecase.png")), tr("Change Case"), Qt::ToolButtonIconOnly);
    pTextChangecase->setEnabled(false);

    toolBar->addSeparator();

    PopupColorButton* highlightColorButton = new PopupColorButton();
    QAction* textHighlightcolor = toolBar->addWidget(QIcon(QStringLiteral(":/res/smallcolor.png")), tr("Highlight Color"), highlightColorButton);
    highlightColorButton->setDefaultAction(textHighlightcolor);
    textHighlightcolor->setEnabled(false);

    m_colorButton = new PopupColorButton();
    m_actionTextColor = toolBar->addWidget(QIcon(QStringLiteral(":/res/smallcolor.png")), tr("Color"), m_colorButton);
    m_colorButton->setDefaultAction(m_actionTextColor);
    connect(m_colorButton, SIGNAL(colorChanged(const QColor&)), this, SLOT(textColor(const QColor&)));
    connect(m_actionTextColor, SIGNAL(triggered()), this, SLOT(setColorText()));
    fontGroup->addControl(toolBar);
}

void TextEditChild::createGroupParagraph(RibbonPage* page)
{
    RibbonGroup * paragraphGroup = page->addGroup(tr("&Paragraph"));
    RibbonToolBarControl* toolBar = new RibbonToolBarControl(paragraphGroup);
    paragraphGroup->setContentAlignment(Qt::AlignVCenter);

    QMenu * pMenu = new QMenu(this);
    toolBar->addAction(QIcon(QStringLiteral(":/res/smallbullets.png")), tr("Bullets"), Qt::ToolButtonIconOnly, pMenu);
    toolBar->addAction(QIcon(QStringLiteral(":/res/smallnumbering.png")), tr("Numbering"), Qt::ToolButtonIconOnly, pMenu);
    toolBar->addAction(QIcon(QStringLiteral(":/res/smallmultilevellist.png")), tr("Multilevel List"), Qt::ToolButtonIconOnly, pMenu);
    toolBar->addSeparator();
    toolBar->addAction(QIcon(QStringLiteral(":/res/smalldecreaseindent.png")), tr("Decrease Indent"), Qt::ToolButtonIconOnly);
    toolBar->addAction(QIcon(QStringLiteral(":/res/smallincreaseindent.png")), tr("Increase Indent"), Qt::ToolButtonIconOnly);
    toolBar->addSeparator();
    toolBar->addAction(QIcon(QStringLiteral(":/res/smallsort.png")), tr("Sort"), Qt::ToolButtonIconOnly);
    toolBar->addAction(QIcon(QStringLiteral(":/res/smallshow_hide_marks.png")), tr("Show/Hide Marks"), Qt::ToolButtonIconOnly);
    toolBar->addSeparator();
    QActionGroup *grp = new QActionGroup(this);
    connect(grp, SIGNAL(triggered(QAction*)), this, SLOT(textAlign(QAction*)));

    toolBar->addAction(m_actionAlignLeft, Qt::ToolButtonIconOnly);
    toolBar->addAction(m_actionAlignCenter, Qt::ToolButtonIconOnly);
    toolBar->addAction(m_actionAlignRight, Qt::ToolButtonIconOnly);
    toolBar->addAction(m_actionAlignJustify, Qt::ToolButtonIconOnly);

    toolBar->addSeparator();
    toolBar->addAction(QIcon(QStringLiteral(":/res/smalllinespacing.png")), tr("Line spacing"), Qt::ToolButtonIconOnly);
    toolBar->addSeparator();
    toolBar->addAction(QIcon(QStringLiteral(":/res/smallshading.png")), tr("Shading"), Qt::ToolButtonIconOnly, pMenu);
    toolBar->addSeparator();
    toolBar->addAction(QIcon(QStringLiteral(":/res/smallnoborder.png")), tr("No Border"), Qt::ToolButtonIconOnly, pMenu);
    paragraphGroup->addControl(toolBar);
}

void TextEditChild::closeEvent(QCloseEvent *event)
{
    if (maybeSave())
        event->accept();
    else
        event->ignore();
}

void TextEditChild::textBold()
{
    QTextCharFormat fmt;
    fmt.setFontWeight(m_actionTextBold->isChecked() ? QFont::Bold : QFont::Normal);
    mergeFormatOnWordOrSelection(fmt);
}

void TextEditChild::textUnderline()
{
    QTextCharFormat fmt;
    fmt.setFontUnderline(m_actionTextUnderline->isChecked());
    mergeFormatOnWordOrSelection(fmt);
}

void TextEditChild::textItalic()
{
    QTextCharFormat fmt;
    fmt.setFontItalic(m_actionTextItalic->isChecked());
    mergeFormatOnWordOrSelection(fmt);
}

void TextEditChild::textFamily(const QString &f)
{
    QTextCharFormat fmt;
    fmt.setFontFamily(f);
    mergeFormatOnWordOrSelection(fmt);
}

void TextEditChild::textSize(const QString &p)
{
    qreal pointSize = p.toFloat();
    if (p.toFloat() > 0) {
        QTextCharFormat fmt;
        fmt.setFontPointSize(pointSize);
        mergeFormatOnWordOrSelection(fmt);
    }
}

void TextEditChild::textStyle(int styleIndex)
{
    QTextCursor cursor = textCursor();
    if (styleIndex != 0)
    {
        QTextListFormat::Style style = QTextListFormat::ListDisc;
        switch (styleIndex)
        {
            default:
            case 1:
                style = QTextListFormat::ListDisc;
                break;
            case 2:
                style = QTextListFormat::ListCircle;
                break;
            case 3:
                style = QTextListFormat::ListSquare;
                break;
            case 4:
                style = QTextListFormat::ListDecimal;
                break;
            case 5:
                style = QTextListFormat::ListLowerAlpha;
                break;
            case 6:
                style = QTextListFormat::ListUpperAlpha;
                break;
            case 7:
                style = QTextListFormat::ListLowerRoman;
                break;
            case 8:
                style = QTextListFormat::ListUpperRoman;
                break;
        }

        cursor.beginEditBlock();

        QTextBlockFormat blockFmt = cursor.blockFormat();

        QTextListFormat listFmt;
        if (cursor.currentList())
        {
            listFmt = cursor.currentList()->format();
        }
        else
        {
            listFmt.setIndent(blockFmt.indent() + 1);
            blockFmt.setIndent(0);
            cursor.setBlockFormat(blockFmt);
        }

        listFmt.setStyle(style);

        cursor.createList(listFmt);

        cursor.endEditBlock();
    }
    else
    {
        // ####
        QTextBlockFormat bfmt;
        bfmt.setObjectIndex(-1);
        cursor.mergeBlockFormat(bfmt);
    }
}

void TextEditChild::textColor(const QColor& col)
{
    if (!col.isValid())
        return;
    QTextCharFormat fmt;
    fmt.setForeground(col);
    mergeFormatOnWordOrSelection(fmt);
    colorChanged(col);
}

void TextEditChild::setColorText()
{
    textColor(m_colorButton->color());
}

void TextEditChild::textAlign(QAction *a)
{
    if (a == m_actionAlignLeft)
        setAlignment(Qt::AlignLeft | Qt::AlignAbsolute);
    else if (a == m_actionAlignCenter)
        setAlignment(Qt::AlignHCenter);
    else if (a == m_actionAlignRight)
        setAlignment(Qt::AlignRight | Qt::AlignAbsolute);
    else if (a == m_actionAlignJustify)
        setAlignment(Qt::AlignJustify);
}

void TextEditChild::selectAll()
{
    QTextEdit::selectAll();
}

void TextEditChild::currentCharFormatChanged(const QTextCharFormat &format)
{
    fontChanged(format.font());
}

void TextEditChild::cursorPositionChanged()
{
    alignmentChanged(alignment());
}

void TextEditChild::documentWasModified()
{
    setWindowModified(document()->isModified());
}

void TextEditChild::clipboardDataChanged()
{
#ifndef QT_NO_CLIPBOARD
    m_actionPaste->setEnabled(!QApplication::clipboard()->text().isEmpty());
    m_actionPaste->setEnabled(!QApplication::clipboard()->text().isEmpty());
#endif
}

void TextEditChild::mergeFormatOnWordOrSelection(const QTextCharFormat& format)
{
    QTextCursor cursor = textCursor();
    if (!cursor.hasSelection())
        cursor.select(QTextCursor::WordUnderCursor);
    cursor.mergeCharFormat(format);
    mergeCurrentCharFormat(format);
}

void TextEditChild::colorChanged(const QColor& c)
{
    m_colorButton->setColor(c);
}

void TextEditChild::fontChanged(const QFont& f)
{
    m_comboFont->setCurrentIndex(m_comboFont->findText(QFontInfo(f).family()));
    m_comboSize->setCurrentIndex(m_comboSize->findText(QString::number(f.pointSize())));
    m_actionTextBold->setChecked(f.bold());
    m_actionTextItalic->setChecked(f.italic());
    m_actionTextUnderline->setChecked(f.underline());
}

bool TextEditChild::maybeSave()
{
    if (document()->isModified())
    {
        QMessageBox::StandardButton ret;
        ret = QMessageBox::warning(this, tr("MDI"), tr("'%1' has been modified.\n"
                        "Do you want to save your changes?").arg(userFriendlyCurrentFile()),
            QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
        if (ret == QMessageBox::Save)
            return save();
        else if (ret == QMessageBox::Cancel)
            return false;
    }
    return true;
}

void TextEditChild::setCurrentFile(const QString &fileName)
{
    m_curFile = QFileInfo(fileName).canonicalFilePath();
    m_isUntitled = false;
    document()->setModified(false);
    setWindowModified(false);
    setWindowTitle(userFriendlyCurrentFile() + QStringLiteral("[*]"));
}

QString TextEditChild::strippedName(const QString &fullFileName)
{
    return QFileInfo(fullFileName).fileName();
}

void TextEditChild::alignmentChanged(Qt::Alignment a)
{
    if (a & Qt::AlignLeft)
        m_actionAlignLeft->setChecked(true);
    else if (a & Qt::AlignHCenter)
        m_actionAlignCenter->setChecked(true);
    else if (a & Qt::AlignRight)
        m_actionAlignRight->setChecked(true);
    else if (a & Qt::AlignJustify)
        m_actionAlignJustify->setChecked(true);
}

//#undef m_pimpl