moved to shstk
This commit is contained in:
439
libs/application/emainwindow.cpp
Normal file
439
libs/application/emainwindow.cpp
Normal file
@@ -0,0 +1,439 @@
|
||||
#include "emainwindow.h"
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QMenu>
|
||||
#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) {
|
||||
tid = 0;
|
||||
menu_recent = 0;
|
||||
action_clear_recent = new QAction(QIcon(":/icons/edit-clear.png"), tr("Clear recent list"), this);
|
||||
connect(action_clear_recent, SIGNAL(triggered()), this, SLOT(clearRecent()));
|
||||
qRegisterMetaType<Qt::DockWidgetArea>("Qt::DockWidgetArea");
|
||||
action_show_all_tools.setText(tr("Show all"));
|
||||
action_show_all_docks.setText(tr("Show all"));
|
||||
action_hide_all_tools.setText(tr("Hide all"));
|
||||
action_hide_all_docks.setText(tr("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"));
|
||||
max_recent = 8;
|
||||
setChanged(false);
|
||||
initMenus();
|
||||
initSession();
|
||||
tid = startTimer(200); // bad timer, too much overload
|
||||
}
|
||||
|
||||
|
||||
EMainWindow::~EMainWindow() {
|
||||
if (tid > 0) killTimer(tid);
|
||||
tid = 0;
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::setRecentFiles(const QStringList & rl) {
|
||||
clearRecent();
|
||||
for (int i = rl.size() - 1; i >= 0; --i)
|
||||
addToRecent(rl[i]);
|
||||
}
|
||||
|
||||
|
||||
QStringList EMainWindow::recentFiles() const {
|
||||
QStringList ret;
|
||||
foreach (QAction * a, actions_recent)
|
||||
ret << a->data().toString();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::setRecentMenu(QMenu * m) {
|
||||
menu_recent = m;
|
||||
prepareRecent();
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
else saveSession();
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::changeEvent(QEvent * e) {
|
||||
QMainWindow::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
action_show_all_tools.setText(tr("Show all"));
|
||||
action_show_all_docks.setText(tr("Show all"));
|
||||
action_hide_all_tools.setText(tr("Hide all"));
|
||||
action_hide_all_docks.setText(tr("Hide all"));
|
||||
action_clear_recent->setText(tr("Clear recent list"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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(tr("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(tr("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::addToRecent(const QString & path) {
|
||||
if (path.isEmpty()) return;
|
||||
QFileInfo fi(path);
|
||||
QString fp = fi.absoluteFilePath();
|
||||
bool insert = true;
|
||||
for (int i = 0; i < actions_recent.size(); ++i)
|
||||
if (actions_recent[i]->data().toString() == fp) {
|
||||
actions_recent.push_front(actions_recent.takeAt(i));
|
||||
insert = false;
|
||||
prepareRecent();
|
||||
break;
|
||||
}
|
||||
if (!insert) return;
|
||||
QAction * a = new QAction(this);
|
||||
a->setData(fp);
|
||||
connect(a, SIGNAL(triggered()), this, SLOT(recentTriggered()));
|
||||
actions_recent.push_front(a);
|
||||
while (actions_recent.size() > max_recent)
|
||||
delete actions_recent.takeLast();
|
||||
prepareRecent();
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::prepareRecent() {
|
||||
for (int i = 0; i < actions_recent.size(); ++i) {
|
||||
QAction * a = actions_recent[i];
|
||||
a->setText(QString("&%1 - %2").arg(i + 1).arg(a->data().toString()));
|
||||
}
|
||||
if (!menu_recent) return;
|
||||
menu_recent->clear();
|
||||
menu_recent->addActions(actions_recent);
|
||||
menu_recent->addSeparator();
|
||||
menu_recent->addAction(action_clear_recent);
|
||||
}
|
||||
|
||||
|
||||
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 & )));
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
#ifndef Q_OS_MACOS
|
||||
t->setIconSize(dockTabsIconSize());
|
||||
#endif
|
||||
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 (!docks.contains(dock)) continue;
|
||||
#ifndef Q_OS_MACOS
|
||||
t->setIconSize(dockTabsIconSize());
|
||||
#endif
|
||||
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::recentTriggered() {
|
||||
QAction * a = qobject_cast<QAction * >(sender());
|
||||
if (!a) return;
|
||||
QString path = a->data().toString();
|
||||
if (path.isEmpty()) return;
|
||||
if (!checkSave()) return;
|
||||
if (load(path))
|
||||
addToRecent(path);
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::setMaxRecentItems(int mr) {
|
||||
max_recent = qMax(0, mr);
|
||||
for (int i = actions_recent.size() - 1; i >= mr; --i)
|
||||
delete actions_recent.takeLast();
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::newFile() {
|
||||
if (!checkSave()) return;
|
||||
reset(true);
|
||||
setWindowModified(false);
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::openFile() {
|
||||
if (!checkSave()) return;
|
||||
QString ret = QFileDialog::getOpenFileName(this, tr("Select file to open"), file_name, loadFilter());
|
||||
if (ret.isEmpty()) return;
|
||||
if (load(ret))
|
||||
addToRecent(ret);
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::openFiles() {
|
||||
if (!checkSave()) return;
|
||||
QStringList ret = QFileDialog::getOpenFileNames(this, tr("Select files to open"), file_name, loadFilter());
|
||||
foreach (QString s, ret) {
|
||||
if (load(s))
|
||||
addToRecent(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool EMainWindow::saveFile(bool ask) {
|
||||
if (ask) {
|
||||
int ret = QMessageBox::question(this, windowTitle(), tr("Save changes%1?").arg(!file_name.isEmpty() ? (tr(" 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();
|
||||
if (save(file_name))
|
||||
addToRecent(file_name);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool EMainWindow::saveAsFile() {
|
||||
QString ret = QFileDialog::getSaveFileName(this, tr("Select file to save"), file_name, saveFilter());
|
||||
if (ret.isEmpty()) return false;
|
||||
if (save(ret))
|
||||
addToRecent(ret);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::clearRecent() {
|
||||
qDeleteAll(actions_recent);
|
||||
actions_recent.clear();
|
||||
prepareRecent();
|
||||
}
|
||||
Reference in New Issue
Block a user