// Copyright (C) 2008 Lukas Lalinsky // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "utils/iconloader/qticonloader.h" #include "diagramitem.h" #include "diagramobject.h" #include "diagramitemfactory.h" #include "diagramitemproperties.h" #include "commands.h" #include "mainwindow.h" #include "export/exporter.h" #include "export/exporterlist.h" class MainWindow::MainWindowPrivate { public: MainWindowPrivate() : printer(0) {} QDockWidget *itemPropsDock; QStackedWidget *propertyEditorsStack; QMap propertyEditorsIndexes; QPrinter *printer; QAction *printAction; QAction *printPreviewAction; QAction *pageSetupAction; QActionGroup *notationActionGroup; QMenu *notationMenu; ExporterList exporters; }; MainWindow::MainWindow(const QString &fileName) : QMainWindow(), d(new MainWindowPrivate), m_model(NULL) { setupUi(); setupActions(); setupToolBar(); setupMenuBar(); if (fileName.isEmpty()) { newModel(); } else { loadFile(fileName); } QIcon icon; icon.addFile(":/icons/16x16/item-table.png", QSize(32, 32)); icon.addFile(":/icons/32x32/item-table.png", QSize(32, 32)); setWindowIcon(icon); updateRecentFileActions(); restoreWindowState(); connect(QApplication::clipboard(), SIGNAL(changed(QClipboard::Mode)), this, SLOT(updateClipboard(QClipboard::Mode))); updateClipboard(QClipboard::Clipboard); updateSelection(); } MainWindow::~MainWindow() { delete d; } void MainWindow::closeEvent(QCloseEvent *event) { if (maybeSave()) { saveWindowState(); event->accept(); } else { event->ignore(); } } void MainWindow::resizeEvent(QResizeEvent *event) { if (!isMaximized()) m_lastSize = size(); QWidget::resizeEvent(event); } void MainWindow::moveEvent(QMoveEvent *event) { if (!isMaximized()) m_lastPos = pos(); QWidget::moveEvent(event); } void MainWindow::showEvent(QShowEvent *event) { m_lastPos = pos(); m_lastSize = size(); QWidget::showEvent(event); } void MainWindow::restoreWindowState() { QSettings settings; restoreState(settings.value("windowState").toByteArray()); QPoint pos = settings.value("windowPos").toPoint(); if (!pos.isNull()) move(pos); resize(settings.value("windowSize", QSize(780, 580)).toSize()); if (settings.value("windowMaximized", false).toBool()) setWindowState(windowState() ^ Qt::WindowMaximized); } void MainWindow::saveWindowState() { QSettings settings; settings.setValue("windowState", saveState()); settings.setValue("windowGeometry", saveGeometry()); settings.setValue("windowMaximized", isMaximized()); settings.setValue("windowPos", m_lastPos); settings.setValue("windowSize", m_lastSize); } void MainWindow::setupUi() { d->itemPropsDock = new QDockWidget(tr("&Properties"), this); d->itemPropsDock->setObjectName("itemPropsDock"); d->itemPropsDock->setFeatures( QDockWidget::AllDockWidgetFeatures | QDockWidget::DockWidgetVerticalTitleBar); addDockWidget(Qt::BottomDockWidgetArea, d->itemPropsDock); d->propertyEditorsStack = new QStackedWidget(d->itemPropsDock); d->propertyEditorsStack->addWidget(new QWidget(this)); foreach (QString name, DiagramItemFactory::keys()) { QWidget *editor = DiagramItemFactory::createPropertiesEditor(name, this); if (editor) d->propertyEditorsIndexes[name] = d->propertyEditorsStack->addWidget(editor); } d->itemPropsDock->setWidget(d->propertyEditorsStack); m_view = new DiagramView(this); setCentralWidget(m_view); } QIcon MainWindow::loadIcon(const QString &name) { QIcon icon = QtIconLoader::icon(name); if (icon.isNull()) { QString path = ":/icons/16x16/" + name + ".png"; if (QFile::exists(path)) { icon.addFile(path, QSize(16, 16)); } } return icon; } void MainWindow::setupActions() { m_actionNew = new QAction(this); m_actionNew->setText(tr("&New")); m_actionNew->setIcon(loadIcon("document-new")); m_actionNew->setShortcut(QKeySequence::New); connect(m_actionNew, SIGNAL(triggered(bool)), SLOT(newModel())); m_actionOpen = new QAction(this); m_actionOpen->setText(tr("&Open...")); m_actionOpen->setIcon(loadIcon("document-open")); m_actionOpen->setShortcut(QKeySequence::Open); connect(m_actionOpen, SIGNAL(triggered(bool)), SLOT(open())); m_actionSave = new QAction(this); m_actionSave->setText(tr("&Save")); m_actionSave->setIcon(loadIcon("document-save")); m_actionSave->setShortcut(QKeySequence::Save); //m_actionSave->setDisabled(true); connect(m_actionSave, SIGNAL(triggered(bool)), SLOT(save())); m_actionSaveAs = new QAction(this); m_actionSaveAs->setText(tr("Save &As...")); m_actionSaveAs->setIcon(loadIcon("document-save-as")); m_actionSaveAs->setShortcut(QKeySequence::SaveAs); //m_actionSaveAs->setDisabled(true); connect(m_actionSaveAs, SIGNAL(triggered(bool)), SLOT(saveAs())); //connect(m_undoGroup, SIGNAL(cleanChanged(bool)), m_actionSave, SLOT(setDisabled(bool))); //connect(m_undoGroup, SIGNAL(cleanChanged(bool)), m_actionSaveAs, SLOT(setDisabled(bool))); m_actionExportPNG = new QAction(this); m_actionExportPNG->setText(tr("E&xport...")); connect(m_actionExportPNG, SIGNAL(triggered(bool)), SLOT(exportDocument())); d->pageSetupAction = new QAction(this); d->pageSetupAction->setText(tr("Page Set&up...")); connect(d->pageSetupAction, SIGNAL(triggered(bool)), SLOT(pageSetup())); d->printAction = new QAction(this); d->printAction->setText(tr("&Print...")); d->printAction->setIcon(loadIcon("document-print")); d->printAction->setShortcut(QKeySequence::Print); connect(d->printAction, SIGNAL(triggered(bool)), SLOT(print())); d->printPreviewAction = new QAction(this); d->printPreviewAction->setText(tr("Print Previe&w...")); d->printPreviewAction->setIcon(loadIcon("document-print-preview")); d->printPreviewAction->setShortcut(QKeySequence("Ctrl+Shift+P")); connect(d->printPreviewAction, SIGNAL(triggered(bool)), SLOT(printPreview())); for (int i = 0; i < MaxRecentFiles; i++) { m_actionRecentFile[i] = new QAction(this); m_actionRecentFile[i]->setVisible(false); connect(m_actionRecentFile[i], SIGNAL(triggered()), this, SLOT(openRecentFile())); } m_actionSwitchMode[0] = new QAction(this); m_actionSwitchMode[0]->setText(tr("Select")); m_actionSwitchMode[0]->setIcon(QIcon(":/icons/cr16-action-mouse_pointer.png")); m_actionSwitchMode[0]->setCheckable(true); m_actionSwitchMode[0]->setChecked(true); m_actionSwitchMode[1] = new QAction(this); m_actionSwitchMode[1]->setText(tr("Add new table")); m_actionSwitchMode[1]->setIcon(QIcon(":/icons/16x16/item-table.png")); m_actionSwitchMode[1]->setCheckable(true); m_actionSwitchMode[2] = new QAction(this); m_actionSwitchMode[2]->setText(tr("Add new relation")); m_actionSwitchMode[2]->setIcon(QIcon(":/icons/16x16/item-relationship.png")); m_actionSwitchMode[2]->setCheckable(true); m_actionUndo = new QAction(tr("&Undo"), this); m_actionUndo->setShortcut(QKeySequence::Undo); m_actionUndo->setIcon(loadIcon("edit-undo")); m_actionRedo = new QAction(tr("Re&do"), this); m_actionRedo->setShortcut(QKeySequence::Redo); m_actionRedo->setIcon(loadIcon("edit-redo")); connect(m_actionSwitchMode[0], SIGNAL(triggered(bool)), SLOT(switchModeSelect())); connect(m_actionSwitchMode[1], SIGNAL(triggered(bool)), SLOT(switchModeAddTable())); connect(m_actionSwitchMode[2], SIGNAL(triggered(bool)), SLOT(switchModeAddRelation())); m_actionCut = new QAction(this); m_actionCut->setText(tr("Cu&t")); m_actionCut->setIcon(loadIcon("edit-cut")); m_actionCut->setShortcut(QKeySequence::Cut); connect(m_actionCut, SIGNAL(triggered(bool)), SLOT(cut())); m_actionCopy = new QAction(this); m_actionCopy->setText(tr("&Copy")); m_actionCopy->setIcon(loadIcon("edit-copy")); m_actionCopy->setShortcut(QKeySequence::Copy); connect(m_actionCopy, SIGNAL(triggered(bool)), SLOT(copy())); m_actionPaste = new QAction(this); m_actionPaste->setText(tr("&Paste")); m_actionPaste->setIcon(loadIcon("edit-paste")); m_actionPaste->setShortcut(QKeySequence::Paste); connect(m_actionPaste, SIGNAL(triggered(bool)), SLOT(paste())); m_actionDelete = new QAction(this); m_actionDelete->setText(tr("&Delete")); m_actionDelete->setIcon(loadIcon("edit-delete")); m_actionDelete->setShortcut(QKeySequence::Delete); connect(m_actionDelete, SIGNAL(triggered(bool)), SLOT(deleteSelectedItems())); m_actionAbout = new QAction(this); m_actionAbout->setText(tr("&About...")); connect(m_actionAbout, SIGNAL(triggered(bool)), SLOT(about())); m_actionClose = new QAction(this); m_actionClose->setText(tr("&Close")); m_actionClose->setIcon(loadIcon("window-close")); m_actionClose->setShortcut(QKeySequence::Close); connect(m_actionClose, SIGNAL(triggered(bool)), SLOT(closeDocument())); m_actionQuit = new QAction(this); m_actionQuit->setText(tr("&Quit")); m_actionQuit->setIcon(loadIcon("application-exit")); m_actionQuit->setShortcut(QKeySequence("Ctrl+Q")); connect(m_actionQuit, SIGNAL(triggered(bool)), SLOT(closeAll())); m_actionShowGrid = new QAction(this); m_actionShowGrid->setText(tr("Show &Grid")); m_actionShowGrid->setCheckable(true); connect(m_actionShowGrid, SIGNAL(triggered(bool)), SLOT(showGrid(bool))); d->notationMenu = new QMenu(tr("&Notation"), this); d->notationActionGroup = new QActionGroup(this); QAction *action; action = d->notationActionGroup->addAction(tr("&Relational")); action->setCheckable(true); action->setData(DiagramDocument::Relational); d->notationMenu->addAction(action); action = d->notationActionGroup->addAction(tr("&Crow's Foot")); action->setCheckable(true); action->setData(DiagramDocument::CrowsFoot); d->notationMenu->addAction(action); connect(d->notationActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(setDiagramNotation(QAction*))); } void MainWindow::showGrid(bool checked) { m_model->undoStack()->push( new SetObjectPropertyCommand(m_model, "gridVisible", checked)); } void MainWindow::setupToolBar() { QToolBar *toolBar = addToolBar(tr("&File")); toolBar->setObjectName("fileToolBar"); toolBar->setIconSize(QSize(16, 16)); toolBar->addAction(m_actionNew); toolBar->addAction(m_actionOpen); toolBar->addSeparator(); toolBar->addAction(m_actionSave); toolBar->addAction(m_actionSaveAs); toolBar->addSeparator(); toolBar->addAction(m_actionUndo); toolBar->addAction(m_actionRedo); toolBar->addSeparator(); toolBar->addAction(m_actionCut); toolBar->addAction(m_actionCopy); toolBar->addAction(m_actionPaste); toolBar = addToolBar(tr("&Mode")); toolBar->setObjectName("modeToolBar"); toolBar->setIconSize(QSize(16, 16)); toolBar->addAction(m_actionSwitchMode[0]); toolBar->addAction(m_actionSwitchMode[1]); toolBar->addAction(m_actionSwitchMode[2]); QComboBox *sceneScaleCombo = new QComboBox; QStringList scales; scales << tr("50%") << tr("70%") << tr("85%") << tr("100%") << tr("125%") << tr("150%"); sceneScaleCombo->addItems(scales); sceneScaleCombo->setEditable(true); sceneScaleCombo->setCurrentIndex(3); connect(sceneScaleCombo, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(setViewScale(const QString &))); toolBar = addToolBar(tr("&View")); toolBar->setObjectName("viewToolBar"); toolBar->addWidget(sceneScaleCombo); } void MainWindow::setViewScale(const QString &scale) { double newScale = scale.left(scale.indexOf("%")).toDouble() / 100.0; QMatrix oldMatrix = m_view->matrix(); m_view->resetMatrix(); m_view->translate(oldMatrix.dx(), oldMatrix.dy()); m_view->scale(newScale, newScale); } void MainWindow::setupMenuBar() { QMenu *menu = menuBar()->addMenu(tr("&File")); menu->addAction(m_actionNew); menu->addAction(m_actionOpen); menu->addSeparator(); menu->addAction(m_actionSave); menu->addAction(m_actionSaveAs); menu->addAction(m_actionExportPNG); menu->addSeparator(); menu->addAction(d->pageSetupAction); menu->addAction(d->printPreviewAction); menu->addAction(d->printAction); m_actionRecentFilesSeparator = menu->addSeparator(); for (int i = 0; i < MaxRecentFiles; i++) menu->addAction(m_actionRecentFile[i]); menu->addSeparator(); menu->addAction(m_actionClose); menu->addAction(m_actionQuit); menu = menuBar()->addMenu(tr("&Edit")); menu->addAction(m_actionUndo); menu->addAction(m_actionRedo); menu->addSeparator(); menu->addAction(m_actionCut); menu->addAction(m_actionCopy); menu->addAction(m_actionPaste); menu->addSeparator(); menu->addAction(m_actionDelete); QMenu *viewMenu = menuBar()->addMenu(tr("&View")); viewMenu->addAction(d->itemPropsDock->toggleViewAction()); viewMenu->addSeparator(); viewMenu->addAction(m_actionShowGrid); QMenu *diagramMenu = menuBar()->addMenu(tr("&Diagram")); diagramMenu->addMenu(d->notationMenu); diagramMenu->addSeparator(); menu = menuBar()->addMenu(tr("&Help")); menu->addAction(m_actionAbout); } void MainWindow::deleteSelectedItems() { m_model->deleteSelectedItems(); } void MainWindow::loadFile(const QString &fileName) { DiagramDocument *model = new DiagramDocument(this); if (model->load(fileName)) { newModel(model); addRecentFile(fileName); } else { QMessageBox::critical(this, tr("Error"), tr("Unknown format.")); newModel(); } } void MainWindow::saveFile(const QString &fileName) { m_model->save(fileName); m_model->undoStack()->setClean(); addRecentFile(fileName); updateWindowTitle(); } bool MainWindow::maybeSave() { if (m_model && !m_model->undoStack()->isClean()) { QMessageBox::StandardButton button = QMessageBox::warning(this, QString(), tr("The document has been modified.\nDo you want to save your changes?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); if (button == QMessageBox::Cancel) return false; if (button == QMessageBox::Yes) return save(); } return true; } void MainWindow::open() { if (!maybeSave()) return; QString fileName = QFileDialog::getOpenFileName(this, QString(), QString(), "Database Model (*.dmf)"); if (!fileName.isNull()) loadFile(fileName); } bool MainWindow::save() { QString fileName = m_model->fileName(); if (fileName.isEmpty()) return saveAs(); saveFile(fileName); return true; } bool MainWindow::saveAs() { QString fileName = QFileDialog::getSaveFileName(this, QString(), m_model->fileName(), "Database Model (*.dmf)"); if (fileName.isNull()) return false; saveFile(fileName); return true; } void MainWindow::exportDocument() { QString selectedFilter; QString fileName = QFileDialog::getSaveFileName(this, QString(), QString(), d->exporters.filters(), &selectedFilter); if (!fileName.isNull()) { Exporter *exporter = d->exporters.lookup(&fileName, selectedFilter); if (!exporter) { QMessageBox::critical(this, tr("Error"), tr("Unknown format.")); return; } exporter->exportToFile(fileName, m_model); } } void MainWindow::initPrinter() { if (!d->printer) d->printer = new QPrinter(); } void MainWindow::print() { initPrinter(); QPrintDialog printDialog(d->printer, this); if (printDialog.exec() == QDialog::Accepted) { m_model->print(d->printer); } } void MainWindow::printPreview() { initPrinter(); QPrintPreviewDialog printPreviewDialog(d->printer, this); connect(&printPreviewDialog, SIGNAL(paintRequested(QPrinter*)), SLOT(printPreview(QPrinter*))); printPreviewDialog.exec(); } void MainWindow::printPreview(QPrinter *printer) { m_model->print(printer); } void MainWindow::pageSetup() { initPrinter(); QPageSetupDialog pageSetupDialog(d->printer, this); pageSetupDialog.exec(); } void MainWindow::newModel(DiagramDocument *newModel) { if (!newModel) { if (!maybeSave()) return; newModel = new DiagramDocument(this); } m_view->setScene(newModel); if (m_model != 0) { QUndoStack *undoStack = m_model->undoStack(); disconnect(undoStack, SIGNAL(cleanChanged(bool)), this, SLOT(updateWindowTitle())); disconnect(undoStack, SIGNAL(canUndoChanged(bool)), m_actionUndo, SLOT(setEnabled(bool))); disconnect(undoStack, SIGNAL(canRedoChanged(bool)), m_actionRedo, SLOT(setEnabled(bool))); disconnect(m_actionUndo, SIGNAL(triggered(bool)), undoStack, SLOT(undo())); disconnect(m_actionRedo, SIGNAL(triggered(bool)), undoStack, SLOT(redo())); disconnect(m_model, 0, this, 0); m_model->deleteLater(); } m_model = newModel; updateMode(m_model->mode()); updateSelection(); m_actionShowGrid->setChecked(m_model->isGridVisible()); foreach (QAction *action, d->notationActionGroup->actions()) { if (action->data() == m_model->notation()) { action->setChecked(true); break; } } QUndoStack *undoStack = m_model->undoStack(); connect(undoStack, SIGNAL(cleanChanged(bool)), this, SLOT(updateWindowTitle())); connect(undoStack, SIGNAL(canUndoChanged(bool)), m_actionUndo, SLOT(setEnabled(bool))); connect(undoStack, SIGNAL(canRedoChanged(bool)), m_actionRedo, SLOT(setEnabled(bool))); connect(m_actionUndo, SIGNAL(triggered(bool)), undoStack, SLOT(undo())); connect(m_actionRedo, SIGNAL(triggered(bool)), undoStack, SLOT(redo())); m_actionUndo->setEnabled(undoStack->canUndo()); m_actionRedo->setEnabled(undoStack->canRedo()); connect(m_model, SIGNAL(modeChanged(DiagramDocument::Mode)), SLOT(updateMode(DiagramDocument::Mode))); connect(m_model, SIGNAL(selectionChanged()), SLOT(updateSelection())); updateWindowTitle(); } void MainWindow::updateSelection() { if (m_model == 0) return; QList items = m_model->selectedItems(); // Update the property editor bool enablePropertiesEditor = false; DiagramItemProperties *previousEditor = qobject_cast(d->propertyEditorsStack->currentWidget()); if (previousEditor) previousEditor->setCurrentItem(NULL); if (items.size() == 1) { DiagramItem *item = items.first(); QString itemTypeName = item->typeName(); if (d->propertyEditorsIndexes.contains(itemTypeName)) { int index = d->propertyEditorsIndexes.value(itemTypeName); d->propertyEditorsStack->setCurrentIndex(index); static_cast(d->propertyEditorsStack->currentWidget())->setCurrentItem(item); enablePropertiesEditor = true; } } if (!enablePropertiesEditor) d->propertyEditorsStack->setCurrentIndex(0); d->propertyEditorsStack->setEnabled(enablePropertiesEditor); // Update edit actions if (items.size() > 0) { m_actionCut->setEnabled(true); m_actionCopy->setEnabled(true); m_actionDelete->setEnabled(true); } else { m_actionCut->setEnabled(false); m_actionCopy->setEnabled(false); m_actionDelete->setEnabled(false); } } void MainWindow::updateMode(DiagramDocument::Mode mode) { m_actionSwitchMode[0]->setChecked(mode == DiagramDocument::Select); m_actionSwitchMode[1]->setChecked(mode == DiagramDocument::AddTable); m_actionSwitchMode[2]->setChecked(mode == DiagramDocument::AddRelation); } void MainWindow::switchModeSelect() { m_model->setMode(DiagramDocument::Select); } void MainWindow::switchModeAddTable() { m_model->setMode(DiagramDocument::AddTable); } void MainWindow::switchModeAddRelation() { m_model->setMode(DiagramDocument::AddRelation); } void MainWindow::openRecentFile() { QAction *action = qobject_cast(sender()); if (action) { if (maybeSave()) { loadFile(action->data().toString()); } } } void MainWindow::addRecentFile(const QString &fileName) { QSettings settings; QStringList files = settings.value("recentFileList").toStringList(); QString absFileName = QFileInfo(fileName).canonicalFilePath(); files.removeAll(absFileName); files.prepend(absFileName); while (files.size() > MaxRecentFiles) files.removeLast(); settings.setValue("recentFileList", files); foreach (QWidget *widget, QApplication::topLevelWidgets()) { MainWindow *mainWin = qobject_cast(widget); if (mainWin) mainWin->updateRecentFileActions(); } } QList MainWindow::mainWindows() { QList result; QWidgetList widgets = QApplication::topLevelWidgets(); int listSize = widgets.size(); for (int i = 0; i < listSize; i++) { MainWindow *mainWin = qobject_cast(widgets.at(i)); if (mainWin) { result.append(mainWin); } } return result; } void MainWindow::closeDocument() { if (mainWindows().size() > 1) { // There are still some windows open, close this one close(); } else { // This is the last window, close the document, but keep the window open newModel(); } } void MainWindow::closeAll() { foreach (MainWindow *window, mainWindows()) { window->close(); } } 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(QFileInfo(files[i]).fileName()); m_actionRecentFile[i]->setText(text); m_actionRecentFile[i]->setData(files[i]); m_actionRecentFile[i]->setVisible(true); } for (int j = numRecentFiles; j < MaxRecentFiles; ++j) m_actionRecentFile[j]->setVisible(false); m_actionRecentFilesSeparator->setVisible(numRecentFiles > 0); } void MainWindow::cut() { QList items = m_model->selectedItems(); if (!items.isEmpty()) { QApplication::clipboard()->setMimeData(items[0]->toMimeData()); // FIXME m_model->deleteSelectedItems(); } } void MainWindow::copy() { QList items = m_model->selectedItems(); if (!items.isEmpty()) { QApplication::clipboard()->setMimeData(items[0]->toMimeData()); // FIXME } } void MainWindow::paste() { const QMimeData *mimeData = QApplication::clipboard()->mimeData(QClipboard::Clipboard); if (mimeData) { DiagramObject *item = dynamic_cast(DiagramItem::fromMimeData(mimeData)); if (item) { m_model->undoStack()->push(new AddObjectCommand(m_model, item)); } } } void MainWindow::updateClipboard(QClipboard::Mode mode) { if (mode != QClipboard::Clipboard) return; const QMimeData *mimeData = QApplication::clipboard()->mimeData(QClipboard::Clipboard); if (mimeData && mimeData->formats().contains("application/dbmodel.item")) m_actionPaste->setEnabled(true); else m_actionPaste->setEnabled(false); } void MainWindow::about() { QMessageBox::about(this, tr("About"), trUtf8( "

\n" "Database Modeller " VERSION "
\n" "http://oxygene.sk/lukas/dbmodel/
\n" "Copyright (C) 2008-2009 Lukas Lalinsky\n" "

\n" )); } void MainWindow::updateWindowTitle() { if (m_model) { QString fileName = m_model->fileName(); if (fileName.isEmpty()) fileName = tr("Untitled"); else fileName = QFileInfo(fileName).fileName(); if (!m_model->undoStack()->isClean()) fileName += "*"; setWindowTitle(fileName + " - " + qApp->applicationName()); } else { setWindowTitle(qApp->applicationName()); } } void MainWindow::setDiagramNotation(QAction *action) { m_model->undoStack()->push( new SetObjectPropertyCommand(m_model, "notation", action->data())); }