diff --git a/demo/MainWindow.cpp b/demo/MainWindow.cpp index 54836af..922530a 100644 --- a/demo/MainWindow.cpp +++ b/demo/MainWindow.cpp @@ -283,7 +283,6 @@ struct MainWindowPrivate void restorePerspectives(); }; - //============================================================================ void MainWindowPrivate::createContent() { @@ -453,6 +452,9 @@ CMainWindow::CMainWindow(QWidget *parent) : // uncomment the following line if you don't want disabled buttons to appear on DockArea's title bar //CDockManager::setConfigFlag(CDockManager::DockAreaHideDisabledButtons, true); + // uncomment the following line if you want to show tabs menu button on DockArea's title bar only when there are more than one tab and at least of them has elided title + //CDockManager::setConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility, true); + // Now create the dock manager and its content d->DockManager = new CDockManager(this); diff --git a/src/DockAreaTabBar.cpp b/src/DockAreaTabBar.cpp index 73f9f39..04f84af 100644 --- a/src/DockAreaTabBar.cpp +++ b/src/DockAreaTabBar.cpp @@ -343,6 +343,7 @@ void CDockAreaTabBar::insertTab(int Index, CDockWidgetTab* Tab) connect(Tab, SIGNAL(closeRequested()), this, SLOT(onTabCloseRequested())); connect(Tab, SIGNAL(closeOtherTabsRequested()), this, SLOT(onCloseOtherTabsRequested())); connect(Tab, SIGNAL(moved(const QPoint&)), this, SLOT(onTabWidgetMoved(const QPoint&))); + connect(Tab, SIGNAL(elidedChanged(bool)), this, SIGNAL(elidedChanged(bool))); Tab->installEventFilter(this); emit tabInserted(Index); if (Index <= d->CurrentIndex || d->CurrentIndex == -1) @@ -562,7 +563,6 @@ void CDockAreaTabBar::onTabWidgetMoved(const QPoint& GlobalPos) } } - //=========================================================================== void CDockAreaTabBar::closeTab(int Index) { diff --git a/src/DockAreaTabBar.h b/src/DockAreaTabBar.h index 13ea615..8e0c487 100644 --- a/src/DockAreaTabBar.h +++ b/src/DockAreaTabBar.h @@ -239,6 +239,11 @@ signals: * This signal is emitted if a tab has been inserted */ void tabInserted(int index); + + /** + * This signal is emitted when a tab title elide state has been changed + */ + void elidedChanged(bool elided); }; // class CDockAreaTabBar } // namespace ads //----------------------------------------------------------------------------- diff --git a/src/DockAreaTitleBar.cpp b/src/DockAreaTitleBar.cpp index 544c20e..d120b7a 100644 --- a/src/DockAreaTitleBar.cpp +++ b/src/DockAreaTitleBar.cpp @@ -151,10 +151,11 @@ protected: if(QEvent::EnabledChange == ev->type() && HideWhenDisabled) { // force setVisible() call - setVisible(isEnabled()); + // Calling setVisible() directly here doesn't work well when button is expected to be shown first time + QMetaObject::invokeMethod(this, "setVisible", Qt::QueuedConnection, Q_ARG(bool, isEnabled())); } - return Super::event(ev);; + return Super::event(ev); } }; @@ -232,6 +233,7 @@ void DockAreaTitleBarPrivate::createTabBar() _this->connect(TabBar, SIGNAL(tabMoved(int, int)), SLOT(markTabsMenuOutdated())); _this->connect(TabBar, SIGNAL(currentChanged(int)), SLOT(onCurrentTabChanged(int))); _this->connect(TabBar, SIGNAL(tabBarClicked(int)), SIGNAL(tabBarClicked(int))); + _this->connect(TabBar, SIGNAL(elidedChanged(bool)), SLOT(markTabsMenuOutdated())); TabBar->setContextMenuPolicy(Qt::CustomContextMenu); _this->connect(TabBar, SIGNAL(customContextMenuRequested(const QPoint&)), @@ -286,14 +288,31 @@ CDockAreaTabBar* CDockAreaTitleBar::tabBar() const return d->TabBar; } - //============================================================================ void CDockAreaTitleBar::markTabsMenuOutdated() { + if(DockAreaTitleBarPrivate::testConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility)) + { + bool hasElidedTabTitle = false; + for (int i = 0; i < d->TabBar->count(); ++i) + { + if (!d->TabBar->isTabOpen(i)) + { + continue; + } + CDockWidgetTab* Tab = d->TabBar->tab(i); + if(Tab->isTitleElided()) + { + hasElidedTabTitle = true; + break; + } + } + bool visible = (hasElidedTabTitle && (d->TabBar->count() > 1)); + QMetaObject::invokeMethod(d->TabsMenuButton, "setVisible", Qt::QueuedConnection, Q_ARG(bool, visible)); + } d->MenuOutdated = true; } - //============================================================================ void CDockAreaTitleBar::onTabsMenuAboutToShow() { diff --git a/src/DockManager.h b/src/DockManager.h index 475f072..68655d6 100644 --- a/src/DockManager.h +++ b/src/DockManager.h @@ -145,7 +145,7 @@ public: { ActiveTabHasCloseButton = 0x0001, //!< If this flag is set, the active tab in a tab area has a close button DockAreaHasCloseButton = 0x0002, //!< If the flag is set each dock area has a close button - DockAreaCloseButtonClosesTab = 0x0004,//!< If the flag is set, the dock area close button closes the active tab, if not set, it closes the complete cock area + DockAreaCloseButtonClosesTab = 0x0004,//!< If the flag is set, the dock area close button closes the active tab, if not set, it closes the complete dock area OpaqueSplitterResize = 0x0008, //!< See QSplitter::setOpaqueResize() documentation XmlAutoFormattingEnabled = 0x0010,//!< If enabled, the XML writer automatically adds line-breaks and indentation to empty sections between elements (ignorable whitespace). XmlCompressionEnabled = 0x0020,//!< If enabled, the XML output will be compressed and is not human readable anymore @@ -156,10 +156,11 @@ public: DragPreviewIsDynamic = 0x0400,///< If opaque undocking is disabled, this flag defines the behavior of the drag preview window, if this flag is enabled, the preview will be adjusted dynamically to the drop area DragPreviewShowsContentPixmap = 0x0800,///< If opaque undocking is disabled, the created drag preview window shows a copy of the content of the dock widget / dock are that is dragged DragPreviewHasWindowFrame = 0x1000,///< If opaque undocking is disabled, then this flag configures if the drag preview is frameless or looks like a real window - AlwaysShowTabs = 0x2000,///< If this option is enabled, the tab of a dock widget is always displayed - even if it is the only visible dock widget in a floating widget. - DockAreaHasUndockButton = 0x4000, //!< If the flag is set each dock area has an undock button - DockAreaHasTabsMenuButton = 0x8000, //!< If the flag is set each dock area has a tabs menu button - DockAreaHideDisabledButtons = 0x10000, //!< If the flag is set disabled dock area buttons will not appear on the tollbar at all (enabling them will bring them back) + AlwaysShowTabs = 0x2000,///< If this option is enabled, the tab of a dock widget is always displayed - even if it is the only visible dock widget in a floating widget. + DockAreaHasUndockButton = 0x4000, //!< If the flag is set each dock area has an undock button + DockAreaHasTabsMenuButton = 0x8000, //!< If the flag is set each dock area has a tabs menu button + DockAreaHideDisabledButtons = 0x10000, //!< If the flag is set disabled dock area buttons will not appear on the tollbar at all (enabling them will bring them back) + DockAreaDynamicTabsMenuButtonVisibility = 0x20000, //!< If the flag is set dock area will disable a tabs menu button when there is only one tab in the area DefaultDockAreaButtons = DockAreaHasCloseButton diff --git a/src/DockWidgetTab.cpp b/src/DockWidgetTab.cpp index 5dfe476..7da12c3 100644 --- a/src/DockWidgetTab.cpp +++ b/src/DockWidgetTab.cpp @@ -170,6 +170,8 @@ void DockWidgetTabPrivate::createLayout() TitleLabel->setText(DockWidget->windowTitle()); TitleLabel->setObjectName("dockWidgetTabLabel"); TitleLabel->setAlignment(Qt::AlignCenter); + _this->connect(TitleLabel, SIGNAL(elidedChanged(bool)), SIGNAL(elidedChanged(bool))); + CloseButton = createCloseButton(); CloseButton->setObjectName("tabCloseButton"); @@ -556,6 +558,11 @@ void CDockWidgetTab::setText(const QString& title) d->TitleLabel->setText(title); } +bool CDockWidgetTab::isTitleElided() const +{ + return d->TitleLabel->isElided(); +} + //============================================================================ diff --git a/src/DockWidgetTab.h b/src/DockWidgetTab.h index 934b8ed..7f35d1f 100644 --- a/src/DockWidgetTab.h +++ b/src/DockWidgetTab.h @@ -132,6 +132,11 @@ public: */ void setText(const QString& title); + /** + * Returns true if text is elided on the tab's title + */ + bool isTitleElided() const; + /** * This function returns true if the assigned dock widget is closable */ @@ -152,6 +157,7 @@ signals: void closeRequested(); void closeOtherTabsRequested(); void moved(const QPoint& GlobalPos); + void elidedChanged(bool elided); }; // class DockWidgetTab } // namespace ads diff --git a/src/ElidingLabel.cpp b/src/ElidingLabel.cpp index 18bb2b3..7f09d34 100644 --- a/src/ElidingLabel.cpp +++ b/src/ElidingLabel.cpp @@ -41,6 +41,7 @@ struct ElidingLabelPrivate CElidingLabel* _this; Qt::TextElideMode ElideMode = Qt::ElideNone; QString Text; + bool IsElided = false; ElidingLabelPrivate(CElidingLabel* _public) : _this(_public) {} @@ -69,6 +70,12 @@ void ElidingLabelPrivate::elideText(int Width) { str = Text.at(0); } + bool WasElided = IsElided; + IsElided = str != Text; + if(IsElided != WasElided) + { + emit _this->elidedChanged(IsElided); + } _this->QLabel::setText(str); } @@ -113,6 +120,12 @@ void CElidingLabel::setElideMode(Qt::TextElideMode mode) d->elideText(size().width()); } +//============================================================================ +bool CElidingLabel::isElided() const +{ + return d->IsElided; +} + //============================================================================ void CElidingLabel::mouseReleaseEvent(QMouseEvent* event) diff --git a/src/ElidingLabel.h b/src/ElidingLabel.h index b678395..89a31e7 100644 --- a/src/ElidingLabel.h +++ b/src/ElidingLabel.h @@ -73,6 +73,10 @@ public: */ void setElideMode(Qt::TextElideMode mode); + /** + * This function indicates whether the text on this label is currently elided + */ + bool isElided() const; public: // reimplements QLabel ---------------------------------------------- virtual QSize minimumSizeHint() const override; @@ -91,6 +95,11 @@ signals: * This signal is emitted if the user does a double click on the label */ void doubleClicked(); + + /** + * This signal is emitted when isElided() state of this label is changed + */ + void elidedChanged(bool elided); }; //class CElidingLabel } // namespace QtLabb