Skip to content

Commit 474dd13

Browse files
authored
Disable tabs menu button when only single tab exists in a Dock area (#111)
1 parent 72496eb commit 474dd13

File tree

9 files changed

+73
-11
lines changed

9 files changed

+73
-11
lines changed

demo/MainWindow.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,6 @@ struct MainWindowPrivate
283283
void restorePerspectives();
284284
};
285285

286-
287286
//============================================================================
288287
void MainWindowPrivate::createContent()
289288
{
@@ -453,6 +452,9 @@ CMainWindow::CMainWindow(QWidget *parent) :
453452
// uncomment the following line if you don't want disabled buttons to appear on DockArea's title bar
454453
//CDockManager::setConfigFlag(CDockManager::DockAreaHideDisabledButtons, true);
455454

455+
// 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
456+
//CDockManager::setConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility, true);
457+
456458
// Now create the dock manager and its content
457459
d->DockManager = new CDockManager(this);
458460

src/DockAreaTabBar.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ void CDockAreaTabBar::insertTab(int Index, CDockWidgetTab* Tab)
343343
connect(Tab, SIGNAL(closeRequested()), this, SLOT(onTabCloseRequested()));
344344
connect(Tab, SIGNAL(closeOtherTabsRequested()), this, SLOT(onCloseOtherTabsRequested()));
345345
connect(Tab, SIGNAL(moved(const QPoint&)), this, SLOT(onTabWidgetMoved(const QPoint&)));
346+
connect(Tab, SIGNAL(elidedChanged(bool)), this, SIGNAL(elidedChanged(bool)));
346347
Tab->installEventFilter(this);
347348
emit tabInserted(Index);
348349
if (Index <= d->CurrentIndex || d->CurrentIndex == -1)
@@ -562,7 +563,6 @@ void CDockAreaTabBar::onTabWidgetMoved(const QPoint& GlobalPos)
562563
}
563564
}
564565

565-
566566
//===========================================================================
567567
void CDockAreaTabBar::closeTab(int Index)
568568
{

src/DockAreaTabBar.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,11 @@ public slots:
239239
* This signal is emitted if a tab has been inserted
240240
*/
241241
void tabInserted(int index);
242+
243+
/**
244+
* This signal is emitted when a tab title elide state has been changed
245+
*/
246+
void elidedChanged(bool elided);
242247
}; // class CDockAreaTabBar
243248
} // namespace ads
244249
//-----------------------------------------------------------------------------

src/DockAreaTitleBar.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,11 @@ class CTitleBarButton : public tTitleBarButton
151151
if(QEvent::EnabledChange == ev->type() && HideWhenDisabled)
152152
{
153153
// force setVisible() call
154-
setVisible(isEnabled());
154+
// Calling setVisible() directly here doesn't work well when button is expected to be shown first time
155+
QMetaObject::invokeMethod(this, "setVisible", Qt::QueuedConnection, Q_ARG(bool, isEnabled()));
155156
}
156157

157-
return Super::event(ev);;
158+
return Super::event(ev);
158159
}
159160
};
160161

@@ -232,6 +233,7 @@ void DockAreaTitleBarPrivate::createTabBar()
232233
_this->connect(TabBar, SIGNAL(tabMoved(int, int)), SLOT(markTabsMenuOutdated()));
233234
_this->connect(TabBar, SIGNAL(currentChanged(int)), SLOT(onCurrentTabChanged(int)));
234235
_this->connect(TabBar, SIGNAL(tabBarClicked(int)), SIGNAL(tabBarClicked(int)));
236+
_this->connect(TabBar, SIGNAL(elidedChanged(bool)), SLOT(markTabsMenuOutdated()));
235237

236238
TabBar->setContextMenuPolicy(Qt::CustomContextMenu);
237239
_this->connect(TabBar, SIGNAL(customContextMenuRequested(const QPoint&)),
@@ -286,14 +288,31 @@ CDockAreaTabBar* CDockAreaTitleBar::tabBar() const
286288
return d->TabBar;
287289
}
288290

289-
290291
//============================================================================
291292
void CDockAreaTitleBar::markTabsMenuOutdated()
292293
{
294+
if(DockAreaTitleBarPrivate::testConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility))
295+
{
296+
bool hasElidedTabTitle = false;
297+
for (int i = 0; i < d->TabBar->count(); ++i)
298+
{
299+
if (!d->TabBar->isTabOpen(i))
300+
{
301+
continue;
302+
}
303+
CDockWidgetTab* Tab = d->TabBar->tab(i);
304+
if(Tab->isTitleElided())
305+
{
306+
hasElidedTabTitle = true;
307+
break;
308+
}
309+
}
310+
bool visible = (hasElidedTabTitle && (d->TabBar->count() > 1));
311+
QMetaObject::invokeMethod(d->TabsMenuButton, "setVisible", Qt::QueuedConnection, Q_ARG(bool, visible));
312+
}
293313
d->MenuOutdated = true;
294314
}
295315

