/* Peri4 Paint Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com 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 3 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, see . */ #include "emainwindow.h" #include #include #include EMainWindow::EMainWindow(QWidget * parent): QMainWindow(parent), action_show_all_tools(this), action_hide_all_tools(this), action_show_all_docks(this), action_hide_all_docks(this), first_show(true) { qRegisterMetaType("Qt::DockWidgetArea"); action_show_all_tools.setText(trUtf8("Show all")); action_show_all_docks.setText(trUtf8("Show all")); action_hide_all_tools.setText(trUtf8("Hide all")); action_hide_all_docks.setText(trUtf8("Hide all")); action_show_all_tools.setIcon(QIcon(":/icons/layer-visible-on.png")); action_show_all_docks.setIcon(QIcon(":/icons/layer-visible-on.png")); action_hide_all_tools.setIcon(QIcon(":/icons/layer-visible-off.png")); action_hide_all_docks.setIcon(QIcon(":/icons/layer-visible-off.png")); setChanged(false); initMenus(); tid = startTimer(200); } EMainWindow::~EMainWindow() { saveSession(); } void EMainWindow::showEvent(QShowEvent * e) { QWidget::showEvent(e); initMenus(); if (!first_show) return; first_show = false; QList docks(findChildren()); foreach (QDockWidget * d, docks) { connect(d, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(changedDock())); connect(d, SIGNAL(topLevelChanged(bool)), this, SLOT(changedDock())); } changedDock(); } void EMainWindow::closeEvent(QCloseEvent * e) { if (!checkSave()) e->ignore(); } bool EMainWindow::eventFilter(QObject * o, QEvent * e) { //qDebug() << o << e; if (tbars.contains((QTabBar*)o) && e->type() == QEvent::MouseButtonDblClick) { int tab = ((QTabBar*)o)->tabAt(((QMouseEvent * )e)->pos()); if (tab >= 0) { QDockWidget * dock = (QDockWidget * )(((QTabBar*)o)->tabData(tab).toULongLong()); if (dock != 0) { dock->setFloating(true); } } } if (e->type() == QEvent::Show || e->type() == QEvent::Hide || e->type() == QEvent::ChildAdded || e->type() == QEvent::ChildRemoved || e->type() == QEvent::MouseButtonPress) { if (tbars.contains((QTabBar*)o) || tdocks.contains((QDockWidget*)o)) { if (e->type() == QEvent::MouseButtonPress) { if (((QMouseEvent*)e)->button() == Qt::RightButton) { bool popup = tbars.contains((QTabBar*)o); if (tdocks.contains((QDockWidget*)o)) popup = popup || ((QDockWidget*)o)->titleBarWidget()->geometry().contains(((QMouseEvent*)e)->pos()); if (popup) { createPopupMenu()->popup(((QMouseEvent*)e)->globalPos()); return true; } } } if (e->type() == QEvent::Show || e->type() == QEvent::Hide /*|| e->type() == QEvent::ChildAdded || e->type() == QEvent::ChildRemoved*/) { //qDebug() << "filter"; //QMetaObject::invokeMethod(this, "changedDock", Qt::QueuedConnection); changedDock(); } } } return QMainWindow::eventFilter(o, e); } void EMainWindow::timerEvent(QTimerEvent * e) { if (e->timerId() == tid) { changedDock(); return; } QMainWindow::timerEvent(e); } QMenu * EMainWindow::createPopupMenu() { QMenu * menuPopup = new QMenu; QWidgetAction * wa; QLabel * lbl; QAction * a; QFont f; f.setBold(true); // Toolbars QList tools = findChildren(); if (!tools.isEmpty()) { wa = new QWidgetAction(menuPopup); lbl = new QLabel(); lbl->setFrameShape(QFrame::StyledPanel); lbl->setFrameShadow(QFrame::Sunken); lbl->setText(trUtf8("Toolbars")); lbl->setFont(f); lbl->setAlignment(Qt::AlignCenter); wa->setDefaultWidget(lbl); menuPopup->addAction(wa); foreach (QToolBar * i, tools) { if (i->property("ribbon").toBool()) continue; a = new QAction(i->windowTitle(), menuPopup); a->setCheckable(true); a->setChecked(!i->isHidden()); a->setIcon(i->windowIcon()); connect(a, SIGNAL(toggled(bool)), i, SLOT(setVisible(bool))); menuPopup->addAction(a); }; menuPopup->addSeparator(); menuPopup->addAction(&action_show_all_tools); menuPopup->addAction(&action_hide_all_tools); } // Docks QList docks = findChildren(); if (!docks.isEmpty()) { wa = new QWidgetAction(menuPopup); lbl = new QLabel(); lbl->setFrameShape(QFrame::StyledPanel); lbl->setFrameShadow(QFrame::Sunken); lbl->setText(trUtf8("Docks")); lbl->setFont(f); lbl->setAlignment(Qt::AlignCenter); wa->setDefaultWidget(lbl); menuPopup->addAction(wa); foreach (QDockWidget * i, docks) { if (i->property("ribbon").toBool()) continue; a = new QAction(i->windowTitle(), menuPopup); a->setCheckable(true); a->setChecked(!i->isHidden()); a->setIcon(i->windowIcon()); connect(a, SIGNAL(toggled(bool)), i, SLOT(setVisible(bool))); menuPopup->addAction(a); }; menuPopup->addSeparator(); menuPopup->addAction(&action_show_all_docks); menuPopup->addAction(&action_hide_all_docks); } return menuPopup; } void EMainWindow::initMenus() { action_show_all_tools.disconnect(); action_hide_all_tools.disconnect(); action_show_all_docks.disconnect(); action_hide_all_docks.disconnect(); QList tools = findChildren(); foreach (QToolBar * i, tools) { if (i->property("ribbon").toBool()) continue; i->toggleViewAction()->setIcon(i->windowIcon()); connect(&action_show_all_tools, SIGNAL(triggered(bool)), i, SLOT(show())); connect(&action_hide_all_tools, SIGNAL(triggered(bool)), i, SLOT(hide())); } QList docks = findChildren(); foreach (QDockWidget * i, docks) { if (i->property("ribbon").toBool()) continue; i->toggleViewAction()->setIcon(i->windowIcon()); connect(&action_show_all_docks, SIGNAL(triggered(bool)), i, SLOT(show())); connect(&action_hide_all_docks, SIGNAL(triggered(bool)), i, SLOT(hide())); } QList actions = findChildren(); foreach (QAction * i, actions) i->setIconVisibleInMenu(true); addActions(actions); } void EMainWindow::initSession() { connect(&session, SIGNAL(loading(QPIConfig & )), this, SLOT(sessionLoading(QPIConfig & ))); connect(&session, SIGNAL(saving(QPIConfig & )), this, SLOT(sessionSaving(QPIConfig & ))); session.addEntry("EMainWindow", this); } void EMainWindow::saveSession() { session.save(); } void EMainWindow::loadSession() { session.load(); } bool EMainWindow::checkSave() { if (!isWindowModified()) return true; return saveFile(true); } void EMainWindow::changedDock() { QList tabs(findChildren()); QList docks = findChildren(); QSet docks_tabs; QDockWidget * dock; //qDebug() << "change"; foreach (QTabBar * t, tabs) { if (!t->objectName().isEmpty() || t->isHidden()) continue; if (!tbars.contains(t)) { tbars << t; connect(t, SIGNAL(tabCloseRequested(int)), this, SLOT(closeDock(int))); t->installEventFilter(this); t->setIconSize(dockTabsIconSIze()); t->setTabsClosable(true); } //qDebug() << "tab"; for (int i = 0; i < t->count(); ++i) { dock = (QDockWidget * )t->tabData(i).toULongLong(); //qDebug() << i << dock; if (dock == 0) continue; t->setTabIcon(i, dock->windowIcon()); docks_tabs << dock; } } foreach (QDockWidget * d, docks) { if (d->titleBarWidget() == 0) continue; QWidget * ctb = d->titleBarWidget(); if (!d->property("__titleWidget").isValid()) { d->setProperty("__titleWidget", qulonglong(ctb)); QWidget * ntb = new QWidget(); int m = style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin); ntb->setLayout(new QBoxLayout(QBoxLayout::BottomToTop)); ntb->layout()->setContentsMargins(m, m, 0, 0); d->setProperty("__titleEmptyWidget", qulonglong(ntb)); } if (!tdocks.contains(d)) { tdocks << d; //connect(t, SIGNAL((QObject*)), this, SLOT(changedDockClose(QObject*))); d->installEventFilter(this); } //d->titleBarWidget()->setHidden(docks_tabs.contains(d)); if (tabifiedDockWidgets(d).isEmpty()) { if (d->titleBarWidget() != (QWidget * )(d->property("__titleWidget").toULongLong())) d->setTitleBarWidget((QWidget * )(d->property("__titleWidget").toULongLong())); } else { if (d->titleBarWidget() != (QWidget * )(d->property("__titleEmptyWidget").toULongLong())) { d->setTitleBarWidget((QWidget * )(d->property("__titleEmptyWidget").toULongLong())); d->layout()->setContentsMargins(0, 20, 0, 0); } } } } void EMainWindow::changedDockClose(QObject * bar) { //qDebug() << "close" << bar; tbars.removeAll((QTabBar * )bar); changedDock(); } void EMainWindow::closeDock(int index) { QDockWidget * dock = (QDockWidget * )((QTabBar*)sender())->tabData(index).toULongLong(); if (dock == 0) return; dock->close(); } void EMainWindow::newFile() { if (!checkSave()) return; reset(true); setWindowModified(false); } void EMainWindow::openFile() { if (!checkSave()) return; QString ret = QFileDialog::getOpenFileName(this, trUtf8("Select file to open"), file_name, loadFilter()); if (ret.isEmpty()) return; load(ret); } bool EMainWindow::saveFile(bool ask) { if (ask) { int ret = QMessageBox::question(this, windowTitle(), trUtf8("Save changes%1?").arg(!file_name.isEmpty() ? (trUtf8("in") + " \"" + file_name + "\"") : ""), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save); if (ret == QMessageBox::Cancel) return false; if (ret == QMessageBox::Save) return saveFile(); return true; } if (file_name.isEmpty()) return saveAsFile(); save(file_name); return true; } bool EMainWindow::saveAsFile() { QString ret = QFileDialog::getSaveFileName(this, trUtf8("Select file to save"), file_name, saveFilter()); if (ret.isEmpty()) return false; save(ret); return true; }