DocumentDemo Example

#include <QApplication>
#include <QScreen>
#include <QStyle>
#include <QHBoxLayout>
#include <QTextEdit>
#include <QToolButton>
#include <QComboBox>
#include <QFileDialog>
#include <QToolBar>
#include <QTreeWidget>

#include "mainwindow.h"
#include "viewpanels.h"
#include "MdiChild.h"

/* MainWindow */
MainWindow::MainWindow(QWidget* parent)
    : DemoDockWindow(parent)
{
    //Start using document layout.
    dockPanelManager()->createDocumentLayout();

    createActions();
    createMainMenu();
    createToolBars();
    createDockPanels();
    createStatusBar();

    openFile(QStringLiteral(":/res/glwidget.h"));
    openFile(QStringLiteral(":/res/glwidget.cpp"));

#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
    const QRect availableGeometry = screen()->availableGeometry();
#else
    const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
#endif
    resize(availableGeometry.width() / 2, availableGeometry.height() / 2);
    move((availableGeometry.width() - width()) / 2, (availableGeometry.height() - height()) / 2);

    readSettings();
}

MainWindow::~MainWindow()
{
    writeSettings();
}

void MainWindow::createActions()
{
    m_navigateBackwardAction = new QAction(QIcon(QStringLiteral(":/res/backward16x16.png")), tr("Navigate Backward"), this);
    m_navigateBackwardAction->setStatusTip(tr("Navigate Backward"));
    m_navigateBackwardAction->setEnabled(false);
    m_navigateForwardAction = new QAction(QIcon(QStringLiteral(":/res/forward16x16.png")), tr("Navigate Forward"), this);
    m_navigateForwardAction->setStatusTip(tr("Navigate Forward"));
    m_navigateForwardAction->setEnabled(false);

    m_newFileAction = new QAction(QIcon(QStringLiteral(":/res/newfile16x16.png")), tr("New"), this);
    m_newFileAction->setPriority(QAction::LowPriority);
    m_newFileAction->setShortcut(QKeySequence::New);
    m_newFileAction->setStatusTip(tr("Create a new document"));
    m_newFileAction->setToolTip(tr("New"));
    connect(m_newFileAction, &QAction::triggered, this, &MainWindow::newFile);

    m_openFileAction = new QAction(QIcon(QStringLiteral(":/res/openfolder16x16.png")), tr("Open..."), this);
    m_openFileAction->setShortcut(QKeySequence::Open);
    m_openFileAction->setToolTip(tr("Open"));
    m_openFileAction->setStatusTip(tr("Open an existing document"));
    connect(m_openFileAction, &QAction::triggered, this, &MainWindow::open);

    m_closeDocFileAction = new QAction(tr("Close"), this);

    m_saveFileAction = new QAction(QIcon(QStringLiteral(":/res/save16x16.png")), tr("Save"), this);
    m_saveFileAction->setShortcut(QKeySequence::Save);
    m_saveFileAction->setToolTip(tr("Save"));
    m_saveFileAction->setStatusTip(tr("Save the active document"));
    m_saveFileAction->setEnabled(false);

    m_saveAllFileAction = new QAction(QIcon(QStringLiteral(":/res/saveall16x16.png")), tr("Save All"), this);
    m_saveAllFileAction->setShortcut(tr("Ctrl+Shift+S"));
    m_saveAllFileAction->setToolTip(tr("Save All"));
    m_saveAllFileAction->setStatusTip(tr("Save All"));

    m_undoAction = new QAction(QIcon(QStringLiteral(":/res/undo16x16.png")), tr("Undo"), this);
    m_undoAction->setShortcut(tr("Ctrl+Z"));

    m_redoAction = new QAction(QIcon(QStringLiteral(":/res/redo16x16.png")), tr("Redo"), this);
    m_redoAction->setShortcut(tr("Ctrl+Y"));
}

