|
29 | 29 | #include "ScintillaNext.h" |
30 | 30 |
|
31 | 31 | #include <QEvent> |
| 32 | +#include <QFontMetrics> |
32 | 33 | #include <QTimer> |
33 | 34 | #include <QUuid> |
34 | 35 |
|
35 | 36 |
|
| 37 | +namespace { |
| 38 | + |
| 39 | +// Upper bound for a center tab's width. File and preview tabs (browser, embed, |
| 40 | +// file preview) can carry long titles; left uncapped a single tab expands to |
| 41 | +// its full text and monopolises the tab bar. Derived from the tab's own font so |
| 42 | +// it scales with the UI font / DPI rather than a hard-coded pixel value: ~28 |
| 43 | +// average glyph widths plus fixed slack for the icon, close button and layout |
| 44 | +// margins. Cheap — one QFontMetrics query per tab creation, never on a hot path. |
| 45 | +int centerTabMaxWidth(const QWidget *tab) |
| 46 | +{ |
| 47 | + const QFontMetrics fm(tab->font()); |
| 48 | + constexpr int kTitleChars = 28; |
| 49 | + constexpr int kChromeSlack = 56; // icon + close button + margins |
| 50 | + return fm.averageCharWidth() * kTitleChars + kChromeSlack; |
| 51 | +} |
| 52 | + |
| 53 | +} // namespace |
| 54 | + |
| 55 | + |
36 | 56 | class DockedEditorComponentsFactory : public ads::CDockComponentsFactory |
37 | 57 | { |
38 | 58 | public: |
@@ -260,8 +280,10 @@ void DockedEditor::addEditor(ScintillaNext *editor) |
260 | 280 | // Create the dock widget for the editor |
261 | 281 | ads::CDockWidget *dockWidget = dockManager->createDockWidget(editor->getName()); |
262 | 282 |
|
263 | | - // Disable elide, elided file names not readable when lots of files opened |
264 | | - dockWidget->tabWidget()->setElideMode(Qt::ElideNone); |
| 283 | + // Keep long file names readable via the tooltip without letting one tab |
| 284 | + // consume the entire tab bar. |
| 285 | + dockWidget->tabWidget()->setElideMode(Qt::ElideRight); |
| 286 | + dockWidget->tabWidget()->setMaximumWidth(centerTabMaxWidth(dockWidget->tabWidget())); |
265 | 287 |
|
266 | 288 | // We need a unique object name. Can't use the name or file path so use a uuid |
267 | 289 | dockWidget->setObjectName(QUuid::createUuid().toString()); |
@@ -400,9 +422,17 @@ ads::CDockWidget *DockedEditor::addPreviewTab(QWidget *widget, const QString &ti |
400 | 422 | dockWidget->setFeature(ads::CDockWidget::DockWidgetFeature::DockWidgetDeleteOnClose, true); |
401 | 423 | dockWidget->setFeature(ads::CDockWidget::DockWidgetFeature::DockWidgetFloatable, false); |
402 | 424 |
|
403 | | - dockWidget->tabWidget()->setElideMode(Qt::ElideNone); |
| 425 | + // Preview tabs (browser/embed/file-preview) can carry long, dynamic titles |
| 426 | + // such as web page <title>s. Cap the tab width and elide from the right so a |
| 427 | + // single tab can't monopolise the tab bar; the full title stays reachable as |
| 428 | + // a hover tooltip, kept in sync with subsequent dock-title changes. |
| 429 | + auto *tab = dockWidget->tabWidget(); |
| 430 | + tab->setElideMode(Qt::ElideRight); |
| 431 | + tab->setMaximumWidth(centerTabMaxWidth(tab)); |
| 432 | + tab->setToolTip(title); |
| 433 | + connect(dockWidget, &QWidget::windowTitleChanged, tab, &QWidget::setToolTip); |
404 | 434 | if (!icon.isNull()) |
405 | | - dockWidget->tabWidget()->setIcon(icon); |
| 435 | + tab->setIcon(icon); |
406 | 436 |
|
407 | 437 | latestDockArea = dockManager->addDockWidget(ads::CenterDockWidgetArea, dockWidget, currentDockArea()); |
408 | 438 |
|
|
0 commit comments