diff options
Diffstat (limited to 'examples/widgets/mainwindows')
25 files changed, 1015 insertions, 1359 deletions
diff --git a/examples/widgets/mainwindows/application/main.cpp b/examples/widgets/mainwindows/application/main.cpp index 41913db07e..73c1cf57d3 100644 --- a/examples/widgets/mainwindows/application/main.cpp +++ b/examples/widgets/mainwindows/application/main.cpp @@ -40,6 +40,8 @@ //! [0] #include <QApplication> +#include <QCommandLineParser> +#include <QCommandLineOption> #include "mainwindow.h" @@ -48,9 +50,19 @@ int main(int argc, char *argv[]) Q_INIT_RESOURCE(application); QApplication app(argc, argv); - app.setOrganizationName("QtProject"); - app.setApplicationName("Application Example"); + QCoreApplication::setOrganizationName("QtProject"); + QCoreApplication::setApplicationName("Application Example"); + QCoreApplication::setApplicationVersion(QT_VERSION_STR); + QCommandLineParser parser; + parser.setApplicationDescription(QCoreApplication::applicationName()); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument("file", "The file to open."); + parser.process(app); + MainWindow mainWin; + if (!parser.positionalArguments().isEmpty()) + mainWin.loadFile(parser.positionalArguments().first()); mainWin.show(); return app.exec(); } diff --git a/examples/widgets/mainwindows/application/mainwindow.cpp b/examples/widgets/mainwindows/application/mainwindow.cpp index d3f9c7645e..86dfae166f 100644 --- a/examples/widgets/mainwindows/application/mainwindow.cpp +++ b/examples/widgets/mainwindows/application/mainwindow.cpp @@ -46,22 +46,20 @@ //! [1] MainWindow::MainWindow() + : textEdit(new QPlainTextEdit) //! [1] //! [2] { - textEdit = new QPlainTextEdit; setCentralWidget(textEdit); createActions(); - createMenus(); - createToolBars(); createStatusBar(); readSettings(); - connect(textEdit->document(), SIGNAL(contentsChanged()), - this, SLOT(documentWasModified())); + connect(textEdit->document(), &QTextDocument::contentsChanged, + this, &MainWindow::documentWasModified); - setCurrentFile(""); + setCurrentFile(QString()); setUnifiedTitleAndToolBarOnMac(true); } //! [2] @@ -85,7 +83,7 @@ void MainWindow::newFile() { if (maybeSave()) { textEdit->clear(); - setCurrentFile(""); + setCurrentFile(QString()); } } //! [6] @@ -121,13 +119,9 @@ bool MainWindow::saveAs() QFileDialog dialog(this); dialog.setWindowModality(Qt::WindowModal); dialog.setAcceptMode(QFileDialog::AcceptSave); - QStringList files; - if (dialog.exec()) - files = dialog.selectedFiles(); - else + if (dialog.exec() != QDialog::Accepted) return false; - - return saveFile(files.at(0)); + return saveFile(dialog.selectedFiles().first()); } //! [12] @@ -154,121 +148,108 @@ void MainWindow::documentWasModified() void MainWindow::createActions() //! [17] //! [18] { - newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this); + + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); + QToolBar *fileToolBar = addToolBar(tr("File")); + const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/images/new.png")); + QAction *newAct = new QAction(newIcon, tr("&New"), this); newAct->setShortcuts(QKeySequence::New); newAct->setStatusTip(tr("Create a new file")); - connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); + connect(newAct, &QAction::triggered, this, &MainWindow::newFile); + fileMenu->addAction(newAct); + fileToolBar->addAction(newAct); //! [19] - openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); + const QIcon openIcon = QIcon::fromTheme("document-open", QIcon(":/images/open.png")); + QAction *openAct = new QAction(openIcon, tr("&Open..."), this); openAct->setShortcuts(QKeySequence::Open); openAct->setStatusTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); + connect(openAct, &QAction::triggered, this, &MainWindow::open); + fileMenu->addAction(openAct); + fileToolBar->addAction(openAct); //! [18] //! [19] - saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this); + const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png")); + QAction *saveAct = new QAction(saveIcon, tr("&Save"), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the document to disk")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); + connect(saveAct, &QAction::triggered, this, &MainWindow::save); + fileMenu->addAction(saveAct); + fileToolBar->addAction(saveAct); - saveAsAct = new QAction(tr("Save &As..."), this); + const QIcon saveAsIcon = QIcon::fromTheme("document-save-as"); + QAction *saveAsAct = fileMenu->addAction(saveAsIcon, tr("Save &As..."), this, &MainWindow::saveAs); saveAsAct->setShortcuts(QKeySequence::SaveAs); saveAsAct->setStatusTip(tr("Save the document under a new name")); - connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); //! [20] - exitAct = new QAction(tr("E&xit"), this); + + fileMenu->addSeparator(); + + const QIcon exitIcon = QIcon::fromTheme("application-exit"); + QAction *exitAct = fileMenu->addAction(exitIcon, tr("E&xit"), this, &QWidget::close); exitAct->setShortcuts(QKeySequence::Quit); //! [20] exitAct->setStatusTip(tr("Exit the application")); - connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); //! [21] - cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this); + QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); + QToolBar *editToolBar = addToolBar(tr("Edit")); +//! +#ifndef QT_NO_CLIPBOARD + const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png")); + QAction *cutAct = new QAction(cutIcon, tr("Cu&t"), this); //! [21] cutAct->setShortcuts(QKeySequence::Cut); cutAct->setStatusTip(tr("Cut the current selection's contents to the " "clipboard")); - connect(cutAct, SIGNAL(triggered()), textEdit, SLOT(cut())); + connect(cutAct, &QAction::triggered, textEdit, &QPlainTextEdit::cut); + editMenu->addAction(cutAct); + editToolBar->addAction(cutAct); - copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this); + const QIcon copyIcon = QIcon::fromTheme("edit-copy", QIcon(":/images/copy.png")); + QAction *copyAct = new QAction(copyIcon, tr("&Copy"), this); copyAct->setShortcuts(QKeySequence::Copy); copyAct->setStatusTip(tr("Copy the current selection's contents to the " "clipboard")); - connect(copyAct, SIGNAL(triggered()), textEdit, SLOT(copy())); + connect(copyAct, &QAction::triggered, textEdit, &QPlainTextEdit::copy); + editMenu->addAction(copyAct); + editToolBar->addAction(copyAct); - pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this); + const QIcon pasteIcon = QIcon::fromTheme("edit-paste", QIcon(":/images/paste.png")); + QAction *pasteAct = new QAction(pasteIcon, tr("&Paste"), this); pasteAct->setShortcuts(QKeySequence::Paste); pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current " "selection")); - connect(pasteAct, SIGNAL(triggered()), textEdit, SLOT(paste())); + connect(pasteAct, &QAction::triggered, textEdit, &QPlainTextEdit::paste); + editMenu->addAction(pasteAct); + editToolBar->addAction(pasteAct); + + menuBar()->addSeparator(); + +#endif // !QT_NO_CLIPBOARD - aboutAct = new QAction(tr("&About"), this); + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); + QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about); aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); //! [22] - aboutQtAct = new QAction(tr("About &Qt"), this); + + QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); //! [22] //! [23] +#ifndef QT_NO_CLIPBOARD cutAct->setEnabled(false); //! [23] //! [24] copyAct->setEnabled(false); - connect(textEdit, SIGNAL(copyAvailable(bool)), - cutAct, SLOT(setEnabled(bool))); - connect(textEdit, SIGNAL(copyAvailable(bool)), - copyAct, SLOT(setEnabled(bool))); + connect(textEdit, &QPlainTextEdit::copyAvailable, cutAct, &QAction::setEnabled); + connect(textEdit, &QPlainTextEdit::copyAvailable, copyAct, &QAction::setEnabled); +#endif // !QT_NO_CLIPBOARD } //! [24] -//! [25] //! [26] -void MainWindow::createMenus() -//! [25] //! [27] -{ - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(newAct); -//! [28] - fileMenu->addAction(openAct); -//! [28] - fileMenu->addAction(saveAct); -//! [26] - fileMenu->addAction(saveAsAct); - fileMenu->addSeparator(); - fileMenu->addAction(exitAct); - - editMenu = menuBar()->addMenu(tr("&Edit")); - editMenu->addAction(cutAct); - editMenu->addAction(copyAct); - editMenu->addAction(pasteAct); - - menuBar()->addSeparator(); - - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); -} -//! [27] - -//! [29] //! [30] -void MainWindow::createToolBars() -{ - fileToolBar = addToolBar(tr("File")); - fileToolBar->addAction(newAct); -//! [29] //! [31] - fileToolBar->addAction(openAct); -//! [31] - fileToolBar->addAction(saveAct); - - editToolBar = addToolBar(tr("Edit")); - editToolBar->addAction(cutAct); - editToolBar->addAction(copyAct); - editToolBar->addAction(pasteAct); -} -//! [30] - //! [32] void MainWindow::createStatusBar() //! [32] //! [33] @@ -281,11 +262,16 @@ void MainWindow::createStatusBar() void MainWindow::readSettings() //! [34] //! [36] { - QSettings settings("QtProject", "Application Example"); - QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); - QSize size = settings.value("size", QSize(400, 400)).toSize(); - resize(size); - move(pos); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray(); + if (geometry.isEmpty()) { + const QRect availableGeometry = QApplication::desktop()->availableGeometry(this); + resize(availableGeometry.width() / 3, availableGeometry.height() / 2); + move((availableGeometry.width() - width()) / 2, + (availableGeometry.height() - height()) / 2); + } else { + restoreGeometry(geometry); + } } //! [35] //! [36] @@ -293,9 +279,8 @@ void MainWindow::readSettings() void MainWindow::writeSettings() //! [37] //! [39] { - QSettings settings("QtProject", "Application Example"); - settings.setValue("pos", pos()); - settings.setValue("size", size()); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + settings.setValue("geometry", saveGeometry()); } //! [38] //! [39] @@ -303,16 +288,20 @@ void MainWindow::writeSettings() bool MainWindow::maybeSave() //! [40] //! [41] { - if (textEdit->document()->isModified()) { - QMessageBox::StandardButton ret; - ret = QMessageBox::warning(this, tr("Application"), - tr("The document has been modified.\n" - "Do you want to save your changes?"), - QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); - if (ret == QMessageBox::Save) - return save(); - else if (ret == QMessageBox::Cancel) - return false; + if (!textEdit->document()->isModified()) + return true; + const QMessageBox::StandardButton ret + = QMessageBox::warning(this, tr("Application"), + tr("The document has been modified.\n" + "Do you want to save your changes?"), + QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + switch (ret) { + case QMessageBox::Save: + return save(); + case QMessageBox::Cancel: + return false; + default: + break; } return true; } @@ -326,8 +315,7 @@ void MainWindow::loadFile(const QString &fileName) if (!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning(this, tr("Application"), tr("Cannot read file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), file.errorString())); return; } @@ -353,8 +341,8 @@ bool MainWindow::saveFile(const QString &fileName) if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr("Application"), tr("Cannot write file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), + file.errorString())); return false; } diff --git a/examples/widgets/mainwindows/application/mainwindow.h b/examples/widgets/mainwindows/application/mainwindow.h index cb791abf00..08b4aa17f5 100644 --- a/examples/widgets/mainwindows/application/mainwindow.h +++ b/examples/widgets/mainwindows/application/mainwindow.h @@ -57,6 +57,8 @@ class MainWindow : public QMainWindow public: MainWindow(); + void loadFile(const QString &fileName); + protected: void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; @@ -70,35 +72,16 @@ private slots: private: void createActions(); - void createMenus(); - void createToolBars(); void createStatusBar(); void readSettings(); void writeSettings(); bool maybeSave(); - void loadFile(const QString &fileName); bool saveFile(const QString &fileName); void setCurrentFile(const QString &fileName); QString strippedName(const QString &fullFileName); QPlainTextEdit *textEdit; QString curFile; - - QMenu *fileMenu; - QMenu *editMenu; - QMenu *helpMenu; - QToolBar *fileToolBar; - QToolBar *editToolBar; - QAction *newAct; - QAction *openAct; - QAction *saveAct; - QAction *saveAsAct; - QAction *exitAct; - QAction *cutAct; - QAction *copyAct; - QAction *pasteAct; - QAction *aboutAct; - QAction *aboutQtAct; }; //! [0] diff --git a/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp b/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp index 20c2bd1c70..c0472b537c 100644 --- a/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp +++ b/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp @@ -49,13 +49,11 @@ //! [1] MainWindow::MainWindow() + : textEdit(new QTextEdit) { - textEdit = new QTextEdit; setCentralWidget(textEdit); createActions(); - createMenus(); - createToolBars(); createStatusBar(); createDockWindows(); @@ -135,17 +133,17 @@ void MainWindow::print() //! [4] void MainWindow::save() { + QMimeDatabase mimeDatabase; QString fileName = QFileDialog::getSaveFileName(this, tr("Choose a file name"), ".", - tr("HTML (*.html *.htm)")); + mimeDatabase.mimeTypeForName("text/html").filterString()); if (fileName.isEmpty()) return; QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr("Dock Widgets"), tr("Cannot write file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), file.errorString())); return; } @@ -222,71 +220,60 @@ void MainWindow::about() void MainWindow::createActions() { - newLetterAct = new QAction(QIcon(":/images/new.png"), tr("&New Letter"), - this); + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); + QToolBar *fileToolBar = addToolBar(tr("File")); + + const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/images/new.png")); + QAction *newLetterAct = new QAction(newIcon, tr("&New Letter"), this); newLetterAct->setShortcuts(QKeySequence::New); newLetterAct->setStatusTip(tr("Create a new form letter")); - connect(newLetterAct, SIGNAL(triggered()), this, SLOT(newLetter())); + connect(newLetterAct, &QAction::triggered, this, &MainWindow::newLetter); + fileMenu->addAction(newLetterAct); + fileToolBar->addAction(newLetterAct); - saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save..."), this); + const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png")); + QAction *saveAct = new QAction(saveIcon, tr("&Save..."), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the current form letter")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); + connect(saveAct, &QAction::triggered, this, &MainWindow::save); + fileMenu->addAction(saveAct); + fileToolBar->addAction(saveAct); - printAct = new QAction(QIcon(":/images/print.png"), tr("&Print..."), this); + const QIcon printIcon = QIcon::fromTheme("document-print", QIcon(":/images/print.png")); + QAction *printAct = new QAction(printIcon, tr("&Print..."), this); printAct->setShortcuts(QKeySequence::Print); printAct->setStatusTip(tr("Print the current form letter")); - connect(printAct, SIGNAL(triggered()), this, SLOT(print())); + connect(printAct, &QAction::triggered, this, &MainWindow::print); + fileMenu->addAction(printAct); + fileToolBar->addAction(printAct); - undoAct = new QAction(QIcon(":/images/undo.png"), tr("&Undo"), this); - undoAct->setShortcuts(QKeySequence::Undo); - undoAct->setStatusTip(tr("Undo the last editing action")); - connect(undoAct, SIGNAL(triggered()), this, SLOT(undo())); + fileMenu->addSeparator(); - quitAct = new QAction(tr("&Quit"), this); + QAction *quitAct = fileMenu->addAction(tr("&Quit"), this, &QWidget::close); quitAct->setShortcuts(QKeySequence::Quit); quitAct->setStatusTip(tr("Quit the application")); - connect(quitAct, SIGNAL(triggered()), this, SLOT(close())); - - aboutAct = new QAction(tr("&About"), this); - aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - - aboutQtAct = new QAction(tr("About &Qt"), this); - aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); -} - -void MainWindow::createMenus() -{ - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(newLetterAct); - fileMenu->addAction(saveAct); - fileMenu->addAction(printAct); - fileMenu->addSeparator(); - fileMenu->addAction(quitAct); - editMenu = menuBar()->addMenu(tr("&Edit")); + QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); + QToolBar *editToolBar = addToolBar(tr("Edit")); + const QIcon undoIcon = QIcon::fromTheme("edit-undo", QIcon(":/images/undo.png")); + QAction *undoAct = new QAction(undoIcon, tr("&Undo"), this); + undoAct->setShortcuts(QKeySequence::Undo); + undoAct->setStatusTip(tr("Undo the last editing action")); + connect(undoAct, &QAction::triggered, this, &MainWindow::undo); editMenu->addAction(undoAct); + editToolBar->addAction(undoAct); viewMenu = menuBar()->addMenu(tr("&View")); menuBar()->addSeparator(); - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); -} + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); -void MainWindow::createToolBars() -{ - fileToolBar = addToolBar(tr("File")); - fileToolBar->addAction(newLetterAct); - fileToolBar->addAction(saveAct); - fileToolBar->addAction(printAct); + QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about); + aboutAct->setStatusTip(tr("Show the application's About box")); - editToolBar = addToolBar(tr("Edit")); - editToolBar->addAction(undoAct); + QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); + aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); } //! [8] @@ -337,9 +324,9 @@ void MainWindow::createDockWindows() addDockWidget(Qt::RightDockWidgetArea, dock); viewMenu->addAction(dock->toggleViewAction()); - connect(customerList, SIGNAL(currentTextChanged(QString)), - this, SLOT(insertCustomer(QString))); - connect(paragraphsList, SIGNAL(currentTextChanged(QString)), - this, SLOT(addParagraph(QString))); + connect(customerList, &QListWidget::currentTextChanged, + this, &MainWindow::insertCustomer); + connect(paragraphsList, &QListWidget::currentTextChanged, + this, &MainWindow::addParagraph); } //! [9] diff --git a/examples/widgets/mainwindows/dockwidgets/mainwindow.h b/examples/widgets/mainwindows/dockwidgets/mainwindow.h index 2fb161a20b..c244febf9a 100644 --- a/examples/widgets/mainwindows/dockwidgets/mainwindow.h +++ b/examples/widgets/mainwindows/dockwidgets/mainwindow.h @@ -69,8 +69,6 @@ private slots: private: void createActions(); - void createMenus(); - void createToolBars(); void createStatusBar(); void createDockWindows(); @@ -78,19 +76,7 @@ private: QListWidget *customerList; QListWidget *paragraphsList; - QMenu *fileMenu; - QMenu *editMenu; QMenu *viewMenu; - QMenu *helpMenu; - QToolBar *fileToolBar; - QToolBar *editToolBar; - QAction *newLetterAct; - QAction *saveAct; - QAction *printAct; - QAction *undoAct; - QAction *aboutAct; - QAction *aboutQtAct; - QAction *quitAct; }; //! [0] diff --git a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp index 408f6c4b0f..d746bbe8d3 100644 --- a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp +++ b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp @@ -42,6 +42,7 @@ #include <QImage> #include <QColor> #include <QDialog> +#include <QDialogButtonBox> #include <QGridLayout> #include <QSpinBox> #include <QLabel> @@ -57,15 +58,15 @@ QColor bgColorForName(const QString &name) { if (name == "Black") return QColor("#D8D8D8"); - else if (name == "White") + if (name == "White") return QColor("#F1F1F1"); - else if (name == "Red") + if (name == "Red") return QColor("#F1D8D8"); - else if (name == "Green") + if (name == "Green") return QColor("#D8E4D8"); - else if (name == "Blue") + if (name == "Blue") return QColor("#D8D8F1"); - else if (name == "Yellow") + if (name == "Yellow") return QColor("#F1F0D8"); return QColor(name).light(110); } @@ -74,15 +75,15 @@ QColor fgColorForName(const QString &name) { if (name == "Black") return QColor("#6C6C6C"); - else if (name == "White") + if (name == "White") return QColor("#F8F8F8"); - else if (name == "Red") + if (name == "Red") return QColor("#F86C6C"); - else if (name == "Green") + if (name == "Green") return QColor("#6CB26C"); - else if (name == "Blue") + if (name == "Blue") return QColor("#6C6CF8"); - else if (name == "Yellow") + if (name == "Yellow") return QColor("#F8F76C"); return QColor(name); } @@ -91,10 +92,10 @@ class ColorDock : public QFrame { Q_OBJECT public: - ColorDock(const QString &c, QWidget *parent); + explicit ColorDock(const QString &c, QWidget *parent); - virtual QSize sizeHint() const Q_DECL_OVERRIDE; - virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; + QSize sizeHint() const Q_DECL_OVERRIDE { return szHint; } + QSize minimumSizeHint() const Q_DECL_OVERRIDE { return minSzHint; } void setCustomSizeHint(const QSize &size); @@ -103,28 +104,22 @@ public slots: protected: void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; - QString color; - QSize szHint, minSzHint; + +private: + const QString color; + QSize szHint; + QSize minSzHint; }; ColorDock::ColorDock(const QString &c, QWidget *parent) - : QFrame(parent) , color(c) + : QFrame(parent) + , color(c) + , szHint(-1, -1) + , minSzHint(125, 75) { QFont font = this->font(); font.setPointSize(8); setFont(font); - szHint = QSize(-1, -1); - minSzHint = QSize(125, 75); -} - -QSize ColorDock::sizeHint() const -{ - return szHint; -} - -QSize ColorDock::minimumSizeHint() const -{ - return minSzHint; } void ColorDock::paintEvent(QPaintEvent *) @@ -178,6 +173,7 @@ static QSpinBox *createSpinBox(int value, QWidget *parent, int max = 1000) void ColorDock::changeSizeHints() { QDialog dialog(this); + dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint); dialog.setWindowTitle(color); QVBoxLayout *topLayout = new QVBoxLayout(&dialog); @@ -188,7 +184,7 @@ void ColorDock::changeSizeHints() inputLayout->addWidget(new QLabel(tr("Size Hint:"), &dialog), 0, 0); inputLayout->addWidget(new QLabel(tr("Min Size Hint:"), &dialog), 1, 0); inputLayout->addWidget(new QLabel(tr("Max Size:"), &dialog), 2, 0); - inputLayout->addWidget(new QLabel(tr("Dockwgt Max Size:"), &dialog), 3, 0); + inputLayout->addWidget(new QLabel(tr("Dock Widget Max Size:"), &dialog), 3, 0); QSpinBox *szHintW = createSpinBox(szHint.width(), &dialog); inputLayout->addWidget(szHintW, 0, 1); @@ -217,19 +213,13 @@ void ColorDock::changeSizeHints() topLayout->addStretch(); - QHBoxLayout *buttonBox = new QHBoxLayout(); - topLayout->addLayout(buttonBox); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); + connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); + connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::reject); - QPushButton *okButton = new QPushButton(tr("Ok"), &dialog); - QPushButton *cancelButton = new QPushButton(tr("Cancel"), &dialog); - connect(okButton, SIGNAL(clicked()), &dialog, SLOT(accept())); - connect(cancelButton, SIGNAL(clicked()), &dialog, SLOT(reject())); - buttonBox->addStretch(); - buttonBox->addWidget(cancelButton); - buttonBox->addWidget(okButton); + topLayout->addWidget(buttonBox); - - if (!dialog.exec()) + if (dialog.exec() != QDialog::Accepted) return; szHint = QSize(szHintW->value(), szHintH->value()); @@ -244,63 +234,62 @@ void ColorDock::changeSizeHints() void ColorDock::setCustomSizeHint(const QSize &size) { - szHint = size; - updateGeometry(); + if (szHint != size) { + szHint = size; + updateGeometry(); + } } -ColorSwatch::ColorSwatch(const QString &colorName, QWidget *parent, Qt::WindowFlags flags) - : QDockWidget(parent, flags) +ColorSwatch::ColorSwatch(const QString &colorName, QMainWindow *parent, Qt::WindowFlags flags) + : QDockWidget(parent, flags), mainWindow(parent) { setObjectName(colorName + QLatin1String(" Dock Widget")); setWindowTitle(objectName() + QLatin1String(" [*]")); - QFrame *swatch = new ColorDock(colorName, this); + ColorDock *swatch = new ColorDock(colorName, this); swatch->setFrameStyle(QFrame::Box | QFrame::Sunken); setWidget(swatch); - changeSizeHintsAction = new QAction(tr("Change Size Hints"), this); - connect(changeSizeHintsAction, SIGNAL(triggered()), swatch, SLOT(changeSizeHints())); - closableAction = new QAction(tr("Closable"), this); closableAction->setCheckable(true); - connect(closableAction, SIGNAL(triggered(bool)), SLOT(changeClosable(bool))); + connect(closableAction, &QAction::triggered, this, &ColorSwatch::changeClosable); movableAction = new QAction(tr("Movable"), this); movableAction->setCheckable(true); - connect(movableAction, SIGNAL(triggered(bool)), SLOT(changeMovable(bool))); + connect(movableAction, &QAction::triggered, this, &ColorSwatch::changeMovable); floatableAction = new QAction(tr("Floatable"), this); floatableAction->setCheckable(true); - connect(floatableAction, SIGNAL(triggered(bool)), SLOT(changeFloatable(bool))); + connect(floatableAction, &QAction::triggered, this, &ColorSwatch::changeFloatable); verticalTitleBarAction = new QAction(tr("Vertical title bar"), this); verticalTitleBarAction->setCheckable(true); - connect(verticalTitleBarAction, SIGNAL(triggered(bool)), - SLOT(changeVerticalTitleBar(bool))); + connect(verticalTitleBarAction, &QAction::triggered, + this, &ColorSwatch::changeVerticalTitleBar); floatingAction = new QAction(tr("Floating"), this); floatingAction->setCheckable(true); - connect(floatingAction, SIGNAL(triggered(bool)), SLOT(changeFloating(bool))); + connect(floatingAction, &QAction::triggered, this, &ColorSwatch::changeFloating); allowedAreasActions = new QActionGroup(this); allowedAreasActions->setExclusive(false); allowLeftAction = new QAction(tr("Allow on Left"), this); allowLeftAction->setCheckable(true); - connect(allowLeftAction, SIGNAL(triggered(bool)), SLOT(allowLeft(bool))); + connect(allowLeftAction, &QAction::triggered, this, &ColorSwatch::allowLeft); allowRightAction = new QAction(tr("Allow on Right"), this); allowRightAction->setCheckable(true); - connect(allowRightAction, SIGNAL(triggered(bool)), SLOT(allowRight(bool))); + connect(allowRightAction, &QAction::triggered, this, &ColorSwatch::allowRight); allowTopAction = new QAction(tr("Allow on Top"), this); allowTopAction->setCheckable(true); - connect(allowTopAction, SIGNAL(triggered(bool)), SLOT(allowTop(bool))); + connect(allowTopAction, &QAction::triggered, this, &ColorSwatch::allowTop); allowBottomAction = new QAction(tr("Allow on Bottom"), this); allowBottomAction->setCheckable(true); - connect(allowBottomAction, SIGNAL(triggered(bool)), SLOT(allowBottom(bool))); + connect(allowBottomAction, &QAction::triggered, this, &ColorSwatch::allowBottom); allowedAreasActions->addAction(allowLeftAction); allowedAreasActions->addAction(allowRightAction); @@ -312,56 +301,56 @@ ColorSwatch::ColorSwatch(const QString &colorName, QWidget *parent, Qt::WindowFl leftAction = new QAction(tr("Place on Left") , this); leftAction->setCheckable(true); - connect(leftAction, SIGNAL(triggered(bool)), SLOT(placeLeft(bool))); + connect(leftAction, &QAction::triggered, this, &ColorSwatch::placeLeft); rightAction = new QAction(tr("Place on Right") , this); rightAction->setCheckable(true); - connect(rightAction, SIGNAL(triggered(bool)), SLOT(placeRight(bool))); + connect(rightAction, &QAction::triggered, this, &ColorSwatch::placeRight); topAction = new QAction(tr("Place on Top") , this); topAction->setCheckable(true); - connect(topAction, SIGNAL(triggered(bool)), SLOT(placeTop(bool))); + connect(topAction, &QAction::triggered, this, &ColorSwatch::placeTop); bottomAction = new QAction(tr("Place on Bottom") , this); bottomAction->setCheckable(true); - connect(bottomAction, SIGNAL(triggered(bool)), SLOT(placeBottom(bool))); + connect(bottomAction, &QAction::triggered, this, &ColorSwatch::placeBottom); areaActions->addAction(leftAction); areaActions->addAction(rightAction); areaActions->addAction(topAction); areaActions->addAction(bottomAction); - connect(movableAction, SIGNAL(triggered(bool)), areaActions, SLOT(setEnabled(bool))); + connect(movableAction, &QAction::triggered, areaActions, &QActionGroup::setEnabled); - connect(movableAction, SIGNAL(triggered(bool)), allowedAreasActions, SLOT(setEnabled(bool))); + connect(movableAction, &QAction::triggered, allowedAreasActions, &QActionGroup::setEnabled); - connect(floatableAction, SIGNAL(triggered(bool)), floatingAction, SLOT(setEnabled(bool))); + connect(floatableAction, &QAction::triggered, floatingAction, &QAction::setEnabled); - connect(floatingAction, SIGNAL(triggered(bool)), floatableAction, SLOT(setDisabled(bool))); - connect(movableAction, SIGNAL(triggered(bool)), floatableAction, SLOT(setEnabled(bool))); + connect(floatingAction, &QAction::triggered, floatableAction, &QAction::setDisabled); + connect(movableAction, &QAction::triggered, floatableAction, &QAction::setEnabled); tabMenu = new QMenu(this); tabMenu->setTitle(tr("Tab into")); - connect(tabMenu, SIGNAL(triggered(QAction*)), this, SLOT(tabInto(QAction*))); + connect(tabMenu, &QMenu::triggered, this, &ColorSwatch::tabInto); splitHMenu = new QMenu(this); splitHMenu->setTitle(tr("Split horizontally into")); - connect(splitHMenu, SIGNAL(triggered(QAction*)), this, SLOT(splitInto(QAction*))); + connect(splitHMenu, &QMenu::triggered, this, &ColorSwatch::splitInto); splitVMenu = new QMenu(this); splitVMenu->setTitle(tr("Split vertically into")); - connect(splitVMenu, SIGNAL(triggered(QAction*)), this, SLOT(splitInto(QAction*))); + connect(splitVMenu, &QMenu::triggered, this, &ColorSwatch::splitInto); - windowModifiedAction = new QAction(tr("Modified"), this); + QAction *windowModifiedAction = new QAction(tr("Modified"), this); windowModifiedAction->setCheckable(true); windowModifiedAction->setChecked(false); - connect(windowModifiedAction, SIGNAL(toggled(bool)), this, SLOT(setWindowModified(bool))); + connect(windowModifiedAction, &QAction::toggled, this, &QWidget::setWindowModified); menu = new QMenu(colorName, this); menu->addAction(toggleViewAction()); - QAction *action = menu->addAction(tr("Raise")); - connect(action, SIGNAL(triggered()), this, SLOT(raise())); - menu->addAction(changeSizeHintsAction); + menu->addAction(tr("Raise"), this, &QWidget::raise); + menu->addAction(tr("Change Size Hints..."), swatch, &ColorDock::changeSizeHints); + menu->addSeparator(); menu->addAction(closableAction); menu->addAction(movableAction); @@ -379,18 +368,17 @@ ColorSwatch::ColorSwatch(const QString &colorName, QWidget *parent, Qt::WindowFl menu->addSeparator(); menu->addAction(windowModifiedAction); - connect(menu, SIGNAL(aboutToShow()), this, SLOT(updateContextMenu())); + connect(menu, &QMenu::aboutToShow, this, &ColorSwatch::updateContextMenu); - if(colorName == "Black") { - leftAction->setShortcut(Qt::CTRL|Qt::Key_W); - rightAction->setShortcut(Qt::CTRL|Qt::Key_E); - toggleViewAction()->setShortcut(Qt::CTRL|Qt::Key_R); + if (colorName == QLatin1String("Black")) { + leftAction->setShortcut(Qt::CTRL | Qt::Key_W); + rightAction->setShortcut(Qt::CTRL | Qt::Key_E); + toggleViewAction()->setShortcut(Qt::CTRL | Qt::Key_R); } } void ColorSwatch::updateContextMenu() { - QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget()); const Qt::DockWidgetArea area = mainWindow->dockWidgetArea(this); const Qt::DockWidgetAreas areas = allowedAreas(); @@ -448,48 +436,36 @@ void ColorSwatch::updateContextMenu() splitVMenu->clear(); QList<ColorSwatch*> dock_list = mainWindow->findChildren<ColorSwatch*>(); foreach (ColorSwatch *dock, dock_list) { -// if (!dock->isVisible() || dock->isFloating()) -// continue; tabMenu->addAction(dock->objectName()); splitHMenu->addAction(dock->objectName()); splitVMenu->addAction(dock->objectName()); } } -void ColorSwatch::splitInto(QAction *action) +static ColorSwatch *findByName(const QMainWindow *mainWindow, const QString &name) { - QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget()); - QList<ColorSwatch*> dock_list = mainWindow->findChildren<ColorSwatch*>(); - ColorSwatch *target = 0; - foreach (ColorSwatch *dock, dock_list) { - if (action->text() == dock->objectName()) { - target = dock; - break; - } + foreach (ColorSwatch *dock, mainWindow->findChildren<ColorSwatch*>()) { + if (name == dock->objectName()) + return dock; } - if (target == 0) + return Q_NULLPTR; +} + +void ColorSwatch::splitInto(QAction *action) +{ + ColorSwatch *target = findByName(mainWindow, action->text()); + if (!target) return; - Qt::Orientation o = action->parent() == splitHMenu - ? Qt::Horizontal : Qt::Vertical; + const Qt::Orientation o = action->parent() == splitHMenu + ? Qt::Horizontal : Qt::Vertical; mainWindow->splitDockWidget(target, this, o); } void ColorSwatch::tabInto(QAction *action) { - QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget()); - QList<ColorSwatch*> dock_list = mainWindow->findChildren<ColorSwatch*>(); - ColorSwatch *target = 0; - foreach (ColorSwatch *dock, dock_list) { - if (action->text() == dock->objectName()) { - target = dock; - break; - } - } - if (target == 0) - return; - - mainWindow->tabifyDockWidget(target, this); + if (ColorSwatch *target = findByName(mainWindow, action->text())) + mainWindow->tabifyDockWidget(target, this); } void ColorSwatch::contextMenuEvent(QContextMenuEvent *event) @@ -506,7 +482,6 @@ void ColorSwatch::resizeEvent(QResizeEvent *e) QDockWidget::resizeEvent(e); } - void ColorSwatch::allow(Qt::DockWidgetArea area, bool a) { Qt::DockWidgetAreas areas = allowedAreas(); @@ -523,9 +498,9 @@ void ColorSwatch::allow(Qt::DockWidgetArea area, bool a) void ColorSwatch::place(Qt::DockWidgetArea area, bool p) { - if (!p) return; + if (!p) + return; - QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget()); mainWindow->addDockWidget(area, this); if (allowedAreasActions->isEnabled()) { @@ -596,10 +571,10 @@ QSize BlueTitleBar::minimumSizeHint() const BlueTitleBar::BlueTitleBar(QWidget *parent) : QWidget(parent) + , leftPm(QPixmap(":/res/titlebarLeft.png")) + , centerPm(QPixmap(":/res/titlebarCenter.png")) + , rightPm(QPixmap(":/res/titlebarRight.png")) { - leftPm = QPixmap(":/res/titlebarLeft.png"); - centerPm = QPixmap(":/res/titlebarCenter.png"); - rightPm = QPixmap(":/res/titlebarRight.png"); } void BlueTitleBar::paintEvent(QPaintEvent*) @@ -687,7 +662,7 @@ void BlueTitleBar::updateMask() { QPainter painter(&bitmap); - ///initialize to transparent + // initialize to transparent painter.fillRect(rect, Qt::color0); QRect contents = rect; @@ -696,10 +671,7 @@ void BlueTitleBar::updateMask() contents.setBottom(contents.bottom()-y()); painter.fillRect(contents, Qt::color1); - - - //let's pait the titlebar - + // let's paint the titlebar QRect titleRect = this->geometry(); if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar) { @@ -722,7 +694,6 @@ void BlueTitleBar::updateMask() QRect rect = titleRect; - painter.drawPixmap(rect.topLeft(), leftPm.mask()); painter.fillRect(rect.left() + leftPm.width(), rect.top(), rect.width() - leftPm.width() - rightPm.width(), diff --git a/examples/widgets/mainwindows/mainwindow/colorswatch.h b/examples/widgets/mainwindows/mainwindow/colorswatch.h index 6d02592b22..8827a7dca7 100644 --- a/examples/widgets/mainwindows/mainwindow/colorswatch.h +++ b/examples/widgets/mainwindows/mainwindow/colorswatch.h @@ -44,45 +44,15 @@ class ColorSwatch : public QDockWidget { Q_OBJECT - QAction *closableAction; - QAction *movableAction; - QAction *floatableAction; - QAction *floatingAction; - QAction *verticalTitleBarAction; - - QActionGroup *allowedAreasActions; - QAction *allowLeftAction; - QAction *allowRightAction; - QAction *allowTopAction; - QAction *allowBottomAction; - - QActionGroup *areaActions; - QAction *leftAction; - QAction *rightAction; - QAction *topAction; - QAction *bottomAction; - - QAction *changeSizeHintsAction; - - QMenu *tabMenu; - QMenu *splitHMenu; - QMenu *splitVMenu; - - QAction *windowModifiedAction; - public: - explicit ColorSwatch(const QString &colorName, QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit ColorSwatch(const QString &colorName, QMainWindow *parent = Q_NULLPTR, Qt::WindowFlags flags = 0); - QMenu *menu; void setCustomSizeHint(const QSize &size); + QMenu *colorSwatchMenu() const { return menu; } protected: - virtual void contextMenuEvent(QContextMenuEvent *event) Q_DECL_OVERRIDE; - virtual void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE; - -private: - void allow(Qt::DockWidgetArea area, bool allow); - void place(Qt::DockWidgetArea area, bool place); + void contextMenuEvent(QContextMenuEvent *event) Q_DECL_OVERRIDE; + void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE; private slots: void changeClosable(bool on); @@ -104,25 +74,57 @@ private slots: void splitInto(QAction *action); void tabInto(QAction *action); + +private: + void allow(Qt::DockWidgetArea area, bool allow); + void place(Qt::DockWidgetArea area, bool place); + + QAction *closableAction; + QAction *movableAction; + QAction *floatableAction; + QAction *floatingAction; + QAction *verticalTitleBarAction; + + QActionGroup *allowedAreasActions; + QAction *allowLeftAction; + QAction *allowRightAction; + QAction *allowTopAction; + QAction *allowBottomAction; + + QActionGroup *areaActions; + QAction *leftAction; + QAction *rightAction; + QAction *topAction; + QAction *bottomAction; + + QMenu *tabMenu; + QMenu *splitHMenu; + QMenu *splitVMenu; + QMenu *menu; + + QMainWindow *mainWindow; }; class BlueTitleBar : public QWidget { Q_OBJECT public: - BlueTitleBar(QWidget *parent = 0); + explicit BlueTitleBar(QWidget *parent = Q_NULLPTR); QSize sizeHint() const Q_DECL_OVERRIDE { return minimumSizeHint(); } QSize minimumSizeHint() const Q_DECL_OVERRIDE; + protected: void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + public slots: void updateMask(); private: - QPixmap leftPm, centerPm, rightPm; + const QPixmap leftPm; + const QPixmap centerPm; + const QPixmap rightPm; }; - -#endif +#endif // COLORSWATCH_H diff --git a/examples/widgets/mainwindows/mainwindow/main.cpp b/examples/widgets/mainwindows/mainwindow/main.cpp index 2192074791..b32b595a2d 100644 --- a/examples/widgets/mainwindows/mainwindow/main.cpp +++ b/examples/widgets/mainwindows/mainwindow/main.cpp @@ -37,9 +37,10 @@ #include <QPainterPath> #include <QPainter> #include <QMap> -#include <qdebug.h> +#include <QDebug> -void render_qt_text(QPainter *painter, int w, int h, const QColor &color) { +void render_qt_text(QPainter *painter, int w, int h, const QColor &color) +{ QPainterPath path; path.moveTo(-0.083695, 0.283849); path.cubicTo(-0.049581, 0.349613, -0.012720, 0.397969, 0.026886, 0.428917); @@ -108,47 +109,67 @@ void render_qt_text(QPainter *painter, int w, int h, const QColor &color) { painter->drawPath(path); } -void usage() +static void usage() { qWarning() << "Usage: mainwindow [-SizeHint<color> <width>x<height>] ..."; exit(1); } -QMap<QString, QSize> parseCustomSizeHints(int argc, char **argv) -{ - QMap<QString, QSize> result; - - for (int i = 1; i < argc; ++i) { - QString arg = QString::fromLocal8Bit(argv[i]); +enum ParseCommandLineArgumentsResult { + CommandLineArgumentsOk, + CommandLineArgumentsError, + HelpRequested +}; +static ParseCommandLineArgumentsResult + parseCustomSizeHints(const QStringList &arguments, MainWindow::CustomSizeHintMap *result) +{ + result->clear(); + const int argumentCount = arguments.size(); + for (int i = 1; i < argumentCount; ++i) { + const QString &arg = arguments.at(i); if (arg.startsWith(QLatin1String("-SizeHint"))) { - QString name = arg.mid(9); + const QString name = arg.mid(9); if (name.isEmpty()) - usage(); - if (++i == argc) - usage(); - QString sizeStr = QString::fromLocal8Bit(argv[i]); - int idx = sizeStr.indexOf(QLatin1Char('x')); + return CommandLineArgumentsError; + if (++i == argumentCount) + return CommandLineArgumentsError; + const QString sizeStr = arguments.at(i); + const int idx = sizeStr.indexOf(QLatin1Char('x')); if (idx == -1) - usage(); + return CommandLineArgumentsError; bool ok; - int w = sizeStr.left(idx).toInt(&ok); + const int w = sizeStr.leftRef(idx).toInt(&ok); if (!ok) - usage(); - int h = sizeStr.mid(idx + 1).toInt(&ok); + return CommandLineArgumentsError; + const int h = sizeStr.midRef(idx + 1).toInt(&ok); if (!ok) - usage(); - result[name] = QSize(w, h); + return CommandLineArgumentsError; + result->insert(name, QSize(w, h)); + } else if (arg == QLatin1String("-h") || arg == QLatin1String("--help")) { + return HelpRequested; + } else { + return CommandLineArgumentsError; } } - return result; + return CommandLineArgumentsOk; } int main(int argc, char **argv) { QApplication app(argc, argv); - QMap<QString, QSize> customSizeHints = parseCustomSizeHints(argc, argv); + MainWindow::CustomSizeHintMap customSizeHints; + switch (parseCustomSizeHints(QCoreApplication::arguments(), &customSizeHints)) { + case CommandLineArgumentsOk: + break; + case CommandLineArgumentsError: + usage(); + return -1; + case HelpRequested: + usage(); + return 0; + } MainWindow mainWin(customSizeHints); mainWin.resize(800, 600); mainWin.show(); diff --git a/examples/widgets/mainwindows/mainwindow/mainwindow.cpp b/examples/widgets/mainwindows/mainwindow/mainwindow.cpp index 6349f7aa2e..91579ae611 100644 --- a/examples/widgets/mainwindows/mainwindow/mainwindow.cpp +++ b/examples/widgets/mainwindows/mainwindow/mainwindow.cpp @@ -44,6 +44,7 @@ #include <QFile> #include <QDataStream> #include <QFileDialog> +#include <QDialogButtonBox> #include <QMessageBox> #include <QSignalMapper> #include <QApplication> @@ -53,9 +54,10 @@ #include <QComboBox> #include <QLabel> #include <QPushButton> -#include <qdebug.h> +#include <QTextEdit> +#include <QDebug> -static const char * const message = +static const char message[] = "<p><b>Qt Main Window Example</b></p>" "<p>This is a demonstration of the QMainWindow, QToolBar and " @@ -75,14 +77,14 @@ static const char * const message = Q_DECLARE_METATYPE(QDockWidget::DockWidgetFeatures) -MainWindow::MainWindow(const QMap<QString, QSize> &customSizeHints, - QWidget *parent, Qt::WindowFlags flags) +MainWindow::MainWindow(const CustomSizeHintMap &customSizeHints, + QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags) { setObjectName("MainWindow"); setWindowTitle("Qt Main Window Example"); - center = new QTextEdit(this); + QTextEdit *center = new QTextEdit(this); center->setReadOnly(true); center->setMinimumSize(400, 205); setCentralWidget(center); @@ -116,49 +118,48 @@ void MainWindow::setupMenuBar() { QMenu *menu = menuBar()->addMenu(tr("&File")); - QAction *action = menu->addAction(tr("Save layout...")); - connect(action, SIGNAL(triggered()), this, SLOT(saveLayout())); - - action = menu->addAction(tr("Load layout...")); - connect(action, SIGNAL(triggered()), this, SLOT(loadLayout())); - - action = menu->addAction(tr("Switch layout direction")); - connect(action, SIGNAL(triggered()), this, SLOT(switchLayoutDirection())); + menu->addAction(tr("Save layout..."), this, &MainWindow::saveLayout); + menu->addAction(tr("Load layout..."), this, &MainWindow::loadLayout); + menu->addAction(tr("Switch layout direction"),this, &MainWindow::switchLayoutDirection); menu->addSeparator(); - - menu->addAction(tr("&Quit"), this, SLOT(close())); + menu->addAction(tr("&Quit"), this, &QWidget::close); mainWindowMenu = menuBar()->addMenu(tr("Main window")); - action = mainWindowMenu->addAction(tr("Animated docks")); + QAction *action = mainWindowMenu->addAction(tr("Animated docks")); action->setCheckable(true); action->setChecked(dockOptions() & AnimatedDocks); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); action = mainWindowMenu->addAction(tr("Allow nested docks")); action->setCheckable(true); action->setChecked(dockOptions() & AllowNestedDocks); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); action = mainWindowMenu->addAction(tr("Allow tabbed docks")); action->setCheckable(true); action->setChecked(dockOptions() & AllowTabbedDocks); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); action = mainWindowMenu->addAction(tr("Force tabbed docks")); action->setCheckable(true); action->setChecked(dockOptions() & ForceTabbedDocks); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); action = mainWindowMenu->addAction(tr("Vertical tabs")); action->setCheckable(true); action->setChecked(dockOptions() & VerticalTabs); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); + + action = mainWindowMenu->addAction(tr("Grouped dragging")); + action->setCheckable(true); + action->setChecked(dockOptions() & GroupedDragging); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); QMenu *toolBarMenu = menuBar()->addMenu(tr("Tool bars")); for (int i = 0; i < toolBars.count(); ++i) - toolBarMenu->addMenu(toolBars.at(i)->menu); + toolBarMenu->addMenu(toolBars.at(i)->toolbarMenu()); #ifdef Q_OS_OSX toolBarMenu->addSeparator(); @@ -166,7 +167,7 @@ void MainWindow::setupMenuBar() action = toolBarMenu->addAction(tr("Unified")); action->setCheckable(true); action->setChecked(unifiedTitleAndToolBarOnMac()); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setUnifiedTitleAndToolBarOnMac(bool))); + connect(action, &QAction::toggled, this, &QMainWindow::setUnifiedTitleAndToolBarOnMac); #endif dockWidgetMenu = menuBar()->addMenu(tr("&Dock Widgets")); @@ -187,6 +188,8 @@ void MainWindow::setDockOptions() opts |= ForceTabbedDocks; if (actions.at(4)->isChecked()) opts |= VerticalTabs; + if (actions.at(5)->isChecked()) + opts |= GroupedDragging; QMainWindow::setDockOptions(opts); } @@ -200,8 +203,7 @@ void MainWindow::saveLayout() QFile file(fileName); if (!file.open(QFile::WriteOnly)) { QString msg = tr("Failed to open %1\n%2") - .arg(fileName) - .arg(file.errorString()); + .arg(QDir::toNativeSeparators(fileName), file.errorString()); QMessageBox::warning(this, tr("Error"), msg); return; } @@ -217,8 +219,7 @@ void MainWindow::saveLayout() if (!ok) { QString msg = tr("Error writing to %1\n%2") - .arg(fileName) - .arg(file.errorString()); + .arg(QDir::toNativeSeparators(fileName), file.errorString()); QMessageBox::warning(this, tr("Error"), msg); return; } @@ -233,8 +234,7 @@ void MainWindow::loadLayout() QFile file(fileName); if (!file.open(QFile::ReadOnly)) { QString msg = tr("Failed to open %1\n%2") - .arg(fileName) - .arg(file.errorString()); + .arg(QDir::toNativeSeparators(fileName), file.errorString()); QMessageBox::warning(this, tr("Error"), msg); return; } @@ -259,56 +259,65 @@ void MainWindow::loadLayout() ok = restoreState(layout_data); if (!ok) { - QString msg = tr("Error reading %1") - .arg(fileName); + QString msg = tr("Error reading %1").arg(QDir::toNativeSeparators(fileName)); QMessageBox::warning(this, tr("Error"), msg); return; } } -QAction *addAction(QMenu *menu, const QString &text, QActionGroup *group, QSignalMapper *mapper, - int id) +class DockWidgetAreaCornerFunctor { +public: + explicit DockWidgetAreaCornerFunctor(QMainWindow *mw, Qt::Corner c, Qt::DockWidgetArea a) + : m_mainWindow(mw), m_area(a), m_corner(c) {} + + void operator()() const { m_mainWindow->setCorner(m_corner, m_area); } + +private: + QMainWindow *m_mainWindow; + Qt::DockWidgetArea m_area; + Qt::Corner m_corner; +}; + +static QAction *addCornerAction(const QString &text, QMainWindow *mw, QMenu *menu, QActionGroup *group, + Qt::Corner c, Qt::DockWidgetArea a) { - bool first = group->actions().isEmpty(); - QAction *result = menu->addAction(text); + QAction *result = menu->addAction(text, mw, DockWidgetAreaCornerFunctor(mw, c, a)); result->setCheckable(true); - result->setChecked(first); group->addAction(result); - QObject::connect(result, SIGNAL(triggered()), mapper, SLOT(map())); - mapper->setMapping(result, id); return result; } -void MainWindow::setupDockWidgets(const QMap<QString, QSize> &customSizeHints) +void MainWindow::setupDockWidgets(const CustomSizeHintMap &customSizeHints) { qRegisterMetaType<QDockWidget::DockWidgetFeatures>(); - mapper = new QSignalMapper(this); - connect(mapper, SIGNAL(mapped(int)), this, SLOT(setCorner(int))); - - QMenu *corner_menu = dockWidgetMenu->addMenu(tr("Top left corner")); + QMenu *cornerMenu = dockWidgetMenu->addMenu(tr("Top left corner")); QActionGroup *group = new QActionGroup(this); group->setExclusive(true); - ::addAction(corner_menu, tr("Top dock area"), group, mapper, 0); - ::addAction(corner_menu, tr("Left dock area"), group, mapper, 1); + QAction *cornerAction = addCornerAction(tr("Top dock area"), this, cornerMenu, group, Qt::TopLeftCorner, Qt::TopDockWidgetArea); + cornerAction->setChecked(true); + addCornerAction(tr("Left dock area"), this, cornerMenu, group, Qt::TopLeftCorner, Qt::LeftDockWidgetArea); - corner_menu = dockWidgetMenu->addMenu(tr("Top right corner")); + cornerMenu = dockWidgetMenu->addMenu(tr("Top right corner")); group = new QActionGroup(this); group->setExclusive(true); - ::addAction(corner_menu, tr("Top dock area"), group, mapper, 2); - ::addAction(corner_menu, tr("Right dock area"), group, mapper, 3); + cornerAction = addCornerAction(tr("Top dock area"), this, cornerMenu, group, Qt::TopRightCorner, Qt::TopDockWidgetArea); + cornerAction->setChecked(true); + addCornerAction(tr("Right dock area"), this, cornerMenu, group, Qt::TopRightCorner, Qt::RightDockWidgetArea); - corner_menu = dockWidgetMenu->addMenu(tr("Bottom left corner")); + cornerMenu = dockWidgetMenu->addMenu(tr("Bottom left corner")); group = new QActionGroup(this); group->setExclusive(true); - ::addAction(corner_menu, tr("Bottom dock area"), group, mapper, 4); - ::addAction(corner_menu, tr("Left dock area"), group, mapper, 5); + cornerAction = addCornerAction(tr("Bottom dock area"), this, cornerMenu, group, Qt::BottomLeftCorner, Qt::BottomDockWidgetArea); + cornerAction->setChecked(true); + addCornerAction(tr("Left dock area"), this, cornerMenu, group, Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); - corner_menu = dockWidgetMenu->addMenu(tr("Bottom right corner")); + cornerMenu = dockWidgetMenu->addMenu(tr("Bottom right corner")); group = new QActionGroup(this); group->setExclusive(true); - ::addAction(corner_menu, tr("Bottom dock area"), group, mapper, 6); - ::addAction(corner_menu, tr("Right dock area"), group, mapper, 7); + cornerAction = addCornerAction(tr("Bottom dock area"), this, cornerMenu, group, Qt::BottomRightCorner, Qt::BottomDockWidgetArea); + cornerAction->setChecked(true); + addCornerAction(tr("Right dock area"), this, cornerMenu, group, Qt::BottomRightCorner, Qt::RightDockWidgetArea); dockWidgetMenu->addSeparator(); @@ -330,16 +339,16 @@ void MainWindow::setupDockWidgets(const QMap<QString, QSize> &customSizeHints) }; const int setCount = sizeof(sets) / sizeof(Set); + const QIcon qtIcon(QPixmap(":/res/qt.png")); for (int i = 0; i < setCount; ++i) { ColorSwatch *swatch = new ColorSwatch(tr(sets[i].name), this, Qt::WindowFlags(sets[i].flags)); - if (i%2) - swatch->setWindowIcon(QIcon(QPixmap(":/res/qt.png"))); + if (i % 2) + swatch->setWindowIcon(qtIcon); if (qstrcmp(sets[i].name, "Blue") == 0) { BlueTitleBar *titlebar = new BlueTitleBar(swatch); swatch->setTitleBarWidget(titlebar); - connect(swatch, SIGNAL(topLevelChanged(bool)), titlebar, SLOT(updateMask())); - connect(swatch, SIGNAL(featuresChanged(QDockWidget::DockWidgetFeatures)), titlebar, SLOT(updateMask()), Qt::QueuedConnection); - + connect(swatch, &QDockWidget::topLevelChanged, titlebar, &BlueTitleBar::updateMask); + connect(swatch, &QDockWidget::featuresChanged, titlebar, &BlueTitleBar::updateMask, Qt::QueuedConnection); } QString name = QString::fromLatin1(sets[i].name); @@ -347,69 +356,32 @@ void MainWindow::setupDockWidgets(const QMap<QString, QSize> &customSizeHints) swatch->setCustomSizeHint(customSizeHints.value(name)); addDockWidget(sets[i].area, swatch); - dockWidgetMenu->addMenu(swatch->menu); + dockWidgetMenu->addMenu(swatch->colorSwatchMenu()); } - createDockWidgetAction = new QAction(tr("Add dock widget..."), this); - connect(createDockWidgetAction, SIGNAL(triggered()), this, SLOT(createDockWidget())); destroyDockWidgetMenu = new QMenu(tr("Destroy dock widget"), this); destroyDockWidgetMenu->setEnabled(false); - connect(destroyDockWidgetMenu, SIGNAL(triggered(QAction*)), this, SLOT(destroyDockWidget(QAction*))); + connect(destroyDockWidgetMenu, &QMenu::triggered, this, &MainWindow::destroyDockWidget); dockWidgetMenu->addSeparator(); - dockWidgetMenu->addAction(createDockWidgetAction); + dockWidgetMenu->addAction(tr("Add dock widget..."), this, &MainWindow::createDockWidget); dockWidgetMenu->addMenu(destroyDockWidgetMenu); } -void MainWindow::setCorner(int id) -{ - switch (id) { - case 0: - QMainWindow::setCorner(Qt::TopLeftCorner, Qt::TopDockWidgetArea); - break; - case 1: - QMainWindow::setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); - break; - case 2: - QMainWindow::setCorner(Qt::TopRightCorner, Qt::TopDockWidgetArea); - break; - case 3: - QMainWindow::setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea); - break; - case 4: - QMainWindow::setCorner(Qt::BottomLeftCorner, Qt::BottomDockWidgetArea); - break; - case 5: - QMainWindow::setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); - break; - case 6: - QMainWindow::setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea); - break; - case 7: - QMainWindow::setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); - break; - } -} - -void MainWindow::showEvent(QShowEvent *event) -{ - QMainWindow::showEvent(event); -} - void MainWindow::switchLayoutDirection() { if (layoutDirection() == Qt::LeftToRight) - qApp->setLayoutDirection(Qt::RightToLeft); + QApplication::setLayoutDirection(Qt::RightToLeft); else - qApp->setLayoutDirection(Qt::LeftToRight); + QApplication::setLayoutDirection(Qt::LeftToRight); } class CreateDockWidgetDialog : public QDialog { public: - CreateDockWidgetDialog(QWidget *parent = 0); + explicit CreateDockWidgetDialog(QWidget *parent = Q_NULLPTR); - QString objectName() const; + QString enteredObjectName() const { return m_objectName->text(); } Qt::DockWidgetArea location() const; private: @@ -419,15 +391,17 @@ private: CreateDockWidgetDialog::CreateDockWidgetDialog(QWidget *parent) : QDialog(parent) + , m_objectName(new QLineEdit(this)) + , m_location(new QComboBox(this)) { + setWindowTitle(tr("Add Dock Widget")); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); QGridLayout *layout = new QGridLayout(this); layout->addWidget(new QLabel(tr("Object name:")), 0, 0); - m_objectName = new QLineEdit; layout->addWidget(m_objectName, 0, 1); layout->addWidget(new QLabel(tr("Location:")), 1, 0); - m_location = new QComboBox; m_location->setEditable(false); m_location->addItem(tr("Top")); m_location->addItem(tr("Left")); @@ -436,23 +410,10 @@ CreateDockWidgetDialog::CreateDockWidgetDialog(QWidget *parent) m_location->addItem(tr("Restore")); layout->addWidget(m_location, 1, 1); - QHBoxLayout *buttonLayout = new QHBoxLayout; - layout->addLayout(buttonLayout, 2, 0, 1, 2); - buttonLayout->addStretch(); - - QPushButton *cancelButton = new QPushButton(tr("Cancel")); - connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject())); - buttonLayout->addWidget(cancelButton); - QPushButton *okButton = new QPushButton(tr("Ok")); - connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); - buttonLayout->addWidget(okButton); - - okButton->setDefault(true); -} - -QString CreateDockWidgetDialog::objectName() const -{ - return m_objectName->text(); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::reject); + layout->addWidget(buttonBox, 2, 0, 1, 2); } Qt::DockWidgetArea CreateDockWidgetDialog::location() const @@ -471,13 +432,13 @@ Qt::DockWidgetArea CreateDockWidgetDialog::location() const void MainWindow::createDockWidget() { CreateDockWidgetDialog dialog(this); - int ret = dialog.exec(); - if (ret == QDialog::Rejected) + if (dialog.exec() == QDialog::Rejected) return; QDockWidget *dw = new QDockWidget; - dw->setObjectName(dialog.objectName()); - dw->setWindowTitle(dialog.objectName()); + const QString name = dialog.enteredObjectName(); + dw->setObjectName(name); + dw->setWindowTitle(name); dw->setWidget(new QTextEdit); Qt::DockWidgetArea area = dialog.location(); @@ -499,7 +460,7 @@ void MainWindow::createDockWidget() extraDockWidgets.append(dw); destroyDockWidgetMenu->setEnabled(true); - destroyDockWidgetMenu->addAction(new QAction(dialog.objectName(), this)); + destroyDockWidgetMenu->addAction(new QAction(name, this)); } void MainWindow::destroyDockWidget(QAction *action) diff --git a/examples/widgets/mainwindows/mainwindow/mainwindow.h b/examples/widgets/mainwindows/mainwindow/mainwindow.h index f9a6176b2d..162e977520 100644 --- a/examples/widgets/mainwindows/mainwindow/mainwindow.h +++ b/examples/widgets/mainwindows/mainwindow/mainwindow.h @@ -35,37 +35,25 @@ #define MAINWINDOW_H #include <QMainWindow> -#include <QTextEdit> class ToolBar; QT_FORWARD_DECLARE_CLASS(QMenu) -QT_FORWARD_DECLARE_CLASS(QSignalMapper) class MainWindow : public QMainWindow { Q_OBJECT - QTextEdit *center; - QList<ToolBar*> toolBars; - QMenu *dockWidgetMenu; - QMenu *mainWindowMenu; - QSignalMapper *mapper; - QList<QDockWidget*> extraDockWidgets; - QAction *createDockWidgetAction; - QMenu *destroyDockWidgetMenu; - public: - MainWindow(const QMap<QString, QSize> &customSizeHints, - QWidget *parent = 0, Qt::WindowFlags flags = 0); + typedef QMap<QString, QSize> CustomSizeHintMap; -protected: - void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; + explicit MainWindow(const CustomSizeHintMap &customSizeHints, + QWidget *parent = Q_NULLPTR, + Qt::WindowFlags flags = 0); public slots: void actionTriggered(QAction *action); void saveLayout(); void loadLayout(); - void setCorner(int id); void switchLayoutDirection(); void setDockOptions(); @@ -75,8 +63,13 @@ public slots: private: void setupToolBar(); void setupMenuBar(); - void setupDockWidgets(const QMap<QString, QSize> &customSizeHints); -}; + void setupDockWidgets(const CustomSizeHintMap &customSizeHints); + QList<ToolBar*> toolBars; + QMenu *dockWidgetMenu; + QMenu *mainWindowMenu; + QList<QDockWidget *> extraDockWidgets; + QMenu *destroyDockWidgetMenu; +}; -#endif +#endif // MAINWINDOW_H diff --git a/examples/widgets/mainwindows/mainwindow/toolbar.cpp b/examples/widgets/mainwindows/mainwindow/toolbar.cpp index 280ba965d6..a9b308370a 100644 --- a/examples/widgets/mainwindows/mainwindow/toolbar.cpp +++ b/examples/widgets/mainwindows/mainwindow/toolbar.cpp @@ -63,15 +63,15 @@ static QPixmap genIcon(const QSize &iconSize, int number, const QColor &color) { return genIcon(iconSize, QString::number(number), color); } ToolBar::ToolBar(const QString &title, QWidget *parent) - : QToolBar(parent), spinbox(0), spinboxAction(0) + : QToolBar(parent) + , spinbox(Q_NULLPTR) + , spinboxAction(Q_NULLPTR) { - tip = 0; setWindowTitle(title); setObjectName(title); setIconSize(QSize(32, 32)); - QColor bg(palette().background().color()); menu = new QMenu("One", this); menu->setIcon(genIcon(iconSize(), 1, Qt::black)); menu->addAction(genIcon(iconSize(), "A", Qt::blue), "A"); @@ -90,43 +90,43 @@ ToolBar::ToolBar(const QString &title, QWidget *parent) addAction(genIcon(iconSize(), 6, Qt::yellow), "Six"); orderAction = new QAction(this); orderAction->setText(tr("Order Items in Tool Bar")); - connect(orderAction, SIGNAL(triggered()), SLOT(order())); + connect(orderAction, &QAction::triggered, this, &ToolBar::order); randomizeAction = new QAction(this); randomizeAction->setText(tr("Randomize Items in Tool Bar")); - connect(randomizeAction, SIGNAL(triggered()), SLOT(randomize())); + connect(randomizeAction, &QAction::triggered, this, &ToolBar::randomize); addSpinBoxAction = new QAction(this); addSpinBoxAction->setText(tr("Add Spin Box")); - connect(addSpinBoxAction, SIGNAL(triggered()), SLOT(addSpinBox())); + connect(addSpinBoxAction, &QAction::triggered, this, &ToolBar::addSpinBox); removeSpinBoxAction = new QAction(this); removeSpinBoxAction->setText(tr("Remove Spin Box")); removeSpinBoxAction->setEnabled(false); - connect(removeSpinBoxAction, SIGNAL(triggered()), SLOT(removeSpinBox())); + connect(removeSpinBoxAction, &QAction::triggered, this, &ToolBar::removeSpinBox); movableAction = new QAction(tr("Movable"), this); movableAction->setCheckable(true); - connect(movableAction, SIGNAL(triggered(bool)), SLOT(changeMovable(bool))); + connect(movableAction, &QAction::triggered, this, &ToolBar::changeMovable); allowedAreasActions = new QActionGroup(this); allowedAreasActions->setExclusive(false); allowLeftAction = new QAction(tr("Allow on Left"), this); allowLeftAction->setCheckable(true); - connect(allowLeftAction, SIGNAL(triggered(bool)), SLOT(allowLeft(bool))); + connect(allowLeftAction, &QAction::triggered, this, &ToolBar::allowLeft); allowRightAction = new QAction(tr("Allow on Right"), this); allowRightAction->setCheckable(true); - connect(allowRightAction, SIGNAL(triggered(bool)), SLOT(allowRight(bool))); + connect(allowRightAction, &QAction::triggered, this, &ToolBar::allowRight); allowTopAction = new QAction(tr("Allow on Top"), this); allowTopAction->setCheckable(true); - connect(allowTopAction, SIGNAL(triggered(bool)), SLOT(allowTop(bool))); + connect(allowTopAction, &QAction::triggered, this, &ToolBar::allowTop); allowBottomAction = new QAction(tr("Allow on Bottom"), this); allowBottomAction->setCheckable(true); - connect(allowBottomAction, SIGNAL(triggered(bool)), SLOT(allowBottom(bool))); + connect(allowBottomAction, &QAction::triggered, this, &ToolBar::allowBottom); allowedAreasActions->addAction(allowLeftAction); allowedAreasActions->addAction(allowRightAction); @@ -138,31 +138,28 @@ ToolBar::ToolBar(const QString &title, QWidget *parent) leftAction = new QAction(tr("Place on Left") , this); leftAction->setCheckable(true); - connect(leftAction, SIGNAL(triggered(bool)), SLOT(placeLeft(bool))); + connect(leftAction, &QAction::triggered, this, &ToolBar::placeLeft); rightAction = new QAction(tr("Place on Right") , this); rightAction->setCheckable(true); - connect(rightAction, SIGNAL(triggered(bool)), SLOT(placeRight(bool))); + connect(rightAction, &QAction::triggered, this, &ToolBar::placeRight); topAction = new QAction(tr("Place on Top") , this); topAction->setCheckable(true); - connect(topAction, SIGNAL(triggered(bool)), SLOT(placeTop(bool))); + connect(topAction, &QAction::triggered, this, &ToolBar::placeTop); bottomAction = new QAction(tr("Place on Bottom") , this); bottomAction->setCheckable(true); - connect(bottomAction, SIGNAL(triggered(bool)), SLOT(placeBottom(bool))); + connect(bottomAction, &QAction::triggered, this, &ToolBar::placeBottom); areaActions->addAction(leftAction); areaActions->addAction(rightAction); areaActions->addAction(topAction); areaActions->addAction(bottomAction); - toolBarBreakAction = new QAction(tr("Insert break"), this); - connect(toolBarBreakAction, SIGNAL(triggered(bool)), this, SLOT(insertToolBarBreak())); + connect(movableAction, &QAction::triggered, areaActions, &QActionGroup::setEnabled); - connect(movableAction, SIGNAL(triggered(bool)), areaActions, SLOT(setEnabled(bool))); - - connect(movableAction, SIGNAL(triggered(bool)), allowedAreasActions, SLOT(setEnabled(bool))); + connect(movableAction, &QAction::triggered, allowedAreasActions, &QActionGroup::setEnabled); menu = new QMenu(title, this); menu->addAction(toggleViewAction()); @@ -179,9 +176,9 @@ ToolBar::ToolBar(const QString &title, QWidget *parent) menu->addSeparator(); menu->addActions(areaActions->actions()); menu->addSeparator(); - menu->addAction(toolBarBreakAction); + menu->addAction(tr("Insert break"), this, &ToolBar::insertToolBarBreak); - connect(menu, SIGNAL(aboutToShow()), this, SLOT(updateMenu())); + connect(menu, &QMenu::aboutToShow, this, &ToolBar::updateMenu); randomize(); } @@ -223,10 +220,9 @@ void ToolBar::updateMenu() void ToolBar::order() { - QList<QAction *> ordered, actions1 = actions(), - actions2 = findChildren<QAction *>(); - while (!actions2.isEmpty()) { - QAction *action = actions2.takeFirst(); + QList<QAction *> ordered; + QList<QAction *> actions1 = actions(); + foreach (QAction *action, findChildren<QAction *>()) { if (!actions1.contains(action)) continue; actions1.removeAll(action); @@ -241,7 +237,8 @@ void ToolBar::order() void ToolBar::randomize() { - QList<QAction *> randomized, actions = this->actions(); + QList<QAction *> randomized; + QList<QAction *> actions = this->actions(); while (!actions.isEmpty()) { QAction *action = actions.takeAt(rand() % actions.size()); randomized.append(action); @@ -254,9 +251,8 @@ void ToolBar::randomize() void ToolBar::addSpinBox() { - if (!spinbox) { + if (!spinbox) spinbox = new QSpinBox(this); - } if (!spinboxAction) spinboxAction = addWidget(spinbox); else @@ -341,35 +337,3 @@ void ToolBar::insertToolBarBreak() mainWindow->insertToolBarBreak(this); } - -void ToolBar::enterEvent(QEvent*) -{ -/* - These labels on top of toolbars look darn ugly - - if (tip == 0) { - tip = new QLabel(windowTitle(), this); - QPalette pal = tip->palette(); - QColor c = Qt::black; - c.setAlpha(100); - pal.setColor(QPalette::Window, c); - pal.setColor(QPalette::Foreground, Qt::white); - tip->setPalette(pal); - tip->setAutoFillBackground(true); - tip->setMargin(3); - tip->setText(windowTitle()); - } - QPoint c = rect().center(); - QSize hint = tip->sizeHint(); - tip->setGeometry(c.x() - hint.width()/2, c.y() - hint.height()/2, - hint.width(), hint.height()); - - tip->show(); -*/ -} - -void ToolBar::leaveEvent(QEvent*) -{ - if (tip != 0) - tip->hide(); -} diff --git a/examples/widgets/mainwindows/mainwindow/toolbar.h b/examples/widgets/mainwindows/mainwindow/toolbar.h index b1674a2034..2629d9d7a7 100644 --- a/examples/widgets/mainwindows/mainwindow/toolbar.h +++ b/examples/widgets/mainwindows/mainwindow/toolbar.h @@ -40,49 +40,15 @@ QT_FORWARD_DECLARE_CLASS(QAction) QT_FORWARD_DECLARE_CLASS(QActionGroup) QT_FORWARD_DECLARE_CLASS(QMenu) QT_FORWARD_DECLARE_CLASS(QSpinBox) -QT_FORWARD_DECLARE_CLASS(QLabel) class ToolBar : public QToolBar { Q_OBJECT - QSpinBox *spinbox; - QAction *spinboxAction; - - QAction *orderAction; - QAction *randomizeAction; - QAction *addSpinBoxAction; - QAction *removeSpinBoxAction; - - QAction *movableAction; - - QActionGroup *allowedAreasActions; - QAction *allowLeftAction; - QAction *allowRightAction; - QAction *allowTopAction; - QAction *allowBottomAction; - - QActionGroup *areaActions; - QAction *leftAction; - QAction *rightAction; - QAction *topAction; - QAction *bottomAction; - - QAction *toolBarBreakAction; - public: - ToolBar(const QString &title, QWidget *parent); - - QMenu *menu; + explicit ToolBar(const QString &title, QWidget *parent); -protected: - void enterEvent(QEvent*) Q_DECL_OVERRIDE; - void leaveEvent(QEvent*) Q_DECL_OVERRIDE; - -private: - void allow(Qt::ToolBarArea area, bool allow); - void place(Qt::ToolBarArea area, bool place); - QLabel *tip; + QMenu *toolbarMenu() const { return menu; } private slots: void order(); @@ -105,6 +71,32 @@ private slots: void updateMenu(); void insertToolBarBreak(); +private: + void allow(Qt::ToolBarArea area, bool allow); + void place(Qt::ToolBarArea area, bool place); + + QSpinBox *spinbox; + QAction *spinboxAction; + + QMenu *menu; + QAction *orderAction; + QAction *randomizeAction; + QAction *addSpinBoxAction; + QAction *removeSpinBoxAction; + + QAction *movableAction; + + QActionGroup *allowedAreasActions; + QAction *allowLeftAction; + QAction *allowRightAction; + QAction *allowTopAction; + QAction *allowBottomAction; + + QActionGroup *areaActions; + QAction *leftAction; + QAction *rightAction; + QAction *topAction; + QAction *bottomAction; }; -#endif +#endif // TOOLBAR_H diff --git a/examples/widgets/mainwindows/mainwindows.pro b/examples/widgets/mainwindows/mainwindows.pro index 52179ec9bd..dcda89abaf 100644 --- a/examples/widgets/mainwindows/mainwindows.pro +++ b/examples/widgets/mainwindows/mainwindows.pro @@ -4,5 +4,4 @@ SUBDIRS = application \ mainwindow \ mdi \ menus \ - recentfiles \ sdi diff --git a/examples/widgets/mainwindows/mdi/main.cpp b/examples/widgets/mainwindows/mdi/main.cpp index 5976c85c1c..f02285d1cf 100644 --- a/examples/widgets/mainwindows/mdi/main.cpp +++ b/examples/widgets/mainwindows/mdi/main.cpp @@ -49,6 +49,8 @@ int main(int argc, char *argv[]) Q_INIT_RESOURCE(mdi); QApplication app(argc, argv); + QCoreApplication::setApplicationName("MDI Example"); + QCoreApplication::setOrganizationName("QtProject"); QCoreApplication::setApplicationVersion(QT_VERSION_STR); QCommandLineParser parser; parser.setApplicationDescription("Qt MDI Example"); diff --git a/examples/widgets/mainwindows/mdi/mainwindow.cpp b/examples/widgets/mainwindows/mdi/mainwindow.cpp index 83ffbf6557..35136c81c4 100644 --- a/examples/widgets/mainwindows/mdi/mainwindow.cpp +++ b/examples/widgets/mainwindows/mdi/mainwindow.cpp @@ -44,20 +44,15 @@ #include "mdichild.h" MainWindow::MainWindow() + : mdiArea(new QMdiArea) { - mdiArea = new QMdiArea; mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); setCentralWidget(mdiArea); - connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)), - this, SLOT(updateMenus())); - windowMapper = new QSignalMapper(this); - connect(windowMapper, SIGNAL(mapped(QWidget*)), - this, SLOT(setActiveSubWindow(QWidget*))); + connect(mdiArea, &QMdiArea::subWindowActivated, + this, &MainWindow::updateMenus); createActions(); - createMenus(); - createToolBars(); createStatusBar(); updateMenus(); @@ -87,20 +82,24 @@ void MainWindow::newFile() void MainWindow::open() { - QString fileName = QFileDialog::getOpenFileName(this); - if (!fileName.isEmpty()) { - QMdiSubWindow *existing = findMdiChild(fileName); - if (existing) { - mdiArea->setActiveSubWindow(existing); - return; - } + const QString fileName = QFileDialog::getOpenFileName(this); + if (!fileName.isEmpty()) + openFile(fileName); +} - if (openFile(fileName)) - statusBar()->showMessage(tr("File loaded"), 2000); +bool MainWindow::openFile(const QString &fileName) +{ + if (QMdiSubWindow *existing = findMdiChild(fileName)) { + mdiArea->setActiveSubWindow(existing); + return true; } + const bool succeeded = loadFile(fileName); + if (succeeded) + statusBar()->showMessage(tr("File loaded"), 2000); + return succeeded; } -bool MainWindow::openFile(const QString &fileName) +bool MainWindow::loadFile(const QString &fileName) { MdiChild *child = createMdiChild(); const bool succeeded = child->loadFile(fileName); @@ -108,9 +107,87 @@ bool MainWindow::openFile(const QString &fileName) child->show(); else child->close(); + MainWindow::prependToRecentFiles(fileName); return succeeded; } +static inline QString recentFilesKey() { return QStringLiteral("recentFileList"); } +static inline QString fileKey() { return QStringLiteral("file"); } + +static QStringList readRecentFiles(QSettings &settings) +{ + QStringList result; + const int count = settings.beginReadArray(recentFilesKey()); + for (int i = 0; i < count; ++i) { + settings.setArrayIndex(i); + result.append(settings.value(fileKey()).toString()); + } + settings.endArray(); + return result; +} + +static void writeRecentFiles(const QStringList &files, QSettings &settings) +{ + const int count = files.size(); + settings.beginWriteArray(recentFilesKey()); + for (int i = 0; i < count; ++i) { + settings.setArrayIndex(i); + settings.setValue(fileKey(), files.at(i)); + } + settings.endArray(); +} + +bool MainWindow::hasRecentFiles() +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + const int count = settings.beginReadArray(recentFilesKey()); + settings.endArray(); + return count > 0; +} + +void MainWindow::prependToRecentFiles(const QString &fileName) +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + + const QStringList oldRecentFiles = readRecentFiles(settings); + QStringList recentFiles = oldRecentFiles; + recentFiles.removeAll(fileName); + recentFiles.prepend(fileName); + if (oldRecentFiles != recentFiles) + writeRecentFiles(recentFiles, settings); + + setRecentFilesVisible(!recentFiles.isEmpty()); +} + +void MainWindow::setRecentFilesVisible(bool visible) +{ + recentFileSubMenuAct->setVisible(visible); + recentFileSeparator->setVisible(visible); +} + +void MainWindow::updateRecentFileActions() +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + + const QStringList recentFiles = readRecentFiles(settings); + const int count = qMin(int(MaxRecentFiles), recentFiles.size()); + int i = 0; + for ( ; i < count; ++i) { + const QString fileName = QFileInfo(recentFiles.at(i)).fileName(); + recentFileActs[i]->setText(tr("&%1 %2").arg(i + 1).arg(fileName)); + recentFileActs[i]->setData(recentFiles.at(i)); + recentFileActs[i]->setVisible(true); + } + for ( ; i < MaxRecentFiles; ++i) + recentFileActs[i]->setVisible(false); +} + +void MainWindow::openRecentFile() +{ + if (const QAction *action = qobject_cast<const QAction *>(sender())) + openFile(action->data().toString()); +} + void MainWindow::save() { if (activeMdiChild() && activeMdiChild()->save()) @@ -119,8 +196,11 @@ void MainWindow::save() void MainWindow::saveAs() { - if (activeMdiChild() && activeMdiChild()->saveAs()) + MdiChild *child = activeMdiChild(); + if (child && child->saveAs()) { statusBar()->showMessage(tr("File saved"), 2000); + MainWindow::prependToRecentFiles(child->currentFile()); + } } #ifndef QT_NO_CLIPBOARD @@ -164,7 +244,7 @@ void MainWindow::updateMenus() cascadeAct->setEnabled(hasMdiChild); nextAct->setEnabled(hasMdiChild); previousAct->setEnabled(hasMdiChild); - separatorAct->setVisible(hasMdiChild); + windowMenuSeparatorAct->setVisible(hasMdiChild); #ifndef QT_NO_CLIPBOARD bool hasSelection = (activeMdiChild() && @@ -174,6 +254,16 @@ void MainWindow::updateMenus() #endif } +class ActiveMdiSubWindowFunctor { +public: + explicit ActiveMdiSubWindowFunctor(QMdiArea *mdiArea, QMdiSubWindow *activeWindow) : m_mdiArea(mdiArea), m_activeWindow(activeWindow) {} + void operator()() const { m_mdiArea->setActiveSubWindow(m_activeWindow); } + +private: + QMdiArea *m_mdiArea; + QMdiSubWindow *m_activeWindow; +}; + void MainWindow::updateWindowMenu() { windowMenu->clear(); @@ -185,13 +275,14 @@ void MainWindow::updateWindowMenu() windowMenu->addSeparator(); windowMenu->addAction(nextAct); windowMenu->addAction(previousAct); - windowMenu->addAction(separatorAct); + windowMenu->addAction(windowMenuSeparatorAct); QList<QMdiSubWindow *> windows = mdiArea->subWindowList(); - separatorAct->setVisible(!windows.isEmpty()); + windowMenuSeparatorAct->setVisible(!windows.isEmpty()); for (int i = 0; i < windows.size(); ++i) { - MdiChild *child = qobject_cast<MdiChild *>(windows.at(i)->widget()); + QMdiSubWindow *mdiSubWindow = windows.at(i); + MdiChild *child = qobject_cast<MdiChild *>(mdiSubWindow->widget()); QString text; if (i < 9) { @@ -201,11 +292,9 @@ void MainWindow::updateWindowMenu() text = tr("%1 %2").arg(i + 1) .arg(child->userFriendlyCurrentFile()); } - QAction *action = windowMenu->addAction(text); + QAction *action = windowMenu->addAction(text, mdiSubWindow, ActiveMdiSubWindowFunctor(mdiArea, mdiSubWindow)); action->setCheckable(true); action ->setChecked(child == activeMdiChild()); - connect(action, SIGNAL(triggered()), windowMapper, SLOT(map())); - windowMapper->setMapping(action, windows.at(i)); } } @@ -215,10 +304,8 @@ MdiChild *MainWindow::createMdiChild() mdiArea->addSubWindow(child); #ifndef QT_NO_CLIPBOARD - connect(child, SIGNAL(copyAvailable(bool)), - cutAct, SLOT(setEnabled(bool))); - connect(child, SIGNAL(copyAvailable(bool)), - copyAct, SLOT(setEnabled(bool))); + connect(child, &QTextEdit::copyAvailable, cutAct, &QAction::setEnabled); + connect(child, &QTextEdit::copyAvailable, copyAct, &QAction::setEnabled); #endif return child; @@ -226,139 +313,143 @@ MdiChild *MainWindow::createMdiChild() void MainWindow::createActions() { - newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this); + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); + QToolBar *fileToolBar = addToolBar(tr("File")); + + const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/images/new.png")); + newAct = new QAction(newIcon, tr("&New"), this); newAct->setShortcuts(QKeySequence::New); newAct->setStatusTip(tr("Create a new file")); - connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); + connect(newAct, &QAction::triggered, this, &MainWindow::newFile); + fileMenu->addAction(newAct); + fileToolBar->addAction(newAct); - openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); + const QIcon openIcon = QIcon::fromTheme("document-open", QIcon(":/images/open.png")); + QAction *openAct = new QAction(openIcon, tr("&Open..."), this); openAct->setShortcuts(QKeySequence::Open); openAct->setStatusTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); + connect(openAct, &QAction::triggered, this, &MainWindow::open); + fileMenu->addAction(openAct); + fileToolBar->addAction(openAct); - saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this); + const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png")); + saveAct = new QAction(saveIcon, tr("&Save"), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the document to disk")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); + connect(saveAct, &QAction::triggered, this, &MainWindow::save); + fileToolBar->addAction(saveAct); - saveAsAct = new QAction(tr("Save &As..."), this); + const QIcon saveAsIcon = QIcon::fromTheme("document-save-as"); + saveAsAct = new QAction(saveAsIcon, tr("Save &As..."), this); saveAsAct->setShortcuts(QKeySequence::SaveAs); saveAsAct->setStatusTip(tr("Save the document under a new name")); - connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); + connect(saveAsAct, &QAction::triggered, this, &MainWindow::saveAs); + fileMenu->addAction(saveAsAct); + + fileMenu->addSeparator(); + + QMenu *recentMenu = fileMenu->addMenu(tr("Recent...")); + connect(recentMenu, &QMenu::aboutToShow, this, &MainWindow::updateRecentFileActions); + recentFileSubMenuAct = recentMenu->menuAction(); + + for (int i = 0; i < MaxRecentFiles; ++i) { + recentFileActs[i] = recentMenu->addAction(QString(), this, &MainWindow::openRecentFile); + recentFileActs[i]->setVisible(false); + } + + recentFileSeparator = fileMenu->addSeparator(); + + setRecentFilesVisible(MainWindow::hasRecentFiles()); + + fileMenu->addAction(tr("Switch layout direction"), this, &MainWindow::switchLayoutDirection); + + fileMenu->addSeparator(); //! [0] - exitAct = new QAction(tr("E&xit"), this); + const QIcon exitIcon = QIcon::fromTheme("application-exit"); + QAction *exitAct = fileMenu->addAction(exitIcon, tr("E&xit"), qApp, &QApplication::closeAllWindows); exitAct->setShortcuts(QKeySequence::Quit); exitAct->setStatusTip(tr("Exit the application")); - connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); + fileMenu->addAction(exitAct); //! [0] #ifndef QT_NO_CLIPBOARD - cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this); + QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); + QToolBar *editToolBar = addToolBar(tr("Edit")); + + const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png")); + cutAct = new QAction(cutIcon, tr("Cu&t"), this); cutAct->setShortcuts(QKeySequence::Cut); cutAct->setStatusTip(tr("Cut the current selection's contents to the " "clipboard")); - connect(cutAct, SIGNAL(triggered()), this, SLOT(cut())); + connect(cutAct, &QAction::triggered, this, &MainWindow::cut); + editMenu->addAction(cutAct); + editToolBar->addAction(cutAct); - copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this); + const QIcon copyIcon = QIcon::fromTheme("edit-copy", QIcon(":/images/copy.png")); + copyAct = new QAction(copyIcon, tr("&Copy"), this); copyAct->setShortcuts(QKeySequence::Copy); copyAct->setStatusTip(tr("Copy the current selection's contents to the " "clipboard")); - connect(copyAct, SIGNAL(triggered()), this, SLOT(copy())); + connect(copyAct, &QAction::triggered, this, &MainWindow::copy); + editMenu->addAction(copyAct); + editToolBar->addAction(copyAct); - pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this); + const QIcon pasteIcon = QIcon::fromTheme("edit-paste", QIcon(":/images/paste.png")); + pasteAct = new QAction(pasteIcon, tr("&Paste"), this); pasteAct->setShortcuts(QKeySequence::Paste); pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current " "selection")); - connect(pasteAct, SIGNAL(triggered()), this, SLOT(paste())); + connect(pasteAct, &QAction::triggered, this, &MainWindow::paste); + editMenu->addAction(pasteAct); + editToolBar->addAction(pasteAct); #endif + windowMenu = menuBar()->addMenu(tr("&Window")); + connect(windowMenu, &QMenu::aboutToShow, this, &MainWindow::updateWindowMenu); + closeAct = new QAction(tr("Cl&ose"), this); closeAct->setStatusTip(tr("Close the active window")); - connect(closeAct, SIGNAL(triggered()), - mdiArea, SLOT(closeActiveSubWindow())); + connect(closeAct, &QAction::triggered, + mdiArea, &QMdiArea::closeActiveSubWindow); closeAllAct = new QAction(tr("Close &All"), this); closeAllAct->setStatusTip(tr("Close all the windows")); - connect(closeAllAct, SIGNAL(triggered()), - mdiArea, SLOT(closeAllSubWindows())); + connect(closeAllAct, &QAction::triggered, mdiArea, &QMdiArea::closeAllSubWindows); tileAct = new QAction(tr("&Tile"), this); tileAct->setStatusTip(tr("Tile the windows")); - connect(tileAct, SIGNAL(triggered()), mdiArea, SLOT(tileSubWindows())); + connect(tileAct, &QAction::triggered, mdiArea, &QMdiArea::tileSubWindows); cascadeAct = new QAction(tr("&Cascade"), this); cascadeAct->setStatusTip(tr("Cascade the windows")); - connect(cascadeAct, SIGNAL(triggered()), mdiArea, SLOT(cascadeSubWindows())); + connect(cascadeAct, &QAction::triggered, mdiArea, &QMdiArea::cascadeSubWindows); nextAct = new QAction(tr("Ne&xt"), this); nextAct->setShortcuts(QKeySequence::NextChild); nextAct->setStatusTip(tr("Move the focus to the next window")); - connect(nextAct, SIGNAL(triggered()), - mdiArea, SLOT(activateNextSubWindow())); + connect(nextAct, &QAction::triggered, mdiArea, &QMdiArea::activateNextSubWindow); previousAct = new QAction(tr("Pre&vious"), this); previousAct->setShortcuts(QKeySequence::PreviousChild); previousAct->setStatusTip(tr("Move the focus to the previous " "window")); - connect(previousAct, SIGNAL(triggered()), - mdiArea, SLOT(activatePreviousSubWindow())); - - separatorAct = new QAction(this); - separatorAct->setSeparator(true); - - aboutAct = new QAction(tr("&About"), this); - aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - - aboutQtAct = new QAction(tr("About &Qt"), this); - aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); -} - -void MainWindow::createMenus() -{ - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(newAct); - fileMenu->addAction(openAct); - fileMenu->addAction(saveAct); - fileMenu->addAction(saveAsAct); - fileMenu->addSeparator(); - QAction *action = fileMenu->addAction(tr("Switch layout direction")); - connect(action, SIGNAL(triggered()), this, SLOT(switchLayoutDirection())); - fileMenu->addAction(exitAct); + connect(previousAct, &QAction::triggered, mdiArea, &QMdiArea::activatePreviousSubWindow); - editMenu = menuBar()->addMenu(tr("&Edit")); -#ifndef QT_NO_CLIPBOARD - editMenu->addAction(cutAct); - editMenu->addAction(copyAct); - editMenu->addAction(pasteAct); -#endif + windowMenuSeparatorAct = new QAction(this); + windowMenuSeparatorAct->setSeparator(true); - windowMenu = menuBar()->addMenu(tr("&Window")); updateWindowMenu(); - connect(windowMenu, SIGNAL(aboutToShow()), this, SLOT(updateWindowMenu())); menuBar()->addSeparator(); - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); -} + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); -void MainWindow::createToolBars() -{ - fileToolBar = addToolBar(tr("File")); - fileToolBar->addAction(newAct); - fileToolBar->addAction(openAct); - fileToolBar->addAction(saveAct); + QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about); + aboutAct->setStatusTip(tr("Show the application's About box")); -#ifndef QT_NO_CLIPBOARD - editToolBar = addToolBar(tr("Edit")); - editToolBar->addAction(cutAct); - editToolBar->addAction(copyAct); - editToolBar->addAction(pasteAct); -#endif + QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); + aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); } void MainWindow::createStatusBar() @@ -368,28 +459,32 @@ void MainWindow::createStatusBar() void MainWindow::readSettings() { - QSettings settings("QtProject", "MDI Example"); - QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); - QSize size = settings.value("size", QSize(400, 400)).toSize(); - move(pos); - resize(size); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray(); + if (geometry.isEmpty()) { + const QRect availableGeometry = QApplication::desktop()->availableGeometry(this); + resize(availableGeometry.width() / 3, availableGeometry.height() / 2); + move((availableGeometry.width() - width()) / 2, + (availableGeometry.height() - height()) / 2); + } else { + restoreGeometry(geometry); + } } void MainWindow::writeSettings() { - QSettings settings("QtProject", "MDI Example"); - settings.setValue("pos", pos()); - settings.setValue("size", size()); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + settings.setValue("geometry", saveGeometry()); } -MdiChild *MainWindow::activeMdiChild() +MdiChild *MainWindow::activeMdiChild() const { if (QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow()) return qobject_cast<MdiChild *>(activeSubWindow->widget()); return 0; } -QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName) +QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName) const { QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath(); @@ -404,14 +499,7 @@ QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName) void MainWindow::switchLayoutDirection() { if (layoutDirection() == Qt::LeftToRight) - qApp->setLayoutDirection(Qt::RightToLeft); + QGuiApplication::setLayoutDirection(Qt::RightToLeft); else - qApp->setLayoutDirection(Qt::LeftToRight); -} - -void MainWindow::setActiveSubWindow(QWidget *window) -{ - if (!window) - return; - mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(window)); + QGuiApplication::setLayoutDirection(Qt::LeftToRight); } diff --git a/examples/widgets/mainwindows/mdi/mainwindow.h b/examples/widgets/mainwindows/mdi/mainwindow.h index fa8e0131e9..3ac60282fd 100644 --- a/examples/widgets/mainwindows/mdi/mainwindow.h +++ b/examples/widgets/mainwindows/mdi/mainwindow.h @@ -49,7 +49,6 @@ class QAction; class QMenu; class QMdiArea; class QMdiSubWindow; -class QSignalMapper; QT_END_NAMESPACE class MainWindow : public QMainWindow @@ -69,6 +68,8 @@ private slots: void open(); void save(); void saveAs(); + void updateRecentFileActions(); + void openRecentFile(); #ifndef QT_NO_CLIPBOARD void cut(); void copy(); @@ -79,32 +80,30 @@ private slots: void updateWindowMenu(); MdiChild *createMdiChild(); void switchLayoutDirection(); - void setActiveSubWindow(QWidget *window); private: + enum { MaxRecentFiles = 5 }; + void createActions(); - void createMenus(); - void createToolBars(); void createStatusBar(); void readSettings(); void writeSettings(); - MdiChild *activeMdiChild(); - QMdiSubWindow *findMdiChild(const QString &fileName); + bool loadFile(const QString &fileName); + static bool hasRecentFiles(); + void prependToRecentFiles(const QString &fileName); + void setRecentFilesVisible(bool visible); + MdiChild *activeMdiChild() const; + QMdiSubWindow *findMdiChild(const QString &fileName) const; QMdiArea *mdiArea; - QSignalMapper *windowMapper; - QMenu *fileMenu; - QMenu *editMenu; QMenu *windowMenu; - QMenu *helpMenu; - QToolBar *fileToolBar; - QToolBar *editToolBar; QAction *newAct; - QAction *openAct; QAction *saveAct; QAction *saveAsAct; - QAction *exitAct; + QAction *recentFileActs[MaxRecentFiles]; + QAction *recentFileSeparator; + QAction *recentFileSubMenuAct; #ifndef QT_NO_CLIPBOARD QAction *cutAct; QAction *copyAct; @@ -116,9 +115,7 @@ private: QAction *cascadeAct; QAction *nextAct; QAction *previousAct; - QAction *separatorAct; - QAction *aboutAct; - QAction *aboutQtAct; + QAction *windowMenuSeparatorAct; }; #endif diff --git a/examples/widgets/mainwindows/mdi/mdichild.cpp b/examples/widgets/mainwindows/mdi/mdichild.cpp index 242e8248a2..73364eb3ee 100644 --- a/examples/widgets/mainwindows/mdi/mdichild.cpp +++ b/examples/widgets/mainwindows/mdi/mdichild.cpp @@ -56,8 +56,8 @@ void MdiChild::newFile() curFile = tr("document%1.txt").arg(sequenceNumber++); setWindowTitle(curFile + "[*]"); - connect(document(), SIGNAL(contentsChanged()), - this, SLOT(documentWasModified())); + connect(document(), &QTextDocument::contentsChanged, + this, &MdiChild::documentWasModified); } bool MdiChild::loadFile(const QString &fileName) @@ -78,8 +78,8 @@ bool MdiChild::loadFile(const QString &fileName) setCurrentFile(fileName); - connect(document(), SIGNAL(contentsChanged()), - this, SLOT(documentWasModified())); + connect(document(), &QTextDocument::contentsChanged, + this, &MdiChild::documentWasModified); return true; } @@ -109,8 +109,7 @@ bool MdiChild::saveFile(const QString &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())); + .arg(QDir::toNativeSeparators(fileName), file.errorString())); return false; } @@ -144,18 +143,22 @@ void MdiChild::documentWasModified() bool MdiChild::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; + if (!document()->isModified()) + return true; + const QMessageBox::StandardButton 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); + switch (ret) { + case QMessageBox::Save: + return save(); + case QMessageBox::Cancel: + return false; + default: + break; } return true; } diff --git a/examples/widgets/mainwindows/menus/mainwindow.cpp b/examples/widgets/mainwindows/menus/mainwindow.cpp index 31515394bd..d487e3a277 100644 --- a/examples/widgets/mainwindows/menus/mainwindow.cpp +++ b/examples/widgets/mainwindows/menus/mainwindow.cpp @@ -198,63 +198,63 @@ void MainWindow::createActions() newAct = new QAction(tr("&New"), this); newAct->setShortcuts(QKeySequence::New); newAct->setStatusTip(tr("Create a new file")); - connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); + connect(newAct, &QAction::triggered, this, &MainWindow::newFile); //! [4] openAct = new QAction(tr("&Open..."), this); openAct->setShortcuts(QKeySequence::Open); openAct->setStatusTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); + connect(openAct, &QAction::triggered, this, &MainWindow::open); //! [5] saveAct = new QAction(tr("&Save"), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the document to disk")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); + connect(saveAct, &QAction::triggered, this, &MainWindow::save); printAct = new QAction(tr("&Print..."), this); printAct->setShortcuts(QKeySequence::Print); printAct->setStatusTip(tr("Print the document")); - connect(printAct, SIGNAL(triggered()), this, SLOT(print())); + connect(printAct, &QAction::triggered, this, &MainWindow::print); exitAct = new QAction(tr("E&xit"), this); exitAct->setShortcuts(QKeySequence::Quit); exitAct->setStatusTip(tr("Exit the application")); - connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); + connect(exitAct, &QAction::triggered, this, &QWidget::close); undoAct = new QAction(tr("&Undo"), this); undoAct->setShortcuts(QKeySequence::Undo); undoAct->setStatusTip(tr("Undo the last operation")); - connect(undoAct, SIGNAL(triggered()), this, SLOT(undo())); + connect(undoAct, &QAction::triggered, this, &MainWindow::undo); redoAct = new QAction(tr("&Redo"), this); redoAct->setShortcuts(QKeySequence::Redo); redoAct->setStatusTip(tr("Redo the last operation")); - connect(redoAct, SIGNAL(triggered()), this, SLOT(redo())); + connect(redoAct, &QAction::triggered, this, &MainWindow::redo); cutAct = new QAction(tr("Cu&t"), this); cutAct->setShortcuts(QKeySequence::Cut); cutAct->setStatusTip(tr("Cut the current selection's contents to the " "clipboard")); - connect(cutAct, SIGNAL(triggered()), this, SLOT(cut())); + connect(cutAct, &QAction::triggered, this, &MainWindow::cut); copyAct = new QAction(tr("&Copy"), this); copyAct->setShortcuts(QKeySequence::Copy); copyAct->setStatusTip(tr("Copy the current selection's contents to the " "clipboard")); - connect(copyAct, SIGNAL(triggered()), this, SLOT(copy())); + connect(copyAct, &QAction::triggered, this, &MainWindow::copy); pasteAct = new QAction(tr("&Paste"), this); pasteAct->setShortcuts(QKeySequence::Paste); pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current " "selection")); - connect(pasteAct, SIGNAL(triggered()), this, SLOT(paste())); + connect(pasteAct, &QAction::triggered, this, &MainWindow::paste); boldAct = new QAction(tr("&Bold"), this); boldAct->setCheckable(true); boldAct->setShortcut(QKeySequence::Bold); boldAct->setStatusTip(tr("Make the text bold")); - connect(boldAct, SIGNAL(triggered()), this, SLOT(bold())); + connect(boldAct, &QAction::triggered, this, &MainWindow::bold); QFont boldFont = boldAct->font(); boldFont.setBold(true); @@ -264,7 +264,7 @@ void MainWindow::createActions() italicAct->setCheckable(true); italicAct->setShortcut(QKeySequence::Italic); italicAct->setStatusTip(tr("Make the text italic")); - connect(italicAct, SIGNAL(triggered()), this, SLOT(italic())); + connect(italicAct, &QAction::triggered, this, &MainWindow::italic); QFont italicFont = italicAct->font(); italicFont.setItalic(true); @@ -273,45 +273,45 @@ void MainWindow::createActions() setLineSpacingAct = new QAction(tr("Set &Line Spacing..."), this); setLineSpacingAct->setStatusTip(tr("Change the gap between the lines of a " "paragraph")); - connect(setLineSpacingAct, SIGNAL(triggered()), this, SLOT(setLineSpacing())); + connect(setLineSpacingAct, &QAction::triggered, this, &MainWindow::setLineSpacing); setParagraphSpacingAct = new QAction(tr("Set &Paragraph Spacing..."), this); setParagraphSpacingAct->setStatusTip(tr("Change the gap between paragraphs")); - connect(setParagraphSpacingAct, SIGNAL(triggered()), - this, SLOT(setParagraphSpacing())); + connect(setParagraphSpacingAct, &QAction::triggered, + this, &MainWindow::setParagraphSpacing); aboutAct = new QAction(tr("&About"), this); aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); + connect(aboutAct, &QAction::triggered, this, &MainWindow::about); aboutQtAct = new QAction(tr("About &Qt"), this); aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); - connect(aboutQtAct, SIGNAL(triggered()), this, SLOT(aboutQt())); + connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt); + connect(aboutQtAct, &QAction::triggered, this, &MainWindow::aboutQt); leftAlignAct = new QAction(tr("&Left Align"), this); leftAlignAct->setCheckable(true); leftAlignAct->setShortcut(tr("Ctrl+L")); leftAlignAct->setStatusTip(tr("Left align the selected text")); - connect(leftAlignAct, SIGNAL(triggered()), this, SLOT(leftAlign())); + connect(leftAlignAct, &QAction::triggered, this, &MainWindow::leftAlign); rightAlignAct = new QAction(tr("&Right Align"), this); rightAlignAct->setCheckable(true); rightAlignAct->setShortcut(tr("Ctrl+R")); rightAlignAct->setStatusTip(tr("Right align the selected text")); - connect(rightAlignAct, SIGNAL(triggered()), this, SLOT(rightAlign())); + connect(rightAlignAct, &QAction::triggered, this, &MainWindow::rightAlign); justifyAct = new QAction(tr("&Justify"), this); justifyAct->setCheckable(true); justifyAct->setShortcut(tr("Ctrl+J")); justifyAct->setStatusTip(tr("Justify the selected text")); - connect(justifyAct, SIGNAL(triggered()), this, SLOT(justify())); + connect(justifyAct, &QAction::triggered, this, &MainWindow::justify); centerAct = new QAction(tr("&Center"), this); centerAct->setCheckable(true); centerAct->setShortcut(tr("Ctrl+E")); centerAct->setStatusTip(tr("Center the selected text")); - connect(centerAct, SIGNAL(triggered()), this, SLOT(center())); + connect(centerAct, &QAction::triggered, this, &MainWindow::center); //! [6] //! [7] alignmentGroup = new QActionGroup(this); diff --git a/examples/widgets/mainwindows/recentfiles/main.cpp b/examples/widgets/mainwindows/recentfiles/main.cpp deleted file mode 100644 index 23ff3eda16..0000000000 --- a/examples/widgets/mainwindows/recentfiles/main.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QApplication> - -#include "mainwindow.h" - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - app.setOrganizationName("QtProject"); - app.setApplicationName("Recent Files Example"); - MainWindow *mainWin = new MainWindow; - mainWin->show(); - return app.exec(); -} diff --git a/examples/widgets/mainwindows/recentfiles/mainwindow.cpp b/examples/widgets/mainwindows/recentfiles/mainwindow.cpp deleted file mode 100644 index b89797092a..0000000000 --- a/examples/widgets/mainwindows/recentfiles/mainwindow.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtWidgets> - -#include "mainwindow.h" - -MainWindow::MainWindow() -{ - setAttribute(Qt::WA_DeleteOnClose); - - textEdit = new QTextEdit; - setCentralWidget(textEdit); - - createActions(); - createMenus(); - (void)statusBar(); - - setWindowFilePath(QString()); - resize(400, 300); -} - -void MainWindow::newFile() -{ - MainWindow *other = new MainWindow; - other->show(); -} - -void MainWindow::open() -{ - QString fileName = QFileDialog::getOpenFileName(this); - if (!fileName.isEmpty()) - loadFile(fileName); -} - -void MainWindow::save() -{ - if (curFile.isEmpty()) - saveAs(); - else - saveFile(curFile); -} - -void MainWindow::saveAs() -{ - QString fileName = QFileDialog::getSaveFileName(this); - if (fileName.isEmpty()) - return; - - saveFile(fileName); -} - -void MainWindow::openRecentFile() -{ - QAction *action = qobject_cast<QAction *>(sender()); - if (action) - loadFile(action->data().toString()); -} - -void MainWindow::about() -{ - QMessageBox::about(this, tr("About Recent Files"), - tr("The <b>Recent Files</b> example demonstrates how to provide a " - "recently used file menu in a Qt application.")); -} - -void MainWindow::createActions() -{ - newAct = new QAction(tr("&New"), this); - newAct->setShortcuts(QKeySequence::New); - newAct->setStatusTip(tr("Create a new file")); - connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); - - openAct = new QAction(tr("&Open..."), this); - openAct->setShortcuts(QKeySequence::Open); - openAct->setStatusTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); - - saveAct = new QAction(tr("&Save"), this); - saveAct->setShortcuts(QKeySequence::Save); - saveAct->setStatusTip(tr("Save the document to disk")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); - - saveAsAct = new QAction(tr("Save &As..."), this); - saveAsAct->setShortcuts(QKeySequence::SaveAs); - saveAsAct->setStatusTip(tr("Save the document under a new name")); - connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); - - for (int i = 0; i < MaxRecentFiles; ++i) { - recentFileActs[i] = new QAction(this); - recentFileActs[i]->setVisible(false); - connect(recentFileActs[i], SIGNAL(triggered()), - this, SLOT(openRecentFile())); - } - - exitAct = new QAction(tr("E&xit"), this); - exitAct->setShortcuts(QKeySequence::Quit); - exitAct->setStatusTip(tr("Exit the application")); - connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); - - aboutAct = new QAction(tr("&About"), this); - aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - - aboutQtAct = new QAction(tr("About &Qt"), this); - aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); -} - -void MainWindow::createMenus() -{ - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(newAct); - fileMenu->addAction(openAct); - fileMenu->addAction(saveAct); - fileMenu->addAction(saveAsAct); - separatorAct = fileMenu->addSeparator(); - for (int i = 0; i < MaxRecentFiles; ++i) - fileMenu->addAction(recentFileActs[i]); - fileMenu->addSeparator(); - fileMenu->addAction(exitAct); - updateRecentFileActions(); - - menuBar()->addSeparator(); - - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); -} - -void MainWindow::loadFile(const QString &fileName) -{ - QFile file(fileName); - if (!file.open(QFile::ReadOnly | QFile::Text)) { - QMessageBox::warning(this, tr("Recent Files"), - tr("Cannot read file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - return; - } - - QTextStream in(&file); - QApplication::setOverrideCursor(Qt::WaitCursor); - textEdit->setPlainText(in.readAll()); - QApplication::restoreOverrideCursor(); - - setCurrentFile(fileName); - statusBar()->showMessage(tr("File loaded"), 2000); -} - -void MainWindow::saveFile(const QString &fileName) -{ - QFile file(fileName); - if (!file.open(QFile::WriteOnly | QFile::Text)) { - QMessageBox::warning(this, tr("Recent Files"), - tr("Cannot write file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - return; - } - - QTextStream out(&file); - QApplication::setOverrideCursor(Qt::WaitCursor); - out << textEdit->toPlainText(); - QApplication::restoreOverrideCursor(); - - setCurrentFile(fileName); - statusBar()->showMessage(tr("File saved"), 2000); -} - -void MainWindow::setCurrentFile(const QString &fileName) -{ - curFile = fileName; - setWindowFilePath(curFile); - - QSettings settings; - QStringList files = settings.value("recentFileList").toStringList(); - files.removeAll(fileName); - files.prepend(fileName); - while (files.size() > MaxRecentFiles) - files.removeLast(); - - settings.setValue("recentFileList", files); - - foreach (QWidget *widget, QApplication::topLevelWidgets()) { - MainWindow *mainWin = qobject_cast<MainWindow *>(widget); - if (mainWin) - mainWin->updateRecentFileActions(); - } -} - -void MainWindow::updateRecentFileActions() -{ - QSettings settings; - QStringList files = settings.value("recentFileList").toStringList(); - - int numRecentFiles = qMin(files.size(), (int)MaxRecentFiles); - - for (int i = 0; i < numRecentFiles; ++i) { - QString text = tr("&%1 %2").arg(i + 1).arg(strippedName(files[i])); - recentFileActs[i]->setText(text); - recentFileActs[i]->setData(files[i]); - recentFileActs[i]->setVisible(true); - } - for (int j = numRecentFiles; j < MaxRecentFiles; ++j) - recentFileActs[j]->setVisible(false); - - separatorAct->setVisible(numRecentFiles > 0); -} - -QString MainWindow::strippedName(const QString &fullFileName) -{ - return QFileInfo(fullFileName).fileName(); -} diff --git a/examples/widgets/mainwindows/recentfiles/mainwindow.h b/examples/widgets/mainwindows/recentfiles/mainwindow.h deleted file mode 100644 index 95252ca525..0000000000 --- a/examples/widgets/mainwindows/recentfiles/mainwindow.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include <QList> -#include <QMainWindow> - -QT_BEGIN_NAMESPACE -class QAction; -class QMenu; -class QTextEdit; -QT_END_NAMESPACE - -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - MainWindow(); - -private slots: - void newFile(); - void open(); - void save(); - void saveAs(); - void openRecentFile(); - void about(); - -private: - void createActions(); - void createMenus(); - void loadFile(const QString &fileName); - void saveFile(const QString &fileName); - void setCurrentFile(const QString &fileName); - void updateRecentFileActions(); - QString strippedName(const QString &fullFileName); - - QString curFile; - - QTextEdit *textEdit; - QMenu *fileMenu; - QMenu *recentFilesMenu; - QMenu *helpMenu; - QAction *newAct; - QAction *openAct; - QAction *saveAct; - QAction *saveAsAct; - QAction *exitAct; - QAction *aboutAct; - QAction *aboutQtAct; - QAction *separatorAct; - - enum { MaxRecentFiles = 5 }; - QAction *recentFileActs[MaxRecentFiles]; -}; - -#endif diff --git a/examples/widgets/mainwindows/recentfiles/recentfiles.pro b/examples/widgets/mainwindows/recentfiles/recentfiles.pro deleted file mode 100644 index ccf948f560..0000000000 --- a/examples/widgets/mainwindows/recentfiles/recentfiles.pro +++ /dev/null @@ -1,9 +0,0 @@ -QT += widgets - -HEADERS = mainwindow.h -SOURCES = main.cpp \ - mainwindow.cpp - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/widgets/mainwindows/recentfiles -INSTALLS += target diff --git a/examples/widgets/mainwindows/sdi/main.cpp b/examples/widgets/mainwindows/sdi/main.cpp index d3350da946..4b125722d8 100644 --- a/examples/widgets/mainwindows/sdi/main.cpp +++ b/examples/widgets/mainwindows/sdi/main.cpp @@ -39,6 +39,7 @@ ****************************************************************************/ #include <QApplication> +#include <QCommandLineParser> #include "mainwindow.h" @@ -46,9 +47,27 @@ int main(int argc, char *argv[]) { Q_INIT_RESOURCE(sdi); QApplication app(argc, argv); - app.setApplicationName("SDI Example"); - app.setOrganizationName("QtProject"); - MainWindow *mainWin = new MainWindow; + QCoreApplication::setApplicationName("SDI Example"); + QCoreApplication::setOrganizationName("QtProject"); + QCoreApplication::setApplicationVersion(QT_VERSION_STR); + QCommandLineParser parser; + parser.setApplicationDescription(QCoreApplication::applicationName()); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument("file", "The file(s) to open."); + parser.process(app); + + MainWindow *mainWin = Q_NULLPTR; + foreach (const QString &file, parser.positionalArguments()) { + MainWindow *newWin = new MainWindow(file); + newWin->tile(mainWin); + newWin->show(); + mainWin = newWin; + } + + if (!mainWin) + mainWin = new MainWindow; mainWin->show(); + return app.exec(); } diff --git a/examples/widgets/mainwindows/sdi/mainwindow.cpp b/examples/widgets/mainwindows/sdi/mainwindow.cpp index 1d6226e45c..f59172f172 100644 --- a/examples/widgets/mainwindows/sdi/mainwindow.cpp +++ b/examples/widgets/mainwindows/sdi/mainwindow.cpp @@ -45,7 +45,7 @@ MainWindow::MainWindow() { init(); - setCurrentFile(""); + setCurrentFile(QString()); } MainWindow::MainWindow(const QString &fileName) @@ -67,44 +67,44 @@ void MainWindow::closeEvent(QCloseEvent *event) void MainWindow::newFile() { MainWindow *other = new MainWindow; - other->move(x() + 40, y() + 40); + other->tile(this); other->show(); } void MainWindow::open() { - QString fileName = QFileDialog::getOpenFileName(this); - if (!fileName.isEmpty()) { - MainWindow *existing = findMainWindow(fileName); - if (existing) { - existing->show(); - existing->raise(); - existing->activateWindow(); - return; - } - - if (isUntitled && textEdit->document()->isEmpty() - && !isWindowModified()) { - loadFile(fileName); - } else { - MainWindow *other = new MainWindow(fileName); - if (other->isUntitled) { - delete other; - return; - } - other->move(x() + 40, y() + 40); - other->show(); - } + const QString fileName = QFileDialog::getOpenFileName(this); + if (!fileName.isEmpty()) + openFile(fileName); +} + +void MainWindow::openFile(const QString &fileName) +{ + MainWindow *existing = findMainWindow(fileName); + if (existing) { + existing->show(); + existing->raise(); + existing->activateWindow(); + return; + } + + if (isUntitled && textEdit->document()->isEmpty() && !isWindowModified()) { + loadFile(fileName); + return; } + + MainWindow *other = new MainWindow(fileName); + if (other->isUntitled) { + delete other; + return; + } + other->tile(this); + other->show(); } bool MainWindow::save() { - if (isUntitled) { - return saveAs(); - } else { - return saveFile(curFile); - } + return isUntitled ? saveAs() : saveFile(curFile); } bool MainWindow::saveAs() @@ -139,123 +139,135 @@ void MainWindow::init() setCentralWidget(textEdit); createActions(); - createMenus(); - createToolBars(); createStatusBar(); readSettings(); - connect(textEdit->document(), SIGNAL(contentsChanged()), - this, SLOT(documentWasModified())); + connect(textEdit->document(), &QTextDocument::contentsChanged, + this, &MainWindow::documentWasModified); setUnifiedTitleAndToolBarOnMac(true); } +void MainWindow::tile(const QMainWindow *previous) +{ + if (!previous) + return; + int topFrameWidth = previous->geometry().top() - previous->pos().y(); + if (!topFrameWidth) + topFrameWidth = 40; + const QPoint pos = previous->pos() + 2 * QPoint(topFrameWidth, topFrameWidth); + if (QApplication::desktop()->availableGeometry(this).contains(rect().bottomRight() + pos)) + move(pos); +} + +//! [implicit tr context] void MainWindow::createActions() { - newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this); + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); +//! [implicit tr context] + QToolBar *fileToolBar = addToolBar(tr("File")); + + const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/images/new.png")); + QAction *newAct = new QAction(newIcon, tr("&New"), this); newAct->setShortcuts(QKeySequence::New); newAct->setStatusTip(tr("Create a new file")); - connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); + connect(newAct, &QAction::triggered, this, &MainWindow::newFile); + fileMenu->addAction(newAct); + fileToolBar->addAction(newAct); - openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); + const QIcon openIcon = QIcon::fromTheme("document-open", QIcon(":/images/open.png")); + QAction *openAct = new QAction(openIcon, tr("&Open..."), this); openAct->setShortcuts(QKeySequence::Open); openAct->setStatusTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); + connect(openAct, &QAction::triggered, this, &MainWindow::open); + fileMenu->addAction(openAct); + fileToolBar->addAction(openAct); - saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this); + const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png")); + QAction *saveAct = new QAction(saveIcon, tr("&Save"), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the document to disk")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); + connect(saveAct, &QAction::triggered, this, &MainWindow::save); + fileMenu->addAction(saveAct); + fileToolBar->addAction(saveAct); - saveAsAct = new QAction(tr("Save &As..."), this); + const QIcon saveAsIcon = QIcon::fromTheme("document-save-as"); + QAction *saveAsAct = fileMenu->addAction(saveAsIcon, tr("Save &As..."), this, &MainWindow::saveAs); saveAsAct->setShortcuts(QKeySequence::SaveAs); saveAsAct->setStatusTip(tr("Save the document under a new name")); - connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); - closeAct = new QAction(tr("&Close"), this); + fileMenu->addSeparator(); + + QMenu *recentMenu = fileMenu->addMenu(tr("Recent...")); + connect(recentMenu, &QMenu::aboutToShow, this, &MainWindow::updateRecentFileActions); + recentFileSubMenuAct = recentMenu->menuAction(); + + for (int i = 0; i < MaxRecentFiles; ++i) { + recentFileActs[i] = recentMenu->addAction(QString(), this, &MainWindow::openRecentFile); + recentFileActs[i]->setVisible(false); + } + + recentFileSeparator = fileMenu->addSeparator(); + + setRecentFilesVisible(MainWindow::hasRecentFiles()); + + QAction *closeAct = fileMenu->addAction(tr("&Close"), this, &QWidget::close); closeAct->setShortcut(tr("Ctrl+W")); closeAct->setStatusTip(tr("Close this window")); - connect(closeAct, SIGNAL(triggered()), this, SLOT(close())); - exitAct = new QAction(tr("E&xit"), this); + const QIcon exitIcon = QIcon::fromTheme("application-exit"); + QAction *exitAct = fileMenu->addAction(exitIcon, tr("E&xit"), qApp, &QApplication::closeAllWindows); exitAct->setShortcuts(QKeySequence::Quit); exitAct->setStatusTip(tr("Exit the application")); - connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); - cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this); + QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); + QToolBar *editToolBar = addToolBar(tr("Edit")); + +#ifndef QT_NO_CLIPBOARD + const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png")); + QAction *cutAct = new QAction(cutIcon, tr("Cu&t"), this); cutAct->setShortcuts(QKeySequence::Cut); cutAct->setStatusTip(tr("Cut the current selection's contents to the " "clipboard")); - connect(cutAct, SIGNAL(triggered()), textEdit, SLOT(cut())); + connect(cutAct, &QAction::triggered, textEdit, &QTextEdit::cut); + editMenu->addAction(cutAct); + editToolBar->addAction(cutAct); - copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this); + const QIcon copyIcon = QIcon::fromTheme("edit-copy", QIcon(":/images/copy.png")); + QAction *copyAct = new QAction(copyIcon, tr("&Copy"), this); copyAct->setShortcuts(QKeySequence::Copy); copyAct->setStatusTip(tr("Copy the current selection's contents to the " "clipboard")); - connect(copyAct, SIGNAL(triggered()), textEdit, SLOT(copy())); + connect(copyAct, &QAction::triggered, textEdit, &QTextEdit::copy); + editMenu->addAction(copyAct); + editToolBar->addAction(copyAct); - pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this); + const QIcon pasteIcon = QIcon::fromTheme("edit-paste", QIcon(":/images/paste.png")); + QAction *pasteAct = new QAction(pasteIcon, tr("&Paste"), this); pasteAct->setShortcuts(QKeySequence::Paste); pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current " "selection")); - connect(pasteAct, SIGNAL(triggered()), textEdit, SLOT(paste())); + connect(pasteAct, &QAction::triggered, textEdit, &QTextEdit::paste); + editMenu->addAction(pasteAct); + editToolBar->addAction(pasteAct); + + menuBar()->addSeparator(); +#endif // !QT_NO_CLIPBOARD - aboutAct = new QAction(tr("&About"), this); + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); + QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about); aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - aboutQtAct = new QAction(tr("About &Qt"), this); + QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); - +#ifndef QT_NO_CLIPBOARD cutAct->setEnabled(false); copyAct->setEnabled(false); - connect(textEdit, SIGNAL(copyAvailable(bool)), - cutAct, SLOT(setEnabled(bool))); - connect(textEdit, SIGNAL(copyAvailable(bool)), - copyAct, SLOT(setEnabled(bool))); -} - -//! [implicit tr context] -void MainWindow::createMenus() -{ - fileMenu = menuBar()->addMenu(tr("&File")); -//! [implicit tr context] - fileMenu->addAction(newAct); - fileMenu->addAction(openAct); - fileMenu->addAction(saveAct); - fileMenu->addAction(saveAsAct); - fileMenu->addSeparator(); - fileMenu->addAction(closeAct); - fileMenu->addAction(exitAct); - - editMenu = menuBar()->addMenu(tr("&Edit")); - editMenu->addAction(cutAct); - editMenu->addAction(copyAct); - editMenu->addAction(pasteAct); - - menuBar()->addSeparator(); - - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); -} - -void MainWindow::createToolBars() -{ -//! [0] - fileToolBar = addToolBar(tr("File")); - fileToolBar->addAction(newAct); - fileToolBar->addAction(openAct); -//! [0] - fileToolBar->addAction(saveAct); - - editToolBar = addToolBar(tr("Edit")); - editToolBar->addAction(cutAct); - editToolBar->addAction(copyAct); - editToolBar->addAction(pasteAct); + connect(textEdit, &QTextEdit::copyAvailable, cutAct, &QAction::setEnabled); + connect(textEdit, &QTextEdit::copyAvailable, copyAct, &QAction::setEnabled); +#endif // !QT_NO_CLIPBOARD } void MainWindow::createStatusBar() @@ -265,33 +277,41 @@ void MainWindow::createStatusBar() void MainWindow::readSettings() { - QSettings settings; - QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); - QSize size = settings.value("size", QSize(400, 400)).toSize(); - move(pos); - resize(size); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray(); + if (geometry.isEmpty()) { + const QRect availableGeometry = QApplication::desktop()->availableGeometry(this); + resize(availableGeometry.width() / 3, availableGeometry.height() / 2); + move((availableGeometry.width() - width()) / 2, + (availableGeometry.height() - height()) / 2); + } else { + restoreGeometry(geometry); + } } void MainWindow::writeSettings() { - QSettings settings; - settings.setValue("pos", pos()); - settings.setValue("size", size()); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + settings.setValue("geometry", saveGeometry()); } bool MainWindow::maybeSave() { - if (textEdit->document()->isModified()) { - QMessageBox::StandardButton ret; - ret = QMessageBox::warning(this, tr("SDI"), - tr("The document has been modified.\n" - "Do you want to save your changes?"), - QMessageBox::Save | QMessageBox::Discard - | QMessageBox::Cancel); - if (ret == QMessageBox::Save) - return save(); - else if (ret == QMessageBox::Cancel) - return false; + if (!textEdit->document()->isModified()) + return true; + const QMessageBox::StandardButton ret + = QMessageBox::warning(this, tr("SDI"), + tr("The document has been modified.\n" + "Do you want to save your changes?"), + QMessageBox::Save | QMessageBox::Discard + | QMessageBox::Cancel); + switch (ret) { + case QMessageBox::Save: + return save(); + case QMessageBox::Cancel: + return false; + default: + break; } return true; } @@ -303,8 +323,7 @@ void MainWindow::loadFile(const QString &fileName) if (!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning(this, tr("SDI"), tr("Cannot read file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), file.errorString())); return; } @@ -317,14 +336,90 @@ void MainWindow::loadFile(const QString &fileName) statusBar()->showMessage(tr("File loaded"), 2000); } +void MainWindow::setRecentFilesVisible(bool visible) +{ + recentFileSubMenuAct->setVisible(visible); + recentFileSeparator->setVisible(visible); +} + +static inline QString recentFilesKey() { return QStringLiteral("recentFileList"); } +static inline QString fileKey() { return QStringLiteral("file"); } + +static QStringList readRecentFiles(QSettings &settings) +{ + QStringList result; + const int count = settings.beginReadArray(recentFilesKey()); + for (int i = 0; i < count; ++i) { + settings.setArrayIndex(i); + result.append(settings.value(fileKey()).toString()); + } + settings.endArray(); + return result; +} + +static void writeRecentFiles(const QStringList &files, QSettings &settings) +{ + const int count = files.size(); + settings.beginWriteArray(recentFilesKey()); + for (int i = 0; i < count; ++i) { + settings.setArrayIndex(i); + settings.setValue(fileKey(), files.at(i)); + } + settings.endArray(); +} + +bool MainWindow::hasRecentFiles() +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + const int count = settings.beginReadArray(recentFilesKey()); + settings.endArray(); + return count > 0; +} + +void MainWindow::prependToRecentFiles(const QString &fileName) +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + + const QStringList oldRecentFiles = readRecentFiles(settings); + QStringList recentFiles = oldRecentFiles; + recentFiles.removeAll(fileName); + recentFiles.prepend(fileName); + if (oldRecentFiles != recentFiles) + writeRecentFiles(recentFiles, settings); + + setRecentFilesVisible(!recentFiles.isEmpty()); +} + +void MainWindow::updateRecentFileActions() +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + + const QStringList recentFiles = readRecentFiles(settings); + const int count = qMin(int(MaxRecentFiles), recentFiles.size()); + int i = 0; + for ( ; i < count; ++i) { + const QString fileName = MainWindow::strippedName(recentFiles.at(i)); + recentFileActs[i]->setText(tr("&%1 %2").arg(i + 1).arg(fileName)); + recentFileActs[i]->setData(recentFiles.at(i)); + recentFileActs[i]->setVisible(true); + } + for ( ; i < MaxRecentFiles; ++i) + recentFileActs[i]->setVisible(false); +} + +void MainWindow::openRecentFile() +{ + if (const QAction *action = qobject_cast<const QAction *>(sender())) + openFile(action->data().toString()); +} + bool MainWindow::saveFile(const QString &fileName) { QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr("SDI"), tr("Cannot write file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), file.errorString())); return false; } @@ -351,6 +446,10 @@ void MainWindow::setCurrentFile(const QString &fileName) textEdit->document()->setModified(false); setWindowModified(false); + + if (!isUntitled && windowFilePath() != curFile) + MainWindow::prependToRecentFiles(curFile); + setWindowFilePath(curFile); } @@ -359,14 +458,15 @@ QString MainWindow::strippedName(const QString &fullFileName) return QFileInfo(fullFileName).fileName(); } -MainWindow *MainWindow::findMainWindow(const QString &fileName) +MainWindow *MainWindow::findMainWindow(const QString &fileName) const { QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath(); - foreach (QWidget *widget, qApp->topLevelWidgets()) { + foreach (QWidget *widget, QApplication::topLevelWidgets()) { MainWindow *mainWin = qobject_cast<MainWindow *>(widget); if (mainWin && mainWin->curFile == canonicalFilePath) return mainWin; } + return 0; } diff --git a/examples/widgets/mainwindows/sdi/mainwindow.h b/examples/widgets/mainwindows/sdi/mainwindow.h index f1860a8511..66ac618c72 100644 --- a/examples/widgets/mainwindows/sdi/mainwindow.h +++ b/examples/widgets/mainwindows/sdi/mainwindow.h @@ -42,6 +42,7 @@ #define MAINWINDOW_H #include <QMainWindow> +#include <QList> QT_BEGIN_NAMESPACE class QAction; @@ -57,7 +58,9 @@ class MainWindow : public QMainWindow public: MainWindow(); //! [class definition with macro] - MainWindow(const QString &fileName); + explicit MainWindow(const QString &fileName); + + void tile(const QMainWindow *previous); protected: void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; @@ -67,44 +70,38 @@ private slots: void open(); bool save(); bool saveAs(); + void updateRecentFileActions(); + void openRecentFile(); void about(); void documentWasModified(); private: + enum { MaxRecentFiles = 5 }; + void init(); void createActions(); - void createMenus(); - void createToolBars(); void createStatusBar(); void readSettings(); void writeSettings(); bool maybeSave(); + void openFile(const QString &fileName); void loadFile(const QString &fileName); + static bool hasRecentFiles(); + void prependToRecentFiles(const QString &fileName); + void setRecentFilesVisible(bool visible); bool saveFile(const QString &fileName); void setCurrentFile(const QString &fileName); - QString strippedName(const QString &fullFileName); - MainWindow *findMainWindow(const QString &fileName); + static QString strippedName(const QString &fullFileName); + MainWindow *findMainWindow(const QString &fileName) const; QTextEdit *textEdit; + + QAction *recentFileActs[MaxRecentFiles]; + QAction *recentFileSeparator; + QAction *recentFileSubMenuAct; + QString curFile; bool isUntitled; - - QMenu *fileMenu; - QMenu *editMenu; - QMenu *helpMenu; - QToolBar *fileToolBar; - QToolBar *editToolBar; - QAction *newAct; - QAction *openAct; - QAction *saveAct; - QAction *saveAsAct; - QAction *closeAct; - QAction *exitAct; - QAction *cutAct; - QAction *copyAct; - QAction *pasteAct; - QAction *aboutAct; - QAction *aboutQtAct; }; #endif |