296-
297316
//============================================================================
298317
void CDockAreaTitleBar::onTabsMenuAboutToShow()
299318
{

src/DockManager.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ class ADS_EXPORT CDockManager : public CDockContainerWidget
145145
{
146146
ActiveTabHasCloseButton = 0x0001, //!< If this flag is set, the active tab in a tab area has a close button
147147
DockAreaHasCloseButton = 0x0002, //!< If the flag is set each dock area has a close button
148-
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
148+
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
149149
OpaqueSplitterResize = 0x0008, //!< See QSplitter::setOpaqueResize() documentation
150150
XmlAutoFormattingEnabled = 0x0010,//!< If enabled, the XML writer automatically adds line-breaks and indentation to empty sections between elements (ignorable whitespace).
151151
XmlCompressionEnabled = 0x0020,//!< If enabled, the XML output will be compressed and is not human readable anymore
@@ -156,10 +156,11 @@ class ADS_EXPORT CDockManager : public CDockContainerWidget
156156
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
157157
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
158158
DragPreviewHasWindowFrame = 0x1000,///< If opaque undocking is disabled, then this flag configures if the drag preview is frameless or looks like a real window
159-
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.
160-
DockAreaHasUndockButton = 0x4000, //!< If the flag is set each dock area has an undock button
161-
DockAreaHasTabsMenuButton = 0x8000, //!< If the flag is set each dock area has a tabs menu button
162-
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)
159+
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.
160+
DockAreaHasUndockButton = 0x4000, //!< If the flag is set each dock area has an undock button
161+
DockAreaHasTabsMenuButton = 0x8000, //!< If the flag is set each dock area has a tabs menu button
162+
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)
163+
DockAreaDynamicTabsMenuButtonVisibility = 0x20000, //!< If the flag is set dock area will disable a tabs menu button when there is only one tab in the area
163164

164165

165166
DefaultDockAreaButtons = DockAreaHasCloseButton

src/DockWidgetTab.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ void DockWidgetTabPrivate::createLayout()
170170
TitleLabel->setText(DockWidget->windowTitle());
171171
TitleLabel->setObjectName("dockWidgetTabLabel");
172172
TitleLabel->setAlignment(Qt::AlignCenter);
173+
_this->connect(TitleLabel, SIGNAL(elidedChanged(bool)), SIGNAL(elidedChanged(bool)));
174+
173175

174176
CloseButton = createCloseButton();
175177
CloseButton->setObjectName("tabCloseButton");
@@ -556,6 +558,11 @@ void CDockWidgetTab::setText(const QString& title)
556558
d->TitleLabel->setText(title);
557559
}
558560

561+
bool CDockWidgetTab::isTitleElided() const
562+
{
563+
return d->TitleLabel->isElided();
564+
}
565+
559566

560567

561568
//============================================================================

src/DockWidgetTab.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ private slots:
132132
*/
133133
void setText(const QString& title);
134134

135+
/**
136+
* Returns true if text is elided on the tab's title
137+
*/
138+
bool isTitleElided() const;
139+
135140
/**
136141
* This function returns true if the assigned dock widget is closable
137142
*/
@@ -152,6 +157,7 @@ public slots:
152157
void closeRequested();
153158
void closeOtherTabsRequested();
154159
void moved(const QPoint& GlobalPos);
160+
void elidedChanged(bool elided);
155161
}; // class DockWidgetTab
156162
}
157163
// namespace ads

src/ElidingLabel.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ struct ElidingLabelPrivate
4141
CElidingLabel* _this;
4242
Qt::TextElideMode ElideMode = Qt::ElideNone;
4343
QString Text;
44+
bool IsElided = false;
4445

4546
ElidingLabelPrivate(CElidingLabel* _public) : _this(_public) {}
4647

@@ -69,6 +70,12 @@ void ElidingLabelPrivate::elideText(int Width)
6970
{
7071
str = Text.at(0);
7172
}
73+
bool WasElided = IsElided;
74+
IsElided = str != Text;
75+
if(IsElided != WasElided)
76+
{
77+
emit _this->elidedChanged(IsElided);
78+
}
7279
_this->QLabel::setText(str);
7380
}
7481

@@ -113,6 +120,12 @@ void CElidingLabel::setElideMode(Qt::TextElideMode mode)
113120
d->elideText(size().width());
114121
}
115122

123+
//============================================================================
124+
bool CElidingLabel::isElided() const
125+
{
126+
return d->IsElided;
127+
}
128+
116129

117130
//============================================================================
118131
void CElidingLabel::mouseReleaseEvent(QMouseEvent* event)

src/ElidingLabel.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ class ADS_EXPORT CElidingLabel : public QLabel
7373
*/
7474
void setElideMode(Qt::TextElideMode mode);
7575

76+
/**
77+
* This function indicates whether the text on this label is currently elided
78+
*/
79+
bool isElided() const;
7680

7781
public: // reimplements QLabel ----------------------------------------------
7882
virtual QSize minimumSizeHint() const override;
@@ -91,6 +95,11 @@ class ADS_EXPORT CElidingLabel : public QLabel
9195
* This signal is emitted if the user does a double click on the label
9296
*/
9397
void doubleClicked();
98+
99+
/**
100+
* This signal is emitted when isElided() state of this label is changed
101+
*/
102+
void elidedChanged(bool elided);
94103
}; //class CElidingLabel
95104

96105
} // namespace QtLabb

0 commit comments

Comments
 (0)