895 lines
17 KiB
C++
Executable File
895 lines
17 KiB
C++
Executable File
|
|
|
|
|
|
#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();
|
|
}
|
|
}
|