void MainWindow::createMainMenu()
{
    m_fileMenu = menuBar()->addMenu(tr("&File"));
    createFileMenu(m_fileMenu);
    m_editMenu = menuBar()->addMenu(tr("&Edit"));
    createEditMenu(m_editMenu);
    m_viewMenu = menuBar()->addMenu(tr("&View"));
    createViewMenu(m_viewMenu);
    addSaveLoadMenu(m_viewMenu);
    m_viewMenu->addSeparator();
    addStyleMenu(m_viewMenu);
#if 0
    m_buildMenu = menuBar()->addMenu(tr("&Build"));
    m_toolsMenu = menuBar()->addMenu(tr("&Tools"));
    m_windowMenu = menuBar()->addMenu(tr("&Window"));
#endif
    m_helpMenu = menuBar()->addMenu(tr("&Help"));
    m_helpMenu->addAction(m_aboutAction);
}

void MainWindow::createFileMenu(QMenu* menu)
{
    menu->addAction(m_newFileAction);
    menu->addAction(m_openFileAction);
    menu->addAction(m_saveFileAction);
    menu->addSeparator();
    menu->addAction(m_closeDocFileAction);
}

void MainWindow::createEditMenu(QMenu* menu)
{
    menu->addAction(m_undoAction);
    menu->addAction(m_redoAction);
}

void MainWindow::createViewMenu(QMenu* menuView)
{
    QAction* actionFullScreen = menuView->addAction(tr("F&ull Screen"));
    actionFullScreen->setEnabled(false);
    menuView->addSeparator();
    // panels...
    m_solutionExplorerAction = menuView->addAction(tr("Solution &Explorer"));
    m_classViewAction = menuView->addAction(tr("&Class View"));
    m_resourceViewAction = menuView->addAction(tr("&Resource View"));
    menuView->addSeparator();
}

void MainWindow::createToolBars()
{
    DockToolBar* toolBar = addToolBar(tr("Standard"), DockBarTop);
    toolBar->addAction(m_navigateBackwardAction);
    toolBar->addAction(m_navigateForwardAction);
    toolBar->addSeparator();
    toolBar->addAction(m_newFileAction);
    toolBar->addAction(m_openFileAction);
    toolBar->addAction(m_saveFileAction);
    toolBar->addAction(m_saveAllFileAction);
    toolBar->addSeparator();
    toolBar->addAction(m_undoAction);
    toolBar->addAction(m_redoAction);
    toolBar->addSeparator();
    QComboBox* configurationsBox = new QComboBox(this);
    configurationsBox->addItem(tr("Debug"));
    configurationsBox->addItem(tr("Release"));
    configurationsBox->addItem(tr("Configuration Manager..."));
    QFontMetrics fm(configurationsBox->font());
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
    configurationsBox->setMaximumWidth(fm.horizontalAdvance(QStringLiteral("XXXXXXXXXXXXX")));
#else
    configurationsBox->setMaximumWidth(fm.width(QStringLiteral("XXXXXXXXXXXXX")));
#endif
    QAction* configurationsAction = toolBar->addWidget(configurationsBox);
    configurationsAction->setToolTip(tr("Solution Configurations"));
    configurationsAction->setStatusTip(tr("Solution Configurations"));

    QComboBox* platformsBox = new QComboBox(this);
    platformsBox->addItem(tr("x64"));
    platformsBox->addItem(tr("Configuration Manager..."));
    platformsBox->setMinimumWidth(100);
    QAction* platformsAction = toolBar->addWidget(platformsBox);
    platformsAction->setToolTip(tr("Solution Platforms"));
    platformsAction->setStatusTip(tr("Solution Platforms"));
    platformsAction->setEnabled(false);

    toolBar->addWidget(new QLabel(tr("   Style:")));
    QAction* stylesAction = toolBar->addWidget(createComboBoxStyle());
    stylesAction->setToolTip(tr("Styles switcher"));
}

