icon change EDockWidget improvements EMainWindow small refactoring Graphic now remember last loaded graphics style and restore it on setGraphicsCount
430 lines
12 KiB
C++
430 lines
12 KiB
C++
#include "emainwindow.h"
|
|
|
|
#include <QFileDialog>
|
|
#include <QLabel>
|
|
#include <QMenu>
|
|
#include <QMessageBox>
|
|
#include <edockwidget.h>
|
|
|
|
|
|
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) {
|
|
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();
|
|
}
|
|
|
|
|
|
EMainWindow::~EMainWindow() {}
|
|
|
|
|
|
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();
|
|
initDocks();
|
|
}
|
|
|
|
|
|
void EMainWindow::closeEvent(QCloseEvent * e) {
|
|
if (!checkSave())
|
|
e->ignore();
|
|
else
|
|
saveSession();
|
|
}
|
|
|
|
|
|
bool EMainWindow::eventFilter(QObject * o, QEvent * 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) {
|
|
dock->setFloating(true);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
/*if (e->type() == QEvent::Show || e->type() == QEvent::Hide) {
|
|
if (tdocks.contains((QDockWidget*)o)) {
|
|
changedDock();
|
|
}
|
|
}*/
|
|
if (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(
|
|
#if QT_VERSION_MAJOR <= 5
|
|
((QMouseEvent *)e)->globalPos()
|
|
#else
|
|
((QMouseEvent *)e)->globalPosition().toPoint()
|
|
#endif
|
|
);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return QMainWindow::eventFilter(o, 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);
|
|
for (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);
|
|
for (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 *>();
|
|
for (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 *>();
|
|
for (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 *>();
|
|
for (QAction * i: actions)
|
|
i->setIconVisibleInMenu(true);
|
|
addActions(actions);
|
|
}
|
|
|
|
|
|
void EMainWindow::initDocks() {
|
|
QList<QDockWidget *> docks(findChildren<QDockWidget *>());
|
|
for (QDockWidget * d: docks) {
|
|
static const char * pname = "__edock_inited__";
|
|
if (d->property(pname).toBool()) continue;
|
|
d->setProperty(pname, true);
|
|
connect(d, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(changedDock()));
|
|
connect(d, SIGNAL(topLevelChanged(bool)), this, SLOT(changedDock()));
|
|
connect(d, SIGNAL(visibilityChanged(bool)), this, SLOT(changedDock()));
|
|
}
|
|
changedDock();
|
|
}
|
|
|
|
|
|
void EMainWindow::initSession() {
|
|
connect(&session, &SessionManager::loading, this, [this](QPIConfig & conf) { loadingSession(conf); });
|
|
connect(&session, &SessionManager::saving, this, [this](QPIConfig & conf) { savingSession(conf); });
|
|
}
|
|
|
|
|
|
void EMainWindow::saveSession() {
|
|
session.save();
|
|
}
|
|
|
|
|
|
void EMainWindow::loadSession() {
|
|
session.load();
|
|
}
|
|
|
|
|
|
bool EMainWindow::checkSave() {
|
|
if (!isWindowModified()) return true;
|
|
return saveFile(true);
|
|
}
|
|
|
|
|
|
void EMainWindow::setChanged(bool yes) {
|
|
is_changed = yes;
|
|
setWindowModified(yes);
|
|
}
|
|
|
|
|
|
void EMainWindow::changedDock() {
|
|
if (isHidden()) return;
|
|
QSet<QDockWidget *> invalid_tab_docks;
|
|
QList<QTabBar *> tabs(findChildren<QTabBar *>());
|
|
QList<QDockWidget *> docks = findChildren<QDockWidget *>();
|
|
QRect geom = rect();
|
|
// qDebug() << "### change" << docks.size() << tabs.size();
|
|
for (QTabBar * t: tabs) {
|
|
if (!t->objectName().isEmpty() || t->isHidden()) continue;
|
|
if (!tbars.contains(t)) {
|
|
// qDebug() << "add tab" << t;
|
|
tbars << t;
|
|
connect(t, SIGNAL(tabCloseRequested(int)), this, SLOT(closeDock(int)));
|
|
connect(t, &QObject::destroyed, this, [this, t]() { tbars.removeOne(t); });
|
|
t->installEventFilter(this);
|
|
#ifndef Q_OS_MACOS
|
|
t->setIconSize(dockTabsIconSize());
|
|
#endif
|
|
t->setTabsClosable(true);
|
|
}
|
|
for (int i = 0; i < t->count(); ++i) {
|
|
QDockWidget * dock = (QDockWidget *)t->tabData(i).toULongLong();
|
|
// qDebug() << i << t->tabText(i) << t->isTabVisible(i) << dock;
|
|
if (!dock) continue;
|
|
if (!docks.contains(dock)) continue;
|
|
if (!geom.intersects(t->geometry())) invalid_tab_docks << dock;
|
|
#ifndef Q_OS_MACOS
|
|
QSize is = dockTabsIconSize();
|
|
if (t->iconSize() != is) t->setIconSize(is);
|
|
#endif
|
|
t->setTabIcon(i, dock->windowIcon());
|
|
}
|
|
}
|
|
|
|
for (QDockWidget * d: docks) {
|
|
if (!d->titleBarWidget()) continue;
|
|
if (!tdocks.contains(d)) {
|
|
// qDebug() << "add dock" << d;
|
|
tdocks << d;
|
|
connect(d, &QObject::destroyed, this, [this, d]() { tdocks.removeOne(d); });
|
|
d->installEventFilter(this);
|
|
}
|
|
auto * ed = qobject_cast<EDockWidget *>(d);
|
|
if (ed) {
|
|
// qDebug() << d->windowTitle() << tabifiedDockWidgets(d);
|
|
if (tabifiedDockWidgets(d).isEmpty() || invalid_tab_docks.contains(d))
|
|
ed->setStandardHeader();
|
|
else
|
|
ed->setEmptyHeader();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
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(file_name);
|
|
return true;
|
|
}
|
|
|
|
|
|
void EMainWindow::clearRecent() {
|
|
qDeleteAll(actions_recent);
|
|
actions_recent.clear();
|
|
prepareRecent();
|
|
}
|