Files
qad/qad_application/emainwindow.cpp

334 lines
10 KiB
C++

/*
Peri4 Paint
Copyright (C) 2017 Ivan Pelipenko peri4ko@yandex.ru
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 <http://www.gnu.org/licenses/>.
*/
#include "emainwindow.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QLabel>
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>("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<QDockWidget * > docks(findChildren<QDockWidget * >());
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<QToolBar * > tools = findChildren<QToolBar * >();
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<QDockWidget * > docks = findChildren<QDockWidget * >();
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<QToolBar * > tools = findChildren<QToolBar * >();
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<QDockWidget * > docks = findChildren<QDockWidget * >();
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<QAction * > actions = findChildren<QAction * >();
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() {
if (isHidden()) return;
QList<QTabBar * > tabs(findChildren<QTabBar * >());
QList<QDockWidget * > docks = findChildren<QDockWidget * >();
QSet<QDockWidget * > 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" << t << t->count();
for (int i = 0; i < t->count(); ++i) {
dock = (QDockWidget * )t->tabData(i).toULongLong();
//qDebug() << i << t->tabData(i);
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;
// qDebug() << "connect" << d;
// connect(d, SIGNAL(destroyed(QObject*)), this, SLOT(changedDockClose(QObject*)), Qt::UniqueConnection);
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 * dock) {
// qDebug() << "changedDockClose" << dock;
// if (!dock) return;
// foreach (QTabBar * t, tbars) {
// for (int i = 0; i < t->count(); ++i)
// if (t->tabData(i).toULongLong() == (qulonglong)dock) {
// t->removeTab(i);
// break;
// }
// }
//}
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;
}