#define EDITOR_H
#include
class Editor : public QTextEdit
{
Q_OBJECT
public:
Editor(QWidget *parent = 0);
void newFile();
bool save();
bool saveAs();
QSize sizeHint() const;
QAction *windowMenuAction() const { return action; }
static Editor *open(QWidget *parent = 0);
static Editor *openFile(const QString &fileName,
QWidget *parent = 0);
protected:
void closeEvent(QCloseEvent *event);
private slots:
void documentWasModified();
private:
bool okToContinue();
bool saveFile(const QString &fileName);
void setCurrentFile(const QString &fileName);
bool readFile(const QString &fileName);
bool writeFile(const QString &fileName);
QString strippedName(const QString &fullFileName);
QString curFile;
bool isUntitled;
QAction *action;
};
#endif
#include "editor.h"
#include
#include
#include
#include
Editor::Editor(QWidget *parent)
: QTextEdit(parent)
{
action = new QAction(this);
action->setCheckable(true);
connect(action, SIGNAL(triggered()), this, SLOT(show()));
connect(action, SIGNAL(triggered()), this, SLOT(setFocus()));
isUntitled = true;
connect(document(), SIGNAL(contentsChanged()),
this, SLOT(documentWasModified()));
setWindowIcon(QPixmap(":/images/document.png"));
setWindowTitle("[*]");
setAttribute(Qt::WA_DeleteOnClose);
}
void Editor::newFile()
{
static int documentNumber = 1;
curFile = tr("document%1.txt").arg(documentNumber);
setWindowTitle(curFile + "[*]");
action->setText(curFile);
isUntitled = true;
++documentNumber;
}
bool Editor::save()
{
if (isUntitled) {
return saveAs();
} else {
return saveFile(curFile);
}
}
bool Editor::saveAs()
{
QString fileName =
QFileDialog::getSaveFileName(this, tr("Save As"), curFile);
if (fileName.isEmpty())
return false;
return saveFile(fileName);
}
QSize Editor::sizeHint() const
{
return QSize(72 * fontMetrics().width('x'),
25 * fontMetrics().lineSpacing());
}
Editor *Editor::open(QWidget *parent)
{
QString fileName =
QFileDialog::getOpenFileName(parent, tr("Open"), ".");
if (fileName.isEmpty())
return 0;
return openFile(fileName, parent);
}
Editor *Editor::openFile(const QString &fileName, QWidget *parent)
{
Editor *editor = new Editor(parent);
if (editor->readFile(fileName)) {
editor->setCurrentFile(fileName);
return editor;
} else {
delete editor;
return 0;
}
}
void Editor::closeEvent(QCloseEvent *event)
{
if (okToContinue()) {
event->accept();
} else {
event->ignore();
}
}
void Editor::documentWasModified()
{
setWindowModified(true);
}
bool Editor::okToContinue()
{
if (document()->isModified()) {
int r = QMessageBox::warning(this, tr("MDI Editor"),
tr("File %1 has been modified.\n"
"Do you want to save your changes?")
.arg(strippedName(curFile)),
QMessageBox::Yes | QMessageBox::No
| QMessageBox::Cancel);
if (r == QMessageBox::Yes) {
return save();
} else if (r == QMessageBox::Cancel) {
return false;
}
}
return true;
}
bool Editor::saveFile(const QString &fileName)
{
if (writeFile(fileName)) {
setCurrentFile(fileName);
return true;
} else {
return false;
}
}
void Editor::setCurrentFile(const QString &fileName)
{
curFile = fileName;
isUntitled = false;
action->setText(strippedName(curFile));
document()->setModified(false);
setWindowTitle(strippedName(curFile) + "[*]");
setWindowModified(false);
}
bool Editor::readFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QMessageBox::warning(this, tr("MDI Editor"),
tr("Cannot read file %1:\n%2.")
.arg(file.fileName())
.arg(file.errorString()));
return false;
}
QTextStream in(&file);
// QApplication::setOverrideCursor(Qt::WaitCursor);
setPlainText(in.readAll());
// QApplication::restoreOverrideCursor();
return true;
}
bool Editor::writeFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::warning(this, tr("MDI Editor"),
tr("Cannot write file %1:\n%2.")
.arg(file.fileName())
.arg(file.errorString()));
return false;
}
QTextStream out(&file);
// QApplication::setOverrideCursor(Qt::WaitCursor);
out << toPlainText();
// QApplication::restoreOverrideCursor();
return true;
}
QString Editor::strippedName(const QString &fullFileName)
{
return QFileInfo(fullFileName).fileName();
}
#define MAINWINDOW_H
#include
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
#include
#include "editor.h"
#include "mainwindow.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
MainWindow::MainWindow()
{
mdiArea = new QMdiArea;
setCentralWidget(mdiArea);
connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)),
this, SLOT(updateActions()));
createActions();
createMenus();
createToolBars();
createStatusBar();
setWindowIcon(QPixmap(":/images/icon.png"));
setWindowTitle(tr("MDI Editor"));
QTimer::singleShot(0, this, SLOT(loadFiles()));
}
void MainWindow::loadFiles()
{
QStringList args = QApplication::arguments();
args.removeFirst();
if (!args.isEmpty()) {
foreach (QString arg, args)
openFile(arg);
mdiArea->cascadeSubWindows();
} else {
newFile();
}
mdiArea->activateNextSubWindow();
}
void MainWindow::newFile()
{
Editor *editor = new Editor;
editor->newFile();
addEditor(editor);
}
void MainWindow::openFile(const QString &fileName)
{
Editor *editor = Editor::openFile(fileName, this);
if (editor)
addEditor(editor);
}
void MainWindow::closeEvent(QCloseEvent *event)
{
mdiArea->closeAllSubWindows();
if (!mdiArea->subWindowList().isEmpty()) {
event->ignore();
} else {
event->accept();
}
}
void MainWindow::open()
{
Editor *editor = Editor::open(this);
if (editor)
addEditor(editor);
}
void MainWindow::save()
{
if (activeEditor())
activeEditor()->save();
}
void MainWindow::saveAs()
{
if (activeEditor())
activeEditor()->saveAs();
}
void MainWindow::cut()
{
if (activeEditor())
activeEditor()->cut();
}
void MainWindow::copy()
{
if (activeEditor())
activeEditor()->copy();
}
void MainWindow::paste()
{
if (activeEditor())
activeEditor()->paste();
}
void MainWindow::about()
{
QMessageBox::about(this, tr("About MDI Editor"),
tr("Editor
1.1"
"Copyright
© 2007 Software Inc."
"MDI
Editor is a small application that demonstrates "
"QMdiArea."));
}
void MainWindow::updateActions()
{
bool hasEditor = (activeEditor() != 0);
bool hasSelection = activeEditor()
&& activeEditor()->textCursor().hasSelection();
saveAction->setEnabled(hasEditor);
saveAsAction->setEnabled(hasEditor);
cutAction->setEnabled(hasSelection);
copyAction->setEnabled(hasSelection);
pasteAction->setEnabled(hasEditor);
closeAction->setEnabled(hasEditor);
closeAllAction->setEnabled(hasEditor);
tileAction->setEnabled(hasEditor);
cascadeAction->setEnabled(hasEditor);
nextAction->setEnabled(hasEditor);
previousAction->setEnabled(hasEditor);
separatorAction->setVisible(hasEditor);
if (activeEditor())
activeEditor()->windowMenuAction()->setChecked(true);
}
void MainWindow::createActions()
{
newAction = new QAction(tr("&New"), this);
newAction->setIcon(QIcon(":/images/new.png"));
newAction->setShortcut(QKeySequence::New);
newAction->setStatusTip(tr("Create a new file"));
connect(newAction, SIGNAL(triggered()), this, SLOT(newFile()));
openAction = new QAction(tr("&Open..."), this);
openAction->setIcon(QIcon(":/images/open.png"));
openAction->setShortcut(QKeySequence::Open);
openAction->setStatusTip(tr("Open an existing file"));
connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
saveAction = new QAction(tr("&Save"), this);
saveAction->setIcon(QIcon(":/images/save.png"));
saveAction->setShortcut(QKeySequence::Save);
saveAction->setStatusTip(tr("Save the file to disk"));
connect(saveAction, SIGNAL(triggered()), this, SLOT(save()));
saveAsAction = new QAction(tr("Save &As..."), this);
saveAsAction->setStatusTip(tr("Save the file under a new name"));
connect(saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs()));
exitAction = new QAction(tr("E&xit"), this);
exitAction->setShortcut(tr("Ctrl+Q"));
exitAction->setStatusTip(tr("Exit the application"));
connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
cutAction = new QAction(tr("Cu&t"), this);
cutAction->setIcon(QIcon(":/images/cut.png"));
cutAction->setShortcut(QKeySequence::Cut);
cutAction->setStatusTip(tr("Cut the current selection to the "
"clipboard"));
connect(cutAction, SIGNAL(triggered()), this, SLOT(cut()));
copyAction = new QAction(tr("&Copy"), this);
copyAction->setIcon(QIcon(":/images/copy.png"));
copyAction->setShortcut(QKeySequence::Copy);
copyAction->setStatusTip(tr("Copy the current selection to the "
"clipboard"));
connect(copyAction, SIGNAL(triggered()), this, SLOT(copy()));
pasteAction = new QAction(tr("&Paste"), this);
pasteAction->setIcon(QIcon(":/images/paste.png"));
pasteAction->setShortcut(QKeySequence::Paste);
pasteAction->setStatusTip(tr("Paste the clipboard's contents at "
"the cursor position"));
connect(pasteAction, SIGNAL(triggered()), this, SLOT(paste()));
closeAction = new QAction(tr("Cl&ose"), this);
closeAction->setShortcut(QKeySequence::Close);
closeAction->setStatusTip(tr("Close the active window"));
connect(closeAction, SIGNAL(triggered()),
mdiArea, SLOT(closeActiveSubWindow()));
closeAllAction = new QAction(tr("Close &All"), this);
closeAllAction->setStatusTip(tr("Close all the windows"));
connect(closeAllAction, SIGNAL(triggered()), this, SLOT(close()));
tileAction = new QAction(tr("&Tile"), this);
tileAction->setStatusTip(tr("Tile the windows"));
connect(tileAction, SIGNAL(triggered()),
mdiArea, SLOT(tileSubWindows()));
cascadeAction = new QAction(tr("&Cascade"), this);
cascadeAction->setStatusTip(tr("Cascade the windows"));
connect(cascadeAction, SIGNAL(triggered()),
mdiArea, SLOT(cascadeSubWindows()));
nextAction = new QAction(tr("Ne&xt"), this);
nextAction->setShortcut(QKeySequence::NextChild);
nextAction->setStatusTip(tr("Move the focus to the next window"));
connect(nextAction, SIGNAL(triggered()),
mdiArea, SLOT(activateNextSubWindow()));
previousAction = new QAction(tr("Pre&vious"), this);
previousAction->setShortcut(QKeySequence::PreviousChild);
previousAction->setStatusTip(tr("Move the focus to the previous "
"window"));
connect(previousAction, SIGNAL(triggered()),
mdiArea, SLOT(activatePreviousSubWindow()));
separatorAction = new QAction(this);
separatorAction->setSeparator(true);
aboutAction = new QAction(tr("&About"), this);
aboutAction->setStatusTip(tr("Show the application's About box"));
connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
aboutQtAction = new QAction(tr("About &Qt"), this);
aboutQtAction->setStatusTip(tr("Show the Qt library's About box"));
connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
windowActionGroup = new QActionGroup(this);
}
void MainWindow::createMenus()
{
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(newAction);
fileMenu->addAction(openAction);
fileMenu->addAction(saveAction);
fileMenu->addAction(saveAsAction);
fileMenu->addSeparator();
fileMenu->addAction(exitAction);
editMenu = menuBar()->addMenu(tr("&Edit"));
editMenu->addAction(cutAction);
editMenu->addAction(copyAction);
editMenu->addAction(pasteAction);
windowMenu = menuBar()->addMenu(tr("&Window"));
windowMenu->addAction(closeAction);
windowMenu->addAction(closeAllAction);
windowMenu->addSeparator();
windowMenu->addAction(tileAction);
windowMenu->addAction(cascadeAction);
windowMenu->addSeparator();
windowMenu->addAction(nextAction);
windowMenu->addAction(previousAction);
windowMenu->addAction(separatorAction);
menuBar()->addSeparator();
helpMenu = menuBar()->addMenu(tr("&Help"));
helpMenu->addAction(aboutAction);
helpMenu->addAction(aboutQtAction);
}
void MainWindow::createToolBars()
{
fileToolBar = addToolBar(tr("File"));
fileToolBar->addAction(newAction);
fileToolBar->addAction(openAction);
fileToolBar->addAction(saveAction);
editToolBar = addToolBar(tr("Edit"));
editToolBar->addAction(cutAction);
editToolBar->addAction(copyAction);
editToolBar->addAction(pasteAction);
}
void MainWindow::createStatusBar()
{
readyLabel = new QLabel(tr(" Ready"));
this->statusBar()->addWidget(readyLabel, 1);
}
void MainWindow::addEditor(Editor *editor)
{
connect(editor, SIGNAL(copyAvailable(bool)),
cutAction, SLOT(setEnabled(bool)));
connect(editor, SIGNAL(copyAvailable(bool)),
copyAction, SLOT(setEnabled(bool)));
QMdiSubWindow *subWindow = mdiArea->addSubWindow(editor);
windowMenu->addAction(editor->windowMenuAction());
windowActionGroup->addAction(editor->windowMenuAction());
subWindow->show();
}
Editor *MainWindow::activeEditor()
{
QMdiSubWindow *subWindow = mdiArea->activeSubWindow();
if (subWindow)
return qobject_cast<Editor *>(subWindow->widget());
return 0;
}
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow mainWin;
mainWin.show();
return app.exec();
}