Continues migration with DDS, Common
This commit is contained in:
1 parent
9b15cee841
commit
fa48db111e
668 files changed
+111841
-2
No files matched your search
Executable
+894
@@ -0,0 +1,894 @@
|
||||
|
||||
|
||||
|
||||
#include "lts_tab_widget.h"
|
||||
#include "lts_tab_bar.h"
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsWidgets/lts_dialog_helper.h>
|
||||
#include <LtsWidgets/lts_splitter.h>
|
||||
#include <QAbstractButton>
|
||||
#include <QDialog>
|
||||
#include <QDebug>
|
||||
#include <QSize>
|
||||
#include <QPaintEvent>
|
||||
#include <QPainter>
|
||||
#include <QBrush>
|
||||
#include <QApplication>
|
||||
#include <QColor>
|
||||
#include <QPen>
|
||||
#include <QFontMetrics>
|
||||
#include <QRectF>
|
||||
#include <QLineF>
|
||||
#include <QPointF>
|
||||
#include <math.h>
|
||||
#include <QTimer>
|
||||
#include <QLabel>
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
LtsTabWidget::LtsTabWidget(QWidget *parent, bool isSecondary)
|
||||
: QTabWidget(parent)
|
||||
, m_tabbar(nullptr)
|
||||
, m_hasSubTabs(false)
|
||||
, m_isSecondary(isSecondary)
|
||||
, m_mainSplitterState(QByteArray())
|
||||
{
|
||||
setDocumentMode(true);
|
||||
setMinimumSize(200, 100);
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
|
||||
|
||||
LtsTabBar *tabBar = new LtsTabBar(isSecondary, this);
|
||||
setTabBar(tabBar);
|
||||
|
||||
QFont currentFont = tabBar->font();
|
||||
|
||||
QFont::Capitalization c = QFont::SmallCaps;
|
||||
bool bold = true;
|
||||
|
||||
if (m_isSecondary)
|
||||
{
|
||||
c = QFont::MixedCase;
|
||||
bold = false;
|
||||
}
|
||||
|
||||
|
||||
currentFont.setCapitalization(c);
|
||||
currentFont.setBold(bold);
|
||||
|
||||
tabBar->setFont(currentFont);
|
||||
|
||||
connect(this, &LtsTabWidget::currentChanged,
|
||||
this, &LtsTabWidget::slotCurrentChanged);
|
||||
|
||||
|
||||
QSplitter *splitter = static_cast<QSplitter*>(parent);
|
||||
if (splitter &&
|
||||
splitter->objectName() == QStringLiteral("mainSplitter") &&
|
||||
splitter->widget(1) == this &&
|
||||
!isSecondary)
|
||||
{
|
||||
int tabBarHeight = m_tabbar->height() * 1.33;
|
||||
int tabBarWidth = 20;
|
||||
|
||||
setStyleSheet(styleSheet() + QStringLiteral("QTabWidget::tab-bar {"
|
||||
"left: %1px; "
|
||||
"} ").arg(tabBarWidth));
|
||||
QPushButton *maxBtn = new QPushButton(this);
|
||||
maxBtn->setObjectName(QStringLiteral("MinMaxTabButton"));
|
||||
maxBtn->setText(QStringLiteral("▲\n▼"));
|
||||
maxBtn->setFixedSize(tabBarWidth, tabBarHeight * 2);
|
||||
maxBtn->setStyleSheet(QStringLiteral("QPushButton { "
|
||||
"border-radius: 0px; "
|
||||
"border: 1px solid gray; "
|
||||
"} "));
|
||||
connect(maxBtn, &QPushButton::clicked, this, &LtsTabWidget::slotMaximizeButtonClicked);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LtsTabWidget::~LtsTabWidget()
|
||||
{
|
||||
|
||||
|
||||
clearAll();
|
||||
}
|
||||
|
||||
|
||||
void LtsTabWidget::slotCurrentChanged(int newIdx)
|
||||
{
|
||||
if (newIdx < 0)
|
||||
return;
|
||||
|
||||
QWidget *w = widget(newIdx);
|
||||
|
||||
if (w == nullptr)
|
||||
return;
|
||||
|
||||
LtsDialogHelper *dialog1 = qobject_cast<LtsDialogHelper *>(w);
|
||||
|
||||
if (dialog1 != nullptr)
|
||||
{
|
||||
LtsDialog *mainDialog = dialog1->getDialog();
|
||||
|
||||
if (mainDialog != nullptr)
|
||||
emit mainDialog->signalFocused();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
LtsTabWidget *tab = qobject_cast<LtsTabWidget *>(w);
|
||||
|
||||
if (tab != nullptr)
|
||||
{
|
||||
LtsDialogHelper *dialog2 = qobject_cast<LtsDialogHelper *>(tab->widget(tab->currentIndex()));
|
||||
|
||||
if (dialog2 != nullptr)
|
||||
{
|
||||
LtsDialog *mainDialog = dialog2->getDialog();
|
||||
|
||||
if (mainDialog != nullptr)
|
||||
emit mainDialog->signalFocused();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LtsTabWidget::slotMaximizeButtonClicked()
|
||||
{
|
||||
LtsSplitter *splitter = static_cast<LtsSplitter*>(parent());
|
||||
if (splitter)
|
||||
{
|
||||
if (splitter->widget(0)->height() != splitter->widget(0)->minimumHeight())
|
||||
{
|
||||
m_mainSplitterState = splitter->saveState();
|
||||
splitter->collapseChild(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
splitter->restoreState(m_mainSplitterState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LtsTabWidget::closeRequestTabWidget(LtsTabWidget *tabWidget)
|
||||
{
|
||||
for (int i = 0; i < tabWidget->count(); i++)
|
||||
{
|
||||
QWidget *w = tabWidget->widget(i);
|
||||
|
||||
LtsDialogHelper *helper = qobject_cast<LtsDialogHelper *>(w);
|
||||
|
||||
if (helper)
|
||||
{
|
||||
LtsDialog *dlg = qobject_cast<LtsDialog *>(helper->getDialog());
|
||||
|
||||
if (dlg)
|
||||
dlg->closeRequest();
|
||||
}
|
||||
|
||||
LtsTabWidget *tab = qobject_cast<LtsTabWidget *>(w);
|
||||
if (tab)
|
||||
closeRequestTabWidget(tab);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LtsTabWidget::slotTabCloseRequested(int index)
|
||||
{
|
||||
QWidget *w = widget(index);
|
||||
|
||||
if (w == nullptr)
|
||||
return;
|
||||
|
||||
LtsDialogHelper *helper = qobject_cast<LtsDialogHelper *>(w);
|
||||
|
||||
if (helper != nullptr)
|
||||
{
|
||||
LtsDialog *dialog = helper->getDialog();
|
||||
|
||||
if (dialog != nullptr)
|
||||
{
|
||||
if (dialog->isClosable())
|
||||
{
|
||||
setCurrentIndex(index);
|
||||
dialog->closeRequest();
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LtsTabWidget *tab = qobject_cast<LtsTabWidget *>(w);
|
||||
|
||||
if (tab != nullptr)
|
||||
{
|
||||
if (LtsTabWidget::hasUnsavedChanges(tab))
|
||||
{
|
||||
LtsWidgets::Buttons buttons;
|
||||
buttons.setFlag(Button::Yes, true);
|
||||
buttons.setFlag(Button::Cancel, true);
|
||||
QHash<Button, QString> buttonTexts;
|
||||
buttonTexts.insert(Button::Yes, tr("Discard All"));
|
||||
const auto ret = LtsMessageDialog::showMessage(this, tr("There are dialogs with unsaved changes.<br>Please save or discard their changes before closing."), tr("Unsaved changes"), Behaviour::Modal, buttons, buttonTexts);
|
||||
switch (ret)
|
||||
{
|
||||
case Button::Yes:
|
||||
tab->deleteLater();
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
closeRequestTabWidget(tab);
|
||||
}
|
||||
}
|
||||
w->deleteLater();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LtsTabWidget::onCheckTabBarVisibility()
|
||||
{
|
||||
|
||||
|
||||
if (!m_isSecondary)
|
||||
{
|
||||
|
||||
if (count() < 1)
|
||||
setHidden(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (count() < 1)
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LtsTabWidget::setSubTabsVisible(bool visible)
|
||||
{
|
||||
if (count())
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_hasSubTabs = visible;
|
||||
}
|
||||
|
||||
|
||||
void LtsTabWidget::addTab(const QString &menuGroup, const QString &identifier, QWidget *widget,
|
||||
bool setClosable, bool focusNewTab)
|
||||
{
|
||||
|
||||
setFocus();
|
||||
LtsTabWidget *tab = this;
|
||||
QString fullName;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (m_hasSubTabs)
|
||||
{
|
||||
fullName = identifier;
|
||||
tab = qobject_cast<LtsTabWidget *>(m_tabMap.value(menuGroup, nullptr));
|
||||
|
||||
if (!tab)
|
||||
{
|
||||
|
||||
tab = new LtsTabWidget(nullptr, true);
|
||||
tab->setMovable(true);
|
||||
addWidget(menuGroup, tab, true , focusNewTab);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
tab->setHidden(false);
|
||||
}
|
||||
|
||||
if (focusNewTab)
|
||||
setCurrentIndex(indexOf(tab));
|
||||
}
|
||||
else
|
||||
{
|
||||
fullName = menuGroup + QLatin1Char('.') + identifier;
|
||||
|
||||
}
|
||||
|
||||
setHidden(false);
|
||||
|
||||
tab->addWidget(fullName, widget, setClosable, focusNewTab);
|
||||
|
||||
|
||||
|
||||
if (m_hasSubTabs)
|
||||
{
|
||||
LtsTabBar *tabbar = tab->tabBar();
|
||||
|
||||
for (int i = 0; i < tabbar->count(); i++)
|
||||
{
|
||||
|
||||
if (tabbar->tabButton(i, QTabBar::RightSide)->isHidden())
|
||||
{
|
||||
m_tabbar->tabButton(currentIndex(), QTabBar::RightSide)->hide();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LtsTabWidget::addWidget(const QString &fullName, QWidget *widget, bool setClosable, bool focusNewTab)
|
||||
{
|
||||
QString theName = fullName;
|
||||
|
||||
if (fullName.isEmpty())
|
||||
{
|
||||
|
||||
const QString possibleCharacters(QStringLiteral("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"));
|
||||
const int randomStringLength = 24;
|
||||
|
||||
QString randomString;
|
||||
for (int i = 0; i < randomStringLength; i++)
|
||||
{
|
||||
int index = qrand() % possibleCharacters.length();
|
||||
QChar nextChar = possibleCharacters.at(index);
|
||||
randomString.append(nextChar);
|
||||
}
|
||||
|
||||
theName = randomString;
|
||||
}
|
||||
|
||||
widget->setObjectName(theName);
|
||||
|
||||
LtsDialogHelper *helper = qobject_cast<LtsDialogHelper *>(widget);
|
||||
if (helper)
|
||||
helper->retranslate();
|
||||
|
||||
QString title = widget->windowTitle();
|
||||
|
||||
if (title.isEmpty())
|
||||
{
|
||||
if (helper)
|
||||
title = QStringLiteral("retranslate() fehlt!");
|
||||
else
|
||||
title = widget->objectName();
|
||||
}
|
||||
|
||||
if (helper)
|
||||
{
|
||||
connect(helper->getDialog(), &LtsDialog::signalHide, this, static_cast<void (LtsTabWidget::*)(QObject*)>(&LtsTabWidget::onRemoveTab),
|
||||
static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection));
|
||||
|
||||
}
|
||||
|
||||
connect(widget, &QWidget::destroyed, this, static_cast<void (LtsTabWidget::*)(QObject*)>(&LtsTabWidget::onRemoveTab), Qt::DirectConnection);
|
||||
connect(widget, &QWidget::windowTitleChanged, this, &LtsTabWidget::slotWindowTitleChanged);
|
||||
|
||||
if (helper)
|
||||
{
|
||||
m_tabMap.insert(theName, helper);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tabMap.insert(theName, widget);
|
||||
|
||||
}
|
||||
|
||||
int newTabIndex = QTabWidget::addTab(widget, title);
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
setTabToolTip(newTabIndex, tr("DEBUG: WindowName: %1").arg(theName));
|
||||
#endif
|
||||
|
||||
if (focusNewTab)
|
||||
setCurrentIndex(newTabIndex);
|
||||
|
||||
LtsTabBar *tabbar = qobject_cast<LtsTabBar *>(tabBar());
|
||||
|
||||
if (tabbar)
|
||||
{
|
||||
|
||||
CloseButton *closeBtn = new CloseButton();
|
||||
connect(closeBtn, &QPushButton::clicked, tabbar, &LtsTabBar::_internal_closeTab);
|
||||
tabbar->setTabButton(newTabIndex, QTabBar::RightSide, closeBtn);
|
||||
}
|
||||
|
||||
if (!setClosable)
|
||||
m_tabbar->tabButton(newTabIndex, QTabBar::RightSide)->hide();
|
||||
|
||||
if (tabbar)
|
||||
tabbar->updateCloseButtonColors();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LtsTabWidget::slotWindowTitleChanged(const QString &title)
|
||||
{
|
||||
QWidget *w = qobject_cast<QWidget *>(sender());
|
||||
|
||||
if (!w)
|
||||
{
|
||||
qWarning() << "LtsTabWidget: slotWindowTitleChanged failed! (not a QWidget) " << sender();
|
||||
return;
|
||||
}
|
||||
|
||||
int index = indexOf(w);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
qWarning() << "LtsTabWidget: slotWindowTitleChanged failed! (widget not found on TabBar)";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
QString realTitle = title;
|
||||
QString readOnlyHint;
|
||||
QStringList sl = title.split(QStringLiteral("- READ-ONLY"));
|
||||
if (sl.size() == 2)
|
||||
{
|
||||
realTitle = sl.first().trimmed();
|
||||
readOnlyHint = sl.back().trimmed();
|
||||
|
||||
|
||||
if (readOnlyHint.startsWith(QStringLiteral("(")))
|
||||
readOnlyHint.remove(0,1);
|
||||
if (readOnlyHint.endsWith(QStringLiteral(")")))
|
||||
readOnlyHint.remove(readOnlyHint.size()-1,1);
|
||||
|
||||
readOnlyHint = tr("Locked by: %1").arg(readOnlyHint);
|
||||
}
|
||||
|
||||
setTabText(index, realTitle);
|
||||
|
||||
QTabBar *tabBar = this->tabBar();
|
||||
|
||||
if (!readOnlyHint.isEmpty())
|
||||
{
|
||||
QLabel *readOnly = new QLabel(QStringLiteral("<b>READ-ONLY</b>"), this);
|
||||
readOnly->setToolTip(readOnlyHint);
|
||||
readOnly->setPixmap(QIcon(QStringLiteral("icon:warning.svg")).pixmap(QSize(25, 25)));
|
||||
|
||||
tabBar->setTabButton(index, QTabBar::ButtonPosition::LeftSide, readOnly);
|
||||
} else {
|
||||
QWidget *readOnly = tabBar->tabButton(index, QTabBar::ButtonPosition::LeftSide);
|
||||
if (readOnly)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
tabBar->setTabButton(index, QTabBar::ButtonPosition::LeftSide, nullptr);
|
||||
readOnly->setParent(this);
|
||||
delete readOnly;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QWidget *LtsTabWidget::getWidget(const QString &menuGroup, const QString &identifier)
|
||||
{
|
||||
LtsTabWidget *tab = this;
|
||||
QString fullName;
|
||||
|
||||
if (m_hasSubTabs)
|
||||
{
|
||||
fullName = identifier;
|
||||
tab = qobject_cast<LtsTabWidget *>(m_tabMap.value(menuGroup, nullptr));
|
||||
|
||||
if (tab == nullptr)
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
fullName = menuGroup + QLatin1Char('.') + identifier;
|
||||
}
|
||||
|
||||
return tab->getWidget(fullName);
|
||||
}
|
||||
|
||||
|
||||
QWidget *LtsTabWidget::getWidget(const QString &fullName)
|
||||
{
|
||||
return m_tabMap.value(fullName, nullptr);
|
||||
}
|
||||
|
||||
|
||||
bool LtsTabWidget::focusTab(const QString &menuGroup, const QString &identifier)
|
||||
{
|
||||
QPointer<LtsTabWidget> tab = this;
|
||||
QString fullName;
|
||||
|
||||
if (m_hasSubTabs)
|
||||
{
|
||||
fullName = identifier;
|
||||
tab = qobject_cast<LtsTabWidget *>(m_tabMap.value(menuGroup, nullptr));
|
||||
|
||||
if (!tab)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
setCurrentIndex(indexOf(tab));
|
||||
}
|
||||
else
|
||||
fullName = menuGroup + QLatin1Char('.') + identifier;
|
||||
|
||||
if (!tab)
|
||||
return false;
|
||||
|
||||
|
||||
LtsSplitter *splitter = static_cast<LtsSplitter*>(parent());
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QTimer::singleShot(500, this, [splitter, tab] (){
|
||||
|
||||
|
||||
if (splitter && tab && (tab->count() >= 1) && splitter->sizes().count() && !(splitter->sizes().at(1)))
|
||||
{
|
||||
splitter->animate(1);
|
||||
}
|
||||
});
|
||||
return tab->focusWidget(fullName);
|
||||
}
|
||||
|
||||
|
||||
bool LtsTabWidget::focusWidget(const QString &fullName)
|
||||
{
|
||||
QWidget *widget = m_tabMap.value(fullName, nullptr);
|
||||
|
||||
if (widget == nullptr)
|
||||
return false;
|
||||
|
||||
setCurrentIndex(indexOf(widget));
|
||||
widget->setFocus();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool LtsTabWidget::removeWidget(QWidget * widget)
|
||||
{
|
||||
if (nullptr == widget)
|
||||
return false;
|
||||
|
||||
for (auto i = m_tabMap.begin(); i != m_tabMap.end(); ++i)
|
||||
{
|
||||
QWidget *w = i.value();
|
||||
|
||||
if (w == nullptr)
|
||||
continue;
|
||||
|
||||
if (w == widget)
|
||||
{
|
||||
m_tabMap.erase(i);
|
||||
disconnect(widget, &QWidget::destroyed, this, static_cast<void (LtsTabWidget::*)(QObject*)>(&LtsTabWidget::onRemoveTab));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_hasSubTabs)
|
||||
{
|
||||
LtsTabWidget *tab = qobject_cast<LtsTabWidget*>(w);
|
||||
if (tab != nullptr && tab->removeWidget(widget))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void LtsTabWidget::onRemoveTab(QObject *object)
|
||||
{
|
||||
if (object == nullptr)
|
||||
{
|
||||
qWarning() << "onRemoveTab: obj == nullptr";
|
||||
return;
|
||||
}
|
||||
|
||||
QWidget *w = static_cast<QWidget *>(object);
|
||||
|
||||
bool rmd = false;
|
||||
for (auto i = m_tabMap.begin(); i != m_tabMap.end(); ++i)
|
||||
{
|
||||
if (i.value() == w)
|
||||
{
|
||||
m_tabMap.erase(i);
|
||||
rmd = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rmd)
|
||||
{
|
||||
qWarning() << "LtsTabWidget::onRemoveTab: widget to remove was not on tab map!";
|
||||
}
|
||||
|
||||
int index = indexOf(w);
|
||||
if (index < 0)
|
||||
{
|
||||
|
||||
qWarning() << "LtsTabWidget::onRemoveTab: cannot remove widget, as it was not found on the tab widget" << (void *)w;
|
||||
}
|
||||
else
|
||||
{
|
||||
removeTab(index);
|
||||
}
|
||||
|
||||
onCheckTabBarVisibility();
|
||||
}
|
||||
|
||||
|
||||
void LtsTabWidget::setActuatorTabStyle(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
setTabBar(new LtsTabBar(false, this));
|
||||
}
|
||||
|
||||
|
||||
LtsTabBar *LtsTabWidget::tabBar()
|
||||
{
|
||||
return m_tabbar;
|
||||
}
|
||||
|
||||
|
||||
void LtsTabWidget::setTabBar(LtsTabBar *tabbar)
|
||||
{
|
||||
if (m_tabbar)
|
||||
m_tabbar->deleteLater();
|
||||
|
||||
|
||||
QFont currentFont = font();
|
||||
currentFont.setCapitalization(QFont::SmallCaps);
|
||||
currentFont.setBold(true);
|
||||
|
||||
tabbar->setFont(currentFont);
|
||||
connect(tabbar, &LtsTabBar::tabCloseRequested, this, &LtsTabWidget::slotTabCloseRequested);
|
||||
|
||||
m_tabbar = tabbar;
|
||||
QTabWidget::setTabBar(m_tabbar);
|
||||
}
|
||||
|
||||
|
||||
void LtsTabWidget::clearAll()
|
||||
{
|
||||
|
||||
|
||||
for (int i = 0; i < count(); i++)
|
||||
{
|
||||
QWidget *w = widget(i);
|
||||
|
||||
if (w == nullptr)
|
||||
continue;
|
||||
|
||||
disconnect(w, &QWidget::destroyed, this, static_cast<void (LtsTabWidget::*)(QObject*)>(&LtsTabWidget::onRemoveTab));
|
||||
|
||||
w->deleteLater();
|
||||
}
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
|
||||
void LtsTabWidget::aboutToClose()
|
||||
{
|
||||
for (int i = 0; i < count(); i++)
|
||||
{
|
||||
if (m_hasSubTabs)
|
||||
{
|
||||
LtsTabWidget *tab = qobject_cast<LtsTabWidget *>(widget(i));
|
||||
tab->aboutToClose();
|
||||
}
|
||||
else
|
||||
{
|
||||
LtsDialogHelper *helper = qobject_cast<LtsDialogHelper *>(widget(i));
|
||||
|
||||
if (helper == nullptr)
|
||||
continue;
|
||||
|
||||
LtsDialog *dialog = qobject_cast<LtsDialog *>(helper->getDialog());
|
||||
|
||||
if (dialog == nullptr)
|
||||
continue;
|
||||
|
||||
dialog->aboutToClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LtsTabWidget::hasUnsavedChanges(LtsTabWidget *tabWidget)
|
||||
{
|
||||
for (int i = 0; i < tabWidget->count(); i++)
|
||||
{
|
||||
QWidget *w = tabWidget->widget(i);
|
||||
|
||||
LtsDialogHelper *helper = qobject_cast<LtsDialogHelper *>(w);
|
||||
|
||||
if (helper)
|
||||
{
|
||||
LtsDialog *dlg = qobject_cast<LtsDialog *>(helper->getDialog());
|
||||
|
||||
if (dlg != nullptr)
|
||||
{
|
||||
|
||||
|
||||
if (dlg->hasUnsavedChanges())
|
||||
{
|
||||
int dlgIndex = tabWidget->indexOf(helper);
|
||||
if (dlgIndex != -1)
|
||||
tabWidget->setCurrentIndex(dlgIndex);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LtsTabWidget *tab = qobject_cast<LtsTabWidget *>(w);
|
||||
|
||||
if (tab)
|
||||
{
|
||||
|
||||
|
||||
bool _hasUnsavedChanges = hasUnsavedChanges(tab);
|
||||
if (_hasUnsavedChanges)
|
||||
{
|
||||
int tabIndex = tabWidget->indexOf(tab);
|
||||
if (tabIndex != -1)
|
||||
tabWidget->setCurrentIndex(tabIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void CloseButton::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter p(this);
|
||||
|
||||
p.save();
|
||||
p.setPen(QPen(QColor(m_fontColor), 1.5));
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
|
||||
p.drawLine(line());
|
||||
|
||||
|
||||
p.setPen(QPen(QColor(m_fontColor), 2.5));
|
||||
|
||||
QRectF c = cross();
|
||||
|
||||
p.drawLine(c.topLeft(), c.bottomRight());
|
||||
p.drawLine(c.bottomLeft(), c.topRight());
|
||||
|
||||
p.restore();
|
||||
}
|
||||
|
||||
|
||||
QLineF CloseButton::line() const
|
||||
{
|
||||
qreal forceBlur = 0.001;
|
||||
qreal lineStart = height() * (0.25 / 2) + forceBlur;
|
||||
qreal lineSize = height() - lineStart;
|
||||
|
||||
return QLineF(QPointF(lineStart, lineStart), QPointF(lineStart, lineSize));
|
||||
}
|
||||
|
||||
|
||||
QRectF CloseButton::cross() const
|
||||
{
|
||||
QLineF l = line();
|
||||
|
||||
qreal lineLeft = l.x1();
|
||||
qreal forceBlur = 0.001;
|
||||
|
||||
qreal crossStartX = lineLeft * 3;
|
||||
qreal crossStartY = lineLeft * 2;
|
||||
qreal crossEndX = width(); crossEndX -= crossEndX * 0.15 + forceBlur;
|
||||
qreal crossEndY = height() - crossStartY;
|
||||
|
||||
return QRectF(QPointF(crossStartX, crossStartY), QPointF(crossEndX, crossEndY));
|
||||
}
|
||||
|
||||
|
||||
QSize CloseButton::sizeHint() const
|
||||
{
|
||||
QFontMetrics fm (QApplication::font());
|
||||
int fontHeight = fm.height();
|
||||
|
||||
int fontHeightQuarter = fontHeight * 0.25;
|
||||
int finalSize = fontHeight + fontHeightQuarter;
|
||||
#ifdef TABLET_MODE
|
||||
finalSize = finalSize*1.5;
|
||||
#endif
|
||||
return QSize(finalSize, finalSize);
|
||||
}
|
||||
|
||||
|
||||
void CloseButton::mousePressEvent(QMouseEvent *e)
|
||||
{
|
||||
e->ignore();
|
||||
m_isPressed = true;
|
||||
}
|
||||
|
||||
|
||||
void CloseButton::mouseReleaseEvent(QMouseEvent *e)
|
||||
{
|
||||
bool isPressed = m_isPressed;
|
||||
m_isPressed = false;
|
||||
|
||||
if (!isPressed)
|
||||
{
|
||||
e->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
QRectF c = cross();
|
||||
QRect adjusted = QRect(QPoint(floor(c.x()), floor(c.y())), QPoint(ceil(c.right()), ceil(c.bottom() +1 )));
|
||||
|
||||
if (!adjusted.contains(e->localPos().toPoint()))
|
||||
{
|
||||
|
||||
e->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
e->accept();
|
||||
emit clicked();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user