MDIApplication Example
#include <QApplication>
#include <QScreen>
#include <QSignalMapper>
#include <QTabBar>
#include <QMdiSubWindow>
#include <QFileDialog>
#include <QPainter>
#include <QButtonGroup>
#include <QCheckBox>
#include <QRadioButton>
#include <QSettings>
#include "mainwindow.h"
#include "texteditchild.h"
#include "sketchchild.h"
#include "aboutdialog.h"
MainWindow::MainWindow()
: DemoRibbonWindow(Q_NULL)
{
m_typeDocCurrent = ChildInterface::td_None;
m_childCurrent = Q_NULL;
m_mdiArea = new QMdiArea(this);
#if (QT_VERSION >= QT_VERSION_CHECK(4, 8, 0))
m_mdiArea->setTabsClosable(true);
#endif
m_mdiArea->setLineWidth(3);
m_mdiArea->setFrameShape(QFrame::Panel);
m_mdiArea->setFrameShadow(QFrame::Sunken);
m_mdiArea->setViewMode(QMdiArea::TabbedView);
qApp->installEventFilter(this);
m_mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
m_mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
setCentralWidget(m_mdiArea);
connect(m_mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(updateMenus()));
connect(m_mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(subWindowActivated(QMdiSubWindow*)));
m_windowMapper = new QSignalMapper(this);
connect(m_windowMapper, SIGNAL(mapped(QWidget*)), this, SLOT(setActiveSubWindow(QWidget*)));
createActions();
createMenuFile();
createRibbon();
createStatusBar();
updateMenus();
setWindowTitle(tr("Ribbon MDI"));
setUnifiedTitleAndToolBarOnMac(true);
setFrameThemeEnabled(true);
m_stateWindow = windowState();
setDefaultWidgetGeometry(this);
RibbonCustomizeManager* customizeManager = ribbonBar()->customizeManager();
customizeManager->setDefaultState();
readSettings();
}
MainWindow::~MainWindow()
{
writeSettings();
}
bool MainWindow::eventFilter(QObject* obj, QEvent* event)
{
switch(event->type())
{
case QEvent::ChildRemoved :
if (QChildEvent* pEvent= static_cast<QChildEvent*>(event))
{
if (qobject_cast<QMdiSubWindow*>(pEvent->child()) && m_childCurrent && m_mdiArea->subWindowList().size() == 1)
{
if (ChildInterface* ifOldChild = qobject_cast<ChildInterface*>(m_childCurrent))
ifOldChild->removeUserInterface(ribbonBar(), statusBar(), Q_NULL);
m_childCurrent = Q_NULL;
m_typeDocCurrent = ChildInterface::td_None;
}
}
break;
default:
break;
}
return RibbonMainWindow::eventFilter(obj, event);
}
void MainWindow::closeEvent(QCloseEvent* event)
{
m_mdiArea->closeAllSubWindows();
if (m_mdiArea->currentSubWindow())
{
event->ignore();
}
else
{
event->accept();
}
}
void MainWindow::newTextFile()
{
TextEditChild* child = createMdiTextChild();
child->newFile();
child->show();
}
void MainWindow::newSketchFile()
{
SketchChild* child = createSketchChild();
child->newFile();
child->show();
}
void MainWindow::open()
{
QString fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty())
{
QMdiSubWindow* existing = findMdiChild(fileName);
if (existing)
{
m_mdiArea->setActiveSubWindow(existing);
return;
}
TextEditChild* child = createMdiTextChild();
if (child->loadFile(fileName))
{
statusBar()->showMessage(tr("File loaded"), 2000);
child->show();
}
else
{
child->close();
}
}
}
void MainWindow::save()
{
ChildInterface* ifChild = qobject_cast<ChildInterface*>(activeMdiChild());
if (ifChild && ifChild->save())
statusBar()->showMessage(tr("File saved"), 2000);
}
void MainWindow::saveAs()
{
ChildInterface* ifChild = qobject_cast<ChildInterface*>(activeMdiChild());
if (ifChild && ifChild->saveAs())
statusBar()->showMessage(tr("File saved"), 2000);
}
void MainWindow::cut()
{
TextEditChild* txtChild = qobject_cast<TextEditChild*>(activeMdiChild());
if (txtChild)
txtChild->cut();
}
void MainWindow::copy()
{
TextEditChild* txtChild = qobject_cast<TextEditChild*>(activeMdiChild());
if (txtChild)
txtChild->copy();
}
void MainWindow::paste()
{
TextEditChild* txtChild = qobject_cast<TextEditChild*>(activeMdiChild());
if (txtChild)
txtChild->paste();
}
void MainWindow::updateMenus()
{
bool hasMdiChild = (activeMdiChild() != Q_NULL);
m_saveAct->setEnabled(hasMdiChild);
m_saveAsAct->setEnabled(hasMdiChild);
m_closeAct->setEnabled(hasMdiChild);
m_closeAllAct->setEnabled(hasMdiChild);
m_cascadeAct->setEnabled(hasMdiChild);
m_nextAct->setEnabled(hasMdiChild);
m_previousAct->setEnabled(hasMdiChild);
}
void MainWindow::updateWindowMenu()
{
m_windowMenu->clear();
QList<QMdiSubWindow*> windows = m_mdiArea->subWindowList();
for (int i = 0; i < windows.size(); ++i)
{
QWidget* child = windows.at(i)->widget();
if(!child)
continue;
ChildInterface* ifChild = qobject_cast<ChildInterface*>(child);
if(!ifChild)
continue;
QString text;
if (i < 9)
text = tr("&%1 %2").arg(i + 1).arg(ifChild->userFriendlyCurrentFile());
else
text = tr("%1 %2").arg(i + 1).arg(ifChild->userFriendlyCurrentFile());
QAction* action = m_windowMenu->addAction(text);
action->setCheckable(true);
action ->setChecked(child == activeMdiChild());
connect(action, SIGNAL(triggered()), m_windowMapper, SLOT(map()));
m_windowMapper->setMapping(action, windows.at(i));
}
}
TextEditChild* MainWindow::createMdiTextChild()
{
TextEditChild* child = new TextEditChild;
m_mdiArea->addSubWindow(child);
return child;
}
SketchChild* MainWindow::createSketchChild()
{
SketchChild* pChild = new SketchChild();
Q_ASSERT(pChild != Q_NULL);
QMdiSubWindow* subChild = m_mdiArea->addSubWindow(pChild);
Q_ASSERT(subChild != Q_NULL);
Q_UNUSED(subChild);
return pChild;
}
void MainWindow::createActions()
{
m_newTextAct = new QAction(QIcon(QStringLiteral(":/res/textedit.png")), tr("&Text Edit"), this);
m_newTextAct->setStatusTip(tr("Create a new file"));
connect(m_newTextAct, SIGNAL(triggered()), this, SLOT(newTextFile()));
m_newSketchAct = new QAction(QIcon(QStringLiteral(":/res/sketch.png")), tr("&Skcetch Edit"), this);
m_newSketchAct->setStatusTip(tr("Create a new file"));
connect(m_newSketchAct, SIGNAL(triggered()), this, SLOT(newSketchFile()));
m_openAct = new QAction(QIcon(QStringLiteral(":/res/open.png")), tr("&Open..."), this);
m_openAct->setShortcuts(QKeySequence::Open);
m_openAct->setStatusTip(tr("Open an existing file"));
connect(m_openAct, SIGNAL(triggered()), this, SLOT(open()));
m_saveAct = new QAction(QIcon(QStringLiteral(":/res/save.png")), tr("&Save"), this);
m_saveAct->setShortcuts(QKeySequence::Save);
m_saveAct->setStatusTip(tr("Save the document to disk"));
connect(m_saveAct, SIGNAL(triggered()), this, SLOT(save()));
m_saveAsAct = new QAction(tr("Save &As..."), this);
m_saveAsAct->setShortcuts(QKeySequence::SaveAs);
m_saveAsAct->setStatusTip(tr("Save the document under a new name"));
connect(m_saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));
m_exitAct = new QAction(tr("E&xit"), this);
m_exitAct->setShortcuts(QKeySequence::Quit);
m_exitAct->setStatusTip(tr("Exit the application"));
connect(m_exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));
m_closeAct = new QAction(QIcon(QStringLiteral(":/res/close.png")), tr("Cl&ose"), this);
m_closeAct->setStatusTip(tr("Close the active window"));
connect(m_closeAct, SIGNAL(triggered()), m_mdiArea, SLOT(closeActiveSubWindow()));
m_closeAllAct = new QAction(tr("Close &All"), this);
m_closeAllAct->setStatusTip(tr("Close all the windows"));
connect(m_closeAllAct, SIGNAL(triggered()), m_mdiArea, SLOT(closeAllSubWindows()));
m_tileAct = new QAction(QIcon(QStringLiteral(":/res/arrangeicons.png")), tr("&Arrange Icons"), this);
m_tileAct->setEnabled(false);
m_tileAct->setStatusTip(tr("Arrange icons at the bottom of the window"));
connect(m_tileAct, SIGNAL(triggered()), m_mdiArea, SLOT(tileSubWindows()));
m_cascadeAct = new QAction(tr("&Cascade"), this);
m_cascadeAct->setStatusTip(tr("Cascade the windows"));
connect(m_cascadeAct, SIGNAL(triggered()), m_mdiArea, SLOT(cascadeSubWindows()));
m_nextAct = new QAction(tr("Ne&xt"), this);
m_nextAct->setShortcuts(QKeySequence::NextChild);
m_nextAct->setStatusTip(tr("Move the focus to the next window"));
connect(m_nextAct, SIGNAL(triggered()), m_mdiArea, SLOT(activateNextSubWindow()));
m_previousAct = new QAction(tr("Pre&vious"), this);
m_previousAct->setShortcuts(QKeySequence::PreviousChild);
m_previousAct->setStatusTip(tr("Move the focus to the previous "
"window"));
connect(m_previousAct, SIGNAL(triggered()), m_mdiArea, SLOT(activatePreviousSubWindow()));
}
void MainWindow::createMenuFile()
{
QIcon iconLogo;
iconLogo.addPixmap(QPixmap(QStringLiteral(":/res/qtitan.png")));
iconLogo.addPixmap(QPixmap(QStringLiteral(":/res/qtitanlogo32x32.png")));
QAction* actionFile = ribbonBar()->addSystemButton(iconLogo, tr("&File"));
actionFile->setToolTip(tr("Click here to see everything<br />you can do with your<br />document"));
RibbonSystemMenu* systemMenu = qobject_cast<RibbonSystemMenu *>(actionFile->menu());
systemMenu->addAction(m_newTextAct);
systemMenu->addAction(m_newSketchAct);
systemMenu->addAction(m_openAct);
systemMenu->addAction(m_saveAct);
systemMenu->addAction(m_saveAsAct);
systemMenu->addSeparator();
systemMenu->addSeparator();
systemMenu->addAction(m_closeAct);
m_appCloseAct = systemMenu->addPopupBarAction(tr("Exit Sample"));
connect(m_appCloseAct, SIGNAL(triggered()), this, SLOT(close()));
QAction* option = systemMenu->addPopupBarAction(tr("Option"));
option->setEnabled(false );
}
void MainWindow::createRibbon()
{
RibbonPage* pageView = ribbonBar()->addPage(tr("&View"));
RibbonGroup* groupDocument = pageView->addGroup(tr("Document Views"));
groupDocument->addAction(QIcon(QStringLiteral(":/res/normal.png")), tr("&Normal"), Qt::ToolButtonTextUnderIcon);
groupDocument->addAction(QIcon(QStringLiteral(":/res/printpreview.png")), tr("&Print Preview"), Qt::ToolButtonTextUnderIcon);
m_actionFullScreen = groupDocument->addAction(QIcon(QStringLiteral(":/res/fullscreen.png")), tr("&Full Screen"), Qt::ToolButtonTextUnderIcon);
m_actionFullScreen->setCheckable(true);
m_actionFullScreen->setChecked(false);
connect(m_actionFullScreen, SIGNAL(triggered(bool)), this, SLOT(fullScreen(bool)));
Qt::CheckState stateWorkspace = Qt::Checked;
RibbonGroup* groupShow_Hide = pageView->addGroup(tr("Show/Hide"));
QCheckBox* checkStatusBar = new QCheckBox(tr("StatusBar"));
checkStatusBar->setCheckState(Qt::Checked);
groupShow_Hide->addWidget(checkStatusBar);
connect(checkStatusBar, SIGNAL(stateChanged(int)), this, SLOT(hideStatusBar(int)));
QCheckBox* checkWorkspace = new QCheckBox(tr("Workspace"));
checkWorkspace->setCheckState(stateWorkspace);
groupShow_Hide->addWidget(checkWorkspace);
connect(checkWorkspace, SIGNAL(stateChanged(int)), this, SLOT(switchViewMode(int)));
QCheckBox* checkFrameTheme = new QCheckBox(tr("FrameTheme"));
checkFrameTheme->setCheckState(Qt::Checked);
m_actFrameTheme = groupShow_Hide->addWidget(checkFrameTheme);
m_actFrameTheme->setCheckable(true);
m_actFrameTheme->setChecked(true);
QObject::connect(checkFrameTheme, SIGNAL(toggled(bool)), m_actFrameTheme, SIGNAL(toggled(bool)));
connect(m_actFrameTheme, SIGNAL(toggled(bool)), this, SLOT(setFrameThemeEnabled(bool)));
QButtonGroup* groupButton = new QButtonGroup(this);
m_groupMdiTabs = pageView->addGroup(tr("Option MDI Tabs"));
m_posTop = new QRadioButton(tr("Position Top"));
groupButton->addButton(m_posTop);
connect(m_posTop, SIGNAL(toggled(bool)), this, SLOT(setTabPositionTop(bool)));
m_posTop->setChecked(true);
m_groupMdiTabs->addWidget(m_posTop);
m_posBottom = new QRadioButton(tr("Position Bottom"));
groupButton->addButton(m_posBottom);
connect(m_posBottom, SIGNAL(toggled(bool)), this, SLOT(setTabPositionBottom(bool)));
m_groupMdiTabs->addWidget(m_posBottom);
m_posLeft = new QRadioButton(tr("Position Left"));
groupButton->addButton(m_posLeft);
connect(m_posLeft, SIGNAL(toggled(bool)), this, SLOT(setTabPositionLeft(bool)));
m_groupMdiTabs->addWidget(m_posLeft);
m_posRight = new QRadioButton(tr("Position Right"));
groupButton->addButton(m_posRight);
connect(m_posRight, SIGNAL(toggled(bool)), this, SLOT(setTabPositionRight(bool)));
m_groupMdiTabs->addWidget(m_posRight);
m_groupMdiTabs->setEnabled(stateWorkspace == Qt::Checked);
RibbonPage* pageWindow = ribbonBar()->addPage(tr("&Window"));
RibbonGroup* groupWindow = pageWindow->addGroup(tr("Window"));
QAction* actionnewWindow = groupWindow->addAction(QIcon(QStringLiteral(":/res/newwindow.png")), tr("&New Window"), Qt::ToolButtonTextUnderIcon);
actionnewWindow->setStatusTip(tr("Open another window for the active document"));
groupWindow->addAction(m_tileAct, Qt::ToolButtonTextUnderIcon);
m_windowMenu = groupWindow->addMenu(QIcon(QStringLiteral(":/res/windowswitch.png")), tr("&Switch Windows"));
updateWindowMenu();
connect(m_windowMenu, SIGNAL(aboutToShow()), this, SLOT(updateWindowMenu()));
}
void MainWindow::createStatusBar()
{
statusBar()->showMessage(tr("Ready"));
}
QWidget* MainWindow::activeMdiChild()
{
if (QMdiSubWindow* activeSubWindow = m_mdiArea->activeSubWindow())
return activeSubWindow->widget();
return Q_NULL;
}
QMdiSubWindow* MainWindow::findMdiChild(const QString& fileName)
{
QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath();
foreach (QMdiSubWindow* window, m_mdiArea->subWindowList())
{
ChildInterface* ifChild = qobject_cast<ChildInterface*>(window->widget());
if (ifChild && ifChild->currentFile() == canonicalFilePath)
return window;
}
return Q_NULL;
}
void MainWindow::switchLayoutDirection()
{
if (layoutDirection() == Qt::LeftToRight)
qApp->setLayoutDirection(Qt::RightToLeft);
else
qApp->setLayoutDirection(Qt::LeftToRight);
}
void MainWindow::setActiveSubWindow(QWidget* window)
{
if (!window)
return;
m_mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow*>(window));
}
void MainWindow::hideStatusBar(int state)
{
statusBar()->setVisible(state == Qt::Checked);
}
void MainWindow::switchViewMode(int state)
{
m_mdiArea->setLineWidth(state == Qt::Checked ? 3 : 0);
m_mdiArea->setViewMode(state == Qt::Checked ? QMdiArea::TabbedView : QMdiArea::SubWindowView);
m_groupMdiTabs->setEnabled(state == Qt::Checked);
m_tileAct->setEnabled(state != Qt::Checked);
}
void MainWindow::setStyleByName(const QString& styleName)
{
DemoRibbonWindow::setStyleByName(styleName);
if (m_actFrameTheme->isChecked() != ribbonBar()->isFrameThemeEnabled())
setFrameThemeEnabled(m_actFrameTheme->isChecked());
}
void MainWindow::setFrameThemeEnabled(bool checked)
{
ribbonBar()->setFrameThemeEnabled(checked);
}
void MainWindow::setTabPositionLeft(bool state)
{
if (state)
m_mdiArea->setTabPosition(QTabWidget::West);
}
void MainWindow::setTabPositionTop(bool state)
{
if (state)
m_mdiArea->setTabPosition(QTabWidget::North);
}
void MainWindow::setTabPositionBottom(bool state)
{
if (state)
m_mdiArea->setTabPosition(QTabWidget::South);
}
void MainWindow::setTabPositionRight(bool state)
{
if (state)
m_mdiArea->setTabPosition(QTabWidget::East);
}
void MainWindow::subWindowActivated(QMdiSubWindow* subWindow)
{
if (subWindow)
{
QWidget* activatWidget = subWindow->widget();
if (m_childCurrent == activatWidget)
return;
if (ChildInterface* ifChild = qobject_cast<ChildInterface*>(activatWidget))
{
ribbonBar()->beginUpdate();
if (ChildInterface* ifOldChild = qobject_cast<ChildInterface*>(m_childCurrent))
ifOldChild->removeUserInterface(ribbonBar(), statusBar(), Q_NULL);
m_childCurrent = activatWidget;
m_typeDocCurrent = ifChild->typeDocument();
ifChild->buildUserInterface(ribbonBar(), statusBar(), Q_NULL);
ribbonBar()->endUpdate();
}
}
}
void MainWindow::fullScreen(bool checked)
{
if (checked)
{
m_stateWindow = windowState();
m_actionFullScreen->setChecked(true);
ribbonBar()->setVisible(false);
setWindowState(Qt::WindowFullScreen);
}
}
void MainWindow::keyPressEvent(QKeyEvent* event)
{
RibbonMainWindow::keyPressEvent(event);
if (event->key() == Qt::Key_Escape && m_actionFullScreen->isChecked())
{
ribbonBar()->setVisible(true);
setWindowState(m_stateWindow);
m_actionFullScreen->setChecked(false);
}
}