forked from qt-creator/qt-creator
ADS: Integrate newest base repository commits
* Update to newest version of ADS * Remove native window and title bar support on linux Base repository was merged until commit 8d4507e9d83434be976ff8c7bc9f59733937a08d Task-number: QDS-10242 Change-Id: If74b6b50421be3b759c61b0f76f4a330991f71fa Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
This commit is contained in:
committed by
Henning Gründl
parent
21983a8377
commit
16ef838f23
@@ -13,340 +13,353 @@
|
||||
#include <QLoggingCategory>
|
||||
#include <QMouseEvent>
|
||||
#include <QScrollBar>
|
||||
#include <QTimer>
|
||||
#include <QtGlobal>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace ADS
|
||||
namespace ADS {
|
||||
/**
|
||||
* Private data class of DockAreaTabBar class (pimpl)
|
||||
*/
|
||||
class DockAreaTabBarPrivate
|
||||
{
|
||||
public:
|
||||
DockAreaTabBar *q;
|
||||
DockAreaWidget *m_dockArea = nullptr;
|
||||
QWidget *m_tabsContainerWidget = nullptr;
|
||||
QBoxLayout *m_tabsLayout = nullptr;
|
||||
int m_currentIndex = -1;
|
||||
|
||||
/**
|
||||
* Private data class of DockAreaTabBar class (pimpl)
|
||||
* Private data constructor
|
||||
*/
|
||||
class DockAreaTabBarPrivate
|
||||
{
|
||||
public:
|
||||
DockAreaTabBar *q;
|
||||
DockAreaWidget *m_dockArea = nullptr;
|
||||
QWidget *m_tabsContainerWidget = nullptr;
|
||||
QBoxLayout *m_tabsLayout = nullptr;
|
||||
int m_currentIndex = -1;
|
||||
DockAreaTabBarPrivate(DockAreaTabBar *parent);
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
*/
|
||||
DockAreaTabBarPrivate(DockAreaTabBar *parent);
|
||||
/**
|
||||
* Update tabs after current index changed or when tabs are removed.
|
||||
* The function reassigns the stylesheet to update the tabs.
|
||||
*/
|
||||
void updateTabs();
|
||||
|
||||
/**
|
||||
* Update tabs after current index changed or when tabs are removed.
|
||||
* The function reassigns the stylesheet to update the tabs
|
||||
*/
|
||||
void updateTabs();
|
||||
/**
|
||||
* Convenience function to access first tab.
|
||||
*/
|
||||
DockWidgetTab *firstTab() const { return q->tab(0); }
|
||||
|
||||
/**
|
||||
* Convenience function to access first tab
|
||||
*/
|
||||
DockWidgetTab *firstTab() const { return q->tab(0); }
|
||||
/**
|
||||
* Convenience function to access last tab.
|
||||
*/
|
||||
DockWidgetTab *lastTab() const { return q->tab(q->count() - 1); }
|
||||
}; // class DockAreaTabBarPrivate
|
||||
|
||||
/**
|
||||
* Convenience function to access last tab
|
||||
*/
|
||||
DockWidgetTab *lastTab() const { return q->tab(q->count() - 1); }
|
||||
}; // class DockAreaTabBarPrivate
|
||||
DockAreaTabBarPrivate::DockAreaTabBarPrivate(DockAreaTabBar *parent)
|
||||
: q(parent)
|
||||
{}
|
||||
|
||||
DockAreaTabBarPrivate::DockAreaTabBarPrivate(DockAreaTabBar *parent)
|
||||
: q(parent)
|
||||
{}
|
||||
void DockAreaTabBarPrivate::updateTabs()
|
||||
{
|
||||
// Set active TAB and update all other tabs to be inactive
|
||||
for (int i = 0; i < q->count(); ++i) {
|
||||
auto tabWidget = q->tab(i);
|
||||
if (!tabWidget)
|
||||
continue;
|
||||
|
||||
void DockAreaTabBarPrivate::updateTabs()
|
||||
{
|
||||
// Set active TAB and update all other tabs to be inactive
|
||||
for (int i = 0; i < q->count(); ++i) {
|
||||
auto tabWidget = q->tab(i);
|
||||
if (!tabWidget)
|
||||
continue;
|
||||
if (i == m_currentIndex) {
|
||||
tabWidget->show();
|
||||
tabWidget->setActiveTab(true);
|
||||
// Sometimes the synchronous calculation of the rectangular area fails. Therefore we
|
||||
// use QTimer::singleShot here to execute the call within the event loop - see #520.
|
||||
QTimer::singleShot(0, q, [&, tabWidget] { q->ensureWidgetVisible(tabWidget); });
|
||||
} else {
|
||||
tabWidget->setActiveTab(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i == m_currentIndex) {
|
||||
tabWidget->show();
|
||||
tabWidget->setActiveTab(true);
|
||||
q->ensureWidgetVisible(tabWidget);
|
||||
} else {
|
||||
tabWidget->setActiveTab(false);
|
||||
DockAreaTabBar::DockAreaTabBar(DockAreaWidget *parent)
|
||||
: QScrollArea(parent)
|
||||
, d(new DockAreaTabBarPrivate(this))
|
||||
{
|
||||
d->m_dockArea = parent;
|
||||
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
setFrameStyle(QFrame::NoFrame);
|
||||
setWidgetResizable(true);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
d->m_tabsContainerWidget = new QWidget();
|
||||
d->m_tabsContainerWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
d->m_tabsContainerWidget->setObjectName("tabsContainerWidget");
|
||||
d->m_tabsLayout = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
d->m_tabsLayout->setContentsMargins(0, 0, 0, 0);
|
||||
d->m_tabsLayout->setSpacing(0);
|
||||
d->m_tabsLayout->addStretch(1);
|
||||
d->m_tabsContainerWidget->setLayout(d->m_tabsLayout);
|
||||
setWidget(d->m_tabsContainerWidget);
|
||||
}
|
||||
|
||||
DockAreaTabBar::~DockAreaTabBar()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void DockAreaTabBar::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
event->accept();
|
||||
const int direction = event->angleDelta().y();
|
||||
if (direction < 0)
|
||||
horizontalScrollBar()->setValue(horizontalScrollBar()->value() + 20);
|
||||
else
|
||||
horizontalScrollBar()->setValue(horizontalScrollBar()->value() - 20);
|
||||
}
|
||||
|
||||
void DockAreaTabBar::setCurrentIndex(int index)
|
||||
{
|
||||
if (index == d->m_currentIndex)
|
||||
return;
|
||||
|
||||
if (index < -1 || index > (count() - 1)) {
|
||||
qWarning() << Q_FUNC_INFO << "Invalid index" << index;
|
||||
return;
|
||||
}
|
||||
|
||||
emit currentChanging(index);
|
||||
d->m_currentIndex = index;
|
||||
d->updateTabs();
|
||||
updateGeometry();
|
||||
emit currentChanged(index);
|
||||
}
|
||||
|
||||
int DockAreaTabBar::count() const
|
||||
{
|
||||
// The tab bar contains a stretch item as last item
|
||||
return d->m_tabsLayout->count() - 1;
|
||||
}
|
||||
|
||||
void DockAreaTabBar::insertTab(int index, DockWidgetTab *dockWidgetTab)
|
||||
{
|
||||
d->m_tabsLayout->insertWidget(index, dockWidgetTab);
|
||||
connect(dockWidgetTab, &DockWidgetTab::clicked, this, [this, dockWidgetTab] {
|
||||
onTabClicked(dockWidgetTab);
|
||||
});
|
||||
connect(dockWidgetTab, &DockWidgetTab::closeRequested, this, [this, dockWidgetTab] {
|
||||
onTabCloseRequested(dockWidgetTab);
|
||||
});
|
||||
connect(dockWidgetTab, &DockWidgetTab::closeOtherTabsRequested, this, [this, dockWidgetTab] {
|
||||
onCloseOtherTabsRequested(dockWidgetTab);
|
||||
});
|
||||
connect(dockWidgetTab,
|
||||
&DockWidgetTab::moved,
|
||||
this,
|
||||
[this, dockWidgetTab](const QPoint &globalPosition) {
|
||||
onTabWidgetMoved(dockWidgetTab, globalPosition);
|
||||
});
|
||||
connect(dockWidgetTab, &DockWidgetTab::elidedChanged, this, &DockAreaTabBar::elidedChanged);
|
||||
dockWidgetTab->installEventFilter(this);
|
||||
emit tabInserted(index);
|
||||
if (index <= d->m_currentIndex)
|
||||
setCurrentIndex(d->m_currentIndex + 1);
|
||||
else if (d->m_currentIndex == -1)
|
||||
setCurrentIndex(index);
|
||||
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void DockAreaTabBar::removeTab(DockWidgetTab *dockWidgetTab)
|
||||
{
|
||||
if (!count())
|
||||
return;
|
||||
|
||||
qCInfo(adsLog) << Q_FUNC_INFO;
|
||||
int newCurrentIndex = currentIndex();
|
||||
int removeIndex = d->m_tabsLayout->indexOf(dockWidgetTab);
|
||||
if (count() == 1)
|
||||
newCurrentIndex = -1;
|
||||
|
||||
if (newCurrentIndex > removeIndex) {
|
||||
newCurrentIndex--;
|
||||
} else if (newCurrentIndex == removeIndex) {
|
||||
newCurrentIndex = -1;
|
||||
// First we walk to the right to search for the next visible tab
|
||||
for (int i = (removeIndex + 1); i < count(); ++i) {
|
||||
if (tab(i)->isVisibleTo(this)) {
|
||||
newCurrentIndex = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DockAreaTabBar::DockAreaTabBar(DockAreaWidget *parent)
|
||||
: QScrollArea(parent)
|
||||
, d(new DockAreaTabBarPrivate(this))
|
||||
{
|
||||
d->m_dockArea = parent;
|
||||
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
setFrameStyle(QFrame::NoFrame);
|
||||
setWidgetResizable(true);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
d->m_tabsContainerWidget = new QWidget();
|
||||
d->m_tabsContainerWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
d->m_tabsContainerWidget->setObjectName("tabsContainerWidget");
|
||||
d->m_tabsLayout = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
d->m_tabsLayout->setContentsMargins(0, 0, 0, 0);
|
||||
d->m_tabsLayout->setSpacing(0);
|
||||
d->m_tabsLayout->addStretch(1);
|
||||
d->m_tabsContainerWidget->setLayout(d->m_tabsLayout);
|
||||
setWidget(d->m_tabsContainerWidget);
|
||||
}
|
||||
|
||||
DockAreaTabBar::~DockAreaTabBar() { delete d; }
|
||||
|
||||
void DockAreaTabBar::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
event->accept();
|
||||
const int direction = event->angleDelta().y();
|
||||
if (direction < 0)
|
||||
horizontalScrollBar()->setValue(horizontalScrollBar()->value() + 20);
|
||||
else
|
||||
horizontalScrollBar()->setValue(horizontalScrollBar()->value() - 20);
|
||||
}
|
||||
|
||||
void DockAreaTabBar::setCurrentIndex(int index)
|
||||
{
|
||||
if (index == d->m_currentIndex)
|
||||
return;
|
||||
|
||||
if (index < -1 || index > (count() - 1)) {
|
||||
qWarning() << Q_FUNC_INFO << "Invalid index" << index;
|
||||
return;
|
||||
}
|
||||
|
||||
emit currentChanging(index);
|
||||
d->m_currentIndex = index;
|
||||
d->updateTabs();
|
||||
updateGeometry();
|
||||
emit currentChanged(index);
|
||||
}
|
||||
|
||||
int DockAreaTabBar::count() const
|
||||
{
|
||||
// The tab bar contains a stretch item as last item
|
||||
return d->m_tabsLayout->count() - 1;
|
||||
}
|
||||
|
||||
void DockAreaTabBar::insertTab(int index, DockWidgetTab *dockWidgetTab)
|
||||
{
|
||||
d->m_tabsLayout->insertWidget(index, dockWidgetTab);
|
||||
connect(dockWidgetTab, &DockWidgetTab::clicked,
|
||||
this, [this, dockWidgetTab] { onTabClicked(dockWidgetTab); });
|
||||
connect(dockWidgetTab, &DockWidgetTab::closeRequested,
|
||||
this, [this, dockWidgetTab] { onTabCloseRequested(dockWidgetTab); });
|
||||
connect(dockWidgetTab, &DockWidgetTab::closeOtherTabsRequested,
|
||||
this, [this, dockWidgetTab] { onCloseOtherTabsRequested(dockWidgetTab); });
|
||||
connect(dockWidgetTab, &DockWidgetTab::moved,
|
||||
this, [this, dockWidgetTab](const QPoint &globalPosition) {
|
||||
onTabWidgetMoved(dockWidgetTab, globalPosition);
|
||||
});
|
||||
connect(dockWidgetTab, &DockWidgetTab::elidedChanged,
|
||||
this, &DockAreaTabBar::elidedChanged);
|
||||
dockWidgetTab->installEventFilter(this);
|
||||
emit tabInserted(index);
|
||||
if (index <= d->m_currentIndex)
|
||||
setCurrentIndex(d->m_currentIndex + 1);
|
||||
else if (d->m_currentIndex == -1)
|
||||
setCurrentIndex(index);
|
||||
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void DockAreaTabBar::removeTab(DockWidgetTab *dockWidgetTab)
|
||||
{
|
||||
if (!count())
|
||||
return;
|
||||
|
||||
qCInfo(adsLog) << Q_FUNC_INFO;
|
||||
int newCurrentIndex = currentIndex();
|
||||
int removeIndex = d->m_tabsLayout->indexOf(dockWidgetTab);
|
||||
if (count() == 1)
|
||||
newCurrentIndex = -1;
|
||||
|
||||
if (newCurrentIndex > removeIndex) {
|
||||
newCurrentIndex--;
|
||||
} else if (newCurrentIndex == removeIndex) {
|
||||
newCurrentIndex = -1;
|
||||
// First we walk to the right to search for the next visible tab
|
||||
for (int i = (removeIndex + 1); i < count(); ++i) {
|
||||
// If there is no visible tab right to this tab then we walk to the left to find a visible tab.
|
||||
if (newCurrentIndex < 0) {
|
||||
for (int i = (removeIndex - 1); i >= 0; --i) {
|
||||
if (tab(i)->isVisibleTo(this)) {
|
||||
newCurrentIndex = i - 1;
|
||||
newCurrentIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If there is no visible tab right to this tab then we walk to
|
||||
// the left to find a visible tab
|
||||
if (newCurrentIndex < 0) {
|
||||
for (int i = (removeIndex - 1); i >= 0; --i) {
|
||||
if (tab(i)->isVisibleTo(this)) {
|
||||
newCurrentIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emit removingTab(removeIndex);
|
||||
d->m_tabsLayout->removeWidget(dockWidgetTab);
|
||||
dockWidgetTab->disconnect(this);
|
||||
dockWidgetTab->removeEventFilter(this);
|
||||
qCInfo(adsLog) << "NewCurrentIndex " << newCurrentIndex;
|
||||
if (newCurrentIndex != d->m_currentIndex)
|
||||
setCurrentIndex(newCurrentIndex);
|
||||
else
|
||||
d->updateTabs();
|
||||
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
int DockAreaTabBar::currentIndex() const { return d->m_currentIndex; }
|
||||
|
||||
DockWidgetTab *DockAreaTabBar::currentTab() const
|
||||
{
|
||||
if (d->m_currentIndex < 0)
|
||||
return nullptr;
|
||||
else
|
||||
return qobject_cast<DockWidgetTab *>(
|
||||
d->m_tabsLayout->itemAt(d->m_currentIndex)->widget());
|
||||
}
|
||||
|
||||
void DockAreaTabBar::onTabClicked(DockWidgetTab *sourceTab)
|
||||
{
|
||||
const int index = d->m_tabsLayout->indexOf(sourceTab);
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
setCurrentIndex(index);
|
||||
emit tabBarClicked(index);
|
||||
}
|
||||
|
||||
void DockAreaTabBar::onTabCloseRequested(DockWidgetTab *sourceTab)
|
||||
{
|
||||
const int index = d->m_tabsLayout->indexOf(sourceTab);
|
||||
closeTab(index);
|
||||
}
|
||||
|
||||
void DockAreaTabBar::onCloseOtherTabsRequested(DockWidgetTab *sourceTab)
|
||||
{
|
||||
for (int i = 0; i < count(); ++i) {
|
||||
auto currentTab = tab(i);
|
||||
if (currentTab->isClosable() && !currentTab->isHidden() && currentTab != sourceTab) {
|
||||
// If the dock widget is deleted with the closeTab() call, its tab it will no longer
|
||||
// be in the layout, and thus the index needs to be updated to not skip any tabs
|
||||
int offset = currentTab->dockWidget()->features().testFlag(
|
||||
DockWidget::DockWidgetDeleteOnClose)
|
||||
? 1
|
||||
: 0;
|
||||
closeTab(i);
|
||||
// If the the dock widget blocks closing, i.e. if the flag
|
||||
// CustomCloseHandling is set, and the dock widget is still open,
|
||||
// then we do not need to correct the index
|
||||
if (currentTab->dockWidget()->isClosed())
|
||||
i -= offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DockWidgetTab *DockAreaTabBar::tab(int index) const
|
||||
{
|
||||
if (index >= count() || index < 0)
|
||||
return nullptr;
|
||||
emit removingTab(removeIndex);
|
||||
d->m_tabsLayout->removeWidget(dockWidgetTab);
|
||||
dockWidgetTab->disconnect(this);
|
||||
dockWidgetTab->removeEventFilter(this);
|
||||
qCInfo(adsLog) << "NewCurrentIndex" << newCurrentIndex;
|
||||
if (newCurrentIndex != d->m_currentIndex)
|
||||
setCurrentIndex(newCurrentIndex);
|
||||
else
|
||||
d->updateTabs();
|
||||
|
||||
return qobject_cast<DockWidgetTab *>(d->m_tabsLayout->itemAt(index)->widget());
|
||||
}
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void DockAreaTabBar::onTabWidgetMoved(DockWidgetTab *sourceTab, const QPoint &globalPosition)
|
||||
{
|
||||
const int fromIndex = d->m_tabsLayout->indexOf(sourceTab);
|
||||
auto mousePos = mapFromGlobal(globalPosition);
|
||||
mousePos.rx() = qMax(d->firstTab()->geometry().left(), mousePos.x());
|
||||
mousePos.rx() = qMin(d->lastTab()->geometry().right(), mousePos.x());
|
||||
int toIndex = -1;
|
||||
// Find tab under mouse
|
||||
for (int i = 0; i < count(); ++i) {
|
||||
DockWidgetTab *dropTab = tab(i);
|
||||
if (dropTab == sourceTab || !dropTab->isVisibleTo(this)
|
||||
|| !dropTab->geometry().contains(mousePos))
|
||||
continue;
|
||||
int DockAreaTabBar::currentIndex() const
|
||||
{
|
||||
return d->m_currentIndex;
|
||||
}
|
||||
|
||||
toIndex = d->m_tabsLayout->indexOf(dropTab);
|
||||
if (toIndex == fromIndex)
|
||||
toIndex = -1;
|
||||
DockWidgetTab *DockAreaTabBar::currentTab() const
|
||||
{
|
||||
if (d->m_currentIndex < 0)
|
||||
return nullptr;
|
||||
else
|
||||
return qobject_cast<DockWidgetTab *>(d->m_tabsLayout->itemAt(d->m_currentIndex)->widget());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
void DockAreaTabBar::onTabClicked(DockWidgetTab *sourceTab)
|
||||
{
|
||||
const int index = d->m_tabsLayout->indexOf(sourceTab);
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
if (toIndex > -1) {
|
||||
d->m_tabsLayout->removeWidget(sourceTab);
|
||||
d->m_tabsLayout->insertWidget(toIndex, sourceTab);
|
||||
qCInfo(adsLog) << "tabMoved from" << fromIndex << "to" << toIndex;
|
||||
emit tabMoved(fromIndex, toIndex);
|
||||
setCurrentIndex(toIndex);
|
||||
} else {
|
||||
// Ensure that the moved tab is reset to its start position
|
||||
d->m_tabsLayout->update();
|
||||
setCurrentIndex(index);
|
||||
emit tabBarClicked(index);
|
||||
}
|
||||
|
||||
void DockAreaTabBar::onTabCloseRequested(DockWidgetTab *sourceTab)
|
||||
{
|
||||
const int index = d->m_tabsLayout->indexOf(sourceTab);
|
||||
closeTab(index);
|
||||
}
|
||||
|
||||
void DockAreaTabBar::onCloseOtherTabsRequested(DockWidgetTab *sourceTab)
|
||||
{
|
||||
for (int i = 0; i < count(); ++i) {
|
||||
auto currentTab = tab(i);
|
||||
if (currentTab->isClosable() && !currentTab->isHidden() && currentTab != sourceTab) {
|
||||
// If the dock widget is deleted with the closeTab() call, its tab it will no longer
|
||||
// be in the layout, and thus the index needs to be updated to not skip any tabs.
|
||||
int offset = currentTab->dockWidget()->features().testFlag(
|
||||
DockWidget::DockWidgetDeleteOnClose)
|
||||
? 1
|
||||
: 0;
|
||||
closeTab(i);
|
||||
// If the the dock widget blocks closing, i.e. if the flag CustomCloseHandling is set,
|
||||
// and the dock widget is still open, then we do not need to correct the index.
|
||||
if (currentTab->dockWidget()->isClosed())
|
||||
i -= offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DockAreaTabBar::closeTab(int index)
|
||||
{
|
||||
if (index < 0 || index >= count())
|
||||
return;
|
||||
DockWidgetTab *DockAreaTabBar::tab(int index) const
|
||||
{
|
||||
if (index >= count() || index < 0)
|
||||
return nullptr;
|
||||
|
||||
auto dockWidgetTab = tab(index);
|
||||
if (dockWidgetTab->isHidden())
|
||||
return;
|
||||
return qobject_cast<DockWidgetTab *>(d->m_tabsLayout->itemAt(index)->widget());
|
||||
}
|
||||
|
||||
emit tabCloseRequested(index);
|
||||
void DockAreaTabBar::onTabWidgetMoved(DockWidgetTab *sourceTab, const QPoint &globalPosition)
|
||||
{
|
||||
const int fromIndex = d->m_tabsLayout->indexOf(sourceTab);
|
||||
auto mousePos = mapFromGlobal(globalPosition);
|
||||
mousePos.rx() = qMax(d->firstTab()->geometry().left(), mousePos.x());
|
||||
mousePos.rx() = qMin(d->lastTab()->geometry().right(), mousePos.x());
|
||||
int toIndex = -1;
|
||||
// Find tab under mouse
|
||||
for (int i = 0; i < count(); ++i) {
|
||||
DockWidgetTab *dropTab = tab(i);
|
||||
if (dropTab == sourceTab || !dropTab->isVisibleTo(this)
|
||||
|| !dropTab->geometry().contains(mousePos))
|
||||
continue;
|
||||
|
||||
toIndex = d->m_tabsLayout->indexOf(dropTab);
|
||||
if (toIndex == fromIndex)
|
||||
toIndex = -1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
bool DockAreaTabBar::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
bool result = Super::eventFilter(watched, event);
|
||||
DockWidgetTab *dockWidgetTab = qobject_cast<DockWidgetTab *>(watched);
|
||||
if (!dockWidgetTab)
|
||||
return result;
|
||||
if (toIndex > -1) {
|
||||
d->m_tabsLayout->removeWidget(sourceTab);
|
||||
d->m_tabsLayout->insertWidget(toIndex, sourceTab);
|
||||
qCInfo(adsLog) << "tabMoved from" << fromIndex << "to" << toIndex;
|
||||
emit tabMoved(fromIndex, toIndex);
|
||||
setCurrentIndex(toIndex);
|
||||
} else {
|
||||
// Ensure that the moved tab is reset to its start position
|
||||
d->m_tabsLayout->update();
|
||||
}
|
||||
}
|
||||
|
||||
switch (event->type()) {
|
||||
case QEvent::Hide:
|
||||
emit tabClosed(d->m_tabsLayout->indexOf(dockWidgetTab));
|
||||
updateGeometry();
|
||||
break;
|
||||
case QEvent::Show:
|
||||
emit tabOpened(d->m_tabsLayout->indexOf(dockWidgetTab));
|
||||
updateGeometry();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
void DockAreaTabBar::closeTab(int index)
|
||||
{
|
||||
if (index < 0 || index >= count())
|
||||
return;
|
||||
|
||||
auto dockWidgetTab = tab(index);
|
||||
if (dockWidgetTab->isHidden())
|
||||
return;
|
||||
|
||||
emit tabCloseRequested(index);
|
||||
}
|
||||
|
||||
bool DockAreaTabBar::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
bool result = Super::eventFilter(watched, event);
|
||||
DockWidgetTab *dockWidgetTab = qobject_cast<DockWidgetTab *>(watched);
|
||||
if (!dockWidgetTab)
|
||||
return result;
|
||||
|
||||
switch (event->type()) {
|
||||
case QEvent::Hide:
|
||||
emit tabClosed(d->m_tabsLayout->indexOf(dockWidgetTab));
|
||||
updateGeometry();
|
||||
break;
|
||||
case QEvent::Show:
|
||||
emit tabOpened(d->m_tabsLayout->indexOf(dockWidgetTab));
|
||||
updateGeometry();
|
||||
break;
|
||||
// Setting the text of a tab will cause a LayoutRequest event
|
||||
case QEvent::LayoutRequest:
|
||||
updateGeometry();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bool DockAreaTabBar::isTabOpen(int index) const
|
||||
{
|
||||
if (index < 0 || index >= count())
|
||||
return false;
|
||||
return result;
|
||||
}
|
||||
|
||||
return !tab(index)->isHidden();
|
||||
}
|
||||
bool DockAreaTabBar::isTabOpen(int index) const
|
||||
{
|
||||
if (index < 0 || index >= count())
|
||||
return false;
|
||||
|
||||
QSize DockAreaTabBar::minimumSizeHint() const
|
||||
{
|
||||
QSize size = sizeHint();
|
||||
size.setWidth(10);
|
||||
return size;
|
||||
}
|
||||
return !tab(index)->isHidden();
|
||||
}
|
||||
|
||||
QSize DockAreaTabBar::sizeHint() const
|
||||
{
|
||||
return d->m_tabsContainerWidget->sizeHint();
|
||||
}
|
||||
QSize DockAreaTabBar::minimumSizeHint() const
|
||||
{
|
||||
QSize size = sizeHint();
|
||||
size.setWidth(10);
|
||||
return size;
|
||||
}
|
||||
|
||||
QSize DockAreaTabBar::sizeHint() const
|
||||
{
|
||||
return d->m_tabsContainerWidget->sizeHint();
|
||||
}
|
||||
|
||||
} // namespace ADS
|
||||
|
||||
Reference in New Issue
Block a user