void MainWindow::createDockPanels()
{
    m_panelClassView = new ClassViewPanelCreator(this);
    dockPanelManager()->insertDockPanel(m_panelClassView->widgetPanel(), Qtitan::LeftDockPanelArea);
    connect(m_classViewAction, SIGNAL(triggered(bool)), m_panelClassView->widgetPanel()->visibleAction(), SIGNAL(triggered(bool)));

    m_panelResourceView = new ResourceViewPanelCreator(this);
    dockPanelManager()->insertDockPanel(m_panelResourceView->widgetPanel(), Qtitan::InsideDockPanelArea, m_panelClassView->widgetPanel());
    connect(m_resourceViewAction, SIGNAL(triggered(bool)), m_panelResourceView->widgetPanel()->visibleAction(), SIGNAL(triggered(bool)));

    m_panelSolutionExplorer = new FileViewPanelCreator(this);
    dockPanelManager()->insertDockPanel(m_panelSolutionExplorer->widgetPanel(), Qtitan::InsideDockPanelArea, m_panelResourceView->widgetPanel());
    connect(m_solutionExplorerAction, SIGNAL(triggered(bool)), m_panelSolutionExplorer->widgetPanel()->visibleAction(), SIGNAL(triggered(bool)));

    m_panelOutput = new OutputListPanelCreator(this);
    dockPanelManager()->insertDockPanel(m_panelOutput->widgetPanel(), Qtitan::BottomDockPanelArea);
    m_panelOutput->widgetPanel()->setAutoHide(true);

    m_panelWatch = new WatchPanelCreator(this);
    dockPanelManager()->insertDockPanel(m_panelWatch->widgetPanel(), Qtitan::BottomDockPanelArea, m_panelOutput->widgetPanel());
    m_panelWatch->widgetPanel()->setAutoHide(true);

    m_panelToolBox = new ToolBoxPanelCreator(this);
    dockPanelManager()->insertDockPanel(m_panelToolBox->widgetPanel(), Qtitan::RightDockPanelArea);
}

void MainWindow::createStatusBar()
{
    statusBar()->showMessage(tr("Ready"));
}

bool MainWindow::openFile(const QString& fileName)
{
    if (DockWidgetPanel* panel = findMdiChild(fileName))
    {
        panel->activate();
        return true;
    }
    const bool succeeded = loadFile(fileName);
    if (succeeded)
        statusBar()->showMessage(tr("File loaded"), 2000);
    return succeeded;
}

void MainWindow::newFile()
{
    MdiChild* child = createMdiChild();
    child->newFile();
    DockWidgetPanel* documentPanel = addDocumentPanel(child->windowTitle());
    documentPanel->setWidget(child);
    connect(child, SIGNAL(windowTitleChanged(const QString&)), documentPanel, SLOT(setCaption(const QString&)));
    child->setFocus();
}

void MainWindow::open()
{
    const QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), QString(), QStringLiteral("C++ Files (*.cpp *.h)"));
    if (!fileName.isEmpty())
        openFile(fileName);
}

MdiChild* MainWindow::createMdiChild()
{
    MdiChild* child = new MdiChild;
    child->setVisible(false);
    return child;
}

bool MainWindow::loadFile(const QString& fileName)
{
    MdiChild* child = createMdiChild();
    const bool succeeded = child->loadFile(fileName);
    if (!succeeded)
        child->close();
    DockWidgetPanel* documentPanel = addDocumentPanel(child->windowTitle());
    documentPanel->setWidget(child);
    connect(child, SIGNAL(windowTitleChanged(const QString&)), documentPanel, SLOT(setCaption(const QString&)));
    return succeeded;
}

DockWidgetPanel* MainWindow::findMdiChild(const QString& fileName) const
{
    QList<DockDocumentPanel*> lstPanel = findChildren<DockDocumentPanel*>();
    QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath();
    foreach (DockPanelBase* panel, lstPanel)
    {
        if (DockWidgetPanel* widgetPanel = qobject_cast<DockWidgetPanel*>(panel))
        {
            MdiChild* mdiChild = qobject_cast<MdiChild *>(widgetPanel->widget());
            if (mdiChild->currentFileName() == canonicalFilePath)
                return widgetPanel;
        }
    }
    return Q_NULL;
}

void MainWindow::closeEvent(QCloseEvent* event)
{
    QList<DockDocumentPanel*> lstPanel = findChildren<DockDocumentPanel*>();
    for (QList<DockDocumentPanel*>::iterator it = lstPanel.begin(); it != lstPanel.end(); ++it)
        dockPanelManager()->closeDockPanel((*it));
    if (findChildren<DockDocumentPanel*>().count() > 0)
        event->ignore();
    else
        event->accept();
}